summaryrefslogtreecommitdiff
path: root/libavcodec
diff options
context:
space:
mode:
authorJames Almer <jamrial@gmail.com>2020-04-22 12:09:45 -0300
committerJames Almer <jamrial@gmail.com>2020-05-03 11:38:03 -0300
commit3921eed398c9ac01e9923e51d1bf9086556e03d1 (patch)
tree37534b215bf05b9b4c29734e30414954d54fb664 /libavcodec
parent449eaeb7a72a9fca437923660bfcdb6af844b353 (diff)
avcodec/av1_metadata: filter parameter sets in packet side data
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 av1C box will not. This is especially important for AV1 as both currently supported encoders don't export the Sequence Header in the codec context extradata, but as packet side data instead. Signed-off-by: James Almer <jamrial@gmail.com>
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/av1_metadata_bsf.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/libavcodec/av1_metadata_bsf.c b/libavcodec/av1_metadata_bsf.c
index dd0c9b6148..e5dde6754f 100644
--- a/libavcodec/av1_metadata_bsf.c
+++ b/libavcodec/av1_metadata_bsf.c
@@ -111,6 +111,50 @@ static int av1_metadata_update_sequence_header(AVBSFContext *bsf,
return 0;
}
+static int av1_metadata_update_side_data(AVBSFContext *bsf, AVPacket *pkt)
+{
+ AV1MetadataContext *ctx = bsf->priv_data;
+ CodedBitstreamFragment *frag = &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, frag, side_data, side_data_size);
+ if (err < 0) {
+ av_log(bsf, AV_LOG_ERROR, "Failed to read extradata from packet side data.\n");
+ return err;
+ }
+
+ for (i = 0; i < frag->nb_units; i++) {
+ if (frag->units[i].type == AV1_OBU_SEQUENCE_HEADER) {
+ AV1RawOBU *obu = frag->units[i].content;
+ err = av1_metadata_update_sequence_header(bsf, &obu->obu.sequence_header);
+ if (err < 0)
+ return err;
+ }
+ }
+
+ err = ff_cbs_write_fragment_data(ctx->cbc, frag);
+ if (err < 0) {
+ av_log(bsf, AV_LOG_ERROR, "Failed to write extradata into packet side data.\n");
+ return err;
+ }
+
+ side_data = av_packet_new_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, frag->data_size);
+ if (!side_data)
+ return AVERROR(ENOMEM);
+ memcpy(side_data, frag->data, frag->data_size);
+
+ ff_cbs_fragment_reset(ctx->cbc, frag);
+
+ return 0;
+}
+
static int av1_metadata_filter(AVBSFContext *bsf, AVPacket *pkt)
{
AV1MetadataContext *ctx = bsf->priv_data;
@@ -122,6 +166,10 @@ static int av1_metadata_filter(AVBSFContext *bsf, AVPacket *pkt)
if (err < 0)
return err;
+ err = av1_metadata_update_side_data(bsf, pkt);
+ if (err < 0)
+ goto fail;
+
err = ff_cbs_read_packet(ctx->cbc, frag, pkt);
if (err < 0) {
av_log(bsf, AV_LOG_ERROR, "Failed to read packet.\n");