Le 31/10/2017 à 6:28 PM, Michael Niedermayer a écrit :
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.str...@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.str...@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


hello Michael,

quite right, check removed;
+                    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

right again, I misread the API, sorry.
+                    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

ok check removed
+                    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
done
also a temporary variable would be cleaner than using
st->codecpar->extradata[21 + i] 3 times
done
I've also corrected a mistake for channel_config_code >= 0x82 and shortened long lines.

Regards
pkv

[...]




_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


From c33999c06a1204fb086386716419811427c585bb Mon Sep 17 00:00:00 2001
From: pkviet <pkv.str...@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).
---
 libavformat/mpegts.c | 86 ++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 73 insertions(+), 13 deletions(-)

diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index 53cbcfb..6f5998e 100644
--- a/libavformat/mpegts.c
+++ b/libavformat/mpegts.c
@@ -1633,7 +1633,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,6 +1644,17 @@ 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,
@@ -1651,6 +1662,8 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, 
AVStream *st, int stream_type
 {
     const uint8_t *desc_end;
     int desc_len, desc_tag, desc_es_id, ext_desc_tag, channels, 
channel_config_code;
+    uint8_t channel_count, mapping_family, stream_count, coupled_stream_count, 
channel_mapping, sc_csc;
+    GetBitContext gb;
     char language[252];
     int i;
 
@@ -1871,26 +1884,73 @@ 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)
+                        return AVERROR_INVALIDDATA;
+                    if (mapping_family < 0)
+                        return AVERROR_INVALIDDATA;
+                    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) * 8);
+                    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));
+                    sc_csc = stream_count + coupled_stream_count;
+                    if (stream_count > channel_count)
+                        return AVERROR_INVALIDDATA;
+                    if (coupled_stream_count > stream_count)
+                        return AVERROR_INVALIDDATA;
+                    st->codecpar->extradata[19] = stream_count;
+                    st->codecpar->extradata[20] = coupled_stream_count;
+                    for (i = 0; i < channel_count; i++) {
+                        channel_mapping = get_bits(&gb, av_ceil_log2_c(sc_csc 
+ 1));
+                        if (channel_mapping > sc_csc
+                            || channel_mapping > (1 << sc_csc + 1) -1)
+                            return AVERROR_INVALIDDATA;
+                        st->codecpar->extradata[21 + i] = channel_mapping;
+                    }
+                } else if ((channel_config_code >= 0x82) &&
+                           (channel_config_code <= 0x88)) {
+                    channels = channel_config_code - 0x80;
+                    st->codecpar->extradata[9] = channels;
+                    st->codecpar->extradata[18] = 1;
+                    st->codecpar->extradata[19] = channels;
+                    st->codecpar->extradata[20] = 0;
+                    memcpy(&st->codecpar->extradata[21],
+                           opus_channel_map_b[channels - 1], channels);
+                 } else {
+                    avpriv_request_sample(fc, "Opus in MPEG-TS - 
channel_config_code %i",
+                                          channel_config_code);
+                 }
                 st->need_parsing = AVSTREAM_PARSE_FULL;
                 st->internal->need_context_update = 1;
             }
-- 
2.10.1.windows.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to