From bfeca7beb63bc297c8c59469a53e469d11ec4d23 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 19 Apr 2009 15:05:32 +0000 Subject: [PATCH] Add channel layout support to the AC-3 decoder and AC-3 parser. Originally committed as revision 18622 to svn://svn.ffmpeg.org/ffmpeg/trunk --- libavcodec/aac_ac3_parser.c | 1 + libavcodec/aac_ac3_parser.h | 1 + libavcodec/ac3.h | 1 + libavcodec/ac3_parser.c | 4 ++++ libavcodec/ac3dec.c | 3 +++ libavcodec/ac3dec.h | 1 + libavcodec/ac3tab.c | 15 +++++++++++++++ libavcodec/ac3tab.h | 1 + 8 files changed, 27 insertions(+) diff --git a/libavcodec/aac_ac3_parser.c b/libavcodec/aac_ac3_parser.c index ab3269f2db..b51f1769f7 100644 --- a/libavcodec/aac_ac3_parser.c +++ b/libavcodec/aac_ac3_parser.c @@ -85,6 +85,7 @@ get_next: avctx->channels = avctx->request_channels; } else { avctx->channels = s->channels; + avctx->channel_layout = s->channel_layout; } avctx->bit_rate = s->bit_rate; avctx->frame_size = s->samples; diff --git a/libavcodec/aac_ac3_parser.h b/libavcodec/aac_ac3_parser.h index 04fd8f1974..75f6d4be4a 100644 --- a/libavcodec/aac_ac3_parser.h +++ b/libavcodec/aac_ac3_parser.h @@ -48,6 +48,7 @@ typedef struct AACAC3ParseContext { int sample_rate; int bit_rate; int samples; + int64_t channel_layout; int remaining_size; uint64_t state; diff --git a/libavcodec/ac3.h b/libavcodec/ac3.h index 7391be1b82..276ecba4c7 100644 --- a/libavcodec/ac3.h +++ b/libavcodec/ac3.h @@ -100,6 +100,7 @@ typedef struct { uint32_t bit_rate; uint8_t channels; uint16_t frame_size; + int64_t channel_layout; /** @} */ } AC3HeaderInfo; diff --git a/libavcodec/ac3_parser.c b/libavcodec/ac3_parser.c index 35d8a17fb1..856f97aafb 100644 --- a/libavcodec/ac3_parser.c +++ b/libavcodec/ac3_parser.c @@ -121,6 +121,9 @@ int ff_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr) (hdr->num_blocks * 256.0)); hdr->channels = ff_ac3_channels_tab[hdr->channel_mode] + hdr->lfe_on; } + hdr->channel_layout = ff_ac3_channel_layout_tab[hdr->channel_mode]; + if (hdr->lfe_on) + hdr->channel_layout |= CH_LOW_FREQUENCY; return 0; } @@ -174,6 +177,7 @@ static int ac3_sync(uint64_t state, AACAC3ParseContext *hdr_info, hdr_info->sample_rate = hdr.sample_rate; hdr_info->bit_rate = hdr.bit_rate; hdr_info->channels = hdr.channels; + hdr_info->channel_layout = hdr.channel_layout; hdr_info->samples = hdr.num_blocks * 256; if(hdr.bitstream_id>10) hdr_info->codec_id = CODEC_ID_EAC3; diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c index 4a177aae69..c142ca9bb2 100644 --- a/libavcodec/ac3dec.c +++ b/libavcodec/ac3dec.c @@ -285,6 +285,7 @@ static int parse_frame_header(AC3DecodeContext *s) /* get decoding parameters from header info */ s->bit_alloc_params.sr_code = hdr.sr_code; s->channel_mode = hdr.channel_mode; + s->channel_layout = hdr.channel_layout; s->lfe_on = hdr.lfe_on; s->bit_alloc_params.sr_shift = hdr.sr_shift; s->sample_rate = hdr.sample_rate; @@ -1307,8 +1308,10 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size, avctx->request_channels < s->channels) { s->out_channels = avctx->request_channels; s->output_mode = avctx->request_channels == 1 ? AC3_CHMODE_MONO : AC3_CHMODE_STEREO; + s->channel_layout = ff_ac3_channel_layout_tab[s->output_mode]; } avctx->channels = s->out_channels; + avctx->channel_layout = s->channel_layout; /* set downmixing coefficients if needed */ if(s->channels != s->out_channels && !((s->output_mode & AC3_OUTPUT_LFEON) && diff --git a/libavcodec/ac3dec.h b/libavcodec/ac3dec.h index 29eb04182e..bdee7e78cf 100644 --- a/libavcodec/ac3dec.h +++ b/libavcodec/ac3dec.h @@ -58,6 +58,7 @@ typedef struct { int sample_rate; ///< sample frequency, in Hz int num_blocks; ///< number of audio blocks int channel_mode; ///< channel mode (acmod) + int channel_layout; ///< channel layout int lfe_on; ///< lfe channel in use int channel_map; ///< custom channel map int center_mix_level; ///< Center mix level index diff --git a/libavcodec/ac3tab.c b/libavcodec/ac3tab.c index cb07ac6255..ba7b204b21 100644 --- a/libavcodec/ac3tab.c +++ b/libavcodec/ac3tab.c @@ -24,6 +24,7 @@ * tables taken directly from the AC-3 spec. */ +#include "avcodec.h" #include "ac3tab.h" /** @@ -79,6 +80,20 @@ const uint8_t ff_ac3_channels_tab[8] = { 2, 1, 2, 3, 3, 4, 4, 5 }; +/** + * Maps audio coding mode (acmod) to channel layout mask. + */ +const uint16_t ff_ac3_channel_layout_tab[8] = { + CH_LAYOUT_STEREO, + CH_LAYOUT_MONO, + CH_LAYOUT_STEREO, + CH_LAYOUT_SURROUND, + CH_LAYOUT_2_1, + CH_LAYOUT_4POINT0, + CH_LAYOUT_2_2, + CH_LAYOUT_5POINT0 +}; + #define COMMON_CHANNEL_MAP \ { { 0, 1, }, { 0, 1, 2, } },\ { { 0, }, { 0, 1, } },\ diff --git a/libavcodec/ac3tab.h b/libavcodec/ac3tab.h index e4d0ce8aea..b5c2b77c9d 100644 --- a/libavcodec/ac3tab.h +++ b/libavcodec/ac3tab.h @@ -26,6 +26,7 @@ extern const uint16_t ff_ac3_frame_size_tab[38][3]; extern const uint8_t ff_ac3_channels_tab[8]; +extern const uint16_t ff_ac3_channel_layout_tab[8]; extern const uint8_t ff_ac3_enc_channel_map[8][2][6]; extern const uint8_t ff_ac3_dec_channel_map[8][2][6]; extern const uint16_t ff_ac3_sample_rate_tab[3];