Message ID | b7aed1af-74ce-b3f1-595b-988f5325e2ce@gmail.com |
---|---|
State | New |
Headers | show |
Le 14/09/2017 à 6:48 PM, pkv.stream a écrit : > Thanks for your comments Moritz. > Corrected patch in attachment. > Regards > > Le 14/09/2017 à 5:46 PM, Moritz Barsnick a écrit : >> 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 >> _______________________________________________ >> ffmpeg-devel mailing list >> ffmpeg-devel@ffmpeg.org >> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > ping
On Thu, Sep 14, 2017 at 06:48:33PM +0200, pkv.stream wrote: > Thanks for your comments Moritz. > Corrected patch in attachment. > Regards > > Le 14/09/2017 à 5:46 PM, Moritz Barsnick a écrit : > >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 > >_______________________________________________ > >ffmpeg-devel mailing list > >ffmpeg-devel@ffmpeg.org > >http://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > > mpegts.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- > mpegtsenc.c | 19 ++++++++++++----- > 2 files changed, 74 insertions(+), 9 deletions(-) > d2e34a72c7152584ae9423174f254d5d761325c3 0001-avformat-mpegts-opus-muxing-demuxing-expanded.patch > From 9175cb61dabce42417199cc6d6272d8290c39a5c Mon Sep 17 00:00:00 2001 > From: pkviet <pkv.stream@gmail.com> > Date: Fri, 8 Sep 2017 01:34:22 +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(-) > > diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c > index 4d2f5c6..8d8977b 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; this produces warnings: libavformat/mpegts.c:1906:25: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement] > + extradata = av_malloc(extradata_size); > + if (!extradata) > + return AVERROR(ENOMEM); > + for (i = 0; i <= (22+channels); i++) { the extradata_size expression is repeated 3 times, code duplication should be avoided > + if (i < 9) { > + extradata[i] = opus_default_extradata[i]; > + } > + else { > + extradata[i] = 0; > + } > + } > + memcpy(st->codecpar->extradata, extradata, sizeof(extradata)); this looks wrong > + 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); the channels value is not checked before use in memcpy > + } > + 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; > diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c > index fdfa544..af1dfc6 100644 > --- a/libavformat/mpegtsenc.c > +++ b/libavformat/mpegtsenc.c muxer and demuxer changes should be in seperate patches thx [...]
>> 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; > this produces warnings: > libavformat/mpegts.c:1906:25: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement] > Thanks a lot Michael for your review. I have cleaned this warning and others issued by gcc. >> + extradata = av_malloc(extradata_size); >> + if (!extradata) >> + return AVERROR(ENOMEM); >> + for (i = 0; i <= (22+channels); i++) { > the extradata_size expression is repeated 3 times, code duplication > should be avoided > removed >> + if (i < 9) { >> + extradata[i] = opus_default_extradata[i]; >> + } >> + else { >> + extradata[i] = 0; >> + } >> + } >> + memcpy(st->codecpar->extradata, extradata, sizeof(extradata)); > this looks wrong > right, fixed (removed) >> + 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); > the channels value is not checked before use in memcpy fixed; I have added other checks for all the data read from header; > >> + } >> + 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; >> diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c >> index fdfa544..af1dfc6 100644 >> --- a/libavformat/mpegtsenc.c >> +++ b/libavformat/mpegtsenc.c > muxer and demuxer changes should be in seperate patches done; see next posts. My previous code was not following strictly the draft spec here: https://people.xiph.org/~tterribe/opus/ETSI_TS_opus-v0.1.3-draft.doc So I have rewritten it to have strict adherence regarding the bits allocated in header. I have also run fate + patcheck ; no issues (just some unused variables warnings for variables antedating this patch). Regards
diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index 4d2f5c6..8d8977b 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 %i", 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) {