]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/dca.c
imc: fix undefined float to int conversion
[ffmpeg] / libavcodec / dca.c
index 0d4fa5aee64fc1d61890329383c4f0e4f4987ea3..e8627a23d95830872d3cb867b4eb31b35b6ccfcc 100644 (file)
@@ -288,6 +288,10 @@ typedef struct {
     int current_subframe;
     int current_subsubframe;
 
+    /* XCh extension information */
+    int xch_present;
+    int xch_base_channel;       ///< index of first (only) channel containing XCH data
+
     int debug_flag;             ///< used for suppressing repeated error messages output
     DSPContext dsp;
     FFTContext imdct;
@@ -687,7 +691,7 @@ static int dca_subframe_header(DCAContext * s, int base_channel, int block_index
     }
 
     /* Dynamic range coefficient */
-    if (s->dynrange)
+    if (!base_channel && s->dynrange)
         s->dynrange_coef = get_bits(&s->gb, 8);
 
     /* Side information CRC check word */
@@ -875,17 +879,19 @@ static void lfe_interpolation_fir(DCAContext *s, int decimation_select,
 
 /* downmixing routines */
 #define MIX_REAR1(samples, si1, rs, coef) \
-     samples[i]     += samples[si1] * coef[rs][0]; \
-     samples[i+256] += samples[si1] * coef[rs][1];
+     samples[i]     += (samples[si1] - add_bias) * coef[rs][0];  \
+     samples[i+256] += (samples[si1] - add_bias) * coef[rs][1];
 
 #define MIX_REAR2(samples, si1, si2, rs, coef) \
-     samples[i]     += samples[si1] * coef[rs][0] + samples[si2] * coef[rs+1][0]; \
-     samples[i+256] += samples[si1] * coef[rs][1] + samples[si2] * coef[rs+1][1];
+     samples[i]     += (samples[si1] - add_bias) * coef[rs][0] + (samples[si2] - add_bias) * coef[rs+1][0]; \
+     samples[i+256] += (samples[si1] - add_bias) * coef[rs][1] + (samples[si2] - add_bias) * coef[rs+1][1];
 
 #define MIX_FRONT3(samples, coef) \
-    t = samples[i]; \
-    samples[i]     = t * coef[0][0] + samples[i+256] * coef[1][0] + samples[i+512] * coef[2][0]; \
-    samples[i+256] = t * coef[0][1] + samples[i+256] * coef[1][1] + samples[i+512] * coef[2][1];
+    t = samples[i+c] - add_bias; \
+    u = samples[i+l] - add_bias; \
+    v = samples[i+r] - add_bias; \
+    samples[i]     = t * coef[0][0] + u * coef[1][0] + v * coef[2][0] + add_bias; \
+    samples[i+256] = t * coef[0][1] + u * coef[1][1] + v * coef[2][1] + add_bias;
 
 #define DOWNMIX_TO_STEREO(op1, op2) \
     for (i = 0; i < 256; i++){ \
@@ -894,10 +900,12 @@ static void lfe_interpolation_fir(DCAContext *s, int decimation_select,
     }
 
 static void dca_downmix(float *samples, int srcfmt,
-                        int downmix_coef[DCA_PRIM_CHANNELS_MAX][2])
+                        int downmix_coef[DCA_PRIM_CHANNELS_MAX][2],
+                        const int8_t *channel_mapping, float add_bias)
 {
+    int c,l,r,sl,sr,s;
     int i;
-    float t;
+    float t, u, v;
     float coef[DCA_PRIM_CHANNELS_MAX][2];
 
     for (i=0; i<DCA_PRIM_CHANNELS_MAX; i++) {
@@ -916,21 +924,36 @@ static void dca_downmix(float *samples, int srcfmt,
     case DCA_STEREO:
         break;
     case DCA_3F:
+        c = channel_mapping[0] * 256;
+        l = channel_mapping[1] * 256;
+        r = channel_mapping[2] * 256;
         DOWNMIX_TO_STEREO(MIX_FRONT3(samples, coef),);
         break;
     case DCA_2F1R:
-        DOWNMIX_TO_STEREO(MIX_REAR1(samples, i + 512, 2, coef),);
+        s = channel_mapping[2] * 256;
+        DOWNMIX_TO_STEREO(MIX_REAR1(samples, i + s, 2, coef),);
         break;
     case DCA_3F1R:
+        c = channel_mapping[0] * 256;
+        l = channel_mapping[1] * 256;
+        r = channel_mapping[2] * 256;
+        s = channel_mapping[3] * 256;
         DOWNMIX_TO_STEREO(MIX_FRONT3(samples, coef),
-                          MIX_REAR1(samples, i + 768, 3, coef));
+                          MIX_REAR1(samples, i + s, 3, coef));
         break;
     case DCA_2F2R:
-        DOWNMIX_TO_STEREO(MIX_REAR2(samples, i + 512, i + 768, 2, coef),);
+        sl = channel_mapping[2] * 256;
+        sr = channel_mapping[3] * 256;
+        DOWNMIX_TO_STEREO(MIX_REAR2(samples, i + sl, i + sr, 2, coef),);
         break;
     case DCA_3F2R:
+        c =  channel_mapping[0] * 256;
+        l =  channel_mapping[1] * 256;
+        r =  channel_mapping[2] * 256;
+        sl = channel_mapping[3] * 256;
+        sr = channel_mapping[4] * 256;
         DOWNMIX_TO_STEREO(MIX_FRONT3(samples, coef),
-                          MIX_REAR2(samples, i + 768, i + 1024, 3, coef));
+                          MIX_REAR2(samples, i + sl, i + sr, 3, coef));
         break;
     }
 }
@@ -1113,7 +1136,7 @@ static int dca_filter_channels(DCAContext * s, int block_index)
 
     /* Down mixing */
     if (s->avctx->request_channels == 2 && s->prim_channels > 2) {
-        dca_downmix(s->samples, s->amode, s->downmix_coef);
+        dca_downmix(s->samples, s->amode, s->downmix_coef, s->channel_order_tab, s->add_bias);
     }
 
     /* Generate LFE samples for this subsubframe FIXME!!! */
@@ -1230,7 +1253,7 @@ static int dca_convert_bitstream(const uint8_t * src, int src_size, uint8_t * ds
         return src_size;
     case DCA_MARKER_RAW_LE:
         for (i = 0; i < (src_size + 1) >> 1; i++)
-            *sdst++ = bswap_16(*ssrc++);
+            *sdst++ = av_bswap16(*ssrc++);
         return src_size;
     case DCA_MARKER_14B_BE:
     case DCA_MARKER_14B_LE:
@@ -1260,12 +1283,12 @@ static int dca_decode_frame(AVCodecContext * avctx,
     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;
 
 
+    s->xch_present = 0;
     s->dca_buffer_size = dca_convert_bitstream(buf, buf_size, s->dca_buffer, DCA_MAX_FRAME_SIZE);
     if (s->dca_buffer_size == -1) {
         av_log(avctx, AV_LOG_ERROR, "Not a valid DCA frame\n");
@@ -1290,15 +1313,22 @@ static int dca_decode_frame(AVCodecContext * avctx,
     num_core_channels = s->prim_channels;
 
     /* extensions start at 32-bit boundaries into bitstream */
-    skip_bits(&s->gb, (-get_bits_count(&s->gb)) & 31);
+    skip_bits_long(&s->gb, (-get_bits_count(&s->gb)) & 31);
 
     while(get_bits_left(&s->gb) >= 32) {
-        uint32_t bits = get_bits(&s->gb, 32);
+        uint32_t bits = get_bits_long(&s->gb, 32);
 
         switch(bits) {
         case 0x5a5a5a5a: {
-            int ext_base_ch = s->prim_channels;
-            int ext_amode;
+            int ext_amode, xch_fsize;
+
+            s->xch_base_channel = s->prim_channels;
+
+            /* validate sync word using XCHFSIZE field */
+            xch_fsize = show_bits(&s->gb, 10);
+            if((s->frame_size != (get_bits_count(&s->gb) >> 3) - 4 + xch_fsize) &&
+               (s->frame_size != (get_bits_count(&s->gb) >> 3) - 4 + xch_fsize + 1))
+                continue;
 
             /* skip length-to-end-of-frame field for the moment */
             skip_bits(&s->gb, 10);
@@ -1312,13 +1342,13 @@ static int dca_decode_frame(AVCodecContext * avctx,
             }
 
             /* much like core primary audio coding header */
-            dca_parse_audio_coding_header(s, ext_base_ch);
+            dca_parse_audio_coding_header(s, s->xch_base_channel);
 
             for (i = 0; i < (s->sample_blocks / 8); i++) {
-                dca_decode_block(s, ext_base_ch, i);
+                dca_decode_block(s, s->xch_base_channel, i);
             }
 
-            xch_present = 1;
+            s->xch_present = 1;
             break;
         }
         case 0x1d95f262:
@@ -1328,7 +1358,7 @@ static int dca_decode_frame(AVCodecContext * avctx,
             break;
         }
 
-        skip_bits(&s->gb, (-get_bits_count(&s->gb)) & 31);
+        skip_bits_long(&s->gb, (-get_bits_count(&s->gb)) & 31);
     }
 
     channels = s->prim_channels + !!s->lfe;
@@ -1336,8 +1366,8 @@ static int dca_decode_frame(AVCodecContext * avctx,
     if (s->amode<16) {
         avctx->channel_layout = dca_core_channel_layout[s->amode];
 
-        if (xch_present && (!avctx->request_channels ||
-                            avctx->request_channels > num_core_channels)) {
+        if (s->xch_present && (!avctx->request_channels ||
+                               avctx->request_channels > num_core_channels + !!s->lfe)) {
             avctx->channel_layout |= CH_BACK_CENTER;
             if (s->lfe) {
                 avctx->channel_layout |= CH_LOW_FREQUENCY;
@@ -1346,6 +1376,8 @@ static int dca_decode_frame(AVCodecContext * avctx,
                 s->channel_order_tab = dca_channel_reorder_nolfe_xch[s->amode];
             }
         } else {
+            channels = num_core_channels + !!s->lfe;
+            s->xch_present = 0; /* disable further xch processing */
             if (s->lfe) {
                 avctx->channel_layout |= CH_LOW_FREQUENCY;
                 s->channel_order_tab = dca_channel_reorder_lfe[s->amode];
@@ -1353,8 +1385,8 @@ static int dca_decode_frame(AVCodecContext * avctx,
                 s->channel_order_tab = dca_channel_reorder_nolfe[s->amode];
         }
 
-        if (s->prim_channels > 0 &&
-            s->channel_order_tab[s->prim_channels - 1] < 0)
+        if (channels > !!s->lfe &&
+            s->channel_order_tab[channels - 1 - !!s->lfe] < 0)
             return -1;
 
         if (avctx->request_channels == 2 && s->prim_channels > 2) {
@@ -1373,8 +1405,7 @@ static int dca_decode_frame(AVCodecContext * avctx,
        unset. Ideally during the first probe for channels the crc should be checked
        and only set avctx->channels when the crc is ok. Right now the decoder could
        set the channels based on a broken first frame.*/
-    if (!avctx->channels)
-        avctx->channels = channels;
+    avctx->channels = channels;
 
     if (*data_size < (s->sample_blocks / 8) * 256 * sizeof(int16_t) * channels)
         return -1;
@@ -1383,6 +1414,20 @@ static int dca_decode_frame(AVCodecContext * avctx,
     /* filter to get final output */
     for (i = 0; i < (s->sample_blocks / 8); i++) {
         dca_filter_channels(s, i);
+
+        /* If this was marked as a DTS-ES stream we need to subtract back- */
+        /* channel from SL & SR to remove matrixed back-channel signal */
+        if((s->source_pcm_res & 1) && s->xch_present) {
+            float* back_chan = s->samples + s->channel_order_tab[s->xch_base_channel] * 256;
+            float* lt_chan   = s->samples + s->channel_order_tab[s->xch_base_channel - 2] * 256;
+            float* rt_chan   = s->samples + s->channel_order_tab[s->xch_base_channel - 1] * 256;
+            int j;
+            for(j = 0; j < 256; ++j) {
+                lt_chan[j] -= (back_chan[j] - s->add_bias) * M_SQRT1_2;
+                rt_chan[j] -= (back_chan[j] - s->add_bias) * M_SQRT1_2;
+            }
+        }
+
         s->dsp.float_to_int16_interleave(samples, s->samples_chanptr, 256, channels);
         samples += 256 * channels;
     }