[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