[FFmpeg-devel] [PATCH 3/3] avcodec/h265_metadata: filter parameter sets in packet side data

James Almer jamrial at gmail.com
Wed Apr 22 18:09:47 EEST 2020


Extradata included in packet side data is meant to replace the codec context
extradata. So when muxing for example to MP4 without this change and if
extradata is present in a packet side data, the result will be that the
parameter sets present in keyframes will be filtered, but the parameter sets
ultimately included in the hvcC box will not.

Signed-off-by: James Almer <jamrial at gmail.com>
---
 libavcodec/h265_metadata_bsf.c | 58 ++++++++++++++++++++++++++++++++++
 1 file changed, 58 insertions(+)

diff --git a/libavcodec/h265_metadata_bsf.c b/libavcodec/h265_metadata_bsf.c
index 730f7ac28f..135ef05509 100644
--- a/libavcodec/h265_metadata_bsf.c
+++ b/libavcodec/h265_metadata_bsf.c
@@ -336,6 +336,60 @@ static int h265_metadata_update_sps(AVBSFContext *bsf,
     return 0;
 }
 
+static int h265_metadata_update_side_data(AVBSFContext *bsf, AVPacket *pkt)
+{
+    H265MetadataContext *ctx = bsf->priv_data;
+    CodedBitstreamFragment *au = &ctx->access_unit;
+    uint8_t *side_data;
+    int side_data_size;
+    int err, i;
+
+    side_data = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA,
+                                        &side_data_size);
+    if (!side_data_size)
+        return 0;
+
+    err = ff_cbs_read(ctx->cbc, au, side_data, side_data_size);
+    if (err < 0) {
+        av_log(bsf, AV_LOG_ERROR, "Failed to read extradata from packet side data.\n");
+        goto fail;
+    }
+
+    if (ctx->level == LEVEL_AUTO && !ctx->level_guess)
+        h265_metadata_guess_level(bsf, au);
+
+    for (i = 0; i < au->nb_units; i++) {
+        if (au->units[i].type == HEVC_NAL_VPS) {
+            err = h265_metadata_update_vps(bsf, au->units[i].content);
+            if (err < 0)
+                goto fail;
+        }
+        if (au->units[i].type == HEVC_NAL_SPS) {
+            err = h265_metadata_update_sps(bsf, au->units[i].content);
+            if (err < 0)
+                goto fail;
+        }
+    }
+
+    err = ff_cbs_write_fragment_data(ctx->cbc, au);
+    if (err < 0) {
+        av_log(bsf, AV_LOG_ERROR, "Failed to write extradata into packet side data.\n");
+        goto fail;
+    }
+
+    side_data = av_packet_new_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, au->data_size);
+    if (!side_data) {
+        err = AVERROR(ENOMEM);
+        goto fail;
+    }
+    memcpy(side_data, au->data, au->data_size);
+
+    err = 0;
+fail:
+    ff_cbs_fragment_reset(ctx->cbc, au);
+    return err;
+}
+
 static int h265_metadata_filter(AVBSFContext *bsf, AVPacket *pkt)
 {
     H265MetadataContext *ctx = bsf->priv_data;
@@ -346,6 +400,10 @@ static int h265_metadata_filter(AVBSFContext *bsf, AVPacket *pkt)
     if (err < 0)
         return err;
 
+    err = h265_metadata_update_side_data(bsf, pkt);
+    if (err < 0)
+        goto fail;
+
     err = ff_cbs_read_packet(ctx->cbc, au, pkt);
     if (err < 0) {
         av_log(bsf, AV_LOG_ERROR, "Failed to read packet.\n");
-- 
2.26.0



More information about the ffmpeg-devel mailing list