[FFmpeg-devel] [PATCH 2/3] Support DTS-ES extension (XCh) in dca

Benjamin Larsson banan
Mon Jun 21 10:23:48 CEST 2010


Nick Brereton skrev 2010-06-21 00:39:
> Index: libavcodec/dca.c
> ===================================================================
> --- libavcodec/dca.c	(revision 23670)
> +++ libavcodec/dca.c	(working copy)
> @@ -45,6 +45,7 @@
>   #define DCA_SUBBANDS (32)
>   #define DCA_ABITS_MAX (32)      /* Should be 28 */
>   #define DCA_SUBSUBFRAMES_MAX (4)
> +#define DCA_BLOCKS_MAX (16)
>   #define DCA_LFE_MAX (3)
>    

Ok.


>
>   enum DCAMode {
> @@ -237,6 +238,7 @@
>       float add_bias;             ///<  output bias
>       float scale_bias;           ///<  output scale
>    



>
> +    DECLARE_ALIGNED(16, float, subband_samples)[DCA_BLOCKS_MAX][DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS][8];
>    

>@@ -915,7 +926,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];
>      LOCAL_ALIGNED_16(int, block, [8]);
  

After split this is ok to be committed.


>       DECLARE_ALIGNED(16, float, samples)[1536];  /* 6 * 256 = 1536, might only need 5 */
>       const float *samples_chanptr[6];
>
> @@ -324,13 +326,85 @@
>           *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;
> +}
>    

Move and rename in a separate patch.


> +
> +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 +494,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);
>   }
>
>
> @@ -501,7 +509,7 @@
>      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;
> @@ -658,10 +666,11 @@
>       /* 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);
>           }
> @@ -672,7 +681,7 @@
>           /* 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;
>       }
>
> @@ -738,9 +747,11 @@
>           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");
>       }
> @@ -907,7 +918,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 block_index)
>   {
>       int k, l;
>       int subsubframe = s->current_subsubframe;
>
>       /*
> @@ -1041,6 +1052,14 @@
>               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] =
> @@ -1051,18 +1070,14 @@
>       }
>
>       /* 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 */
> @@ -1075,7 +1090,6 @@
>   static int dca_subframe_footer(DCAContext * s)
>   {
>       int aux_data_count = 0, i;
> -    int lfe_samples;
>
>       /*
>        * Unpack optional information
> @@ -1093,11 +1107,6 @@
>       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;
>   }
>
> @@ -1107,7 +1116,7 @@
>    * @param s     pointer to the DCAContext
>    */
>
> -static int dca_decode_block(DCAContext * s)
> +static int dca_decode_block(DCAContext * s, int block_index)
>   {
>
>       /* Sanity check */
> @@ -1122,7 +1131,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, block_index))
>               return -1;
>       }
>
> @@ -1130,7 +1139,7 @@
>   #ifdef TRACE
>       av_log(s->avctx, AV_LOG_DEBUG, "DSYNC dca_subsubframe\n");
>   #endif
> -    if (dca_subsubframe(s))
> +    if (dca_subsubframe(s, block_index))
>           return -1;
>
>       /* Update state */
> @@ -1203,6 +1212,7 @@
>       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;
> @@ -1225,6 +1235,10 @@
>       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) {
> @@ -1262,12 +1276,20 @@
>       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);
> +        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;
>   }
>
> @@ -1292,7 +1314,7 @@
>       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;
>
>    

Rest is ok after the other parts are split out.

MvH
Benjamin Larsson




More information about the ffmpeg-devel mailing list