[FFmpeg-devel,PATCHv3] avformat/mpegts: opus muxing & demuxing for mapping family 255

Submitted by pkv.stream on Sept. 7, 2017, 11:46 p.m.

Details

Message ID 103114c7-8ba7-d798-6353-83d346990995@gmail.com
State New
Headers show

Commit Message

pkv.stream Sept. 7, 2017, 11:46 p.m.
Hi,

I've removed inline declarations in the patch since they're not accepted 
in ffmpeg.

Thanks for any more comments or reviews.

Regards
From d05c62039b3edfd151b8c3824cc8f509f9ea8053 Mon Sep 17 00:00:00 2001
From: pkviet <pkv.stream@gmail.com>
Date: Tue, 29 Aug 2017 01:24:12 +0200
Subject: [PATCH] avformat/mpegts: opus muxing & demuxing expanded

Support for opus in mpegts demuxer was brought by commit
9cfa68c560bdec82d2d5ec079f9c5b0f9ca37af0 (Kieran Kunhya).
Support for opus in mpegts muxer was then added by commit
01509cdf9287b975eced1fd609a8201fbd1438e3 (S. Droge).
Later commit 37941878f193a2316c514bd5ba55bfe9d2dfdfcf by Michael Graczyk
added support of mapping_family encoder parameter which allows for up to 255
audio channels (for family 255).
While matroska muxer & demuxer readily accepts mapping_family, it is not the
case for mpegts muxer & demuxer for all the range of the parameter (family 255
and also part of family 1 with channel_config_code > 0x81 unsupported).
This commit brings such a support.
---
 libavformat/mpegts.c    | 64 ++++++++++++++++++++++++++++++++++++++++++++++---
 libavformat/mpegtsenc.c | 19 ++++++++++-----
 2 files changed, 74 insertions(+), 9 deletions(-)

Comments

pkv.stream Sept. 13, 2017, 7:36 p.m.
Le 08/09/2017 à 1:46 AM, pkv.stream a écrit :
> Hi,
>
> I've removed inline declarations in the patch since they're not 
> accepted in ffmpeg.
>
> Thanks for any more comments or reviews.
>
> Regards
>
>
bump, initial submission 08/29

Got some comments from Michael (thanks again Michael) but that's all.

Should I ping those who brought opus support to mpegts / mapping_family 
to opus , for instance ?

Regards
Moritz Barsnick Sept. 14, 2017, 3:46 p.m.
On Fri, Sep 08, 2017 at 01:46:38 +0200, pkv.stream wrote:
> -                    avpriv_request_sample(fc, "Opus in MPEG-TS - channel_config_code > 0x8");
[...]
> +                            avpriv_request_sample(fc, "Opus in MPEG-TS - channel_config_code");

You probably need to mention the channel_config_code in the new
message.

> +                        for (j = 0; j < channels; j++) {
> +                            opus_channel_map255[j] = j;
> +                            }

Misplaced closing bracket.

Moritz
Michael Niedermayer Sept. 15, 2017, 8:33 p.m.
On Wed, Sep 13, 2017 at 09:36:25PM +0200, pkv.stream wrote:
> Le 08/09/2017 à 1:46 AM, pkv.stream a écrit :
> >Hi,
> >
> >I've removed inline declarations in the patch since they're not
> >accepted in ffmpeg.
> >
> >Thanks for any more comments or reviews.
> >
> >Regards
> >
> >
> bump, initial submission 08/29
> 
> Got some comments from Michael (thanks again Michael) but that's all.
> 
> Should I ping those who brought opus support to mpegts /
> mapping_family to opus , for instance ?

Thats probably a good idea.
If they approve or you hear nothing from them then ping me and ill
take a look and apply if it looks ok

thx

[...]
pkv.stream Oct. 4, 2017, 6:24 p.m.
Le 15/09/2017 à 10:33 PM, Michael Niedermayer a écrit :
> On Wed, Sep 13, 2017 at 09:36:25PM +0200, pkv.stream wrote:
>> Le 08/09/2017 à 1:46 AM, pkv.stream a écrit :
>>> Hi,
>>>
>>> I've removed inline declarations in the patch since they're not
>>> accepted in ffmpeg.
>>>
>>> Thanks for any more comments or reviews.
>>>
>>> Regards
>>>
>>>
>> bump, initial submission 08/29
>>
>> Got some comments from Michael (thanks again Michael) but that's all.
>>
>> Should I ping those who brought opus support to mpegts /
>> mapping_family to opus , for instance ?
> Thats probably a good idea.
> If they approve or you hear nothing from them then ping me and ill
> take a look and apply if it looks ok
>
> thx
>
> [...]
>
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

ping

Patch hide | download patch | download mbox

diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index 4d2f5c6..fd2857c 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,
@@ -1887,9 +1898,56 @@  int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type
                     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);
+                    memcpy(&st->codecpar->extradata[21], opus_channel_map_a[channels - 1], channels);
                 } else {
-                    avpriv_request_sample(fc, "Opus in MPEG-TS - channel_config_code > 0x8");
+                    if (channel_config_code == 0x81) {
+                        channels = get8(pp, desc_end);
+                        st->codecpar->extradata_size = 22 + channels;
+                        size_t extradata_size;
+                        extradata_size = (22 + channels) * sizeof(uint8_t);
+                        uint8_t *extradata;
+                        extradata = av_malloc(extradata_size);
+                        if (!extradata)
+                            return AVERROR(ENOMEM);
+                        for (i = 0; i <= (22+channels); i++) {
+                            if (i < 9) {
+                                extradata[i] = opus_default_extradata[i];
+                            }
+                            else {
+                                extradata[i] = 0;
+                            }
+                        }
+                        memcpy(st->codecpar->extradata, extradata, sizeof(extradata));
+                        av_free(extradata);
+                        st->codecpar->extradata[9] = channels;
+                        st->codecpar->extradata[18] = 255;
+                        st->codecpar->extradata[19] = channels;
+                        st->codecpar->extradata[20] = 0;
+                        size_t channel_map_size = channels * sizeof(uint8_t);
+                        uint8_t *opus_channel_map255;
+                        opus_channel_map255 = av_malloc(channel_map_size);
+                        if (!opus_channel_map255)
+                            return AVERROR(ENOMEM);
+                        uint8_t j;
+                        for (j = 0; j < channels; j++) {
+                            opus_channel_map255[j] = j;
+                            }
+                        memcpy(&st->codecpar->extradata[21], opus_channel_map255, channels);
+                        av_free(opus_channel_map255);
+                    } else {
+                        if ((channel_config_code >= 0x82) && (channel_config_code <= 0x88)) {
+                            channels = get8(pp, desc_end);
+                            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");
+                        }
+
+                    }
                 }
                 st->need_parsing = AVSTREAM_PARSE_FULL;
                 st->internal->need_context_update = 1;
diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c
index fdfa544..af1dfc6 100644
--- a/libavformat/mpegtsenc.c
+++ b/libavformat/mpegtsenc.c
@@ -421,8 +421,8 @@  static int mpegts_write_pmt(AVFormatContext *s, MpegTSService *service)
                 *q++ = 'D';
             }
             if (st->codecpar->codec_id==AV_CODEC_ID_OPUS) {
-                /* 6 bytes registration descriptor, 4 bytes Opus audio descriptor */
-                if (q - data > SECTION_LENGTH - 6 - 4) {
+                /* 6 bytes registration descriptor, 6 bytes Opus audio descriptor */
+                if (q - data > SECTION_LENGTH - 6 - 6) {
                     err = 1;
                     break;
                 }
@@ -435,7 +435,7 @@  static int mpegts_write_pmt(AVFormatContext *s, MpegTSService *service)
                 *q++ = 's';
 
                 *q++ = 0x7f; /* DVB extension descriptor */
-                *q++ = 2;
+                *q++ = 4;
                 *q++ = 0x80;
 
                 if (st->codecpar->extradata && st->codecpar->extradata_size >= 19) {
@@ -483,9 +483,14 @@  static int mpegts_write_pmt(AVFormatContext *s, MpegTSService *service)
                             *q++ = 0xff;
                         }
                     } else {
-                        /* Unsupported */
-                        av_log(s, AV_LOG_ERROR, "Unsupported Opus channel mapping for family %d", st->codecpar->extradata[18]);
-                        *q++ = 0xff;
+                        /* mapping family 255 , set channel_config_code to 0x81 */
+                        if (st->codecpar->extradata[18] == 255) {
+                            *q++ = 0x81;
+                        } else {
+                            /* Unsupported */
+                            av_log(s, AV_LOG_ERROR, "Unsupported Opus channel mapping for family %d", st->codecpar->extradata[18]);
+                            *q++ = 0xff;
+                        }
                     }
                 } else if (st->codecpar->channels <= 2) {
                     /* Assume RTP mapping family */
@@ -495,6 +500,8 @@  static int mpegts_write_pmt(AVFormatContext *s, MpegTSService *service)
                     av_log(s, AV_LOG_ERROR, "Unsupported Opus channel mapping");
                     *q++ = 0xff;
                 }
+                *q++ = st->codecpar->extradata[9];
+                *q++ = st->codecpar->extradata[18];
             }
 
             if (lang) {