On 1/11/2021 1:33 PM, Nuo Mi wrote:
---
  configure                             |    2 +
  libavcodec/Makefile                   |    1 +
  libavcodec/cbs.c                      |    6 +
  libavcodec/cbs_h2645.c                |  374 ++++
  libavcodec/cbs_h266.h                 |  758 +++++++
  libavcodec/cbs_h266_syntax_template.c | 2774 +++++++++++++++++++++++++
  libavcodec/cbs_internal.h             |    3 +-
  7 files changed, 3917 insertions(+), 1 deletion(-)
  create mode 100644 libavcodec/cbs_h266.h
  create mode 100644 libavcodec/cbs_h266_syntax_template.c


[...]

+static int cbs_h266_replace_ph(CodedBitstreamContext *ctx,
+                               CodedBitstreamUnit *unit)
+{
+    CodedBitstreamH266Context *priv = ctx->priv_data;
+    int err;
+    err = ff_cbs_make_unit_refcounted(ctx, unit);
+    if (err < 0)
+        return err;
+    av_buffer_unref(&priv->ph_ref);
+    av_assert0(unit->content_ref);
+    priv->ph_ref = av_buffer_ref(unit->content_ref);
+    if (!priv->ph_ref)
+        return AVERROR(ENOMEM);
+    priv->ph = (H266RawPH *)priv->ph_ref->data;

Make this function take a pointer to H266RawPH as argument, and set it here.
See below.

+    return 0;
+}
+
+static int cbs_h266_read_nal_unit(CodedBitstreamContext *ctx,
+                                  CodedBitstreamUnit *unit)
+{
+    GetBitContext gbc;
+    int err;
+
+    err = init_get_bits8(&gbc, unit->data, unit->data_size);
+    if (err < 0)
+        return err;
+
+    err = ff_cbs_alloc_unit_content2(ctx, unit);
+    if (err < 0)
+        return err;
+
+    switch (unit->type) {
+    case VVC_SPS_NUT:
+        {
+            H266RawSPS *sps = unit->content;
+
+            err = cbs_h266_read_sps(ctx, &gbc, sps);
+            if (err < 0)
+                return err;
+
+            err = cbs_h266_replace_sps(ctx, unit);
+            if (err < 0)
+                return err;
+        }
+        break;
+
+    case VVC_PPS_NUT:
+        {
+            H266RawPPS *pps = unit->content;
+
+            err = cbs_h266_read_pps(ctx, &gbc, pps);
+            if (err < 0)
+                return err;
+
+            err = cbs_h266_replace_pps(ctx, unit);
+            if (err < 0)
+                return err;
+        }
+        break;
+
+    case VVC_PH_NUT:
+        {
+            H266RawPH *ph = unit->content;
+            err = cbs_h266_read_ph(ctx, &gbc, ph);
+            if (err < 0)
+                return err;
+
+            err = cbs_h266_replace_ph(ctx, unit);

Pass ph as mentioned above.

+            if (err < 0)
+                return err;
+        }
+        break;
+
+    case VVC_TRAIL_NUT:
+    case VVC_STSA_NUT:
+    case VVC_RADL_NUT:
+    case VVC_RASL_NUT:
+    case VVC_IDR_W_RADL:
+    case VVC_IDR_N_LP:
+    case VVC_CRA_NUT:
+    case VVC_GDR_NUT:
+        {
+            H266RawSlice *slice = unit->content;
+            int pos, len;
+
+            err = cbs_h266_read_slice_header(ctx, &gbc, &slice->header);
+            if (err < 0)
+                return err;

Add a call to cbs_h266_replace_ph() here when slice->header.sh_picture_header_in_slice_header_flag is true, and pass a pointer to slice->header.sh_picture_header to it.

Do the same for the writing functions.

[...]

+static int FUNC(slice_header)(CodedBitstreamContext *ctx, RWContext *rw,
+                              H266RawSliceHeader *current)
+{
+    CodedBitstreamH266Context *h266 = ctx->priv_data;
+    const H266RawSPS *sps;
+    const H266RawPPS *pps;
+    const H266RawPH  *ph;
+    const H266RefPicLists *ref_pic_lists;
+    int      err, i;
+    uint8_t  nal_unit_type, qp_bd_offset;
+    uint16_t curr_subpic_idx;
+    uint16_t num_slices_in_subpic;
+
+    HEADER("Slice Header");
+
+    CHECK(FUNC(nal_unit_header)(ctx, rw, &current->nal_unit_header, -1));
+
+    flag(sh_picture_header_in_slice_header_flag);
+    if (current->sh_picture_header_in_slice_header_flag){
+        CHECK(FUNC(picture_header)(ctx, rw, &current->sh_picture_header));
+        if (!h266->ph_ref) {
+            h266->ph_ref = av_buffer_allocz(sizeof(H266RawPH));
+            if (!h266->ph_ref)
+                return AVERROR(ENOMEM);
+        }
+        h266->ph = (H266RawPH*)h266->ph_ref->data;
+        memcpy(h266->ph, &current->sh_picture_header, sizeof(H266RawPH));

With the above, you can remove all this and simply set ph to &current->sh_picture_header when current->sh_picture_header_in_slice_header_flag is true, or to h266->ph otherwise.

This saves an unnecessary buffer alloc per slice header that includes a picture header. The buffer reference most assuredly already exists, and you can reuse it.

+    }
+    sps = h266->active_sps;
+    pps = h266->active_pps;
+    ph  = h266->ph;
+
+    if (!ph) {
+        av_log(ctx->log_ctx, AV_LOG_ERROR, "Picture header not available.\n");
+        return AVERROR_INVALIDDATA;
+    }
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Reply via email to