Quoting Mark Thompson (2017-08-15 01:02:38)
> ---
>  configure                       |   1 +
>  doc/bitstream_filters.texi      |  36 ++++
>  libavcodec/Makefile             |   1 +
>  libavcodec/bitstream_filters.c  |   1 +
>  libavcodec/mpeg2_metadata_bsf.c | 356 
> ++++++++++++++++++++++++++++++++++++++++
>  5 files changed, 395 insertions(+)
>  create mode 100644 libavcodec/mpeg2_metadata_bsf.c
> 
> +static int mpeg2_metadata_update_fragment(AVBSFContext *bsf,
> +                                          CodedBitstreamFragment *frag)
> +{
> +    MPEG2MetadataContext             *ctx = bsf->priv_data;
> +    MPEG2RawSequenceHeader            *sh = NULL;
> +    MPEG2RawSequenceExtension         *se = NULL;
> +    MPEG2RawSequenceDisplayExtension *sde = NULL;
> +    int i, se_pos, add_sde = 0;
> +
> +    for (i = 0; i < frag->nb_units; i++) {
> +        if (frag->units[i].type == MPEG2_START_SEQUENCE_HEADER) {
> +            sh = frag->units[i].content;
> +        } else if (frag->units[i].type == MPEG2_START_EXTENSION) {
> +            MPEG2RawExtensionData *ext = frag->units[i].content;
> +            if (ext->extension_start_code_identifier ==
> +                MPEG2_EXTENSION_SEQUENCE) {
> +                se = &ext->data.sequence;
> +                se_pos = i;
> +            } else if (ext->extension_start_code_identifier ==
> +                MPEG2_EXTENSION_SEQUENCE_DISPLAY) {
> +                sde = &ext->data.sequence_display;
> +            }
> +        }
> +    }
> +
> +    if (!sh || !se) {
> +        // No sequence header and sequence extension: not an MPEG-2 video
> +        // sequence.
> +        if (sh) {
> +            av_log(bsf, AV_LOG_WARNING, "Stream contains a sequence "
> +                   "header but not a sequence extension: maybe it's "
> +                   "actually MPEG-1?\n");

If it actually is MPEG-1 then this will get spammy, won't it? Maybe only
print it once.

> +static int mpeg2_metadata_filter(AVBSFContext *bsf, AVPacket *out)
> +{
> +    MPEG2MetadataContext *ctx = bsf->priv_data;
> +    AVPacket *in = NULL;
> +    CodedBitstreamFragment *frag = &ctx->fragment;
> +    int err;
> +
> +    err = ff_bsf_get_packet(bsf, &in);
> +    if (err < 0)
> +        goto fail;
> +
> +    err = ff_cbs_read_packet(&ctx->cbc, frag, in);
> +    if (err < 0) {
> +        av_log(bsf, AV_LOG_ERROR, "Failed to read packet.\n");
> +        goto fail;
> +    }
> +
> +    err = mpeg2_metadata_update_fragment(bsf, frag);
> +    if (err < 0) {
> +        av_log(bsf, AV_LOG_ERROR, "Failed to update frame fragment.\n");
> +        goto fail;
> +    }
> +
> +    err = ff_cbs_write_packet(&ctx->cbc, out, frag);
> +    if (err < 0) {
> +        av_log(bsf, AV_LOG_ERROR, "Failed to write packet.\n");
> +        goto fail;
> +    }
> +
> +    err = av_packet_copy_props(out, in);
> +    if (err < 0)
> +        goto fail;

This leaks the contents of out I think.
Not sure if we should make the generic code unref it on failure.

-- 
Anton Khirnov
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to