]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/dca.c
prores: only call get_buffer once per frame
[ffmpeg] / libavcodec / dca.c
index e11439f939b1054efa317f313b4bcc586628f9b1..d900d883bd8afc0a682b353ff63e2f4b2b60196a 100644 (file)
 #include "dcadsp.h"
 #include "fmtconvert.h"
 
+#if ARCH_ARM
+#   include "arm/dca.h"
+#endif
+
 //#define TRACE
 
 #define DCA_PRIM_CHANNELS_MAX (7)
@@ -320,7 +324,7 @@ typedef struct {
     int lfe_scale_factor;
 
     /* Subband samples history (for ADPCM) */
-    float subband_samples_hist[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS][4];
+    DECLARE_ALIGNED(16, float, subband_samples_hist)[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS][4];
     DECLARE_ALIGNED(32, float, subband_fir_hist)[DCA_PRIM_CHANNELS_MAX][512];
     DECLARE_ALIGNED(32, float, subband_fir_noidea)[DCA_PRIM_CHANNELS_MAX][32];
     int hist_index[DCA_PRIM_CHANNELS_MAX];
@@ -898,15 +902,17 @@ static void qmf_32_subbands(DCAContext * s, int chans,
     else                        /* Perfect reconstruction */
         prCoeff = fir_32bands_perfect;
 
+    for (i = sb_act; i < 32; i++)
+        s->raXin[i] = 0.0;
+
     /* Reconstructed channel sample index */
     for (subindex = 0; subindex < 8; subindex++) {
         /* Load in one sample from each subband and clear inactive subbands */
         for (i = 0; i < sb_act; i++){
-            uint32_t v = AV_RN32A(&samples_in[i][subindex]) ^ ((i-1)&2)<<30;
+            unsigned sign = (i - 1) & 2;
+            uint32_t v = AV_RN32A(&samples_in[i][subindex]) ^ sign << 30;
             AV_WN32A(&s->raXin[i], v);
         }
-        for (; i < 32; i++)
-            s->raXin[i] = 0.0;
 
         s->synth.synth_filter_float(&s->imdct,
                               s->subband_fir_hist[chans], &s->hist_index[chans],
@@ -1056,6 +1062,16 @@ static int decode_blockcode(int code, int levels, int *values)
 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 };
 
+#ifndef int8x8_fmul_int32
+static inline void int8x8_fmul_int32(float *dst, const int8_t *src, int scale)
+{
+    float fscale = scale / 16.0;
+    int i;
+    for (i = 0; i < 8; i++)
+        dst[i] = src[i] * fscale;
+}
+#endif
+
 static int dca_subsubframe(DCAContext * s, int base_channel, int block_index)
 {
     int k, l;
@@ -1160,19 +1176,16 @@ static int dca_subsubframe(DCAContext * s, int base_channel, int block_index)
         for (l = s->vq_start_subband[k]; l < s->subband_activity[k]; l++) {
             /* 1 vector -> 32 samples but we only need the 8 samples
              * for this subsubframe. */
-            int m;
+            int hfvq = s->high_freq_vq[k][l];
 
             if (!s->debug_flag & 0x01) {
                 av_log(s->avctx, AV_LOG_DEBUG, "Stream with high frequencies VQ coding\n");
                 s->debug_flag |= 0x01;
             }
 
-            for (m = 0; m < 8; m++) {
-                subband_samples[k][l][m] =
-                    high_freq_vq[s->high_freq_vq[k][l]][subsubframe * 8 +
-                                                        m]
-                    * (float) s->scale_factor[k][l][0] / 16.0;
-            }
+            int8x8_fmul_int32(subband_samples[k][l],
+                              &high_freq_vq[hfvq][subsubframe * 8],
+                              s->scale_factor[k][l][0]);
         }
     }
 
@@ -1833,11 +1846,8 @@ static int dca_decode_frame(AVCodecContext * avctx,
             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] * M_SQRT1_2;
-                rt_chan[j] -= back_chan[j] * M_SQRT1_2;
-            }
+            s->dsp.vector_fmac_scalar(lt_chan, back_chan, -M_SQRT1_2, 256);
+            s->dsp.vector_fmac_scalar(rt_chan, back_chan, -M_SQRT1_2, 256);
         }
 
         if (avctx->sample_fmt == AV_SAMPLE_FMT_FLT) {