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".

Reply via email to