Proper channel output reordering for the dca decoder.

Originally committed as revision 15832 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
Benjamin Larsson 2008-11-15 20:31:03 +00:00
parent 8257d2ad51
commit 92765276fb

View File

@ -88,6 +88,48 @@ static const int64_t dca_core_channel_layout[] = {
CH_FRONT_LEFT_OF_CENTER|CH_FRONT_CENTER|CH_FRONT_RIGHT_OF_CENTER|CH_LAYOUT_STEREO|CH_SIDE_LEFT|CH_BACK_CENTER|CH_SIDE_RIGHT, ///< 8, CL + C+ CR + L + R + SL + S+ SR CH_FRONT_LEFT_OF_CENTER|CH_FRONT_CENTER|CH_FRONT_RIGHT_OF_CENTER|CH_LAYOUT_STEREO|CH_SIDE_LEFT|CH_BACK_CENTER|CH_SIDE_RIGHT, ///< 8, CL + C+ CR + L + R + SL + S+ SR
}; };
static const int8_t dca_lfe_index[] = {
1,2,2,2,2,3,2,3,2,3,2,3,1,3,2,3
};
static const int8_t dca_channel_reorder_lfe[][8] = {
{ 0, -1, -1, -1, -1, -1, -1, -1},
{ 0, 1, -1, -1, -1, -1, -1, -1},
{ 0, 1, -1, -1, -1, -1, -1, -1},
{ 0, 1, -1, -1, -1, -1, -1, -1},
{ 0, 1, -1, -1, -1, -1, -1, -1},
{ 2, 0, 1, -1, -1, -1, -1, -1},
{ 0, 1, 3, -1, -1, -1, -1, -1},
{ 2, 0, 1, 4, -1, -1, -1, -1},
{ 0, 1, 3, 4, -1, -1, -1, -1},
{ 2, 0, 1, 4, 5, -1, -1, -1},
{ 3, 4, 0, 1, 5, 6, -1, -1},
{ 2, 0, 1, 4, 5, 6, -1, -1},
{ 0, 6, 4, 5, 2, 3, -1, -1},
{ 4, 2, 5, 0, 1, 6, 7, -1},
{ 5, 6, 0, 1, 7, 3, 8, 4},
{ 4, 2, 5, 0, 1, 6, 8, 7},
};
static const int8_t dca_channel_reorder_nolfe[][8] = {
{ 0, -1, -1, -1, -1, -1, -1, -1},
{ 0, 1, -1, -1, -1, -1, -1, -1},
{ 0, 1, -1, -1, -1, -1, -1, -1},
{ 0, 1, -1, -1, -1, -1, -1, -1},
{ 0, 1, -1, -1, -1, -1, -1, -1},
{ 2, 0, 1, -1, -1, -1, -1, -1},
{ 0, 1, 2, -1, -1, -1, -1, -1},
{ 2, 0, 1, 3, -1, -1, -1, -1},
{ 0, 1, 2, 3, -1, -1, -1, -1},
{ 2, 0, 1, 3, 4, -1, -1, -1},
{ 2, 3, 0, 1, 4, 5, -1, -1},
{ 2, 0, 1, 3, 4, 5, -1, -1},
{ 0, 5, 3, 4, 1, 2, -1, -1},
{ 3, 2, 4, 0, 1, 5, 6, -1},
{ 4, 5, 0, 1, 6, 2, 7, 3},
{ 3, 2, 4, 0, 1, 5, 7, 6},
};
#define DCA_DOLBY 101 /* FIXME */ #define DCA_DOLBY 101 /* FIXME */
@ -198,6 +240,7 @@ typedef struct {
uint8_t dca_buffer[DCA_MAX_FRAME_SIZE]; uint8_t dca_buffer[DCA_MAX_FRAME_SIZE];
int dca_buffer_size; ///< how much data is in the dca_buffer int dca_buffer_size; ///< how much data is in the dca_buffer
const int8_t* channel_order_tab; ///< channel reordering table, lfe and non lfe
GetBitContext gb; GetBitContext gb;
/* Current position in DCA frame */ /* Current position in DCA frame */
int current_subframe; int current_subframe;
@ -1013,7 +1056,7 @@ static int dca_subsubframe(DCAContext * s)
for (k = 0; k < s->prim_channels; k++) { for (k = 0; k < s->prim_channels; k++) {
/* static float pcm_to_double[8] = /* static float pcm_to_double[8] =
{32768.0, 32768.0, 524288.0, 524288.0, 0, 8388608.0, 8388608.0};*/ {32768.0, 32768.0, 524288.0, 524288.0, 0, 8388608.0, 8388608.0};*/
qmf_32_subbands(s, k, subband_samples[k], &s->samples[256 * k], qmf_32_subbands(s, k, subband_samples[k], &s->samples[256 * s->channel_order_tab[k]],
M_SQRT1_2*s->scale_bias /*pcm_to_double[s->source_pcm_res] */ , M_SQRT1_2*s->scale_bias /*pcm_to_double[s->source_pcm_res] */ ,
s->add_bias ); s->add_bias );
} }
@ -1027,12 +1070,11 @@ static int dca_subsubframe(DCAContext * s)
/* Generate LFE samples for this subsubframe FIXME!!! */ /* Generate LFE samples for this subsubframe FIXME!!! */
if (s->output & DCA_LFE) { if (s->output & DCA_LFE) {
int lfe_samples = 2 * s->lfe * s->subsubframes; int lfe_samples = 2 * s->lfe * s->subsubframes;
int i_channels = dca_channels[s->output & DCA_CHANNEL_MASK];
lfe_interpolation_fir(s->lfe, 2 * s->lfe, lfe_interpolation_fir(s->lfe, 2 * s->lfe,
s->lfe_data + lfe_samples + s->lfe_data + lfe_samples +
2 * s->lfe * subsubframe, 2 * s->lfe * subsubframe,
&s->samples[256 * i_channels], &s->samples[256 * dca_lfe_index[s->amode]],
(1.0/256.0)*s->scale_bias, s->add_bias); (1.0/256.0)*s->scale_bias, s->add_bias);
/* Outputs 20bits pcm samples */ /* Outputs 20bits pcm samples */
} }
@ -1192,15 +1234,26 @@ static int dca_decode_frame(AVCodecContext * avctx,
avctx->bit_rate = s->bit_rate; avctx->bit_rate = s->bit_rate;
channels = s->prim_channels + !!s->lfe; channels = s->prim_channels + !!s->lfe;
if(avctx->request_channels == 2 && s->prim_channels > 2) {
channels = 2; if (s->amode<16) {
s->output = DCA_STEREO;
avctx->channel_layout = CH_LAYOUT_STEREO;
}
if (s->amode<16)
avctx->channel_layout = dca_core_channel_layout[s->amode]; avctx->channel_layout = dca_core_channel_layout[s->amode];
if (s->lfe) avctx->channel_layout |= CH_LOW_FREQUENCY; if (s->lfe) {
avctx->channel_layout |= CH_LOW_FREQUENCY;
s->channel_order_tab = dca_channel_reorder_lfe[s->amode];
} else
s->channel_order_tab = dca_channel_reorder_nolfe[s->amode];
if(avctx->request_channels == 2 && s->prim_channels > 2) {
channels = 2;
s->output = DCA_STEREO;
avctx->channel_layout = CH_LAYOUT_STEREO;
}
} else {
av_log(avctx, AV_LOG_ERROR, "Non standard configuration %d !\n",s->amode);
return -1;
}
/* There is nothing that prevents a dts frame to change channel configuration /* There is nothing that prevents a dts frame to change channel configuration
but FFmpeg doesn't support that so only set the channels if it is previously but FFmpeg doesn't support that so only set the channels if it is previously