[FFmpeg-devel] [PATCH 13/18] lavc: Add mpeg2_metadata bitstream filter

Mark Thompson sw at jkqxz.net
Mon Aug 28 14:02:49 EEST 2017


On 21/08/17 19:21, Michael Niedermayer wrote:
> On Sun, Aug 20, 2017 at 11:41:41PM +0100, Mark Thompson wrote:
>> (cherry picked from commit b78c30d7ec26af67c00ce2002709a189f6a87a7e)
>> ---
>>  configure                       |   1 +
>>  doc/bitstream_filters.texi      |  36 ++++
>>  libavcodec/Makefile             |   1 +
>>  libavcodec/bitstream_filters.c  |   1 +
>>  libavcodec/mpeg2_metadata_bsf.c | 360 ++++++++++++++++++++++++++++++++++++++++
>>  5 files changed, 399 insertions(+)
>>  create mode 100644 libavcodec/mpeg2_metadata_bsf.c
>>
>> diff --git a/configure b/configure
>> index 7641bd98d4..1e99038dca 100755
>> --- a/configure
>> +++ b/configure
>> @@ -2836,6 +2836,7 @@ h264_metadata_bsf_select="cbs_h264"
>>  h264_redundant_pps_bsf_select="cbs_h264"
>>  hevc_metadata_bsf_select="cbs_h265"
>>  mjpeg2jpeg_bsf_select="jpegtables"
>> +mpeg2_metadata_bsf_select="cbs_mpeg2"
>>  trace_headers_bsf_select="cbs_h264 cbs_h265 cbs_mpeg2"
>>  
>>  # external libraries
>> diff --git a/doc/bitstream_filters.texi b/doc/bitstream_filters.texi
>> index 71c307f2e2..8a8756bdcc 100644
>> --- a/doc/bitstream_filters.texi
>> +++ b/doc/bitstream_filters.texi
>> @@ -324,6 +324,42 @@ See also the @ref{text2movsub} filter.
>>  
>>  Decompress non-standard compressed MP3 audio headers.
>>  
>> + at section mpeg2_metadata
>> +
>> +Modify metadata embedded in an MPEG-2 stream.
>> +
>> + at table @option
>> + at item display_aspect_ratio
>> +Set the display aspect ratio in the stream.
>> +
>> +The following fixed values are supported:
>> + at table @option
>> + at item 4/3
>> + at item 16/9
>> + at item 221/100
>> + at end table
>> +Any other value will result in square pixels being signalled instead
>> +(see H.262 section 6.3.3 and table 6-3).
>> +
>> + at item frame_rate
>> +Set the frame rate in the stream.  This is constructed from a table
>> +of known values combined with a small multiplier and divisor - if
>> +the supplied value is not exactly representable, the nearest
>> +representable value will be used instead (see H.262 section 6.3.3
>> +and table 6-4).
>> +
>> + at item video_format
>> +Set the video format in the stream (see H.262 section 6.3.6 and
>> +table 6-6).
>> +
>> + at item colour_primaries
>> + at item transfer_characteristics
>> + at item matrix_coefficients
>> +Set the colour description in the stream (see H.262 section 6.3.6
>> +and tables 6-7, 6-8 and 6-9).
>> +
>> + at end table
>> +
>>  @section mpeg4_unpack_bframes
>>  
>>  Unpack DivX-style packed B-frames.
>> diff --git a/libavcodec/Makefile b/libavcodec/Makefile
>> index 72f2bb2a12..3da7b9b508 100644
>> --- a/libavcodec/Makefile
>> +++ b/libavcodec/Makefile
>> @@ -1002,6 +1002,7 @@ OBJS-$(CONFIG_MPEG4_UNPACK_BFRAMES_BSF)   += mpeg4_unpack_bframes_bsf.o
>>  OBJS-$(CONFIG_MOV2TEXTSUB_BSF)            += movsub_bsf.o
>>  OBJS-$(CONFIG_MP3_HEADER_DECOMPRESS_BSF)  += mp3_header_decompress_bsf.o \
>>                                               mpegaudiodata.o
>> +OBJS-$(CONFIG_MPEG2_METADATA_BSF)         += mpeg2_metadata_bsf.o
>>  OBJS-$(CONFIG_NOISE_BSF)                  += noise_bsf.o
>>  OBJS-$(CONFIG_NULL_BSF)                   += null_bsf.o
>>  OBJS-$(CONFIG_REMOVE_EXTRADATA_BSF)       += remove_extradata_bsf.o
>> diff --git a/libavcodec/bitstream_filters.c b/libavcodec/bitstream_filters.c
>> index 6e6b894e7f..7b0cb5032a 100644
>> --- a/libavcodec/bitstream_filters.c
>> +++ b/libavcodec/bitstream_filters.c
>> @@ -38,6 +38,7 @@ extern const AVBitStreamFilter ff_imx_dump_header_bsf;
>>  extern const AVBitStreamFilter ff_mjpeg2jpeg_bsf;
>>  extern const AVBitStreamFilter ff_mjpega_dump_header_bsf;
>>  extern const AVBitStreamFilter ff_mp3_header_decompress_bsf;
>> +extern const AVBitStreamFilter ff_mpeg2_metadata_bsf;
>>  extern const AVBitStreamFilter ff_mpeg4_unpack_bframes_bsf;
>>  extern const AVBitStreamFilter ff_mov2textsub_bsf;
>>  extern const AVBitStreamFilter ff_noise_bsf;
>> diff --git a/libavcodec/mpeg2_metadata_bsf.c b/libavcodec/mpeg2_metadata_bsf.c
>> new file mode 100644
>> index 0000000000..b4449eac71
>> --- /dev/null
>> +++ b/libavcodec/mpeg2_metadata_bsf.c
>> @@ -0,0 +1,360 @@
>> +/*
>> + * This file is part of FFmpeg.
>> + *
>> + * FFmpeg is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU Lesser General Public
>> + * License as published by the Free Software Foundation; either
>> + * version 2.1 of the License, or (at your option) any later version.
>> + *
>> + * FFmpeg is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>> + * Lesser General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU Lesser General Public
>> + * License along with FFmpeg; if not, write to the Free Software
>> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
>> + */
>> +
>> +#include "libavutil/avstring.h"
>> +#include "libavutil/common.h"
>> +#include "libavutil/opt.h"
>> +
>> +#include "bsf.h"
>> +#include "cbs.h"
>> +#include "cbs_mpeg2.h"
>> +
>> +typedef struct MPEG2MetadataContext {
>> +    const AVClass *class;
>> +
>> +    CodedBitstreamContext cbc;
>> +    CodedBitstreamFragment fragment;
>> +
>> +    MPEG2RawExtensionData sequence_display_extension;
>> +
>> +    AVRational display_aspect_ratio;
>> +
>> +    AVRational frame_rate;
>> +
>> +    int video_format;
>> +    int colour_primaries;
>> +    int transfer_characteristics;
>> +    int matrix_coefficients;
>> +
>> +    int mpeg1_warned;
>> +} MPEG2MetadataContext;
>> +
>> +
>> +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 && !ctx->mpeg1_warned) {
>> +            av_log(bsf, AV_LOG_WARNING, "Stream contains a sequence "
>> +                   "header but not a sequence extension: maybe it's "
>> +                   "actually MPEG-1?\n");
>> +            ctx->mpeg1_warned = 1;
>> +        }
>> +        return 0;
>> +    }
>> +
>> +    if (ctx->display_aspect_ratio.num && ctx->display_aspect_ratio.den) {
>> +        int num, den;
>> +
>> +        av_reduce(&num, &den, ctx->display_aspect_ratio.num,
>> +                  ctx->display_aspect_ratio.den, 65535);
>> +
>> +        if (num == 4 && den == 3)
>> +            sh->aspect_ratio_information = 2;
>> +        else if (num == 16 && den == 9)
>> +            sh->aspect_ratio_information = 3;
>> +        else if (num == 221 && den == 100)
>> +            sh->aspect_ratio_information = 4;
>> +        else
>> +            sh->aspect_ratio_information = 1;
>> +    }
>> +
>> +    if (ctx->frame_rate.num && ctx->frame_rate.den) {
>> +        // Table 6-4.
> 
>> +        static AVRational frame_rate_table[] = {
>> +            { 0, 0 },
>> +            { 24000, 1001 },
>> +            { 24,    1    },
>> +            { 25,    1    },
>> +            { 30000, 1001 },
>> +            { 30,    1    },
>> +            { 50,    1    },
>> +            { 60000, 1001 },
>> +            { 60,    1    },
>> +        };
> 
> This is a duplicate of ff_mpeg12_frame_rate_tab
> also should be static const

On further thought, I've extracted this framerate-construction fragment into mpeg12framerate.c next to where the table is - it's also wanted by the MPEG-2 VAAPI encoder code.

>> +#define OFFSET(x) offsetof(MPEG2MetadataContext, x)
>> +static const AVOption mpeg2_metadata_options[] = {
>> +    { "display_aspect_ratio", "Set display aspect ratio (table 6-3)",
>> +        OFFSET(display_aspect_ratio), AV_OPT_TYPE_RATIONAL,
>> +        { .i64 = 0 }, 0, 65535 },
>> +
>> +    { "frame_rate", "Set frame rate",
>> +        OFFSET(frame_rate), AV_OPT_TYPE_RATIONAL,
>> +        { .i64 = 0 }, 0, UINT_MAX },
> 
> for AV_OPT_TYPE_RATIONAL the default is dbl not i64, also this affects
> some of the other patches as well

Hmm, yeah - I guess I've always been saved there by only setting it to zero.  Will fix.

Thanks,

- Mark


More information about the ffmpeg-devel mailing list