*/
/**
- * @file dca.c
+ * @file libavcodec/dca.c
*/
#include <math.h>
#include "avcodec.h"
#include "dsputil.h"
-#include "bitstream.h"
+#include "get_bits.h"
+#include "put_bits.h"
#include "dcadata.h"
#include "dcahuff.h"
#include "dca.h"
+#include "synth_filter.h"
//#define TRACE
DCA_4F2R
};
+/* Tables for mapping dts channel configurations to libavcodec multichannel api.
+ * Some compromises have been made for special configurations. Most configurations
+ * are never used so complete accuracy is not needed.
+ *
+ * L = left, R = right, C = center, S = surround, F = front, R = rear, T = total, OV = overhead.
+ * S -> side, when both rear and back are configured move one of them to the side channel
+ * OV -> center back
+ * All 2 channel configurations -> CH_LAYOUT_STEREO
+ */
+
+static const int64_t dca_core_channel_layout[] = {
+ CH_FRONT_CENTER, ///< 1, A
+ CH_LAYOUT_STEREO, ///< 2, A + B (dual mono)
+ CH_LAYOUT_STEREO, ///< 2, L + R (stereo)
+ CH_LAYOUT_STEREO, ///< 2, (L+R) + (L-R) (sum-difference)
+ CH_LAYOUT_STEREO, ///< 2, LT +RT (left and right total)
+ CH_LAYOUT_STEREO|CH_FRONT_CENTER, ///< 3, C+L+R
+ CH_LAYOUT_STEREO|CH_BACK_CENTER, ///< 3, L+R+S
+ CH_LAYOUT_STEREO|CH_FRONT_CENTER|CH_BACK_CENTER, ///< 4, C + L + R+ S
+ CH_LAYOUT_STEREO|CH_SIDE_LEFT|CH_SIDE_RIGHT, ///< 4, L + R +SL+ SR
+ CH_LAYOUT_STEREO|CH_FRONT_CENTER|CH_SIDE_LEFT|CH_SIDE_RIGHT, ///< 5, C + L + R+ SL+SR
+ CH_LAYOUT_STEREO|CH_SIDE_LEFT|CH_SIDE_RIGHT|CH_FRONT_LEFT_OF_CENTER|CH_FRONT_RIGHT_OF_CENTER, ///< 6, CL + CR + L + R + SL + SR
+ CH_LAYOUT_STEREO|CH_BACK_LEFT|CH_BACK_RIGHT|CH_FRONT_CENTER|CH_BACK_CENTER, ///< 6, C + L + R+ LR + RR + OV
+ CH_FRONT_CENTER|CH_FRONT_RIGHT_OF_CENTER|CH_FRONT_LEFT_OF_CENTER|CH_BACK_CENTER|CH_BACK_LEFT|CH_BACK_RIGHT, ///< 6, CF+ CR+LF+ RF+LR + RR
+ CH_FRONT_LEFT_OF_CENTER|CH_FRONT_CENTER|CH_FRONT_RIGHT_OF_CENTER|CH_LAYOUT_STEREO|CH_SIDE_LEFT|CH_SIDE_RIGHT, ///< 7, CL + C + CR + L + R + SL + SR
+ CH_FRONT_LEFT_OF_CENTER|CH_FRONT_RIGHT_OF_CENTER|CH_LAYOUT_STEREO|CH_SIDE_LEFT|CH_SIDE_RIGHT|CH_BACK_LEFT|CH_BACK_RIGHT, ///< 8, CL + CR + L + R + SL1 + SL2+ SR1 + SR2
+ 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_CHANNEL_BITS 6
/* Subband samples history (for ADPCM) */
float subband_samples_hist[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS][4];
- DECLARE_ALIGNED_16(float, subband_fir_hist[DCA_PRIM_CHANNELS_MAX][512]);
+ DECLARE_ALIGNED_16(float, subband_fir_hist)[DCA_PRIM_CHANNELS_MAX][512];
float subband_fir_noidea[DCA_PRIM_CHANNELS_MAX][32];
int hist_index[DCA_PRIM_CHANNELS_MAX];
+ DECLARE_ALIGNED_16(float, raXin)[32];
int output; ///< type of output
float add_bias; ///< output bias
float scale_bias; ///< output scale
- DECLARE_ALIGNED_16(float, samples[1536]); /* 6 * 256 = 1536, might only need 5 */
+ DECLARE_ALIGNED_16(float, samples)[1536]; /* 6 * 256 = 1536, might only need 5 */
const float *samples_chanptr[6];
uint8_t dca_buffer[DCA_MAX_FRAME_SIZE];
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;
/* Current position in DCA frame */
int current_subframe;
int debug_flag; ///< used for suppressing repeated error messages output
DSPContext dsp;
- MDCTContext imdct;
+ FFTContext imdct;
} DCAContext;
+static const uint16_t dca_vlc_offs[] = {
+ 0, 512, 640, 768, 1282, 1794, 2436, 3080, 3770, 4454, 5364,
+ 5372, 5380, 5388, 5392, 5396, 5412, 5420, 5428, 5460, 5492, 5508,
+ 5572, 5604, 5668, 5796, 5860, 5892, 6412, 6668, 6796, 7308, 7564,
+ 7820, 8076, 8620, 9132, 9388, 9910, 10166, 10680, 11196, 11726, 12240,
+ 12752, 13298, 13810, 14326, 14840, 15500, 16022, 16540, 17158, 17678, 18264,
+ 18796, 19352, 19926, 20468, 21472, 22398, 23014, 23622,
+};
+
static av_cold void dca_init_vlcs(void)
{
static int vlcs_initialized = 0;
- int i, j;
+ int i, j, c = 14;
+ static VLC_TYPE dca_table[23622][2];
if (vlcs_initialized)
return;
dca_bitalloc_index.offset = 1;
dca_bitalloc_index.wrap = 2;
- for (i = 0; i < 5; i++)
+ for (i = 0; i < 5; i++) {
+ dca_bitalloc_index.vlc[i].table = &dca_table[dca_vlc_offs[i]];
+ dca_bitalloc_index.vlc[i].table_allocated = dca_vlc_offs[i + 1] - dca_vlc_offs[i];
init_vlc(&dca_bitalloc_index.vlc[i], bitalloc_12_vlc_bits[i], 12,
bitalloc_12_bits[i], 1, 1,
- bitalloc_12_codes[i], 2, 2, 1);
+ bitalloc_12_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC);
+ }
dca_scalefactor.offset = -64;
dca_scalefactor.wrap = 2;
- for (i = 0; i < 5; i++)
+ for (i = 0; i < 5; i++) {
+ dca_scalefactor.vlc[i].table = &dca_table[dca_vlc_offs[i + 5]];
+ dca_scalefactor.vlc[i].table_allocated = dca_vlc_offs[i + 6] - dca_vlc_offs[i + 5];
init_vlc(&dca_scalefactor.vlc[i], SCALES_VLC_BITS, 129,
scales_bits[i], 1, 1,
- scales_codes[i], 2, 2, 1);
+ scales_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC);
+ }
dca_tmode.offset = 0;
dca_tmode.wrap = 1;
- for (i = 0; i < 4; i++)
+ for (i = 0; i < 4; i++) {
+ dca_tmode.vlc[i].table = &dca_table[dca_vlc_offs[i + 10]];
+ dca_tmode.vlc[i].table_allocated = dca_vlc_offs[i + 11] - dca_vlc_offs[i + 10];
init_vlc(&dca_tmode.vlc[i], tmode_vlc_bits[i], 4,
tmode_bits[i], 1, 1,
- tmode_codes[i], 2, 2, 1);
+ tmode_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC);
+ }
for(i = 0; i < 10; i++)
for(j = 0; j < 7; j++){
if(!bitalloc_codes[i][j]) break;
dca_smpl_bitalloc[i+1].offset = bitalloc_offsets[i];
dca_smpl_bitalloc[i+1].wrap = 1 + (j > 4);
+ dca_smpl_bitalloc[i+1].vlc[j].table = &dca_table[dca_vlc_offs[c]];
+ dca_smpl_bitalloc[i+1].vlc[j].table_allocated = dca_vlc_offs[c + 1] - dca_vlc_offs[c];
init_vlc(&dca_smpl_bitalloc[i+1].vlc[j], bitalloc_maxbits[i][j],
bitalloc_sizes[i],
bitalloc_bits[i][j], 1, 1,
- bitalloc_codes[i][j], 2, 2, 1);
+ bitalloc_codes[i][j], 2, 2, INIT_VLC_USE_NEW_STATIC);
+ c++;
}
vlcs_initialized = 1;
}
s->sample_rate = dca_sample_rates[get_bits(&s->gb, 4)];
if (!s->sample_rate)
return -1;
- s->bit_rate_index; = get_bits(&s->gb, 5);
+ s->bit_rate_index = get_bits(&s->gb, 5);
s->bit_rate = dca_bit_rates[s->bit_rate_index];
if (!s->bit_rate)
return -1;
s->joint_scale_factor[j][k] = scale; /*joint_scale_table[scale]; */
}
- if (!s->debug_flag & 0x02) {
+ if (!(s->debug_flag & 0x02)) {
av_log(s->avctx, AV_LOG_DEBUG,
"Joint stereo coding not supported\n");
s->debug_flag |= 0x02;
float scale, float bias)
{
const float *prCoeff;
- int i, j;
- DECLARE_ALIGNED_16(float, raXin[32]);
-
- int hist_index= s->hist_index[chans];
- float *subband_fir_hist2 = s->subband_fir_noidea[chans];
+ int i;
int subindex;
/* Reconstructed channel sample index */
for (subindex = 0; subindex < 8; subindex++) {
- float *subband_fir_hist = s->subband_fir_hist[chans] + hist_index;
/* Load in one sample from each subband and clear inactive subbands */
for (i = 0; i < s->subband_activity[chans]; i++){
- if((i-1)&2) raXin[i] = -samples_in[i][subindex];
- else raXin[i] = samples_in[i][subindex];
+ if((i-1)&2) s->raXin[i] = -samples_in[i][subindex];
+ else s->raXin[i] = samples_in[i][subindex];
}
for (; i < 32; i++)
- raXin[i] = 0.0;
-
- ff_imdct_half(&s->imdct, subband_fir_hist, raXin);
-
- /* Multiply by filter coefficients */
- for (i = 0; i < 16; i++){
- float a= subband_fir_hist2[i ];
- float b= subband_fir_hist2[i+16];
- float c= 0;
- float d= 0;
- for (j = 0; j < 512-hist_index; j += 64){
- a += prCoeff[i+j ]*(-subband_fir_hist[15-i+j]);
- b += prCoeff[i+j+16]*( subband_fir_hist[ i+j]);
- c += prCoeff[i+j+32]*( subband_fir_hist[16+i+j]);
- d += prCoeff[i+j+48]*( subband_fir_hist[31-i+j]);
- }
- for ( ; j < 512; j += 64){
- a += prCoeff[i+j ]*(-subband_fir_hist[15-i+j-512]);
- b += prCoeff[i+j+16]*( subband_fir_hist[ i+j-512]);
- c += prCoeff[i+j+32]*( subband_fir_hist[16+i+j-512]);
- d += prCoeff[i+j+48]*( subband_fir_hist[31-i+j-512]);
- }
- samples_out[i ] = a * scale + bias;
- samples_out[i+16] = b * scale + bias;
- subband_fir_hist2[i ] = c;
- subband_fir_hist2[i+16] = d;
- }
+ s->raXin[i] = 0.0;
+
+ ff_synth_filter_float(&s->imdct,
+ s->subband_fir_hist[chans], &s->hist_index[chans],
+ s->subband_fir_noidea[chans], prCoeff,
+ samples_out, s->raXin, scale, bias);
samples_out+= 32;
- hist_index = (hist_index-32)&511;
}
- s->hist_index[chans]= hist_index;
}
static void lfe_interpolation_fir(int decimation_select,
for (k = 0; k < s->prim_channels; k++) {
/* static float pcm_to_double[8] =
{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] */ ,
s->add_bias );
}
/* Generate LFE samples for this subsubframe FIXME!!! */
if (s->output & DCA_LFE) {
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,
s->lfe_data + lfe_samples +
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);
/* Outputs 20bits pcm samples */
}
PutBitContext pb;
if((unsigned)src_size > (unsigned)max_size) {
- av_log(NULL, AV_LOG_ERROR, "Input frame size larger then DCA_MAX_FRAME_SIZE!\n");
- return -1;
+// av_log(NULL, AV_LOG_ERROR, "Input frame size larger then DCA_MAX_FRAME_SIZE!\n");
+// return -1;
+ src_size = max_size;
}
mrk = AV_RB32(src);
*/
static int dca_decode_frame(AVCodecContext * avctx,
void *data, int *data_size,
- const uint8_t * buf, int buf_size)
+ AVPacket *avpkt)
{
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
int i;
int16_t *samples = data;
avctx->bit_rate = s->bit_rate;
channels = s->prim_channels + !!s->lfe;
- if(avctx->request_channels == 2 && s->prim_channels > 2) {
- channels = 2;
- s->output = DCA_STEREO;
+
+ if (s->amode<16) {
+ avctx->channel_layout = dca_core_channel_layout[s->amode];
+
+ 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
but FFmpeg doesn't support that so only set the channels if it is previously
unset. Ideally during the first probe for channels the crc should be checked
dca_init_vlcs();
dsputil_init(&s->dsp, avctx);
- ff_mdct_init(&s->imdct, 6, 1);
+ ff_mdct_init(&s->imdct, 6, 1, 1.0);
for(i = 0; i < 6; i++)
s->samples_chanptr[i] = s->samples + i * 256;
avctx->sample_fmt = SAMPLE_FMT_S16;
- if(s->dsp.float_to_int16 == ff_float_to_int16_c) {
+ if(s->dsp.float_to_int16_interleave == ff_float_to_int16_interleave_c) {
s->add_bias = 385.0f;
s->scale_bias = 1.0 / 32768.0;
} else {