[FFmpeg-devel] [PATCH] Support DTS-ES extension (XCh) in dca
Benjamin Larsson
banan
Mon Jun 21 00:08:09 CEST 2010
On 20/06/10 20:07, Nick Brereton wrote:
> Index: libavcodec/dca.c
> ===================================================================
> --- libavcodec/dca.c (revision 23659)
> +++ libavcodec/dca.c (working copy)
> @@ -1,4 +1,4 @@
> -/*
> + /*
Remove.
> * DCA compatible decoder
> * Copyright (C) 2004 Gildas Bazin
> * Copyright (C) 2004 Benjamin Zores
> @@ -41,10 +41,12 @@
>
> //#define TRACE
>
> -#define DCA_PRIM_CHANNELS_MAX (5)
> +#define DCA_PRIM_CHANNELS_MAX (7)
> #define DCA_SUBBANDS (32)
> #define DCA_ABITS_MAX (32) /* Should be 28 */
> -#define DCA_SUBSUBFAMES_MAX (4)
> +#define DCA_SUBSUBFRAMES_MAX (4)
Ok in separate cosmetics patch.
> +#define DCA_SUBFRAMES_MAX (16)
> +#define DCA_BLOCKS_MAX (16)
> #define DCA_LFE_MAX (3)
>
> enum DCAMode {
> @@ -94,45 +96,82 @@
> 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_lfe[][9] = {
> + { 0, -1, -1, -1, -1, -1, -1, -1, -1},
> + { 0, 1, -1, -1, -1, -1, -1, -1, -1},
> + { 0, 1, -1, -1, -1, -1, -1, -1, -1},
> + { 0, 1, -1, -1, -1, -1, -1, -1, -1},
> + { 0, 1, -1, -1, -1, -1, -1, -1, -1},
> + { 2, 0, 1, -1, -1, -1, -1, -1, -1},
> + { 0, 1, 3, -1, -1, -1, -1, -1, -1},
> + { 2, 0, 1, 4, -1, -1, -1, -1, -1},
> + { 0, 1, 3, 4, -1, -1, -1, -1, -1},
> + { 2, 0, 1, 4, 5, -1, -1, -1, -1},
> + { 3, 4, 0, 1, 5, 6, -1, -1, -1},
> + { 2, 0, 1, 4, 5, 6, -1, -1, -1},
> + { 0, 6, 4, 5, 2, 3, -1, -1, -1},
> + { 4, 2, 5, 0, 1, 6, 7, -1, -1},
> + { 5, 6, 0, 1, 7, 3, 8, 4, -1},
> + { 4, 2, 5, 0, 1, 6, 8, 7, -1},
> };
>
> -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},
> +static const int8_t dca_channel_reorder_lfe_xch[][9] = {
> + { 0, 2, -1, -1, -1, -1, -1, -1, -1},
> + { 0, 1, 3, -1, -1, -1, -1, -1, -1},
> + { 0, 1, 3, -1, -1, -1, -1, -1, -1},
> + { 0, 1, 3, -1, -1, -1, -1, -1, -1},
> + { 0, 1, 3, -1, -1, -1, -1, -1, -1},
> + { 2, 0, 1, 4, -1, -1, -1, -1, -1},
> + { 0, 1, 3, 4, -1, -1, -1, -1, -1},
> + { 2, 0, 1, 4, 5, -1, -1, -1, -1},
> + { 0, 1, 4, 5, 3, -1, -1, -1, -1},
> + { 2, 0, 1, 5, 6, 4, -1, -1, -1},
> + { 3, 4, 0, 1, 6, 7, 5, -1, -1},
> + { 2, 0, 1, 4, 5, 6, 7, -1, -1},
> + { 0, 6, 4, 5, 2, 3, 7, -1, -1},
> + { 4, 2, 5, 0, 1, 7, 8, 6, -1},
> + { 5, 6, 0, 1, 8, 3, 9, 4, 7},
> + { 4, 2, 5, 0, 1, 6, 9, 8, 7},
> };
>
> +static const int8_t dca_channel_reorder_nolfe[][9] = {
> + { 0, -1, -1, -1, -1, -1, -1, -1, -1},
> + { 0, 1, -1, -1, -1, -1, -1, -1, -1},
> + { 0, 1, -1, -1, -1, -1, -1, -1, -1},
> + { 0, 1, -1, -1, -1, -1, -1, -1, -1},
> + { 0, 1, -1, -1, -1, -1, -1, -1, -1},
> + { 2, 0, 1, -1, -1, -1, -1, -1, -1},
> + { 0, 1, 2, -1, -1, -1, -1, -1, -1},
> + { 2, 0, 1, 3, -1, -1, -1, -1, -1},
> + { 0, 1, 2, 3, -1, -1, -1, -1, -1},
> + { 2, 0, 1, 3, 4, -1, -1, -1, -1},
> + { 2, 3, 0, 1, 4, 5, -1, -1, -1},
> + { 2, 0, 1, 3, 4, 5, -1, -1, -1},
> + { 0, 5, 3, 4, 1, 2, -1, -1, -1},
> + { 3, 2, 4, 0, 1, 5, 6, -1, -1},
> + { 4, 5, 0, 1, 6, 2, 7, 3, -1},
> + { 3, 2, 4, 0, 1, 5, 7, 6, -1},
> +};
>
> +static const int8_t dca_channel_reorder_nolfe_xch[][9] = {
> + { 0, 1, -1, -1, -1, -1, -1, -1, -1},
> + { 0, 1, 2, -1, -1, -1, -1, -1, -1},
> + { 0, 1, 2, -1, -1, -1, -1, -1, -1},
> + { 0, 1, 2, -1, -1, -1, -1, -1, -1},
> + { 0, 1, 2, -1, -1, -1, -1, -1, -1},
> + { 2, 0, 1, 3, -1, -1, -1, -1, -1},
> + { 0, 1, 2, 3, -1, -1, -1, -1, -1},
> + { 2, 0, 1, 3, 4, -1, -1, -1, -1},
> + { 0, 1, 3, 4, 2, -1, -1, -1, -1},
> + { 2, 0, 1, 4, 5, 3, -1, -1, -1},
> + { 2, 3, 0, 1, 5, 6, 4, -1, -1},
> + { 2, 0, 1, 3, 4, 5, 6, -1, -1},
> + { 0, 5, 3, 4, 1, 2, 6, -1, -1},
> + { 3, 2, 4, 0, 1, 6, 7, 5, -1},
> + { 4, 5, 0, 1, 7, 2, 8, 3, 6},
> + { 3, 2, 4, 0, 1, 5, 8, 7, 6},
> +};
> +
Ok.
> #define DCA_DOLBY 101 /* FIXME */
>
> #define DCA_CHANNEL_BITS 6
> @@ -197,7 +236,7 @@
> /* Primary audio coding header */
> int subframes; ///< number of subframes
> int total_channels; ///< number of channels including extensions
> - int prim_channels; ///< number of primary audio channels
> + int prim_channels; ///< number of primary audio channels (core or extension)
Ok in separate cosmetics patch.
> int subband_activity[DCA_PRIM_CHANNELS_MAX]; ///< subband activity count
> int vq_start_subband[DCA_PRIM_CHANNELS_MAX]; ///< high frequency vq start subband
> int joint_intensity[DCA_PRIM_CHANNELS_MAX]; ///< joint intensity coding index
> @@ -208,8 +247,8 @@
> float scalefactor_adj[DCA_PRIM_CHANNELS_MAX][DCA_ABITS_MAX]; ///< scale factor adjustment
>
> /* Primary audio coding side information */
> - int subsubframes; ///< number of subsubframes
> - int partial_samples; ///< partial subsubframe samples count
> + int subsubframes[DCA_SUBFRAMES_MAX]; ///< number of subsubframes
> + int partial_samples[DCA_SUBFRAMES_MAX]; ///< partial subsubframe samples count
> int prediction_mode[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; ///< prediction mode (ADPCM used or not)
> int prediction_vq[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; ///< prediction VQ coefs
> int bitalloc[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; ///< bit allocation index
> @@ -222,8 +261,7 @@
>
> int high_freq_vq[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; ///< VQ encoded high frequency subbands
>
> - float lfe_data[2 * DCA_SUBSUBFAMES_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) */
> @@ -237,8 +275,9 @@
> float add_bias; ///< output bias
> float scale_bias; ///< output scale
>
> - DECLARE_ALIGNED(16, float, samples)[1536]; /* 6 * 256 = 1536, might only need 5 */
> - const float *samples_chanptr[6];
> + DECLARE_ALIGNED(16, float, subband_samples)[DCA_BLOCKS_MAX][DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS][8];
> + DECLARE_ALIGNED(16, float, samples)[(DCA_PRIM_CHANNELS_MAX+1)*256];
> + const float *samples_chanptr[DCA_PRIM_CHANNELS_MAX+1];
>
> uint8_t dca_buffer[DCA_MAX_FRAME_SIZE];
> int dca_buffer_size; ///< how much data is in the dca_buffer
> @@ -324,13 +363,88 @@
> *dst++ = get_bits(gb, bits);
> }
>
> -static int dca_parse_frame_header(DCAContext * s)
> +static int dca_parse_audio_coding_header(DCAContext * s, int base_channel)
> {
> 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 + base_channel;
> + s->prim_channels = s->total_channels;
> +
> + if (s->prim_channels > DCA_PRIM_CHANNELS_MAX) {
> + av_log(s->avctx, AV_LOG_INFO, "max channels exceeded (recieved %d)\n", s->prim_channels);
> + s->prim_channels = DCA_PRIM_CHANNELS_MAX; /* We only support DTS core */
The comment might be incorrect here now.
> + }
> +
> + for (i = base_channel; 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 = base_channel; 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 + base_channel, s->prim_channels - base_channel, 3);
> + get_array(&s->gb, s->transient_huffman + base_channel, s->prim_channels - base_channel, 2);
> + get_array(&s->gb, s->scalefactor_huffman + base_channel, s->prim_channels - base_channel, 3);
> + get_array(&s->gb, s->bitalloc_huffman + base_channel, s->prim_channels - base_channel, 3);
> +
> + /* Get codebooks quantization indexes */
> + if(!base_channel)
> + memset(s->quant_index_huffman, 0, sizeof(s->quant_index_huffman));
> + for (j = 1; j < 11; j++)
> + for (i = base_channel; 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 = base_channel; i < s->prim_channels; i++)
> + s->scalefactor_adj[i][j] = 1;
> +
> + for (j = 1; j < 11; j++)
> + for (i = base_channel; 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 = base_channel; 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 */
> @@ -420,74 +534,8 @@
>
> /* 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, 0);
> }
>
>
> @@ -501,20 +549,23 @@
> return value;
> }
>
> -static int dca_subframe_header(DCAContext * s)
> +static int dca_subframe_header(DCAContext * s, int base_channel, int block_index)
> {
> /* Primary audio coding side information */
> int j, k;
>
> - s->subsubframes = get_bits(&s->gb, 2) + 1;
> - s->partial_samples = get_bits(&s->gb, 3);
> - for (j = 0; j < s->prim_channels; j++) {
> + if(!base_channel) {
> + s->subsubframes[s->current_subframe] = get_bits(&s->gb, 2) + 1;
> + s->partial_samples[s->current_subframe] = get_bits(&s->gb, 3);
> + }
> +
> + for (j = base_channel; j < s->prim_channels; j++) {
> for (k = 0; k < s->subband_activity[j]; k++)
> s->prediction_mode[j][k] = get_bits(&s->gb, 1);
> }
>
> /* Get prediction codebook */
> - for (j = 0; j < s->prim_channels; j++) {
> + for (j = base_channel; j < s->prim_channels; j++) {
> for (k = 0; k < s->subband_activity[j]; k++) {
> if (s->prediction_mode[j][k] > 0) {
> /* (Prediction coefficient VQ address) */
> @@ -524,7 +575,7 @@
> }
>
> /* Bit allocation index */
> - for (j = 0; j < s->prim_channels; j++) {
> + for (j = base_channel; j < s->prim_channels; j++) {
> for (k = 0; k < s->vq_start_subband[j]; k++) {
> if (s->bitalloc_huffman[j] == 6)
> s->bitalloc[j][k] = get_bits(&s->gb, 5);
> @@ -548,10 +599,10 @@
> }
>
> /* Transition mode */
> - for (j = 0; j < s->prim_channels; j++) {
> + for (j = base_channel; j < s->prim_channels; j++) {
> for (k = 0; k < s->subband_activity[j]; k++) {
> s->transition_mode[j][k] = 0;
> - if (s->subsubframes > 1 &&
> + if (s->subsubframes[s->current_subframe] > 1 &&
> k < s->vq_start_subband[j] && s->bitalloc[j][k] > 0) {
> s->transition_mode[j][k] =
> get_bitalloc(&s->gb, &dca_tmode, s->transient_huffman[j]);
> @@ -559,7 +610,7 @@
> }
> }
>
> - for (j = 0; j < s->prim_channels; j++) {
> + for (j = base_channel; j < s->prim_channels; j++) {
> const uint32_t *scale_table;
> int scale_sum;
>
> @@ -588,14 +639,14 @@
> }
>
> /* Joint subband scale factor codebook select */
> - for (j = 0; j < s->prim_channels; j++) {
> + for (j = base_channel; j < s->prim_channels; j++) {
> /* Transmitted only if joint subband coding enabled */
> if (s->joint_intensity[j] > 0)
> s->joint_huff[j] = get_bits(&s->gb, 3);
> }
>
> /* Scale factors for joint subband coding */
> - for (j = 0; j < s->prim_channels; j++) {
> + for (j = base_channel; j < s->prim_channels; j++) {
> int source_channel;
>
> /* Transmitted only if joint subband coding enabled */
> @@ -621,15 +672,15 @@
> }
>
> /* Stereo downmix coefficients */
> - if (s->prim_channels > 2) {
> + if (!base_channel && s->prim_channels > 2) {
> if(s->downmix) {
> - for (j = 0; j < s->prim_channels; j++) {
> + for (j = base_channel; j < s->prim_channels; j++) {
> s->downmix_coef[j][0] = get_bits(&s->gb, 7);
> s->downmix_coef[j][1] = get_bits(&s->gb, 7);
> }
> } else {
> int am = s->amode & DCA_CHANNEL_MASK;
> - for (j = 0; j < s->prim_channels; j++) {
> + for (j = base_channel; j < s->prim_channels; j++) {
> s->downmix_coef[j][0] = dca_default_coeffs[am][j][0];
> s->downmix_coef[j][1] = dca_default_coeffs[am][j][1];
> }
> @@ -650,18 +701,19 @@
> */
>
> /* VQ encoded high frequency subbands */
> - for (j = 0; j < s->prim_channels; j++)
> + for (j = base_channel; j < s->prim_channels; j++)
> for (k = s->vq_start_subband[j]; k < s->subband_activity[j]; k++)
> /* 1 vector -> 32 samples */
> s->high_freq_vq[j][k] = get_bits(&s->gb, 10);
>
> /* Low frequency effect data */
> - if (s->lfe) {
> + if (!base_channel && 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[s->current_subframe]);
> 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);
> }
> @@ -672,21 +724,21 @@
> /* 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;
> }
>
> #ifdef TRACE
> - av_log(s->avctx, AV_LOG_DEBUG, "subsubframes: %i\n", s->subsubframes);
> + av_log(s->avctx, AV_LOG_DEBUG, "subsubframes: %i\n", s->subsubframes[s->current_subframe]);
> av_log(s->avctx, AV_LOG_DEBUG, "partial samples: %i\n",
> - s->partial_samples);
> - for (j = 0; j < s->prim_channels; j++) {
> + s->partial_samples[s->current_subframe]);
> + for (j = base_channel; j < s->prim_channels; j++) {
> av_log(s->avctx, AV_LOG_DEBUG, "prediction mode:");
> for (k = 0; k < s->subband_activity[j]; k++)
> av_log(s->avctx, AV_LOG_DEBUG, " %i", s->prediction_mode[j][k]);
> av_log(s->avctx, AV_LOG_DEBUG, "\n");
> }
> - for (j = 0; j < s->prim_channels; j++) {
> + for (j = base_channel; j < s->prim_channels; j++) {
> for (k = 0; k < s->subband_activity[j]; k++)
> av_log(s->avctx, AV_LOG_DEBUG,
> "prediction coefs: %f, %f, %f, %f\n",
> @@ -695,19 +747,19 @@
> (float) adpcm_vb[s->prediction_vq[j][k]][2] / 8192,
> (float) adpcm_vb[s->prediction_vq[j][k]][3] / 8192);
> }
> - for (j = 0; j < s->prim_channels; j++) {
> + for (j = base_channel; j < s->prim_channels; j++) {
> av_log(s->avctx, AV_LOG_DEBUG, "bitalloc index: ");
> for (k = 0; k < s->vq_start_subband[j]; k++)
> av_log(s->avctx, AV_LOG_DEBUG, "%2.2i ", s->bitalloc[j][k]);
> av_log(s->avctx, AV_LOG_DEBUG, "\n");
> }
> - for (j = 0; j < s->prim_channels; j++) {
> + for (j = base_channel; j < s->prim_channels; j++) {
> av_log(s->avctx, AV_LOG_DEBUG, "Transition mode:");
> for (k = 0; k < s->subband_activity[j]; k++)
> av_log(s->avctx, AV_LOG_DEBUG, " %i", s->transition_mode[j][k]);
> av_log(s->avctx, AV_LOG_DEBUG, "\n");
> }
> - for (j = 0; j < s->prim_channels; j++) {
> + for (j = base_channel; j < s->prim_channels; j++) {
> av_log(s->avctx, AV_LOG_DEBUG, "Scale factor:");
> for (k = 0; k < s->subband_activity[j]; k++) {
> if (k >= s->vq_start_subband[j] || s->bitalloc[j][k] > 0)
> @@ -717,7 +769,7 @@
> }
> av_log(s->avctx, AV_LOG_DEBUG, "\n");
> }
> - for (j = 0; j < s->prim_channels; j++) {
> + for (j = base_channel; j < s->prim_channels; j++) {
> if (s->joint_intensity[j] > 0) {
> int source_channel = s->joint_intensity[j] - 1;
> av_log(s->avctx, AV_LOG_DEBUG, "Joint scale factor index:\n");
> @@ -726,7 +778,7 @@
> av_log(s->avctx, AV_LOG_DEBUG, "\n");
> }
> }
> - if (s->prim_channels > 2 && s->downmix) {
> + if (!base_channel && s->prim_channels > 2 && s->downmix) {
> av_log(s->avctx, AV_LOG_DEBUG, "Downmix coeffs:\n");
> for (j = 0; j < s->prim_channels; j++) {
> av_log(s->avctx, AV_LOG_DEBUG, "Channel 0,%d = %f\n", j, dca_downmix_coeffs[s->downmix_coef[j][0]]);
> @@ -734,13 +786,15 @@
> }
> av_log(s->avctx, AV_LOG_DEBUG, "\n");
> }
> - for (j = 0; j < s->prim_channels; j++)
> + for (j = base_channel; j < s->prim_channels; j++)
> 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;
> + if(!base_channel && s->lfe){
> + 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");
> }
> @@ -907,7 +961,7 @@
> static const uint8_t abits_sizes[7] = { 7, 10, 12, 13, 15, 17, 19 };
> static const uint8_t abits_levels[7] = { 3, 5, 7, 9, 13, 17, 25 };
>
> -static int dca_subsubframe(DCAContext * s)
> +static int dca_subsubframe(DCAContext * s, int base_channel, int block_index)
> {
> int k, l;
> int subsubframe = s->current_subsubframe;
> @@ -915,7 +969,7 @@
> const float *quant_step_table;
>
> /* FIXME */
> - LOCAL_ALIGNED_16(float, subband_samples, [DCA_PRIM_CHANNELS_MAX], [DCA_SUBBANDS][8]);
> + float (*subband_samples)[DCA_SUBBANDS][8] = s->subband_samples[block_index];
This should be in its own patch.
> LOCAL_ALIGNED_16(int, block, [8]);
>
> /*
> @@ -928,7 +982,7 @@
> else
> quant_step_table = lossy_quant_d;
>
> - for (k = 0; k < s->prim_channels; k++) {
> + for (k = base_channel; k < s->prim_channels; k++) {
> for (l = 0; l < s->vq_start_subband[k]; l++) {
> int m;
>
> @@ -1025,7 +1079,7 @@
> }
>
> /* Check for DSYNC after subsubframe */
> - if (s->aspf || subsubframe == s->subsubframes - 1) {
> + if (s->aspf || subsubframe == s->subsubframes[s->current_subframe] - 1) {
> if (0xFFFF == get_bits(&s->gb, 16)) { /* 0xFFFF */
> #ifdef TRACE
> av_log(s->avctx, AV_LOG_DEBUG, "Got subframe DSYNC\n");
> @@ -1036,33 +1090,34 @@
> }
>
> /* Backup predictor history for adpcm */
> - for (k = 0; k < s->prim_channels; k++)
> + for (k = base_channel; k < s->prim_channels; k++)
> for (l = 0; l < s->vq_start_subband[k]; l++)
> 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] =
> - {32768.0, 32768.0, 524288.0, 524288.0, 0, 8388608.0, 8388608.0};*/
> 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 );
> + M_SQRT1_2*s->scale_bias, s->add_bias);
> }
>
> /* 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 */
> @@ -1071,31 +1126,27 @@
> return 0;
> }
>
> -
> -static int dca_subframe_footer(DCAContext * s)
> +static int dca_subframe_footer(DCAContext * s, int base_channel)
> {
> int aux_data_count = 0, i;
> - int lfe_samples;
>
> /*
> * Unpack optional information
> */
>
> - if (s->timestamp)
> - get_bits(&s->gb, 32);
> + /* presumably optional information only appears in the core? */
> + if (!base_channel) {
> + if (s->timestamp)
> + get_bits(&s->gb, 32);
>
> - if (s->aux_data)
> - aux_data_count = get_bits(&s->gb, 6);
> + if (s->aux_data)
> + aux_data_count = get_bits(&s->gb, 6);
>
> - for (i = 0; i < aux_data_count; i++)
> - get_bits(&s->gb, 8);
> + for (i = 0; i < aux_data_count; i++)
> + get_bits(&s->gb, 8);
>
> - 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];
> + if (s->crc_present && (s->downmix || s->dynrange))
> + get_bits(&s->gb, 16);
> }
>
> return 0;
> @@ -1107,7 +1158,7 @@
> * @param s pointer to the DCAContext
> */
>
> -static int dca_decode_block(DCAContext * s)
> +static int dca_decode_block(DCAContext * s, int base_channel, int block_index)
> {
>
> /* Sanity check */
> @@ -1122,7 +1173,7 @@
> 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, base_channel, block_index))
> return -1;
> }
>
> @@ -1130,12 +1181,12 @@
> #ifdef TRACE
> av_log(s->avctx, AV_LOG_DEBUG, "DSYNC dca_subsubframe\n");
> #endif
> - if (dca_subsubframe(s))
> + if (dca_subsubframe(s, base_channel, block_index))
> return -1;
>
> /* Update state */
> s->current_subsubframe++;
> - if (s->current_subsubframe >= s->subsubframes) {
> + if (s->current_subsubframe >= s->subsubframes[s->current_subframe]) {
> s->current_subsubframe = 0;
> s->current_subframe++;
> }
> @@ -1144,7 +1195,7 @@
> av_log(s->avctx, AV_LOG_DEBUG, "DSYNC dca_subframe_footer\n");
> #endif
> /* Read subframe footer */
> - if (dca_subframe_footer(s))
> + if (dca_subframe_footer(s, base_channel))
> return -1;
> }
>
> @@ -1203,7 +1254,10 @@
> const uint8_t *buf = avpkt->data;
> int buf_size = avpkt->size;
>
> + int lfe_samples;
> + int num_core_channels = 0;
> int i;
> + int xch_present = 0;
> int16_t *samples = data;
> DCAContext *s = avctx->priv_data;
> int channels;
> @@ -1225,16 +1279,76 @@
> 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, 0, i);
> + }
> +
> + /* record number of core channels incase less than max channels are requested */
> + num_core_channels = s->prim_channels;
> +
> + /* extensions start at 32-bit boundaries into bitstream */
> + skip_bits(&s->gb, (-get_bits_count(&s->gb)) & 31);
> +
> + while(get_bits_left(&s->gb) >= 32) {
> + uint32_t bits = get_bits(&s->gb, 32);
> +
> + switch(bits) {
> + case 0x5a5a5a5a: {
> + int ext_base_ch = s->prim_channels;
> + int ext_amode;
> +
> + /* skip length-to-end-of-frame field for the moment */
> + get_bits(&s->gb, 10);
skip_bits()
All in all the code is ok. Just split up the patches abit and I'll start
applying them.
MvH
Benjamin Larsson
More information about the ffmpeg-devel
mailing list