[FFmpeg-devel] [PATCH v6 3/3] hevc_mp4toannexb: Parse extradata directly from HVCC format

Andriy Gelman andriy.gelman at gmail.com
Wed Oct 16 05:50:41 EEST 2019


From: Andriy Gelman <andriy.gelman at gmail.com>

Since the original extradata is in HVCC format, there is no need to
segment the output extradata into nal units.
---
 libavcodec/hevc_mp4toannexb_bsf.c | 66 ++++++++++++++++---------------
 1 file changed, 34 insertions(+), 32 deletions(-)

diff --git a/libavcodec/hevc_mp4toannexb_bsf.c b/libavcodec/hevc_mp4toannexb_bsf.c
index 1ca5f13807..938e01171d 100644
--- a/libavcodec/hevc_mp4toannexb_bsf.c
+++ b/libavcodec/hevc_mp4toannexb_bsf.c
@@ -243,12 +243,17 @@ static int update_paramset(AVBSFContext *ctx, H2645NAL *nal)
 
 static int hevc_extradata_to_annexb(AVBSFContext *ctx)
 {
+    HEVCBSFContext *s = ctx->priv_data;
     GetByteContext gb;
     int length_size, num_arrays, i, j;
     int ret = 0;
 
     uint8_t *new_extradata = NULL;
     size_t   new_extradata_size = 0;
+    size_t   start, end;
+
+    H2645Packet pkt;
+    memset(&pkt, 0, sizeof(H2645Packet)); /* in case goto fail is called before pkt is initialized*/
 
     bytestream2_init(&gb, ctx->par_in->extradata, ctx->par_in->extradata_size);
 
@@ -268,6 +273,7 @@ static int hevc_extradata_to_annexb(AVBSFContext *ctx)
             goto fail;
         }
 
+        start = bytestream2_tell(&gb);
         for (j = 0; j < cnt; j++) {
             int nalu_len = bytestream2_get_be16(&gb);
 
@@ -284,6 +290,32 @@ static int hevc_extradata_to_annexb(AVBSFContext *ctx)
             new_extradata_size += 4 + nalu_len;
             memset(new_extradata + new_extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
         }
+        end = bytestream2_tell(&gb);
+
+        /* split extradata into nalu packets*/
+        ret = ff_h2645_packet_split(&pkt, ctx->par_in->extradata + start,
+                                    end - start, ctx, 1, 2, AV_CODEC_ID_HEVC, 1, 0);
+        if (ret < 0)
+            goto fail;
+
+        /* parse the segmented nals*/
+        for (j = 0; j < pkt.nb_nals; j++) {
+            H2645NAL *nal = &pkt.nals[j];
+
+            if (IS_PARAMSET(nal)) {
+                ret = update_paramset(ctx, nal);
+                if (ret < 0)
+                    goto fail;
+                continue;
+            }
+
+            if (nal->type == HEVC_NAL_SEI_PREFIX || nal->type == HEVC_NAL_SEI_SUFFIX) {
+                ret = append_sei_annexb(&s->ps.sei, nal);
+                if (ret < 0)
+                    goto fail;
+            }
+        }
+        ff_h2645_packet_uninit(&pkt);
     }
 
     av_freep(&ctx->par_out->extradata);
@@ -295,6 +327,7 @@ static int hevc_extradata_to_annexb(AVBSFContext *ctx)
 
     return length_size;
 fail:
+    ff_h2645_packet_uninit(&pkt);
     av_freep(&new_extradata);
     return ret;
 }
@@ -302,7 +335,6 @@ fail:
 static int hevc_mp4toannexb_init(AVBSFContext *ctx)
 {
     HEVCBSFContext *s = ctx->priv_data;
-    H2645Packet pkt;
     int ret;
 
     if (ctx->par_in->extradata_size < MIN_HEVCC_LENGTH ||
@@ -310,44 +342,14 @@ static int hevc_mp4toannexb_init(AVBSFContext *ctx)
         AV_RB32(ctx->par_in->extradata) == 1) {
         av_log(ctx, AV_LOG_VERBOSE,
                "The input looks like it is Annex B already\n");
-        return 0;
     } else {
         ret = hevc_extradata_to_annexb(ctx);
         if (ret < 0)
             return ret;
         s->length_size      = ret;
         s->extradata_parsed = 1;
-
-        memset(&pkt, 0, sizeof(H2645Packet));
-        ret = ff_h2645_packet_split(&pkt, ctx->par_out->extradata, ctx->par_out->extradata_size,
-                                     ctx, 0, 0, AV_CODEC_ID_HEVC, 1, 0);
-        if (ret < 0)
-            goto done;
-
-        for (int i = 0; i < pkt.nb_nals; ++i) {
-            H2645NAL *nal = &pkt.nals[i];
-
-            /*current segmentation algorithm includes next 0x00 from next nal unit*/
-            if (nal->raw_data[nal->raw_size - 1] == 0x00)
-                nal->raw_size--;
-
-            if (IS_PARAMSET(nal)) {
-                ret = update_paramset(ctx, nal);
-                if (ret < 0)
-                    goto done;
-                continue;
-            }
-
-            if (nal->type == HEVC_NAL_SEI_PREFIX || nal->type == HEVC_NAL_SEI_SUFFIX) {
-                ret = append_sei_annexb(&s->ps.sei, nal);
-                if (ret < 0)
-                    goto done;
-            }
-        }
     }
-done:
-    ff_h2645_packet_uninit(&pkt);
-    return ret;
+    return 0;
 }
 
 static void ps_uninit(ParamSets *ps)
-- 
2.23.0



More information about the ffmpeg-devel mailing list