Based in part on work from Niel van der Westhuizen <es...@pequalsnp.com>.
---
 libavcodec/Makefile     |  3 ++-
 libavcodec/aac.h        |  2 ++
 libavcodec/aacdec.c     | 38 ++++++++++++++++++++++++++------------
 libavcodec/mpeg4audio.h |  1 +
 4 files changed, 31 insertions(+), 13 deletions(-)

diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 8c0c345..92e8b67 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -91,7 +91,8 @@ OBJS-$(CONFIG_WMA_FREQS)               += wma_freqs.o
 OBJS-$(CONFIG_A64MULTI_ENCODER)        += a64multienc.o elbg.o
 OBJS-$(CONFIG_A64MULTI5_ENCODER)       += a64multienc.o elbg.o
 OBJS-$(CONFIG_AAC_DECODER)             += aacdec.o aactab.o aacsbr.o aacps.o \
-                                          aacadtsdec.o mpeg4audio.o kbdwin.o \
+                                          aacadtsdec.o opus_imdct.o \
+                                          mpeg4audio.o kbdwin.o \
                                           sbrdsp.o aacpsdsp.o
 OBJS-$(CONFIG_AAC_ENCODER)             += aacenc.o aaccoder.o    \
                                           aacpsy.o aactab.o      \
diff --git a/libavcodec/aac.h b/libavcodec/aac.h
index 375e6b1..e80b518 100644
--- a/libavcodec/aac.h
+++ b/libavcodec/aac.h
@@ -32,6 +32,7 @@
 
 #include "libavutil/float_dsp.h"
 #include "avcodec.h"
+#include "opus_imdct.h"
 #include "fft.h"
 #include "mpeg4audio.h"
 #include "sbr.h"
@@ -291,6 +292,7 @@ typedef struct AACContext {
     FFTContext mdct_small;
     FFTContext mdct_ld;
     FFTContext mdct_ltp;
+    CeltIMDCTContext *mdct480;
     FmtConvertContext fmt_conv;
     AVFloatDSPContext fdsp;
     int random_state;
diff --git a/libavcodec/aacdec.c b/libavcodec/aacdec.c
index e21ed0d..a1a3f49 100644
--- a/libavcodec/aacdec.c
+++ b/libavcodec/aacdec.c
@@ -84,6 +84,7 @@
 #include "avcodec.h"
 #include "internal.h"
 #include "get_bits.h"
+#include "opus_imdct.h"
 #include "fft.h"
 #include "fmtconvert.h"
 #include "lpc.h"
@@ -719,6 +720,7 @@ static int decode_ga_specific_config(AACContext *ac, 
AVCodecContext *avctx,
         avpriv_request_sample(avctx, "960/120 MDCT window");
         return AVERROR_PATCHWELCOME;
     }
+    m4ac->frame_length_short = 0;
 
     if (get_bits1(gb))       // dependsOnCoreCoder
         skip_bits(gb, 14);   // coreCoderDelay
@@ -796,11 +798,7 @@ static int decode_eld_specific_config(AACContext *ac, 
AVCodecContext *avctx,
     m4ac->ps  = 0;
     m4ac->sbr = 0;
 
-    if (get_bits1(gb)) { // frameLengthFlag
-        avpriv_request_sample(avctx, "960/120 MDCT window");
-        return AVERROR_PATCHWELCOME;
-    }
-
+    m4ac->frame_length_short = get_bits1(gb);
     res_flags = get_bits(gb, 3);
     if (res_flags) {
         avpriv_report_missing_feature(avctx,
@@ -1066,6 +1064,10 @@ static av_cold int aac_decode_init(AVCodecContext *avctx)
     ff_mdct_init(&ac->mdct_ld,    10, 1, 1.0 / (32768.0 * 512.0));
     ff_mdct_init(&ac->mdct_small,  8, 1, 1.0 / (32768.0 * 128.0));
     ff_mdct_init(&ac->mdct_ltp,   11, 0, -2.0 * 32768.0);
+    ret = ff_celt_imdct_init(&ac->mdct480, 5);
+    if (ret < 0)
+        return ret;
+
     // window initialization
     ff_kbd_window_init(ff_aac_kbd_long_1024, 4.0, 1024);
     ff_kbd_window_init(ff_aac_kbd_short_128, 6.0, 128);
@@ -1180,9 +1182,15 @@ static int decode_ics_info(AACContext *ac, 
IndividualChannelStream *ics,
         ics->max_sfb           = get_bits(gb, 6);
         ics->num_windows       = 1;
         if (aot == AOT_ER_AAC_LD || aot == AOT_ER_AAC_ELD) {
-            ics->swb_offset    =     ff_swb_offset_512[sampling_index];
-            ics->num_swb       =    ff_aac_num_swb_512[sampling_index];
-            ics->tns_max_bands =  ff_tns_max_bands_512[sampling_index];
+            if (m4ac->frame_length_short) {
+                ics->swb_offset    =     ff_swb_offset_480[sampling_index];
+                ics->num_swb       =    ff_aac_num_swb_480[sampling_index];
+                ics->tns_max_bands =  ff_tns_max_bands_480[sampling_index];
+            } else {
+                ics->swb_offset    =     ff_swb_offset_512[sampling_index];
+                ics->num_swb       =    ff_aac_num_swb_512[sampling_index];
+                ics->tns_max_bands =  ff_tns_max_bands_512[sampling_index];
+            }
             if (!ics->num_swb || !ics->swb_offset)
                 return AVERROR_BUG;
         } else {
@@ -2457,12 +2465,13 @@ static void imdct_and_windowing_eld(AACContext *ac, 
SingleChannelElement *sce)
     float *in    = sce->coeffs;
     float *out   = sce->ret;
     float *saved = sce->saved;
-    const float *const window = ff_aac_eld_window_512;
     float *buf  = ac->buf_mdct;
     int i;
-    const int n  = 512;
+    const int n  = ac->oc[1].m4ac.frame_length_short ? 480 : 512;
     const int n2 = n >> 1;
     const int n4 = n >> 2;
+    const float *const window = n == 480 ? ff_aac_eld_window_480 :
+                                           ff_aac_eld_window_512;
 
     // Inverse transform, mapped to the conventional IMDCT by
     // Chivukula, R.K.; Reznik, Y.A.; Devarajan, V.,
@@ -2474,7 +2483,10 @@ static void imdct_and_windowing_eld(AACContext *ac, 
SingleChannelElement *sce)
         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;
     }
-    ac->mdct.imdct_half(&ac->mdct_ld, buf, in);
+    if (n == 480)
+        ac->mdct480->imdct_half(ac->mdct480, buf, in, 1, -1.f/(16*1024*960));
+    else
+        ac->mdct.imdct_half(&ac->mdct_ld, buf, in);
     for (i = 0; i < n; i+=2) {
         buf[i] = -buf[i];
     }
@@ -2687,6 +2699,7 @@ static int parse_adts_frame_header(AACContext *ac, 
GetBitContext *gb)
         ac->oc[1].m4ac.sample_rate     = hdr_info.sample_rate;
         ac->oc[1].m4ac.sampling_index  = hdr_info.sampling_index;
         ac->oc[1].m4ac.object_type     = hdr_info.object_type;
+        ac->oc[1].m4ac.frame_length_short = 0;
         if (ac->oc[0].status != OC_LOCKED ||
             ac->oc[0].m4ac.chan_config != hdr_info.chan_config ||
             ac->oc[0].m4ac.sample_rate != hdr_info.sample_rate) {
@@ -2706,7 +2719,7 @@ static int aac_decode_er_frame(AVCodecContext *avctx, 
void *data,
     const MPEG4AudioConfig *const m4ac = &ac->oc[1].m4ac;
     ChannelElement *che;
     int err, i;
-    int samples = 1024;
+    int samples = m4ac->frame_length_short ? 960 : 1024;
     int chan_config = m4ac->chan_config;
     int aot = m4ac->object_type;
 
@@ -2982,6 +2995,7 @@ static av_cold int aac_decode_close(AVCodecContext *avctx)
     ff_mdct_end(&ac->mdct_small);
     ff_mdct_end(&ac->mdct_ld);
     ff_mdct_end(&ac->mdct_ltp);
+    ff_celt_imdct_uninit(&ac->mdct480);
     return 0;
 }
 
diff --git a/libavcodec/mpeg4audio.h b/libavcodec/mpeg4audio.h
index e71122d..2eef220 100644
--- a/libavcodec/mpeg4audio.h
+++ b/libavcodec/mpeg4audio.h
@@ -38,6 +38,7 @@ typedef struct MPEG4AudioConfig {
     int ext_chan_config;
     int channels;
     int ps;  ///< -1 implicit, 1 presence
+    int frame_length_short;
 } MPEG4AudioConfig;
 
 extern av_export const int avpriv_mpeg4audio_sample_rates[16];
-- 
2.2.0.rc0.207.ga3a616c

_______________________________________________
libav-devel mailing list
libav-devel@libav.org
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to