diff mbox series

[FFmpeg-devel,2/3] avcodec/h264_metadata: filter parameter sets in packet side data

Message ID 20200422150947.850-2-jamrial@gmail.com
State Accepted
Headers show
Series [FFmpeg-devel,1/3] avcodec/av1_metadata: filter parameter sets in packet side data | expand

Checks

Context Check Description
andriy/default pending
andriy/make success Make finished
andriy/make_fate success Make fate finished

Commit Message

James Almer April 22, 2020, 3:09 p.m. UTC
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 avcC box will not.

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

Comments

James Almer April 22, 2020, 6:05 p.m. UTC | #1
On 4/22/2020 12:09 PM, James Almer wrote:
> 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 avcC box will not.

Actually, unlike av1, the mp4 example doesn't apply for h264 and h265.
The mp4 muxer ignores new extradata in packet side data for those codecs.

Amended the commit message locally to remove it.

> 
> Signed-off-by: James Almer <jamrial@gmail.com>
> ---
>  libavcodec/h264_metadata_bsf.c | 50 ++++++++++++++++++++++++++++++++++
>  1 file changed, 50 insertions(+)
> 
> diff --git a/libavcodec/h264_metadata_bsf.c b/libavcodec/h264_metadata_bsf.c
> index d96a50dbf7..1347279b9d 100644
> --- a/libavcodec/h264_metadata_bsf.c
> +++ b/libavcodec/h264_metadata_bsf.c
> @@ -275,6 +275,52 @@ static int h264_metadata_update_sps(AVBSFContext *bsf,
>      return 0;
>  }
>  
> +static int h264_metadata_update_side_data(AVBSFContext *bsf, AVPacket *pkt)
> +{
> +    H264MetadataContext *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;
> +    }
> +
> +    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);
> +            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 h264_metadata_filter(AVBSFContext *bsf, AVPacket *pkt)
>  {
>      H264MetadataContext *ctx = bsf->priv_data;
> @@ -286,6 +332,10 @@ static int h264_metadata_filter(AVBSFContext *bsf, AVPacket *pkt)
>      if (err < 0)
>          return err;
>  
> +    err = h264_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");
>
Andreas Rheinhardt April 23, 2020, 12:40 a.m. UTC | #2
James Almer:
> 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 avcC box will not.
> 
> Signed-off-by: James Almer <jamrial@gmail.com>
> ---
>  libavcodec/h264_metadata_bsf.c | 50 ++++++++++++++++++++++++++++++++++
>  1 file changed, 50 insertions(+)
> 
> diff --git a/libavcodec/h264_metadata_bsf.c b/libavcodec/h264_metadata_bsf.c
> index d96a50dbf7..1347279b9d 100644
> --- a/libavcodec/h264_metadata_bsf.c
> +++ b/libavcodec/h264_metadata_bsf.c
> @@ -275,6 +275,52 @@ static int h264_metadata_update_sps(AVBSFContext *bsf,
>      return 0;
>  }
>  
> +static int h264_metadata_update_side_data(AVBSFContext *bsf, AVPacket *pkt)
> +{
> +    H264MetadataContext *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;

Same here. You can return immediately.

> +    }
> +
> +    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);
> +            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 h264_metadata_filter(AVBSFContext *bsf, AVPacket *pkt)
>  {
>      H264MetadataContext *ctx = bsf->priv_data;
> @@ -286,6 +332,10 @@ static int h264_metadata_filter(AVBSFContext *bsf, AVPacket *pkt)
>      if (err < 0)
>          return err;
>  
> +    err = h264_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");
>
diff mbox series

Patch

diff --git a/libavcodec/h264_metadata_bsf.c b/libavcodec/h264_metadata_bsf.c
index d96a50dbf7..1347279b9d 100644
--- a/libavcodec/h264_metadata_bsf.c
+++ b/libavcodec/h264_metadata_bsf.c
@@ -275,6 +275,52 @@  static int h264_metadata_update_sps(AVBSFContext *bsf,
     return 0;
 }
 
+static int h264_metadata_update_side_data(AVBSFContext *bsf, AVPacket *pkt)
+{
+    H264MetadataContext *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;
+    }
+
+    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);
+            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 h264_metadata_filter(AVBSFContext *bsf, AVPacket *pkt)
 {
     H264MetadataContext *ctx = bsf->priv_data;
@@ -286,6 +332,10 @@  static int h264_metadata_filter(AVBSFContext *bsf, AVPacket *pkt)
     if (err < 0)
         return err;
 
+    err = h264_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");