[FFmpeg-cvslog] aacdec: template windowing and transforms separately

Lynne git at videolan.org
Tue Apr 23 09:58:39 EEST 2024


ffmpeg | branch: master | Lynne <dev at lynne.ee> | Sat Mar 16 00:14:32 2024 +0100| [091d85217d82d5ee0f96b4dbc665cb3c598a0451] | committer: Lynne

aacdec: template windowing and transforms separately

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=091d85217d82d5ee0f96b4dbc665cb3c598a0451
---

 libavcodec/aac/aacdec_dsp_template.c | 221 ++++++++++++++++++++++++++++++++++
 libavcodec/aacdec.h                  |   1 -
 libavcodec/aacdec_template.c         | 225 +----------------------------------
 libavcodec/mips/aacdec_mips.c        |   2 +-
 4 files changed, 226 insertions(+), 223 deletions(-)

diff --git a/libavcodec/aac/aacdec_dsp_template.c b/libavcodec/aac/aacdec_dsp_template.c
index 30151604c2..c607383d67 100644
--- a/libavcodec/aac/aacdec_dsp_template.c
+++ b/libavcodec/aac/aacdec_dsp_template.c
@@ -310,6 +310,222 @@ static void AAC_RENAME(update_ltp)(AACDecContext *ac, SingleChannelElement *sce)
            1024 * sizeof(*sce->AAC_RENAME(ltp_state)));
 }
 
+/**
+ * Conduct IMDCT and windowing.
+ */
+static void AAC_RENAME(imdct_and_windowing)(AACDecContext *ac, SingleChannelElement *sce)
+{
+    IndividualChannelStream *ics = &sce->ics;
+    INTFLOAT *in    = sce->AAC_RENAME(coeffs);
+    INTFLOAT *out   = sce->AAC_RENAME(output);
+    INTFLOAT *saved = sce->AAC_RENAME(saved);
+    const INTFLOAT *swindow      = ics->use_kb_window[0] ? AAC_RENAME2(aac_kbd_short_128) : AAC_RENAME2(sine_128);
+    const INTFLOAT *lwindow_prev = ics->use_kb_window[1] ? AAC_RENAME2(aac_kbd_long_1024) : AAC_RENAME2(sine_1024);
+    const INTFLOAT *swindow_prev = ics->use_kb_window[1] ? AAC_RENAME2(aac_kbd_short_128) : AAC_RENAME2(sine_128);
+    INTFLOAT *buf  = ac->AAC_RENAME(buf_mdct);
+    INTFLOAT *temp = ac->AAC_RENAME(temp);
+    int i;
+
+    // imdct
+    if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
+        for (i = 0; i < 1024; i += 128)
+            ac->mdct128_fn(ac->mdct128, buf + i, in + i, sizeof(INTFLOAT));
+    } else {
+        ac->mdct1024_fn(ac->mdct1024, buf, in, sizeof(INTFLOAT));
+    }
+
+    /* window overlapping
+     * NOTE: To simplify the overlapping code, all 'meaningless' short to long
+     * and long to short transitions are considered to be short to short
+     * transitions. This leaves just two cases (long to long and short to short)
+     * with a little special sauce for EIGHT_SHORT_SEQUENCE.
+     */
+    if ((ics->window_sequence[1] == ONLY_LONG_SEQUENCE || ics->window_sequence[1] == LONG_STOP_SEQUENCE) &&
+            (ics->window_sequence[0] == ONLY_LONG_SEQUENCE || ics->window_sequence[0] == LONG_START_SEQUENCE)) {
+        ac->fdsp->vector_fmul_window(    out,               saved,            buf,         lwindow_prev, 512);
+    } else {
+        memcpy(                         out,               saved,            448 * sizeof(*out));
+
+        if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
+            ac->fdsp->vector_fmul_window(out + 448 + 0*128, saved + 448,      buf + 0*128, swindow_prev, 64);
+            ac->fdsp->vector_fmul_window(out + 448 + 1*128, buf + 0*128 + 64, buf + 1*128, swindow,      64);
+            ac->fdsp->vector_fmul_window(out + 448 + 2*128, buf + 1*128 + 64, buf + 2*128, swindow,      64);
+            ac->fdsp->vector_fmul_window(out + 448 + 3*128, buf + 2*128 + 64, buf + 3*128, swindow,      64);
+            ac->fdsp->vector_fmul_window(temp,              buf + 3*128 + 64, buf + 4*128, swindow,      64);
+            memcpy(                     out + 448 + 4*128, temp, 64 * sizeof(*out));
+        } else {
+            ac->fdsp->vector_fmul_window(out + 448,         saved + 448,      buf,         swindow_prev, 64);
+            memcpy(                     out + 576,         buf + 64,         448 * sizeof(*out));
+        }
+    }
+
+    // buffer update
+    if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
+        memcpy(                     saved,       temp + 64,         64 * sizeof(*saved));
+        ac->fdsp->vector_fmul_window(saved + 64,  buf + 4*128 + 64, buf + 5*128, swindow, 64);
+        ac->fdsp->vector_fmul_window(saved + 192, buf + 5*128 + 64, buf + 6*128, swindow, 64);
+        ac->fdsp->vector_fmul_window(saved + 320, buf + 6*128 + 64, buf + 7*128, swindow, 64);
+        memcpy(                     saved + 448, buf + 7*128 + 64,  64 * sizeof(*saved));
+    } else if (ics->window_sequence[0] == LONG_START_SEQUENCE) {
+        memcpy(                     saved,       buf + 512,        448 * sizeof(*saved));
+        memcpy(                     saved + 448, buf + 7*128 + 64,  64 * sizeof(*saved));
+    } else { // LONG_STOP or ONLY_LONG
+        memcpy(                     saved,       buf + 512,        512 * sizeof(*saved));
+    }
+}
+
+/**
+ * Conduct IMDCT and windowing.
+ */
+static void AAC_RENAME(imdct_and_windowing_960)(AACDecContext *ac, SingleChannelElement *sce)
+{
+    IndividualChannelStream *ics = &sce->ics;
+    INTFLOAT *in    = sce->AAC_RENAME(coeffs);
+    INTFLOAT *out   = sce->AAC_RENAME(output);
+    INTFLOAT *saved = sce->AAC_RENAME(saved);
+    const INTFLOAT *swindow      = ics->use_kb_window[0] ? AAC_RENAME(aac_kbd_short_120) : AAC_RENAME(sine_120);
+    const INTFLOAT *lwindow_prev = ics->use_kb_window[1] ? AAC_RENAME(aac_kbd_long_960) : AAC_RENAME(sine_960);
+    const INTFLOAT *swindow_prev = ics->use_kb_window[1] ? AAC_RENAME(aac_kbd_short_120) : AAC_RENAME(sine_120);
+    INTFLOAT *buf  = ac->AAC_RENAME(buf_mdct);
+    INTFLOAT *temp = ac->AAC_RENAME(temp);
+    int i;
+
+    // imdct
+    if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
+        for (i = 0; i < 8; i++)
+            ac->mdct120_fn(ac->mdct120, buf + i * 120, in + i * 128, sizeof(INTFLOAT));
+    } else {
+        ac->mdct960_fn(ac->mdct960, buf, in, sizeof(INTFLOAT));
+    }
+
+    /* window overlapping
+     * NOTE: To simplify the overlapping code, all 'meaningless' short to long
+     * and long to short transitions are considered to be short to short
+     * transitions. This leaves just two cases (long to long and short to short)
+     * with a little special sauce for EIGHT_SHORT_SEQUENCE.
+     */
+
+    if ((ics->window_sequence[1] == ONLY_LONG_SEQUENCE || ics->window_sequence[1] == LONG_STOP_SEQUENCE) &&
+        (ics->window_sequence[0] == ONLY_LONG_SEQUENCE || ics->window_sequence[0] == LONG_START_SEQUENCE)) {
+        ac->fdsp->vector_fmul_window(    out,               saved,            buf,         lwindow_prev, 480);
+    } else {
+        memcpy(                          out,               saved,            420 * sizeof(*out));
+
+        if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
+            ac->fdsp->vector_fmul_window(out + 420 + 0*120, saved + 420,      buf + 0*120, swindow_prev, 60);
+            ac->fdsp->vector_fmul_window(out + 420 + 1*120, buf + 0*120 + 60, buf + 1*120, swindow,      60);
+            ac->fdsp->vector_fmul_window(out + 420 + 2*120, buf + 1*120 + 60, buf + 2*120, swindow,      60);
+            ac->fdsp->vector_fmul_window(out + 420 + 3*120, buf + 2*120 + 60, buf + 3*120, swindow,      60);
+            ac->fdsp->vector_fmul_window(temp,              buf + 3*120 + 60, buf + 4*120, swindow,      60);
+            memcpy(                      out + 420 + 4*120, temp, 60 * sizeof(*out));
+        } else {
+            ac->fdsp->vector_fmul_window(out + 420,         saved + 420,      buf,         swindow_prev, 60);
+            memcpy(                      out + 540,         buf + 60,         420 * sizeof(*out));
+        }
+    }
+
+    // buffer update
+    if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
+        memcpy(                      saved,       temp + 60,         60 * sizeof(*saved));
+        ac->fdsp->vector_fmul_window(saved + 60,  buf + 4*120 + 60, buf + 5*120, swindow, 60);
+        ac->fdsp->vector_fmul_window(saved + 180, buf + 5*120 + 60, buf + 6*120, swindow, 60);
+        ac->fdsp->vector_fmul_window(saved + 300, buf + 6*120 + 60, buf + 7*120, swindow, 60);
+        memcpy(                      saved + 420, buf + 7*120 + 60,  60 * sizeof(*saved));
+    } else if (ics->window_sequence[0] == LONG_START_SEQUENCE) {
+        memcpy(                      saved,       buf + 480,        420 * sizeof(*saved));
+        memcpy(                      saved + 420, buf + 7*120 + 60,  60 * sizeof(*saved));
+    } else { // LONG_STOP or ONLY_LONG
+        memcpy(                      saved,       buf + 480,        480 * sizeof(*saved));
+    }
+}
+static void AAC_RENAME(imdct_and_windowing_ld)(AACDecContext *ac, SingleChannelElement *sce)
+{
+    IndividualChannelStream *ics = &sce->ics;
+    INTFLOAT *in    = sce->AAC_RENAME(coeffs);
+    INTFLOAT *out   = sce->AAC_RENAME(output);
+    INTFLOAT *saved = sce->AAC_RENAME(saved);
+    INTFLOAT *buf   = ac->AAC_RENAME(buf_mdct);
+
+    // imdct
+    ac->mdct512_fn(ac->mdct512, buf, in, sizeof(INTFLOAT));
+
+    // window overlapping
+    if (ics->use_kb_window[1]) {
+        // AAC LD uses a low overlap sine window instead of a KBD window
+        memcpy(out, saved, 192 * sizeof(*out));
+        ac->fdsp->vector_fmul_window(out + 192, saved + 192, buf, AAC_RENAME2(sine_128), 64);
+        memcpy(                     out + 320, buf + 64, 192 * sizeof(*out));
+    } else {
+        ac->fdsp->vector_fmul_window(out, saved, buf, AAC_RENAME2(sine_512), 256);
+    }
+
+    // buffer update
+    memcpy(saved, buf + 256, 256 * sizeof(*saved));
+}
+
+static void AAC_RENAME(imdct_and_windowing_eld)(AACDecContext *ac, SingleChannelElement *sce)
+{
+    UINTFLOAT *in   = sce->AAC_RENAME(coeffs);
+    INTFLOAT *out   = sce->AAC_RENAME(output);
+    INTFLOAT *saved = sce->AAC_RENAME(saved);
+    INTFLOAT *buf   = ac->AAC_RENAME(buf_mdct);
+    int i;
+    const int n  = ac->oc[1].m4ac.frame_length_short ? 480 : 512;
+    const int n2 = n >> 1;
+    const int n4 = n >> 2;
+    const INTFLOAT *const window = n == 480 ? AAC_RENAME(ff_aac_eld_window_480) :
+                                           AAC_RENAME(ff_aac_eld_window_512);
+
+    // Inverse transform, mapped to the conventional IMDCT by
+    // Chivukula, R.K.; Reznik, Y.A.; Devarajan, V.,
+    // "Efficient algorithms for MPEG-4 AAC-ELD, AAC-LD and AAC-LC filterbanks,"
+    // International Conference on Audio, Language and Image Processing, ICALIP 2008.
+    // URL: http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=4590245&isnumber=4589950
+    for (i = 0; i < n2; i+=2) {
+        INTFLOAT temp;
+        temp =  in[i    ]; in[i    ] = -in[n - 1 - i]; in[n - 1 - i] = temp;
+        temp = -in[i + 1]; in[i + 1] =  in[n - 2 - i]; in[n - 2 - i] = temp;
+    }
+
+    if (n == 480)
+        ac->mdct480_fn(ac->mdct480, buf, in, sizeof(INTFLOAT));
+    else
+        ac->mdct512_fn(ac->mdct512, buf, in, sizeof(INTFLOAT));
+
+    for (i = 0; i < n; i+=2) {
+        buf[i + 0] = -(UINTFLOAT)(USE_FIXED + 1)*buf[i + 0];
+        buf[i + 1] =  (UINTFLOAT)(USE_FIXED + 1)*buf[i + 1];
+    }
+    // Like with the regular IMDCT at this point we still have the middle half
+    // of a transform but with even symmetry on the left and odd symmetry on
+    // the right
+
+    // window overlapping
+    // The spec says to use samples [0..511] but the reference decoder uses
+    // samples [128..639].
+    for (i = n4; i < n2; i ++) {
+        out[i - n4] = AAC_MUL31(   buf[    n2 - 1 - i] , window[i       - n4]) +
+                      AAC_MUL31( saved[        i + n2] , window[i +   n - n4]) +
+                      AAC_MUL31(-saved[n + n2 - 1 - i] , window[i + 2*n - n4]) +
+                      AAC_MUL31(-saved[  2*n + n2 + i] , window[i + 3*n - n4]);
+    }
+    for (i = 0; i < n2; i ++) {
+        out[n4 + i] = AAC_MUL31(   buf[              i] , window[i + n2       - n4]) +
+                      AAC_MUL31(-saved[      n - 1 - i] , window[i + n2 +   n - n4]) +
+                      AAC_MUL31(-saved[          n + i] , window[i + n2 + 2*n - n4]) +
+                      AAC_MUL31( saved[2*n + n - 1 - i] , window[i + n2 + 3*n - n4]);
+    }
+    for (i = 0; i < n4; i ++) {
+        out[n2 + n4 + i] = AAC_MUL31(   buf[    i + n2] , window[i +   n - n4]) +
+                           AAC_MUL31(-saved[n2 - 1 - i] , window[i + 2*n - n4]) +
+                           AAC_MUL31(-saved[n + n2 + i] , window[i + 3*n - n4]);
+    }
+
+    // buffer update
+    memmove(saved + n, saved, 2 * n * sizeof(*saved));
+    memcpy( saved,       buf,     n * sizeof(*saved));
+}
+
 const AACDecDSP AAC_RENAME(aac_dsp) = {
     .init_tables = &AAC_RENAME(init_tables),
 
@@ -319,4 +535,9 @@ const AACDecDSP AAC_RENAME(aac_dsp) = {
     .apply_tns = &AAC_RENAME(apply_tns),
     .apply_ltp = &AAC_RENAME(apply_ltp),
     .update_ltp = &AAC_RENAME(update_ltp),
+
+    .imdct_and_windowing = AAC_RENAME(imdct_and_windowing),
+    .imdct_and_windowing_960 = AAC_RENAME(imdct_and_windowing_960),
+    .imdct_and_windowing_ld = AAC_RENAME(imdct_and_windowing_ld),
+    .imdct_and_windowing_eld = AAC_RENAME(imdct_and_windowing_eld),
 };
diff --git a/libavcodec/aacdec.h b/libavcodec/aacdec.h
index 30da1fc198..a0f8790e17 100644
--- a/libavcodec/aacdec.h
+++ b/libavcodec/aacdec.h
@@ -311,7 +311,6 @@ struct AACDecContext {
     int is_fixed;
 
     /* aacdec functions pointers */
-    void (*imdct_and_windowing)(struct AACDecContext *ac, SingleChannelElement *sce);
     union {
         void (*windowing_and_mdct_ltp)(struct AACDecContext *ac, float *out,
                                        float *in, IndividualChannelStream *ics);
diff --git a/libavcodec/aacdec_template.c b/libavcodec/aacdec_template.c
index 11b3d96a44..7985a213eb 100644
--- a/libavcodec/aacdec_template.c
+++ b/libavcodec/aacdec_template.c
@@ -2394,222 +2394,6 @@ static void windowing_and_mdct_ltp(AACDecContext *ac, INTFLOAT *out,
     ac->mdct_ltp_fn(ac->mdct_ltp, out, in, sizeof(INTFLOAT));
 }
 
-/**
- * Conduct IMDCT and windowing.
- */
-static void imdct_and_windowing(AACDecContext *ac, SingleChannelElement *sce)
-{
-    IndividualChannelStream *ics = &sce->ics;
-    INTFLOAT *in    = sce->AAC_RENAME(coeffs);
-    INTFLOAT *out   = sce->AAC_RENAME(output);
-    INTFLOAT *saved = sce->AAC_RENAME(saved);
-    const INTFLOAT *swindow      = ics->use_kb_window[0] ? AAC_RENAME2(aac_kbd_short_128) : AAC_RENAME2(sine_128);
-    const INTFLOAT *lwindow_prev = ics->use_kb_window[1] ? AAC_RENAME2(aac_kbd_long_1024) : AAC_RENAME2(sine_1024);
-    const INTFLOAT *swindow_prev = ics->use_kb_window[1] ? AAC_RENAME2(aac_kbd_short_128) : AAC_RENAME2(sine_128);
-    INTFLOAT *buf  = ac->AAC_RENAME(buf_mdct);
-    INTFLOAT *temp = ac->AAC_RENAME(temp);
-    int i;
-
-    // imdct
-    if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
-        for (i = 0; i < 1024; i += 128)
-            ac->mdct128_fn(ac->mdct128, buf + i, in + i, sizeof(INTFLOAT));
-    } else {
-        ac->mdct1024_fn(ac->mdct1024, buf, in, sizeof(INTFLOAT));
-    }
-
-    /* window overlapping
-     * NOTE: To simplify the overlapping code, all 'meaningless' short to long
-     * and long to short transitions are considered to be short to short
-     * transitions. This leaves just two cases (long to long and short to short)
-     * with a little special sauce for EIGHT_SHORT_SEQUENCE.
-     */
-    if ((ics->window_sequence[1] == ONLY_LONG_SEQUENCE || ics->window_sequence[1] == LONG_STOP_SEQUENCE) &&
-            (ics->window_sequence[0] == ONLY_LONG_SEQUENCE || ics->window_sequence[0] == LONG_START_SEQUENCE)) {
-        ac->fdsp->vector_fmul_window(    out,               saved,            buf,         lwindow_prev, 512);
-    } else {
-        memcpy(                         out,               saved,            448 * sizeof(*out));
-
-        if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
-            ac->fdsp->vector_fmul_window(out + 448 + 0*128, saved + 448,      buf + 0*128, swindow_prev, 64);
-            ac->fdsp->vector_fmul_window(out + 448 + 1*128, buf + 0*128 + 64, buf + 1*128, swindow,      64);
-            ac->fdsp->vector_fmul_window(out + 448 + 2*128, buf + 1*128 + 64, buf + 2*128, swindow,      64);
-            ac->fdsp->vector_fmul_window(out + 448 + 3*128, buf + 2*128 + 64, buf + 3*128, swindow,      64);
-            ac->fdsp->vector_fmul_window(temp,              buf + 3*128 + 64, buf + 4*128, swindow,      64);
-            memcpy(                     out + 448 + 4*128, temp, 64 * sizeof(*out));
-        } else {
-            ac->fdsp->vector_fmul_window(out + 448,         saved + 448,      buf,         swindow_prev, 64);
-            memcpy(                     out + 576,         buf + 64,         448 * sizeof(*out));
-        }
-    }
-
-    // buffer update
-    if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
-        memcpy(                     saved,       temp + 64,         64 * sizeof(*saved));
-        ac->fdsp->vector_fmul_window(saved + 64,  buf + 4*128 + 64, buf + 5*128, swindow, 64);
-        ac->fdsp->vector_fmul_window(saved + 192, buf + 5*128 + 64, buf + 6*128, swindow, 64);
-        ac->fdsp->vector_fmul_window(saved + 320, buf + 6*128 + 64, buf + 7*128, swindow, 64);
-        memcpy(                     saved + 448, buf + 7*128 + 64,  64 * sizeof(*saved));
-    } else if (ics->window_sequence[0] == LONG_START_SEQUENCE) {
-        memcpy(                     saved,       buf + 512,        448 * sizeof(*saved));
-        memcpy(                     saved + 448, buf + 7*128 + 64,  64 * sizeof(*saved));
-    } else { // LONG_STOP or ONLY_LONG
-        memcpy(                     saved,       buf + 512,        512 * sizeof(*saved));
-    }
-}
-
-/**
- * Conduct IMDCT and windowing.
- */
-static void imdct_and_windowing_960(AACDecContext *ac, SingleChannelElement *sce)
-{
-    IndividualChannelStream *ics = &sce->ics;
-    INTFLOAT *in    = sce->AAC_RENAME(coeffs);
-    INTFLOAT *out   = sce->AAC_RENAME(output);
-    INTFLOAT *saved = sce->AAC_RENAME(saved);
-    const INTFLOAT *swindow      = ics->use_kb_window[0] ? AAC_RENAME(aac_kbd_short_120) : AAC_RENAME(sine_120);
-    const INTFLOAT *lwindow_prev = ics->use_kb_window[1] ? AAC_RENAME(aac_kbd_long_960) : AAC_RENAME(sine_960);
-    const INTFLOAT *swindow_prev = ics->use_kb_window[1] ? AAC_RENAME(aac_kbd_short_120) : AAC_RENAME(sine_120);
-    INTFLOAT *buf  = ac->AAC_RENAME(buf_mdct);
-    INTFLOAT *temp = ac->AAC_RENAME(temp);
-    int i;
-
-    // imdct
-    if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
-        for (i = 0; i < 8; i++)
-            ac->mdct120_fn(ac->mdct120, buf + i * 120, in + i * 128, sizeof(INTFLOAT));
-    } else {
-        ac->mdct960_fn(ac->mdct960, buf, in, sizeof(INTFLOAT));
-    }
-
-    /* window overlapping
-     * NOTE: To simplify the overlapping code, all 'meaningless' short to long
-     * and long to short transitions are considered to be short to short
-     * transitions. This leaves just two cases (long to long and short to short)
-     * with a little special sauce for EIGHT_SHORT_SEQUENCE.
-     */
-
-    if ((ics->window_sequence[1] == ONLY_LONG_SEQUENCE || ics->window_sequence[1] == LONG_STOP_SEQUENCE) &&
-        (ics->window_sequence[0] == ONLY_LONG_SEQUENCE || ics->window_sequence[0] == LONG_START_SEQUENCE)) {
-        ac->fdsp->vector_fmul_window(    out,               saved,            buf,         lwindow_prev, 480);
-    } else {
-        memcpy(                          out,               saved,            420 * sizeof(*out));
-
-        if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
-            ac->fdsp->vector_fmul_window(out + 420 + 0*120, saved + 420,      buf + 0*120, swindow_prev, 60);
-            ac->fdsp->vector_fmul_window(out + 420 + 1*120, buf + 0*120 + 60, buf + 1*120, swindow,      60);
-            ac->fdsp->vector_fmul_window(out + 420 + 2*120, buf + 1*120 + 60, buf + 2*120, swindow,      60);
-            ac->fdsp->vector_fmul_window(out + 420 + 3*120, buf + 2*120 + 60, buf + 3*120, swindow,      60);
-            ac->fdsp->vector_fmul_window(temp,              buf + 3*120 + 60, buf + 4*120, swindow,      60);
-            memcpy(                      out + 420 + 4*120, temp, 60 * sizeof(*out));
-        } else {
-            ac->fdsp->vector_fmul_window(out + 420,         saved + 420,      buf,         swindow_prev, 60);
-            memcpy(                      out + 540,         buf + 60,         420 * sizeof(*out));
-        }
-    }
-
-    // buffer update
-    if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
-        memcpy(                      saved,       temp + 60,         60 * sizeof(*saved));
-        ac->fdsp->vector_fmul_window(saved + 60,  buf + 4*120 + 60, buf + 5*120, swindow, 60);
-        ac->fdsp->vector_fmul_window(saved + 180, buf + 5*120 + 60, buf + 6*120, swindow, 60);
-        ac->fdsp->vector_fmul_window(saved + 300, buf + 6*120 + 60, buf + 7*120, swindow, 60);
-        memcpy(                      saved + 420, buf + 7*120 + 60,  60 * sizeof(*saved));
-    } else if (ics->window_sequence[0] == LONG_START_SEQUENCE) {
-        memcpy(                      saved,       buf + 480,        420 * sizeof(*saved));
-        memcpy(                      saved + 420, buf + 7*120 + 60,  60 * sizeof(*saved));
-    } else { // LONG_STOP or ONLY_LONG
-        memcpy(                      saved,       buf + 480,        480 * sizeof(*saved));
-    }
-}
-static void imdct_and_windowing_ld(AACDecContext *ac, SingleChannelElement *sce)
-{
-    IndividualChannelStream *ics = &sce->ics;
-    INTFLOAT *in    = sce->AAC_RENAME(coeffs);
-    INTFLOAT *out   = sce->AAC_RENAME(output);
-    INTFLOAT *saved = sce->AAC_RENAME(saved);
-    INTFLOAT *buf   = ac->AAC_RENAME(buf_mdct);
-
-    // imdct
-    ac->mdct512_fn(ac->mdct512, buf, in, sizeof(INTFLOAT));
-
-    // window overlapping
-    if (ics->use_kb_window[1]) {
-        // AAC LD uses a low overlap sine window instead of a KBD window
-        memcpy(out, saved, 192 * sizeof(*out));
-        ac->fdsp->vector_fmul_window(out + 192, saved + 192, buf, AAC_RENAME2(sine_128), 64);
-        memcpy(                     out + 320, buf + 64, 192 * sizeof(*out));
-    } else {
-        ac->fdsp->vector_fmul_window(out, saved, buf, AAC_RENAME2(sine_512), 256);
-    }
-
-    // buffer update
-    memcpy(saved, buf + 256, 256 * sizeof(*saved));
-}
-
-static void imdct_and_windowing_eld(AACDecContext *ac, SingleChannelElement *sce)
-{
-    UINTFLOAT *in   = sce->AAC_RENAME(coeffs);
-    INTFLOAT *out   = sce->AAC_RENAME(output);
-    INTFLOAT *saved = sce->AAC_RENAME(saved);
-    INTFLOAT *buf   = ac->AAC_RENAME(buf_mdct);
-    int i;
-    const int n  = ac->oc[1].m4ac.frame_length_short ? 480 : 512;
-    const int n2 = n >> 1;
-    const int n4 = n >> 2;
-    const INTFLOAT *const window = n == 480 ? AAC_RENAME(ff_aac_eld_window_480) :
-                                           AAC_RENAME(ff_aac_eld_window_512);
-
-    // Inverse transform, mapped to the conventional IMDCT by
-    // Chivukula, R.K.; Reznik, Y.A.; Devarajan, V.,
-    // "Efficient algorithms for MPEG-4 AAC-ELD, AAC-LD and AAC-LC filterbanks,"
-    // International Conference on Audio, Language and Image Processing, ICALIP 2008.
-    // URL: http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=4590245&isnumber=4589950
-    for (i = 0; i < n2; i+=2) {
-        INTFLOAT temp;
-        temp =  in[i    ]; in[i    ] = -in[n - 1 - i]; in[n - 1 - i] = temp;
-        temp = -in[i + 1]; in[i + 1] =  in[n - 2 - i]; in[n - 2 - i] = temp;
-    }
-
-    if (n == 480)
-        ac->mdct480_fn(ac->mdct480, buf, in, sizeof(INTFLOAT));
-    else
-        ac->mdct512_fn(ac->mdct512, buf, in, sizeof(INTFLOAT));
-
-    for (i = 0; i < n; i+=2) {
-        buf[i + 0] = -(UINTFLOAT)(USE_FIXED + 1)*buf[i + 0];
-        buf[i + 1] =  (UINTFLOAT)(USE_FIXED + 1)*buf[i + 1];
-    }
-    // Like with the regular IMDCT at this point we still have the middle half
-    // of a transform but with even symmetry on the left and odd symmetry on
-    // the right
-
-    // window overlapping
-    // The spec says to use samples [0..511] but the reference decoder uses
-    // samples [128..639].
-    for (i = n4; i < n2; i ++) {
-        out[i - n4] = AAC_MUL31(   buf[    n2 - 1 - i] , window[i       - n4]) +
-                      AAC_MUL31( saved[        i + n2] , window[i +   n - n4]) +
-                      AAC_MUL31(-saved[n + n2 - 1 - i] , window[i + 2*n - n4]) +
-                      AAC_MUL31(-saved[  2*n + n2 + i] , window[i + 3*n - n4]);
-    }
-    for (i = 0; i < n2; i ++) {
-        out[n4 + i] = AAC_MUL31(   buf[              i] , window[i + n2       - n4]) +
-                      AAC_MUL31(-saved[      n - 1 - i] , window[i + n2 +   n - n4]) +
-                      AAC_MUL31(-saved[          n + i] , window[i + n2 + 2*n - n4]) +
-                      AAC_MUL31( saved[2*n + n - 1 - i] , window[i + n2 + 3*n - n4]);
-    }
-    for (i = 0; i < n4; i ++) {
-        out[n2 + n4 + i] = AAC_MUL31(   buf[    i + n2] , window[i +   n - n4]) +
-                           AAC_MUL31(-saved[n2 - 1 - i] , window[i + 2*n - n4]) +
-                           AAC_MUL31(-saved[n + n2 + i] , window[i + 3*n - n4]);
-    }
-
-    // buffer update
-    memmove(saved + n, saved, 2 * n * sizeof(*saved));
-    memcpy( saved,       buf,     n * sizeof(*saved));
-}
-
 /**
  * channel coupling transformation interface
  *
@@ -2654,16 +2438,16 @@ static void spectral_to_sample(AACDecContext *ac, int samples)
     void (*imdct_and_window)(AACDecContext *ac, SingleChannelElement *sce);
     switch (ac->oc[1].m4ac.object_type) {
     case AOT_ER_AAC_LD:
-        imdct_and_window = imdct_and_windowing_ld;
+        imdct_and_window = ac->dsp.imdct_and_windowing_ld;
         break;
     case AOT_ER_AAC_ELD:
-        imdct_and_window = imdct_and_windowing_eld;
+        imdct_and_window = ac->dsp.imdct_and_windowing_eld;
         break;
     default:
         if (ac->oc[1].m4ac.frame_length_short)
-            imdct_and_window = imdct_and_windowing_960;
+            imdct_and_window = ac->dsp.imdct_and_windowing_960;
         else
-            imdct_and_window = ac->imdct_and_windowing;
+            imdct_and_window = ac->dsp.imdct_and_windowing;
     }
     for (type = 3; type >= 0; type--) {
         for (i = 0; i < MAX_ELEM_ID; i++) {
@@ -3135,7 +2919,6 @@ static int aac_decode_frame(AVCodecContext *avctx, AVFrame *frame,
 
 static void aacdec_init(AACDecContext *c)
 {
-    c->imdct_and_windowing                      = imdct_and_windowing;
     c->AAC_RENAME(windowing_and_mdct_ltp)       = windowing_and_mdct_ltp;
 #if USE_FIXED
     c->vector_pow43                             = vector_pow43;
diff --git a/libavcodec/mips/aacdec_mips.c b/libavcodec/mips/aacdec_mips.c
index 5b71bb97ab..b9848baaaa 100644
--- a/libavcodec/mips/aacdec_mips.c
+++ b/libavcodec/mips/aacdec_mips.c
@@ -435,7 +435,7 @@ void ff_aacdec_init_mips(AACDecContext *c)
 {
 #if HAVE_INLINE_ASM
 #if HAVE_MIPSFPU
-    c->imdct_and_windowing         = imdct_and_windowing_mips;
+    c->dsp.imdct_and_windowing     = imdct_and_windowing_mips;
     c->dsp.apply_ltp               = apply_ltp_mips;
     c->update_ltp                  = update_ltp_mips;
 #endif /* HAVE_MIPSFPU */



More information about the ffmpeg-cvslog mailing list