From: ulmus-scott <scott.the....@gmail.com> Defined in ISO/IEC 11172-3 and ISO/IEC 13818-3 as: dual channel mode [audio]: A mode, where two audio channels with independent programme contents (e.g. bilingual) are encoded within one bitstream. The coding process is the same as for the stereo mode.
There is currently no way to signal that an audio channel is monophonic, i.e. that channel comprises the entirety of an audio signal, so two front center channels were chosen since AV_CH_LAYOUT_MONO is represented as a single front center channel. --- libavcodec/audiotoolboxdec.c | 4 ++-- libavcodec/mpegaudio_parser.c | 19 ++++++++++++++++--- libavcodec/mpegaudiodecheader.c | 4 +++- libavcodec/mpegaudiodecheader.h | 2 +- tests/ref/fate/pva-demux | 2 +- 5 files changed, 23 insertions(+), 8 deletions(-) diff --git a/libavcodec/audiotoolboxdec.c b/libavcodec/audiotoolboxdec.c index 08203c5310..667d0f9ad0 100644 --- a/libavcodec/audiotoolboxdec.c +++ b/libavcodec/audiotoolboxdec.c @@ -346,10 +346,10 @@ static av_cold int ffat_create_decoder(AVCodecContext *avctx, avctx->codec_id == AV_CODEC_ID_MP2 || avctx->codec_id == AV_CODEC_ID_MP3)) { enum AVCodecID codec_id; - int bit_rate; + int bit_rate, dual_mono; if (ff_mpa_decode_header(AV_RB32(pkt->data), &avctx->sample_rate, &in_format.mChannelsPerFrame, &avctx->frame_size, - &bit_rate, &codec_id) < 0) + &bit_rate, &codec_id, &dual_mono) < 0) return AVERROR_INVALIDDATA; avctx->bit_rate = bit_rate; in_format.mSampleRate = avctx->sample_rate; diff --git a/libavcodec/mpegaudio_parser.c b/libavcodec/mpegaudio_parser.c index d54366f10a..6711163d03 100644 --- a/libavcodec/mpegaudio_parser.c +++ b/libavcodec/mpegaudio_parser.c @@ -65,12 +65,12 @@ static int mpegaudio_parse(AVCodecParserContext *s1, } }else{ while(i<buf_size){ - int ret, sr, channels, bit_rate, frame_size; + int ret, sr, channels, bit_rate, frame_size, dual_mono; enum AVCodecID codec_id = avctx->codec_id; state= (state<<8) + buf[i++]; - ret = ff_mpa_decode_header(state, &sr, &channels, &frame_size, &bit_rate, &codec_id); + ret = ff_mpa_decode_header(state, &sr, &channels, &frame_size, &bit_rate, &codec_id, &dual_mono); if (ret < 4) { if (i > 4) s->header_count = -2; @@ -85,7 +85,20 @@ static int mpegaudio_parse(AVCodecParserContext *s1, if (s->header_count > header_threshold) { avctx->sample_rate= sr; av_channel_layout_uninit(&avctx->ch_layout); - av_channel_layout_default(&avctx->ch_layout, channels); + if (dual_mono) { + // two independent monophonic audio channels in one bitstream + int ret = av_channel_layout_custom_init(&avctx->ch_layout, 2); + if (ret != 0) { + // parsers can't return error codes + avctx->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC; + avctx->ch_layout.nb_channels = 2; + } else { + avctx->ch_layout.u.map[0].id = AV_CHAN_FRONT_CENTER; + avctx->ch_layout.u.map[1].id = AV_CHAN_FRONT_CENTER; + } + } else { + av_channel_layout_default(&avctx->ch_layout, channels); + } s1->duration = frame_size; avctx->codec_id = codec_id; if (s->no_bitrate || !avctx->bit_rate) { diff --git a/libavcodec/mpegaudiodecheader.c b/libavcodec/mpegaudiodecheader.c index ef63befbf4..5cbfdcb677 100644 --- a/libavcodec/mpegaudiodecheader.c +++ b/libavcodec/mpegaudiodecheader.c @@ -117,7 +117,7 @@ int avpriv_mpegaudio_decode_header(MPADecodeHeader *s, uint32_t header) return 0; } -int ff_mpa_decode_header(uint32_t head, int *sample_rate, int *channels, int *frame_size, int *bit_rate, enum AVCodecID *codec_id) +int ff_mpa_decode_header(uint32_t head, int *sample_rate, int *channels, int *frame_size, int *bit_rate, enum AVCodecID *codec_id, int *dual_mono) { MPADecodeHeader s1, *s = &s1; @@ -148,5 +148,7 @@ int ff_mpa_decode_header(uint32_t head, int *sample_rate, int *channels, int *fr *sample_rate = s->sample_rate; *channels = s->nb_channels; *bit_rate = s->bit_rate; + *dual_mono = (s->mode == MPA_DUAL); + return s->frame_size; } diff --git a/libavcodec/mpegaudiodecheader.h b/libavcodec/mpegaudiodecheader.h index ed5d1f3b33..e599d287f7 100644 --- a/libavcodec/mpegaudiodecheader.h +++ b/libavcodec/mpegaudiodecheader.h @@ -56,7 +56,7 @@ int avpriv_mpegaudio_decode_header(MPADecodeHeader *s, uint32_t header); /* useful helper to get MPEG audio stream info. Return -1 if error in header, otherwise the coded frame size in bytes */ int ff_mpa_decode_header(uint32_t head, int *sample_rate, - int *channels, int *frame_size, int *bitrate, enum AVCodecID *codec_id); + int *channels, int *frame_size, int *bitrate, enum AVCodecID *codec_id, int *dual_mono); /* fast header check for resync */ static inline int ff_mpa_check_header(uint32_t header){ diff --git a/tests/ref/fate/pva-demux b/tests/ref/fate/pva-demux index 5c0e1c1ea0..2749ea9f07 100644 --- a/tests/ref/fate/pva-demux +++ b/tests/ref/fate/pva-demux @@ -7,7 +7,7 @@ #media_type 1: audio #codec_id 1: mp2 #sample_rate 1: 48000 -#channel_layout_name 1: stereo +#channel_layout_name 1: 2 channels (FC+FC) 1, 0, 0, 2160, 384, 0x071abcc8 1, 2160, 2160, 2160, 384, 0x31c9aee0 1, 4320, 4320, 2160, 384, 0xa50eaa94 -- 2.43.0 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".