[FFmpeg-devel] [PATCH 30/31] h264_metadata: Update AVCodecParameters

Andreas Rheinhardt andreas.rheinhardt at gmail.com
Thu Jun 20 02:45:20 EEST 2019


This commit adds an option to also update the AVCodecParameters to align
them with the changes at the bitstream level. It is on by default.

Given the importance of correct frame dimensions they are updated
even when the new option is disabled.

The commit also adds documentation for the new option.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt at gmail.com>
---
 doc/bitstream_filters.texi     |  8 ++++++
 libavcodec/h264_metadata_bsf.c | 48 ++++++++++++++++++++++++++++++----
 2 files changed, 51 insertions(+), 5 deletions(-)

diff --git a/doc/bitstream_filters.texi b/doc/bitstream_filters.texi
index 80be525e0f..8030be233c 100644
--- a/doc/bitstream_filters.texi
+++ b/doc/bitstream_filters.texi
@@ -285,6 +285,14 @@ level_idc value (for example, @samp{42}), or the special name @samp{auto}
 indicating that the filter should attempt to guess the level from the
 input stream properties.
 
+ at item full_update
+If this is set, an effort is made to update the AVCodecParameters in addition
+to the bitstream. If unset, muxers might add header information based upon
+the old AVCodecParameters that contradicts and potentially precedes
+the changes made at the bitstream level. On by default.
+
+The frame dimensions are always updated and not affected by this option.
+
 @end table
 
 @section h264_mp4toannexb
diff --git a/libavcodec/h264_metadata_bsf.c b/libavcodec/h264_metadata_bsf.c
index 40886bdde0..0a993c9d99 100644
--- a/libavcodec/h264_metadata_bsf.c
+++ b/libavcodec/h264_metadata_bsf.c
@@ -82,11 +82,13 @@ typedef struct H264MetadataContext {
     int flip;
 
     int level;
+
+    int full_update;
 } H264MetadataContext;
 
 
-static int h264_metadata_update_sps(AVBSFContext *bsf,
-                                    H264RawSPS *sps)
+static int h264_metadata_update_sps(AVBSFContext *bsf, H264RawSPS *sps,
+                                    int *width, int *height, int *level)
 {
     H264MetadataContext *ctx = bsf->priv_data;
     int need_vui = 0;
@@ -201,6 +203,14 @@ static int h264_metadata_update_sps(AVBSFContext *bsf,
     CROP(bottom, crop_unit_y);
 #undef CROP
 
+    if (width && height) {
+        *width  = 16 * (sps->pic_width_in_mbs_minus1 + 1) - crop_unit_x *
+                  (sps->frame_crop_left_offset + sps->frame_crop_right_offset);
+        *height = 16 * (sps->pic_height_in_map_units_minus1 + 1)
+                     * (2 - sps->frame_mbs_only_flag)     - crop_unit_y *
+                  (sps->frame_crop_top_offset + sps->frame_crop_bottom_offset);
+    }
+
     if (ctx->level != LEVEL_UNSET) {
         int level_idc;
 
@@ -260,6 +270,9 @@ static int h264_metadata_update_sps(AVBSFContext *bsf,
         } else {
             sps->level_idc = level_idc;
         }
+
+        if (level)
+            *level = sps->level_idc;
     }
 
     if (need_vui)
@@ -349,7 +362,8 @@ static int h264_metadata_filter(AVBSFContext *bsf, AVPacket *pkt)
     has_sps = 0;
     for (i = 0; i < au->nb_units; i++) {
         if (au->units[i].type == H264_NAL_SPS) {
-            err = h264_metadata_update_sps(bsf, au->units[i].content);
+            err = h264_metadata_update_sps(bsf, au->units[i].content,
+                                           NULL, NULL, NULL);
             if (err < 0)
                 goto fail;
             has_sps = 1;
@@ -575,7 +589,7 @@ static int h264_metadata_init(AVBSFContext *bsf)
 {
     H264MetadataContext *ctx = bsf->priv_data;
     CodedBitstreamFragment *au = &ctx->access_unit;
-    int err, i;
+    int err, i, width = -1, height = -1, level = -1;
 
     err = ff_cbs_init(&ctx->cbc, AV_CODEC_ID_H264, bsf);
     if (err < 0)
@@ -590,7 +604,8 @@ static int h264_metadata_init(AVBSFContext *bsf)
 
         for (i = 0; i < au->nb_units; i++) {
             if (au->units[i].type == H264_NAL_SPS) {
-                err = h264_metadata_update_sps(bsf, au->units[i].content);
+                err = h264_metadata_update_sps(bsf, au->units[i].content,
+                                               &width, &height, &level);
                 if (err < 0)
                     goto fail;
             }
@@ -603,6 +618,26 @@ static int h264_metadata_init(AVBSFContext *bsf)
         }
     }
 
+    if (ctx->full_update) {
+        int color_range     = ctx->video_full_range_flag;
+        int chroma_location = ctx->chroma_sample_loc_type;
+
+        if (color_range >= 0)
+            color_range++;
+        if (chroma_location >= 0)
+            chroma_location++;
+
+        ff_cbs_update_video_parameters(ctx->cbc, bsf->par_out, -1, level,
+                                       width, height, -1, color_range,
+                                       ctx->colour_primaries,
+                                       ctx->transfer_characteristics,
+                                       ctx->matrix_coefficients,
+                                       chroma_location, -1);
+    } else
+        ff_cbs_update_video_parameters(ctx->cbc, bsf->par_out, -1,
+                                       -1, width, height, -1, -1,
+                                       -1, -1, -1, -1, -1);
+
     err = 0;
 fail:
     ff_cbs_fragment_reset(ctx->cbc, au);
@@ -735,6 +770,9 @@ static const AVOption h264_metadata_options[] = {
     { LEVEL("6.2", 62) },
 #undef LEVEL
 
+    { "full_update", "Update not only bitstream, but also AVCodecParameters",
+        OFFSET(full_update), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, FLAGS},
+
     { NULL }
 };
 
-- 
2.21.0



More information about the ffmpeg-devel mailing list