[FFmpeg-devel,30/31] h264_metadata: Update AVCodecParameters during init

Submitted by Andreas Rheinhardt on July 9, 2019, 1:10 a.m.

Details

Message ID 20190709011048.29601-5-andreas.rheinhardt@gmail.com
State New
Headers show

Commit Message

Andreas Rheinhardt July 9, 2019, 1:10 a.m.
This commit makes h264_metadata update the AVCodecParameters during init
to align them with the changes at the bitstream level.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
---
 libavcodec/h264_metadata_bsf.c | 37 +++++++++++++++++++++++++++++-----
 1 file changed, 32 insertions(+), 5 deletions(-)

Patch hide | download patch | download mbox

diff --git a/libavcodec/h264_metadata_bsf.c b/libavcodec/h264_metadata_bsf.c
index cbf2025fd4..1dfcee6a31 100644
--- a/libavcodec/h264_metadata_bsf.c
+++ b/libavcodec/h264_metadata_bsf.c
@@ -85,8 +85,8 @@  typedef struct H264MetadataContext {
 } 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 +201,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 +268,9 @@  static int h264_metadata_update_sps(AVBSFContext *bsf,
         } else {
             sps->level_idc = level_idc;
         }
+
+        if (level)
+            *level = sps->level_idc;
     }
 
     if (need_vui)
@@ -347,7 +358,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;
@@ -571,7 +583,9 @@  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;
+    int chroma_location = ctx->chroma_sample_loc_type;
+    int color_range     = ctx->video_full_range_flag;
 
     err = ff_cbs_init(&ctx->cbc, AV_CODEC_ID_H264, bsf);
     if (err < 0)
@@ -586,7 +600,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;
             }
@@ -599,6 +614,18 @@  static int h264_metadata_init(AVBSFContext *bsf)
         }
     }
 
+    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);
+
     err = 0;
 fail:
     ff_cbs_fragment_reset(ctx->cbc, au);