]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/aacsbr.c
floatdsp: move butterflies_float from dsputil to avfloatdsp.
[ffmpeg] / libavcodec / aacsbr.c
index 01601b035ccaac992c174cf4ad7798d48979dd7e..8b290340d4ec3637ce8779bb46cdad7e85d08447 100644 (file)
@@ -74,7 +74,6 @@ enum {
 static VLC vlc_sbr[10];
 static const int8_t vlc_sbr_lav[10] =
     { 60, 60, 24, 24, 31, 31, 12, 12, 31, 12 };
-static const DECLARE_ALIGNED(16, float, zero64)[64];
 
 #define SBR_INIT_VLC_STATIC(num, size) \
     INIT_VLC_STATIC(&vlc_sbr[num], 9, sbr_tmp[num].table_size / sbr_tmp[num].elem_size,     \
@@ -127,19 +126,28 @@ av_cold void ff_aac_sbr_init(void)
     ff_ps_init();
 }
 
+/** Places SBR in pure upsampling mode. */
+static void sbr_turnoff(SpectralBandReplication *sbr) {
+    sbr->start = 0;
+    // Init defults used in pure upsampling mode
+    sbr->kx[1] = 32; //Typo in spec, kx' inits to 32
+    sbr->m[1] = 0;
+    // Reset values for first SBR header
+    sbr->data[0].e_a[1] = sbr->data[1].e_a[1] = -1;
+    memset(&sbr->spectrum_params, -1, sizeof(SpectrumParameters));
+}
+
 av_cold void ff_aac_sbr_ctx_init(AACContext *ac, SpectralBandReplication *sbr)
 {
-    float mdct_scale;
-    sbr->kx[0] = sbr->kx[1] = 32; //Typo in spec, kx' inits to 32
-    sbr->data[0].e_a[1] = sbr->data[1].e_a[1] = -1;
+    sbr->kx[0] = sbr->kx[1];
+    sbr_turnoff(sbr);
     sbr->data[0].synthesis_filterbank_samples_offset = SBR_SYNTHESIS_BUF_SIZE - (1280 - 128);
     sbr->data[1].synthesis_filterbank_samples_offset = SBR_SYNTHESIS_BUF_SIZE - (1280 - 128);
     /* SBR requires samples to be scaled to +/-32768.0 to work correctly.
      * mdct scale factors are adjusted to scale up from +/-1.0 at analysis
      * and scale back down at synthesis. */
-    mdct_scale = ac->avctx->sample_fmt == AV_SAMPLE_FMT_FLT ? 32768.0f : 1.0f;
-    ff_mdct_init(&sbr->mdct,     7, 1, 1.0 / (64 * mdct_scale));
-    ff_mdct_init(&sbr->mdct_ana, 7, 1, -2.0 * mdct_scale);
+    ff_mdct_init(&sbr->mdct,     7, 1, 1.0 / (64 * 32768.0));
+    ff_mdct_init(&sbr->mdct_ana, 7, 1, -2.0 * 32768.0);
     ff_ps_ctx_init(&sbr->ps);
     ff_sbrdsp_init(&sbr->dsp);
 }
@@ -903,7 +911,7 @@ static void read_sbr_extension(AACContext *ac, SpectralBandReplication *sbr,
 {
     switch (bs_extension_id) {
     case EXTENSION_ID_PS:
-        if (!ac->m4ac.ps) {
+        if (!ac->oc[1].m4ac.ps) {
             av_log(ac->avctx, AV_LOG_ERROR, "Parametric Stereo signaled to be not-present but was found in the bitstream.\n");
             skip_bits_long(gb, *num_bits_left); // bs_fill_bits
             *num_bits_left = 0;
@@ -911,14 +919,14 @@ static void read_sbr_extension(AACContext *ac, SpectralBandReplication *sbr,
 #if 1
             *num_bits_left -= ff_ps_read_data(ac->avctx, gb, &sbr->ps, *num_bits_left);
 #else
-            av_log_missing_feature(ac->avctx, "Parametric Stereo is", 0);
+            av_log_missing_feature(ac->avctx, "Parametric Stereo", 0);
             skip_bits_long(gb, *num_bits_left); // bs_fill_bits
             *num_bits_left = 0;
 #endif
         }
         break;
     default:
-        av_log_missing_feature(ac->avctx, "Reserved SBR extensions are", 1);
+        av_log_missing_feature(ac->avctx, "Reserved SBR extensions", 1);
         skip_bits_long(gb, *num_bits_left); // bs_fill_bits
         *num_bits_left = 0;
         break;
@@ -994,18 +1002,18 @@ static unsigned int read_sbr_data(AACContext *ac, SpectralBandReplication *sbr,
 
     if (id_aac == TYPE_SCE || id_aac == TYPE_CCE) {
         if (read_sbr_single_channel_element(ac, sbr, gb)) {
-            sbr->start = 0;
+            sbr_turnoff(sbr);
             return get_bits_count(gb) - cnt;
         }
     } else if (id_aac == TYPE_CPE) {
         if (read_sbr_channel_pair_element(ac, sbr, gb)) {
-            sbr->start = 0;
+            sbr_turnoff(sbr);
             return get_bits_count(gb) - cnt;
         }
     } else {
         av_log(ac->avctx, AV_LOG_ERROR,
             "Invalid bitstream - cannot apply SBR to element type %d\n", id_aac);
-        sbr->start = 0;
+        sbr_turnoff(sbr);
         return get_bits_count(gb) - cnt;
     }
     if (get_bits1(gb)) { // bs_extended_data
@@ -1037,7 +1045,7 @@ static void sbr_reset(AACContext *ac, SpectralBandReplication *sbr)
     if (err < 0) {
         av_log(ac->avctx, AV_LOG_ERROR,
                "SBR reset failed. Switching SBR to pure upsampling mode.\n");
-        sbr->start = 0;
+        sbr_turnoff(sbr);
     }
 }
 
@@ -1060,9 +1068,9 @@ int ff_decode_sbr_extension(AACContext *ac, SpectralBandReplication *sbr,
     sbr->reset = 0;
 
     if (!sbr->sample_rate)
-        sbr->sample_rate = 2 * ac->m4ac.sample_rate; //TODO use the nominal sample rate for arbitrary sample rate support
-    if (!ac->m4ac.ext_sample_rate)
-        ac->m4ac.ext_sample_rate = 2 * ac->m4ac.sample_rate;
+        sbr->sample_rate = 2 * ac->oc[1].m4ac.sample_rate; //TODO use the nominal sample rate for arbitrary sample rate support
+    if (!ac->oc[1].m4ac.ext_sample_rate)
+        ac->oc[1].m4ac.ext_sample_rate = 2 * ac->oc[1].m4ac.sample_rate;
 
     if (crc) {
         skip_bits(gb, 10); // bs_sbr_crc_bits; TODO - implement CRC check
@@ -1072,6 +1080,7 @@ int ff_decode_sbr_extension(AACContext *ac, SpectralBandReplication *sbr,
     //Save some state from the previous frame.
     sbr->kx[0] = sbr->kx[1];
     sbr->m[0] = sbr->m[1];
+    sbr->kx_and_m_pushed = 1;
 
     num_sbr_bits++;
     if (get_bits1(gb)) // bs_header_flag
@@ -1141,12 +1150,11 @@ static void sbr_dequant(SpectralBandReplication *sbr, int id_aac)
  * @param   x       pointer to the beginning of the first sample window
  * @param   W       array of complex-valued samples split into subbands
  */
-static void sbr_qmf_analysis(DSPContext *dsp, FFTContext *mdct,
+static void sbr_qmf_analysis(AVFloatDSPContext *dsp, FFTContext *mdct,
                              SBRDSPContext *sbrdsp, const float *in, float *x,
-                             float z[320], float W[2][32][32][2])
+                             float z[320], float W[2][32][32][2], int buf_idx)
 {
     int i;
-    memcpy(W[0], W[1], sizeof(W[0]));
     memcpy(x    , x+1024, (320-32)*sizeof(x[0]));
     memcpy(x+288, in,         1024*sizeof(x[0]));
     for (i = 0; i < 32; i++) { // numTimeSlots*RATE = 16*2 as 960 sample frames
@@ -1155,7 +1163,7 @@ static void sbr_qmf_analysis(DSPContext *dsp, FFTContext *mdct,
         sbrdsp->sum64x5(z);
         sbrdsp->qmf_pre_shuffle(z);
         mdct->imdct_half(mdct, z, z+64);
-        sbrdsp->qmf_post_shuffle(W[1][i], z);
+        sbrdsp->qmf_post_shuffle(W[buf_idx][i], z);
         x += 32;
     }
 }
@@ -1164,8 +1172,8 @@ static void sbr_qmf_analysis(DSPContext *dsp, FFTContext *mdct,
  * Synthesis QMF Bank (14496-3 sp04 p206) and Downsampled Synthesis QMF Bank
  * (14496-3 sp04 p206)
  */
-static void sbr_qmf_synthesis(DSPContext *dsp, FFTContext *mdct,
-                              SBRDSPContext *sbrdsp,
+static void sbr_qmf_synthesis(FFTContext *mdct,
+                              SBRDSPContext *sbrdsp, AVFloatDSPContext *dsp,
                               float *out, float X[2][38][64],
                               float mdct_buf[2][64],
                               float *v0, int *v_off, const unsigned int div)
@@ -1196,7 +1204,7 @@ static void sbr_qmf_synthesis(DSPContext *dsp, FFTContext *mdct,
             mdct->imdct_half(mdct, mdct_buf[1], X[1][i]);
             sbrdsp->qmf_deint_bfly(v, mdct_buf[1], mdct_buf[0]);
         }
-        dsp->vector_fmul_add(out, v                , sbr_qmf_window               , zero64, 64 >> div);
+        dsp->vector_fmul    (out, v                , sbr_qmf_window                       , 64 >> div);
         dsp->vector_fmul_add(out, v + ( 192 >> div), sbr_qmf_window + ( 64 >> div), out   , 64 >> div);
         dsp->vector_fmul_add(out, v + ( 256 >> div), sbr_qmf_window + (128 >> div), out   , 64 >> div);
         dsp->vector_fmul_add(out, v + ( 448 >> div), sbr_qmf_window + (192 >> div), out   , 64 >> div);
@@ -1220,7 +1228,8 @@ static void sbr_hf_inverse_filter(SBRDSPContext *dsp,
 {
     int k;
     for (k = 0; k < k0; k++) {
-        float phi[3][2][2], dk;
+        LOCAL_ALIGNED_16(float, phi, [3], [2][2]);
+        float dk;
 
         dsp->autocorrelate(X_low[k], phi);
 
@@ -1290,7 +1299,8 @@ static void sbr_chirp(SpectralBandReplication *sbr, SBRData *ch_data)
 
 /// Generate the subband filtered lowband
 static int sbr_lf_gen(AACContext *ac, SpectralBandReplication *sbr,
-                      float X_low[32][40][2], const float W[2][32][32][2])
+                      float X_low[32][40][2], const float W[2][32][32][2],
+                      int buf_idx)
 {
     int i, k;
     const int t_HFGen = 8;
@@ -1298,14 +1308,15 @@ static int sbr_lf_gen(AACContext *ac, SpectralBandReplication *sbr,
     memset(X_low, 0, 32*sizeof(*X_low));
     for (k = 0; k < sbr->kx[1]; k++) {
         for (i = t_HFGen; i < i_f + t_HFGen; i++) {
-            X_low[k][i][0] = W[1][i - t_HFGen][k][0];
-            X_low[k][i][1] = W[1][i - t_HFGen][k][1];
+            X_low[k][i][0] = W[buf_idx][i - t_HFGen][k][0];
+            X_low[k][i][1] = W[buf_idx][i - t_HFGen][k][1];
         }
     }
+    buf_idx = 1-buf_idx;
     for (k = 0; k < sbr->kx[0]; k++) {
         for (i = 0; i < t_HFGen; i++) {
-            X_low[k][i][0] = W[0][i + i_f - t_HFGen][k][0];
-            X_low[k][i][1] = W[0][i + i_f - t_HFGen][k][1];
+            X_low[k][i][0] = W[buf_idx][i + i_f - t_HFGen][k][0];
+            X_low[k][i][1] = W[buf_idx][i + i_f - t_HFGen][k][1];
         }
     }
     return 0;
@@ -1348,8 +1359,8 @@ static int sbr_hf_gen(AACContext *ac, SpectralBandReplication *sbr,
 
 /// Generate the subband filtered lowband
 static int sbr_x_gen(SpectralBandReplication *sbr, float X[2][38][64],
-                     const float X_low[32][40][2], const float Y[2][38][64][2],
-                     int ch)
+                     const float Y0[38][64][2], const float Y1[38][64][2],
+                     const float X_low[32][40][2], int ch)
 {
     int k, i;
     const int i_f = 32;
@@ -1363,8 +1374,8 @@ static int sbr_x_gen(SpectralBandReplication *sbr, float X[2][38][64],
     }
     for (; k < sbr->kx[0] + sbr->m[0]; k++) {
         for (i = 0; i < i_Temp; i++) {
-            X[0][i][k] = Y[0][i + i_f][k][0];
-            X[1][i][k] = Y[0][i + i_f][k][1];
+            X[0][i][k] = Y0[i + i_f][k][0];
+            X[1][i][k] = Y0[i + i_f][k][1];
         }
     }
 
@@ -1376,8 +1387,8 @@ static int sbr_x_gen(SpectralBandReplication *sbr, float X[2][38][64],
     }
     for (; k < sbr->kx[1] + sbr->m[1]; k++) {
         for (i = i_Temp; i < i_f; i++) {
-            X[0][i][k] = Y[1][i][k][0];
-            X[1][i][k] = Y[1][i][k][1];
+            X[0][i][k] = Y1[i][k][0];
+            X[1][i][k] = Y1[i][k][1];
         }
     }
     return 0;
@@ -1386,7 +1397,7 @@ static int sbr_x_gen(SpectralBandReplication *sbr, float X[2][38][64],
 /** High Frequency Adjustment (14496-3 sp04 p217) and Mapping
  * (14496-3 sp04 p217)
  */
-static void sbr_mapping(AACContext *ac, SpectralBandReplication *sbr,
+static int sbr_mapping(AACContext *ac, SpectralBandReplication *sbr,
                         SBRData *ch_data, int e_a[2])
 {
     int e, i, m;
@@ -1397,6 +1408,12 @@ static void sbr_mapping(AACContext *ac, SpectralBandReplication *sbr,
         uint16_t *table = ch_data->bs_freq_res[e + 1] ? sbr->f_tablehigh : sbr->f_tablelow;
         int k;
 
+        if (sbr->kx[1] != table[0]) {
+            av_log(ac->avctx, AV_LOG_ERROR, "kx != f_table{high,low}[0]. "
+                   "Derived frequency tables were not regenerated.\n");
+            sbr_turnoff(sbr);
+            return AVERROR_BUG;
+        }
         for (i = 0; i < ilim; i++)
             for (m = table[i]; m < table[i + 1]; m++)
                 sbr->e_origmapped[e][m - sbr->kx[1]] = ch_data->env_facs[e+1][i];
@@ -1431,6 +1448,7 @@ static void sbr_mapping(AACContext *ac, SpectralBandReplication *sbr,
     }
 
     memcpy(ch_data->s_indexmapped[0], ch_data->s_indexmapped[ch_data->bs_num_env], sizeof(ch_data->s_indexmapped[0]));
+    return 0;
 }
 
 /// Estimation of current envelope (14496-3 sp04 p218)
@@ -1536,7 +1554,8 @@ static void sbr_gain_calc(AACContext *ac, SpectralBandReplication *sbr,
 }
 
 /// Assembling HF Signals (14496-3 sp04 p220)
-static void sbr_hf_assemble(float Y[2][38][64][2], const float X_high[64][40][2],
+static void sbr_hf_assemble(float Y1[38][64][2],
+                            const float X_high[64][40][2],
                             SpectralBandReplication *sbr, SBRData *ch_data,
                             const int e_a[2])
 {
@@ -1558,7 +1577,6 @@ static void sbr_hf_assemble(float Y[2][38][64][2], const float X_high[64][40][2]
     float (*g_temp)[48] = ch_data->g_temp, (*q_temp)[48] = ch_data->q_temp;
     int indexnoise = ch_data->f_indexnoise;
     int indexsine  = ch_data->f_indexsine;
-    memcpy(Y[0], Y[1], sizeof(Y[0]));
 
     if (sbr->reset) {
         for (i = 0; i < h_SL; i++) {
@@ -1580,8 +1598,9 @@ static void sbr_hf_assemble(float Y[2][38][64][2], const float X_high[64][40][2]
     for (e = 0; e < ch_data->bs_num_env; e++) {
         for (i = 2 * ch_data->t_env[e]; i < 2 * ch_data->t_env[e + 1]; i++) {
             int phi_sign = (1 - 2*(kx & 1));
-            float g_filt_tab[48], *g_filt;
-            float q_filt_tab[48], *q_filt;
+            LOCAL_ALIGNED_16(float, g_filt_tab, [48]);
+            LOCAL_ALIGNED_16(float, q_filt_tab, [48]);
+            float *g_filt, *q_filt;
 
             if (h_SL && e != e_a[0] && e != e_a[1]) {
                 g_filt = g_filt_tab;
@@ -1600,18 +1619,18 @@ static void sbr_hf_assemble(float Y[2][38][64][2], const float X_high[64][40][2]
                 q_filt = q_temp[i];
             }
 
-            sbr->dsp.hf_g_filt(Y[1][i] + kx, X_high + kx, g_filt, m_max,
+            sbr->dsp.hf_g_filt(Y1[i] + kx, X_high + kx, g_filt, m_max,
                                i + ENVELOPE_ADJUSTMENT_OFFSET);
 
             if (e != e_a[0] && e != e_a[1]) {
-                sbr->dsp.hf_apply_noise[indexsine](Y[1][i] + kx, sbr->s_m[e],
+                sbr->dsp.hf_apply_noise[indexsine](Y1[i] + kx, sbr->s_m[e],
                                                    q_filt, indexnoise,
                                                    kx, m_max);
             } else {
                 for (m = 0; m < m_max; m++) {
-                    Y[1][i][m + kx][0] +=
+                    Y1[i][m + kx][0] +=
                         sbr->s_m[e][m] * phi[0][indexsine];
-                    Y[1][i][m + kx][1] +=
+                    Y1[i][m + kx][1] +=
                         sbr->s_m[e][m] * (phi[1][indexsine] * phi_sign);
                     phi_sign = -phi_sign;
                 }
@@ -1627,19 +1646,28 @@ static void sbr_hf_assemble(float Y[2][38][64][2], const float X_high[64][40][2]
 void ff_sbr_apply(AACContext *ac, SpectralBandReplication *sbr, int id_aac,
                   float* L, float* R)
 {
-    int downsampled = ac->m4ac.ext_sample_rate < sbr->sample_rate;
+    int downsampled = ac->oc[1].m4ac.ext_sample_rate < sbr->sample_rate;
     int ch;
     int nch = (id_aac == TYPE_CPE) ? 2 : 1;
+    int err;
+
+    if (!sbr->kx_and_m_pushed) {
+        sbr->kx[0] = sbr->kx[1];
+        sbr->m[0] = sbr->m[1];
+    } else {
+        sbr->kx_and_m_pushed = 0;
+    }
 
     if (sbr->start) {
         sbr_dequant(sbr, id_aac);
     }
     for (ch = 0; ch < nch; ch++) {
         /* decode channel */
-        sbr_qmf_analysis(&ac->dsp, &sbr->mdct_ana, &sbr->dsp, ch ? R : L, sbr->data[ch].analysis_filterbank_samples,
+        sbr_qmf_analysis(&ac->fdsp, &sbr->mdct_ana, &sbr->dsp, ch ? R : L, sbr->data[ch].analysis_filterbank_samples,
                          (float*)sbr->qmf_filter_scratch,
-                         sbr->data[ch].W);
-        sbr_lf_gen(ac, sbr, sbr->X_low, sbr->data[ch].W);
+                         sbr->data[ch].W, sbr->data[ch].Ypos);
+        sbr_lf_gen(ac, sbr, sbr->X_low, sbr->data[ch].W, sbr->data[ch].Ypos);
+        sbr->data[ch].Ypos ^= 1;
         if (sbr->start) {
             sbr_hf_inverse_filter(&sbr->dsp, sbr->alpha0, sbr->alpha1, sbr->X_low, sbr->k[0]);
             sbr_chirp(sbr, &sbr->data[ch]);
@@ -1648,18 +1676,24 @@ void ff_sbr_apply(AACContext *ac, SpectralBandReplication *sbr, int id_aac,
                        sbr->data[ch].bs_num_env);
 
             // hf_adj
-            sbr_mapping(ac, sbr, &sbr->data[ch], sbr->data[ch].e_a);
-            sbr_env_estimate(sbr->e_curr, sbr->X_high, sbr, &sbr->data[ch]);
-            sbr_gain_calc(ac, sbr, &sbr->data[ch], sbr->data[ch].e_a);
-            sbr_hf_assemble(sbr->data[ch].Y, sbr->X_high, sbr, &sbr->data[ch],
-                            sbr->data[ch].e_a);
+            err = sbr_mapping(ac, sbr, &sbr->data[ch], sbr->data[ch].e_a);
+            if (!err) {
+                sbr_env_estimate(sbr->e_curr, sbr->X_high, sbr, &sbr->data[ch]);
+                sbr_gain_calc(ac, sbr, &sbr->data[ch], sbr->data[ch].e_a);
+                sbr_hf_assemble(sbr->data[ch].Y[sbr->data[ch].Ypos],
+                                sbr->X_high, sbr, &sbr->data[ch],
+                                sbr->data[ch].e_a);
+            }
         }
 
         /* synthesis */
-        sbr_x_gen(sbr, sbr->X[ch], sbr->X_low, sbr->data[ch].Y, ch);
+        sbr_x_gen(sbr, sbr->X[ch],
+                  sbr->data[ch].Y[1-sbr->data[ch].Ypos],
+                  sbr->data[ch].Y[  sbr->data[ch].Ypos],
+                  sbr->X_low, ch);
     }
 
-    if (ac->m4ac.ps == 1) {
+    if (ac->oc[1].m4ac.ps == 1) {
         if (sbr->ps.start) {
             ff_ps_apply(ac->avctx, &sbr->ps, sbr->X[0], sbr->X[1], sbr->kx[1] + sbr->m[1]);
         } else {
@@ -1668,12 +1702,14 @@ void ff_sbr_apply(AACContext *ac, SpectralBandReplication *sbr, int id_aac,
         nch = 2;
     }
 
-    sbr_qmf_synthesis(&ac->dsp, &sbr->mdct, &sbr->dsp, L, sbr->X[0], sbr->qmf_filter_scratch,
+    sbr_qmf_synthesis(&sbr->mdct, &sbr->dsp, &ac->fdsp,
+                      L, sbr->X[0], sbr->qmf_filter_scratch,
                       sbr->data[0].synthesis_filterbank_samples,
                       &sbr->data[0].synthesis_filterbank_samples_offset,
                       downsampled);
     if (nch == 2)
-        sbr_qmf_synthesis(&ac->dsp, &sbr->mdct, &sbr->dsp, R, sbr->X[1], sbr->qmf_filter_scratch,
+        sbr_qmf_synthesis(&sbr->mdct, &sbr->dsp, &ac->fdsp,
+                          R, sbr->X[1], sbr->qmf_filter_scratch,
                           sbr->data[1].synthesis_filterbank_samples,
                           &sbr->data[1].synthesis_filterbank_samples_offset,
                           downsampled);