[FFmpeg-devel] [PATCH v5 2/2 ] avformat/mpegts: opus demuxing for mapping family 255

Michael Niedermayer michael at niedermayer.cc
Tue Oct 31 19:28:00 EET 2017


On Sun, Oct 29, 2017 at 11:11:43PM +0100, pkv.stream wrote:
> minor change, adding a test for number of channels for
> mapping_family 1 when channel_config_code is > 0x82
> Passes fate + patcheck.
> Regards
> pkv

>  mpegts.c |   84 ++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
>  1 file changed, 70 insertions(+), 14 deletions(-)
> 6648bab53735f1efaf0d6cd698dbc2398b483c3f  0002-libavf-mpegts-opus-demuxing-for-mapping-family-255.patch
> From 2e0504728b81e0f35ba856c24cff14fa70680d8b Mon Sep 17 00:00:00 2001
> From: pkviet <pkv.stream at gmail.com>
> Date: Sun, 29 Oct 2017 22:57:25 +0100
> Subject: [PATCH 2/2] libavf/mpegts: opus demuxing for mapping family 255
> 
> Adds to mpegts muxer the capability  to demux libopus with mapping
> family 255, following the provisional spec for opus in mepg-ts
> (https://people.xiph.org/~tterribe/opus/ETSI_TS_opus-v0.1.3-draft.doc).
> 
> Signed-off-by: pkviet <pkv.stream at gmail.com>
> ---
>  libavformat/mpegts.c | 84 +++++++++++++++++++++++++++++++++++++++++++---------
>  1 file changed, 70 insertions(+), 14 deletions(-)
> 
> diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
> index 53cbcfb..3aa06f0 100644
> --- a/libavformat/mpegts.c
> +++ b/libavformat/mpegts.c
> @@ -37,6 +37,7 @@
>  #include "avio_internal.h"
>  #include "mpeg.h"
>  #include "isom.h"
> +#include "math.h"
>  
>  /* maximum size in which we look for synchronization if
>   * synchronization is lost */
> @@ -1633,7 +1634,7 @@ static const uint8_t opus_stream_cnt[9] = {
>      1, 1, 1, 2, 2, 3, 4, 4, 5,
>  };
>  
> -static const uint8_t opus_channel_map[8][8] = {
> +static const uint8_t opus_channel_map_a[8][8] = {
>      { 0 },
>      { 0,1 },
>      { 0,2,1 },
> @@ -1644,13 +1645,25 @@ static const uint8_t opus_channel_map[8][8] = {
>      { 0,6,1,2,3,4,5,7 },
>  };
>  
> +static const uint8_t opus_channel_map_b[8][8] = {
> +    { 0 },
> +    { 0,1 },
> +    { 0,1,2 },
> +    { 0,1,2,3 },
> +    { 0,1,2,3,4 },
> +    { 0,1,2,3,4,5 },
> +    { 0,1,2,3,4,5,6 },
> +    { 0,1,2,3,4,5,6,7 },
> +};
> +
>  int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type,
>                                const uint8_t **pp, const uint8_t *desc_list_end,
>                                Mp4Descr *mp4_descr, int mp4_descr_count, int pid,
>                                MpegTSContext *ts)
>  {
>      const uint8_t *desc_end;
> -    int desc_len, desc_tag, desc_es_id, ext_desc_tag, channels, channel_config_code;
> +    int desc_len, desc_tag, desc_es_id, ext_desc_tag, channels, channel_config_code, channel_count, mapping_family, stream_count, coupled_stream_count;
> +    GetBitContext gb;
>      char language[252];
>      int i;
>  
> @@ -1660,6 +1673,7 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type
>      desc_len = get8(pp, desc_list_end);
>      if (desc_len < 0)
>          return AVERROR_INVALIDDATA;
> +
>      desc_end = *pp + desc_len;
>      if (desc_end > desc_list_end)
>          return AVERROR_INVALIDDATA;
> @@ -1871,26 +1885,68 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type
>          if (st->codecpar->codec_id == AV_CODEC_ID_OPUS &&
>              ext_desc_tag == 0x80) { /* User defined (provisional Opus) */
>              if (!st->codecpar->extradata) {
> -                st->codecpar->extradata = av_mallocz(sizeof(opus_default_extradata) +
> -                                                     AV_INPUT_BUFFER_PADDING_SIZE);
> -                if (!st->codecpar->extradata)
> -                    return AVERROR(ENOMEM);
> -
> -                st->codecpar->extradata_size = sizeof(opus_default_extradata);
> -                memcpy(st->codecpar->extradata, opus_default_extradata, sizeof(opus_default_extradata));
> -
>                  channel_config_code = get8(pp, desc_end);
>                  if (channel_config_code < 0)
>                      return AVERROR_INVALIDDATA;
> +
> +                if (channel_config_code != 0x81) {
> +                    st->codecpar->extradata = av_mallocz(sizeof(opus_default_extradata) +
> +                        AV_INPUT_BUFFER_PADDING_SIZE);
> +                    if (!st->codecpar->extradata)
> +                        return AVERROR(ENOMEM);
> +                    st->codecpar->extradata_size = sizeof(opus_default_extradata);
> +                    memcpy(st->codecpar->extradata, opus_default_extradata, sizeof(opus_default_extradata));
> +                }
> +
>                  if (channel_config_code <= 0x8) {
>                      st->codecpar->extradata[9]  = channels = channel_config_code ? channel_config_code : 2;
>                      st->codecpar->extradata[18] = channel_config_code ? (channels > 2) : /* Dual Mono */ 255;
>                      st->codecpar->extradata[19] = opus_stream_cnt[channel_config_code];
>                      st->codecpar->extradata[20] = opus_coupled_stream_cnt[channel_config_code];
> -                    memcpy(&st->codecpar->extradata[21], opus_channel_map[channels - 1], channels);
> -                } else {
> -                    avpriv_request_sample(fc, "Opus in MPEG-TS - channel_config_code > 0x8");
> -                }
> +                    memcpy(&st->codecpar->extradata[21], opus_channel_map_a[channels - 1], channels);
> +                } else if (channel_config_code == 0x81) {
> +                    channel_count = get8(pp, desc_end);
> +                    mapping_family = get8(pp, desc_end);

> +                    if (channel_count < 0 || channel_count > 255)
> +                        return AVERROR_INVALIDDATA;
> +                    if (mapping_family < 0 || mapping_family > 255)
> +                        return AVERROR_INVALIDDATA;

 > 255 is impossible i think


> +                    st->codecpar->extradata_size = 22 + channel_count;
> +                    st->codecpar->extradata = av_mallocz(st->codecpar->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
> +                    if (!st->codecpar->extradata)
> +                        return AVERROR(ENOMEM);
> +                    for (i = 0; i < 9; i++) {
> +                        st->codecpar->extradata[i] = opus_default_extradata[i];
> +                    }
> +                    st->codecpar->extradata[9] = channel_count;
> +                    st->codecpar->extradata[18] = mapping_family;

> +                    init_get_bits(&gb, *pp, (channel_count + 2 + AV_INPUT_BUFFER_PADDING_SIZE) * 8);

The AV_INPUT_BUFFER_PADDING_SIZE looks odd here


> +                    stream_count = get_bits(&gb, av_ceil_log2_c(channel_count)) + 1;
> +                    coupled_stream_count = get_bits(&gb, av_ceil_log2_c(stream_count + 1));
> +                    if (stream_count < 0 || stream_count > channel_count)
> +                        return AVERROR_INVALIDDATA;
> +                    if (coupled_stream_count < 0 || coupled_stream_count > stream_count)
> +                        return AVERROR_INVALIDDATA;

get_bits shouldnt return negative numbers


> +                    st->codecpar->extradata[19] = stream_count;
> +                    st->codecpar->extradata[20] = coupled_stream_count;
> +                    for (i = 0; i < channel_count; i++) {
> +                        st->codecpar->extradata[21 + i] = get_bits(&gb, av_ceil_log2_c(stream_count + coupled_stream_count + 1));
> +                        if (st->codecpar->extradata[21 + i] > stream_count + coupled_stream_count
> +                            || st->codecpar->extradata[21 + i] > (int)(pow(2, stream_count + coupled_stream_count + 1) -1))
> +                            return AVERROR_INVALIDDATA;

pow(2 can be changed to a simple shift
also a temporary variable would be cleaner than using
st->codecpar->extradata[21 + i] 3 times

[...]


-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

I have never wished to cater to the crowd; for what I know they do not
approve, and what they approve I do not know. -- Epicurus
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20171031/58bb0fa6/attachment.sig>


More information about the ffmpeg-devel mailing list