Commit bfeca7be authored by Justin Ruggles's avatar Justin Ruggles

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
parent be233a56
...@@ -85,6 +85,7 @@ get_next: ...@@ -85,6 +85,7 @@ get_next:
avctx->channels = avctx->request_channels; avctx->channels = avctx->request_channels;
} else { } else {
avctx->channels = s->channels; avctx->channels = s->channels;
avctx->channel_layout = s->channel_layout;
} }
avctx->bit_rate = s->bit_rate; avctx->bit_rate = s->bit_rate;
avctx->frame_size = s->samples; avctx->frame_size = s->samples;
......
...@@ -48,6 +48,7 @@ typedef struct AACAC3ParseContext { ...@@ -48,6 +48,7 @@ typedef struct AACAC3ParseContext {
int sample_rate; int sample_rate;
int bit_rate; int bit_rate;
int samples; int samples;
int64_t channel_layout;
int remaining_size; int remaining_size;
uint64_t state; uint64_t state;
......
...@@ -100,6 +100,7 @@ typedef struct { ...@@ -100,6 +100,7 @@ typedef struct {
uint32_t bit_rate; uint32_t bit_rate;
uint8_t channels; uint8_t channels;
uint16_t frame_size; uint16_t frame_size;
int64_t channel_layout;
/** @} */ /** @} */
} AC3HeaderInfo; } AC3HeaderInfo;
......
...@@ -121,6 +121,9 @@ int ff_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr) ...@@ -121,6 +121,9 @@ int ff_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr)
(hdr->num_blocks * 256.0)); (hdr->num_blocks * 256.0));
hdr->channels = ff_ac3_channels_tab[hdr->channel_mode] + hdr->lfe_on; 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; return 0;
} }
...@@ -174,6 +177,7 @@ static int ac3_sync(uint64_t state, AACAC3ParseContext *hdr_info, ...@@ -174,6 +177,7 @@ static int ac3_sync(uint64_t state, AACAC3ParseContext *hdr_info,
hdr_info->sample_rate = hdr.sample_rate; hdr_info->sample_rate = hdr.sample_rate;
hdr_info->bit_rate = hdr.bit_rate; hdr_info->bit_rate = hdr.bit_rate;
hdr_info->channels = hdr.channels; hdr_info->channels = hdr.channels;
hdr_info->channel_layout = hdr.channel_layout;
hdr_info->samples = hdr.num_blocks * 256; hdr_info->samples = hdr.num_blocks * 256;
if(hdr.bitstream_id>10) if(hdr.bitstream_id>10)
hdr_info->codec_id = CODEC_ID_EAC3; hdr_info->codec_id = CODEC_ID_EAC3;
......
...@@ -285,6 +285,7 @@ static int parse_frame_header(AC3DecodeContext *s) ...@@ -285,6 +285,7 @@ static int parse_frame_header(AC3DecodeContext *s)
/* get decoding parameters from header info */ /* get decoding parameters from header info */
s->bit_alloc_params.sr_code = hdr.sr_code; s->bit_alloc_params.sr_code = hdr.sr_code;
s->channel_mode = hdr.channel_mode; s->channel_mode = hdr.channel_mode;
s->channel_layout = hdr.channel_layout;
s->lfe_on = hdr.lfe_on; s->lfe_on = hdr.lfe_on;
s->bit_alloc_params.sr_shift = hdr.sr_shift; s->bit_alloc_params.sr_shift = hdr.sr_shift;
s->sample_rate = hdr.sample_rate; s->sample_rate = hdr.sample_rate;
...@@ -1307,8 +1308,10 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size, ...@@ -1307,8 +1308,10 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size,
avctx->request_channels < s->channels) { avctx->request_channels < s->channels) {
s->out_channels = avctx->request_channels; s->out_channels = avctx->request_channels;
s->output_mode = avctx->request_channels == 1 ? AC3_CHMODE_MONO : AC3_CHMODE_STEREO; 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->channels = s->out_channels;
avctx->channel_layout = s->channel_layout;
/* set downmixing coefficients if needed */ /* set downmixing coefficients if needed */
if(s->channels != s->out_channels && !((s->output_mode & AC3_OUTPUT_LFEON) && if(s->channels != s->out_channels && !((s->output_mode & AC3_OUTPUT_LFEON) &&
......
...@@ -58,6 +58,7 @@ typedef struct { ...@@ -58,6 +58,7 @@ typedef struct {
int sample_rate; ///< sample frequency, in Hz int sample_rate; ///< sample frequency, in Hz
int num_blocks; ///< number of audio blocks int num_blocks; ///< number of audio blocks
int channel_mode; ///< channel mode (acmod) int channel_mode; ///< channel mode (acmod)
int channel_layout; ///< channel layout
int lfe_on; ///< lfe channel in use int lfe_on; ///< lfe channel in use
int channel_map; ///< custom channel map int channel_map; ///< custom channel map
int center_mix_level; ///< Center mix level index int center_mix_level; ///< Center mix level index
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
* tables taken directly from the AC-3 spec. * tables taken directly from the AC-3 spec.
*/ */
#include "avcodec.h"
#include "ac3tab.h" #include "ac3tab.h"
/** /**
...@@ -79,6 +80,20 @@ const uint8_t ff_ac3_channels_tab[8] = { ...@@ -79,6 +80,20 @@ const uint8_t ff_ac3_channels_tab[8] = {
2, 1, 2, 3, 3, 4, 4, 5 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 \ #define COMMON_CHANNEL_MAP \
{ { 0, 1, }, { 0, 1, 2, } },\ { { 0, 1, }, { 0, 1, 2, } },\
{ { 0, }, { 0, 1, } },\ { { 0, }, { 0, 1, } },\
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
extern const uint16_t ff_ac3_frame_size_tab[38][3]; extern const uint16_t ff_ac3_frame_size_tab[38][3];
extern const uint8_t ff_ac3_channels_tab[8]; 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_enc_channel_map[8][2][6];
extern const uint8_t ff_ac3_dec_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]; extern const uint16_t ff_ac3_sample_rate_tab[3];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment