]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/dcadec.c
lcl: Disentangle pointers to input data and decompression buffer
[ffmpeg] / libavcodec / dcadec.c
index 92edce7e4288b30c04f421d06b8b05803c9b49a3..e988e944642af73cd744aee18471dff5b5c1409a 100644 (file)
@@ -1695,6 +1695,13 @@ static void dca_exss_parse_header(DCAContext *s)
      * from the asset header */
 }
 
+static float dca_dmix_code(unsigned code)
+{
+    int sign = (code >> 8) - 1;
+    code &= 0xff;
+    return ((dca_dmixtable[code] ^ sign) - sign) * (1.0 / (1U << 15));
+}
+
 /**
  * Main frame decoding function
  * FIXME add arguments
@@ -1724,7 +1731,6 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data,
         return AVERROR_INVALIDDATA;
     }
 
-    init_get_bits(&s->gb, s->dca_buffer, s->dca_buffer_size * 8);
     if ((ret = dca_parse_frame_header(s)) < 0) {
         //seems like the frame is corrupt, try with the next one
         return ret;
@@ -1850,6 +1856,16 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data,
     if (s->amode < 16) {
         avctx->channel_layout = dca_core_channel_layout[s->amode];
 
+        if (s->prim_channels + !!s->lfe > 2 &&
+            avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) {
+            /*
+             * Neither the core's auxiliary data nor our default tables contain
+             * downmix coefficients for the additional channel coded in the XCh
+             * extension, so when we're doing a Stereo downmix, don't decode it.
+             */
+            s->xch_disable = 1;
+        }
+
 #if FF_API_REQUEST_CHANNELS
 FF_DISABLE_DEPRECATION_WARNINGS
         if (s->xch_present && !s->xch_disable &&
@@ -1880,7 +1896,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
             s->channel_order_tab[channels - 1 - !!s->lfe] < 0)
             return AVERROR_INVALIDDATA;
 
-        if (s->prim_channels + !!s->lfe > 2 &&
+        if (num_core_channels + !!s->lfe > 2 &&
             avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) {
             channels = 2;
             s->output = s->prim_channels == 2 ? s->amode : DCA_STEREO;
@@ -1893,16 +1909,10 @@ FF_ENABLE_DEPRECATION_WARNINGS
              */
             if (s->core_downmix && (s->core_downmix_amode == DCA_STEREO ||
                                     s->core_downmix_amode == DCA_STEREO_TOTAL)) {
-                int sign, code;
-                for (i = 0; i < s->prim_channels + !!s->lfe; i++) {
-                    sign = s->core_downmix_codes[i][0] & 0x100 ? 1 : -1;
-                    code = s->core_downmix_codes[i][0] & 0x0FF;
-                    s->downmix_coef[i][0] = (!code ? 0.0f :
-                                             sign * dca_dmixtable[code - 1]);
-                    sign = s->core_downmix_codes[i][1] & 0x100 ? 1 : -1;
-                    code = s->core_downmix_codes[i][1] & 0x0FF;
-                    s->downmix_coef[i][1] = (!code ? 0.0f :
-                                             sign * dca_dmixtable[code - 1]);
+                for (i = 0; i < num_core_channels + !!s->lfe; i++) {
+                    /* Range checked earlier */
+                    s->downmix_coef[i][0] = dca_dmix_code(s->core_downmix_codes[i][0]);
+                    s->downmix_coef[i][1] = dca_dmix_code(s->core_downmix_codes[i][1]);
                 }
                 s->output = s->core_downmix_amode;
             } else {
@@ -1912,19 +1922,19 @@ FF_ENABLE_DEPRECATION_WARNINGS
                            "Invalid channel mode %d\n", am);
                     return AVERROR_INVALIDDATA;
                 }
-                if (s->prim_channels + !!s->lfe >
+                if (num_core_channels + !!s->lfe >
                     FF_ARRAY_ELEMS(dca_default_coeffs[0])) {
                     avpriv_request_sample(s->avctx, "Downmixing %d channels",
                                           s->prim_channels + !!s->lfe);
                     return AVERROR_PATCHWELCOME;
                 }
-                for (i = 0; i < s->prim_channels + !!s->lfe; i++) {
+                for (i = 0; i < num_core_channels + !!s->lfe; i++) {
                     s->downmix_coef[i][0] = dca_default_coeffs[am][i][0];
                     s->downmix_coef[i][1] = dca_default_coeffs[am][i][1];
                 }
             }
             av_dlog(s->avctx, "Stereo downmix coeffs:\n");
-            for (i = 0; i < s->prim_channels + !!s->lfe; i++) {
+            for (i = 0; i < num_core_channels + !!s->lfe; i++) {
                 av_dlog(s->avctx, "L, input channel %d = %f\n", i,
                         s->downmix_coef[i][0]);
                 av_dlog(s->avctx, "R, input channel %d = %f\n", i,