diff options
author | Nick Brereton <nick@nbrereton.net> | 2010-06-22 08:33:00 +0000 |
---|---|---|
committer | Martin Storsjö <martin@martin.st> | 2010-06-22 08:33:00 +0000 |
commit | 6baef06e8f14d98eb3f3ca89c6d9c938b965e975 (patch) | |
tree | 8da95976d934d9b002e65b7b09130f857a9003b6 | |
parent | 77b4b7c383c4709b9d7aebf808ada1198c19aab3 (diff) | |
download | ffmpeg-6baef06e8f14d98eb3f3ca89c6d9c938b965e975.tar.gz |
Support DTS-ES extension (XCh) in dca: move original code around to allow reused by DTS-ES code
Patch by Nick Brereton, nick at nbrereton dot net
Originally committed as revision 23695 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r-- | libavcodec/dca.c | 201 |
1 files changed, 110 insertions, 91 deletions
diff --git a/libavcodec/dca.c b/libavcodec/dca.c index 407d2bf7c6..c1b19e30e7 100644 --- a/libavcodec/dca.c +++ b/libavcodec/dca.c @@ -223,8 +223,7 @@ typedef struct { int high_freq_vq[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; ///< VQ encoded high frequency subbands - float lfe_data[2 * DCA_SUBSUBFRAMES_MAX * DCA_LFE_MAX * - 2 /*history */ ]; ///< Low frequency effect data + float lfe_data[2 * DCA_LFE_MAX * (DCA_BLOCKS_MAX + 4)]; ///< Low frequency effect data int lfe_scale_factor; /* Subband samples history (for ADPCM) */ @@ -326,13 +325,85 @@ static inline void get_array(GetBitContext *gb, int *dst, int len, int bits) *dst++ = get_bits(gb, bits); } -static int dca_parse_frame_header(DCAContext * s) +static int dca_parse_audio_coding_header(DCAContext * s) { int i, j; static const float adj_table[4] = { 1.0, 1.1250, 1.2500, 1.4375 }; static const int bitlen[11] = { 0, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3 }; static const int thr[11] = { 0, 1, 3, 3, 3, 3, 7, 7, 7, 7, 7 }; + s->total_channels = get_bits(&s->gb, 3) + 1; + s->prim_channels = s->total_channels; + if (s->prim_channels > DCA_PRIM_CHANNELS_MAX) + s->prim_channels = DCA_PRIM_CHANNELS_MAX; /* We only support DTS core */ + + + for (i = 0; i < s->prim_channels; i++) { + s->subband_activity[i] = get_bits(&s->gb, 5) + 2; + if (s->subband_activity[i] > DCA_SUBBANDS) + s->subband_activity[i] = DCA_SUBBANDS; + } + for (i = 0; i < s->prim_channels; i++) { + s->vq_start_subband[i] = get_bits(&s->gb, 5) + 1; + if (s->vq_start_subband[i] > DCA_SUBBANDS) + s->vq_start_subband[i] = DCA_SUBBANDS; + } + get_array(&s->gb, s->joint_intensity, s->prim_channels, 3); + get_array(&s->gb, s->transient_huffman, s->prim_channels, 2); + get_array(&s->gb, s->scalefactor_huffman, s->prim_channels, 3); + get_array(&s->gb, s->bitalloc_huffman, s->prim_channels, 3); + + /* Get codebooks quantization indexes */ + memset(s->quant_index_huffman, 0, sizeof(s->quant_index_huffman)); + for (j = 1; j < 11; j++) + for (i = 0; i < s->prim_channels; i++) + s->quant_index_huffman[i][j] = get_bits(&s->gb, bitlen[j]); + + /* Get scale factor adjustment */ + for (j = 0; j < 11; j++) + for (i = 0; i < s->prim_channels; i++) + s->scalefactor_adj[i][j] = 1; + + for (j = 1; j < 11; j++) + for (i = 0; i < s->prim_channels; i++) + if (s->quant_index_huffman[i][j] < thr[j]) + s->scalefactor_adj[i][j] = adj_table[get_bits(&s->gb, 2)]; + + if (s->crc_present) { + /* Audio header CRC check */ + get_bits(&s->gb, 16); + } + + s->current_subframe = 0; + s->current_subsubframe = 0; + +#ifdef TRACE + av_log(s->avctx, AV_LOG_DEBUG, "subframes: %i\n", s->subframes); + av_log(s->avctx, AV_LOG_DEBUG, "prim channels: %i\n", s->prim_channels); + for (i = 0; i < s->prim_channels; i++){ + av_log(s->avctx, AV_LOG_DEBUG, "subband activity: %i\n", s->subband_activity[i]); + av_log(s->avctx, AV_LOG_DEBUG, "vq start subband: %i\n", s->vq_start_subband[i]); + av_log(s->avctx, AV_LOG_DEBUG, "joint intensity: %i\n", s->joint_intensity[i]); + av_log(s->avctx, AV_LOG_DEBUG, "transient mode codebook: %i\n", s->transient_huffman[i]); + av_log(s->avctx, AV_LOG_DEBUG, "scale factor codebook: %i\n", s->scalefactor_huffman[i]); + av_log(s->avctx, AV_LOG_DEBUG, "bit allocation quantizer: %i\n", s->bitalloc_huffman[i]); + av_log(s->avctx, AV_LOG_DEBUG, "quant index huff:"); + for (j = 0; j < 11; j++) + av_log(s->avctx, AV_LOG_DEBUG, " %i", + s->quant_index_huffman[i][j]); + av_log(s->avctx, AV_LOG_DEBUG, "\n"); + av_log(s->avctx, AV_LOG_DEBUG, "scalefac adj:"); + for (j = 0; j < 11; j++) + av_log(s->avctx, AV_LOG_DEBUG, " %1.3f", s->scalefactor_adj[i][j]); + av_log(s->avctx, AV_LOG_DEBUG, "\n"); + } +#endif + + return 0; +} + +static int dca_parse_frame_header(DCAContext * s) +{ init_get_bits(&s->gb, s->dca_buffer, s->dca_buffer_size * 8); /* Sync code */ @@ -422,74 +493,8 @@ static int dca_parse_frame_header(DCAContext * s) /* Primary audio coding header */ s->subframes = get_bits(&s->gb, 4) + 1; - s->total_channels = get_bits(&s->gb, 3) + 1; - s->prim_channels = s->total_channels; - if (s->prim_channels > DCA_PRIM_CHANNELS_MAX) - s->prim_channels = DCA_PRIM_CHANNELS_MAX; /* We only support DTS core */ - - - for (i = 0; i < s->prim_channels; i++) { - s->subband_activity[i] = get_bits(&s->gb, 5) + 2; - if (s->subband_activity[i] > DCA_SUBBANDS) - s->subband_activity[i] = DCA_SUBBANDS; - } - for (i = 0; i < s->prim_channels; i++) { - s->vq_start_subband[i] = get_bits(&s->gb, 5) + 1; - if (s->vq_start_subband[i] > DCA_SUBBANDS) - s->vq_start_subband[i] = DCA_SUBBANDS; - } - get_array(&s->gb, s->joint_intensity, s->prim_channels, 3); - get_array(&s->gb, s->transient_huffman, s->prim_channels, 2); - get_array(&s->gb, s->scalefactor_huffman, s->prim_channels, 3); - get_array(&s->gb, s->bitalloc_huffman, s->prim_channels, 3); - - /* Get codebooks quantization indexes */ - memset(s->quant_index_huffman, 0, sizeof(s->quant_index_huffman)); - for (j = 1; j < 11; j++) - for (i = 0; i < s->prim_channels; i++) - s->quant_index_huffman[i][j] = get_bits(&s->gb, bitlen[j]); - - /* Get scale factor adjustment */ - for (j = 0; j < 11; j++) - for (i = 0; i < s->prim_channels; i++) - s->scalefactor_adj[i][j] = 1; - - for (j = 1; j < 11; j++) - for (i = 0; i < s->prim_channels; i++) - if (s->quant_index_huffman[i][j] < thr[j]) - s->scalefactor_adj[i][j] = adj_table[get_bits(&s->gb, 2)]; - - if (s->crc_present) { - /* Audio header CRC check */ - get_bits(&s->gb, 16); - } - - s->current_subframe = 0; - s->current_subsubframe = 0; - -#ifdef TRACE - av_log(s->avctx, AV_LOG_DEBUG, "subframes: %i\n", s->subframes); - av_log(s->avctx, AV_LOG_DEBUG, "prim channels: %i\n", s->prim_channels); - for(i = 0; i < s->prim_channels; i++){ - av_log(s->avctx, AV_LOG_DEBUG, "subband activity: %i\n", s->subband_activity[i]); - av_log(s->avctx, AV_LOG_DEBUG, "vq start subband: %i\n", s->vq_start_subband[i]); - av_log(s->avctx, AV_LOG_DEBUG, "joint intensity: %i\n", s->joint_intensity[i]); - av_log(s->avctx, AV_LOG_DEBUG, "transient mode codebook: %i\n", s->transient_huffman[i]); - av_log(s->avctx, AV_LOG_DEBUG, "scale factor codebook: %i\n", s->scalefactor_huffman[i]); - av_log(s->avctx, AV_LOG_DEBUG, "bit allocation quantizer: %i\n", s->bitalloc_huffman[i]); - av_log(s->avctx, AV_LOG_DEBUG, "quant index huff:"); - for (j = 0; j < 11; j++) - av_log(s->avctx, AV_LOG_DEBUG, " %i", - s->quant_index_huffman[i][j]); - av_log(s->avctx, AV_LOG_DEBUG, "\n"); - av_log(s->avctx, AV_LOG_DEBUG, "scalefac adj:"); - for (j = 0; j < 11; j++) - av_log(s->avctx, AV_LOG_DEBUG, " %1.3f", s->scalefactor_adj[i][j]); - av_log(s->avctx, AV_LOG_DEBUG, "\n"); - } -#endif - return 0; + return dca_parse_audio_coding_header(s); } @@ -503,7 +508,7 @@ static inline int get_scale(GetBitContext *gb, int level, int value) return value; } -static int dca_subframe_header(DCAContext * s) +static int dca_subframe_header(DCAContext * s, int block_index) { /* Primary audio coding side information */ int j, k; @@ -660,10 +665,11 @@ static int dca_subframe_header(DCAContext * s) /* Low frequency effect data */ if (s->lfe) { /* LFE samples */ - int lfe_samples = 2 * s->lfe * s->subsubframes; + int lfe_samples = 2 * s->lfe * (4 + block_index); + int lfe_end_sample = 2 * s->lfe * (4 + block_index + s->subsubframes); float lfe_scale; - for (j = lfe_samples; j < lfe_samples * 2; j++) { + for (j = lfe_samples; j < lfe_end_sample; j++) { /* Signed 8 bits int */ s->lfe_data[j] = get_sbits(&s->gb, 8); } @@ -674,7 +680,7 @@ static int dca_subframe_header(DCAContext * s) /* Quantization step size * scale factor */ lfe_scale = 0.035 * s->lfe_scale_factor; - for (j = lfe_samples; j < lfe_samples * 2; j++) + for (j = lfe_samples; j < lfe_end_sample; j++) s->lfe_data[j] *= lfe_scale; } @@ -740,9 +746,11 @@ static int dca_subframe_header(DCAContext * s) for (k = s->vq_start_subband[j]; k < s->subband_activity[j]; k++) av_log(s->avctx, AV_LOG_DEBUG, "VQ index: %i\n", s->high_freq_vq[j][k]); if(s->lfe){ - int lfe_samples = 2 * s->lfe * s->subsubframes; + int lfe_samples = 2 * s->lfe * (4 + block_index); + int lfe_end_sample = 2 * s->lfe * (4 + block_index + s->subsubframes[s->current_subframe]); + av_log(s->avctx, AV_LOG_DEBUG, "LFE samples:\n"); - for (j = lfe_samples; j < lfe_samples * 2; j++) + for (j = lfe_samples; j < lfe_end_sample; j++) av_log(s->avctx, AV_LOG_DEBUG, " %f", s->lfe_data[j]); av_log(s->avctx, AV_LOG_DEBUG, "\n"); } @@ -1043,6 +1051,14 @@ static int dca_subsubframe(DCAContext * s, int block_index) memcpy(s->subband_samples_hist[k][l], &subband_samples[k][l][4], 4 * sizeof(subband_samples[0][0][0])); + return 0; +} + +static int dca_filter_channels(DCAContext * s, int block_index) +{ + float (*subband_samples)[DCA_SUBBANDS][8] = s->subband_samples[block_index]; + int k; + /* 32 subbands QMF */ for (k = 0; k < s->prim_channels; k++) { /* static float pcm_to_double[8] = @@ -1053,18 +1069,14 @@ static int dca_subsubframe(DCAContext * s, int block_index) } /* Down mixing */ - - if (s->prim_channels > dca_channels[s->output & DCA_CHANNEL_MASK]) { + if (s->avctx->request_channels == 2 && s->prim_channels > 2) { dca_downmix(s->samples, s->amode, s->downmix_coef); } /* Generate LFE samples for this subsubframe FIXME!!! */ if (s->output & DCA_LFE) { - int lfe_samples = 2 * s->lfe * s->subsubframes; - lfe_interpolation_fir(s, s->lfe, 2 * s->lfe, - s->lfe_data + lfe_samples + - 2 * s->lfe * subsubframe, + s->lfe_data + 2 * s->lfe * (block_index + 4), &s->samples[256 * dca_lfe_index[s->amode]], (1.0/256.0)*s->scale_bias, s->add_bias); /* Outputs 20bits pcm samples */ @@ -1077,7 +1089,6 @@ static int dca_subsubframe(DCAContext * s, int block_index) static int dca_subframe_footer(DCAContext * s) { int aux_data_count = 0, i; - int lfe_samples; /* * Unpack optional information @@ -1095,11 +1106,6 @@ static int dca_subframe_footer(DCAContext * s) if (s->crc_present && (s->downmix || s->dynrange)) get_bits(&s->gb, 16); - lfe_samples = 2 * s->lfe * s->subsubframes; - for (i = 0; i < lfe_samples; i++) { - s->lfe_data[i] = s->lfe_data[i + lfe_samples]; - } - return 0; } @@ -1124,7 +1130,7 @@ static int dca_decode_block(DCAContext * s, int block_index) av_log(s->avctx, AV_LOG_DEBUG, "DSYNC dca_subframe_header\n"); #endif /* Read subframe header */ - if (dca_subframe_header(s)) + if (dca_subframe_header(s, block_index)) return -1; } @@ -1205,6 +1211,7 @@ static int dca_decode_frame(AVCodecContext * avctx, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; + int lfe_samples; int i; int16_t *samples = data; DCAContext *s = avctx->priv_data; @@ -1227,6 +1234,10 @@ static int dca_decode_frame(AVCodecContext * avctx, avctx->sample_rate = s->sample_rate; avctx->bit_rate = s->bit_rate; + for (i = 0; i < (s->sample_blocks / 8); i++) { + dca_decode_block(s, i); + } + channels = s->prim_channels + !!s->lfe; if (s->amode<16) { @@ -1264,12 +1275,20 @@ static int dca_decode_frame(AVCodecContext * avctx, if(*data_size < (s->sample_blocks / 8) * 256 * sizeof(int16_t) * channels) return -1; *data_size = 256 / 8 * s->sample_blocks * sizeof(int16_t) * channels; + + /* filter to get final output */ for (i = 0; i < (s->sample_blocks / 8); i++) { - dca_decode_block(s, i); + dca_filter_channels(s, i); s->dsp.float_to_int16_interleave(samples, s->samples_chanptr, 256, channels); samples += 256 * channels; } + /* update lfe history */ + lfe_samples = 2 * s->lfe * (s->sample_blocks / 8); + for (i = 0; i < 2 * s->lfe * 4; i++) { + s->lfe_data[i] = s->lfe_data[i + lfe_samples]; + } + return buf_size; } @@ -1294,7 +1313,7 @@ static av_cold int dca_decode_init(AVCodecContext * avctx) ff_synth_filter_init(&s->synth); ff_dcadsp_init(&s->dcadsp); - for(i = 0; i < 6; i++) + for (i = 0; i < DCA_PRIM_CHANNELS_MAX+1; i++) s->samples_chanptr[i] = s->samples + i * 256; avctx->sample_fmt = SAMPLE_FMT_S16; |