diff mbox series

[FFmpeg-devel] avcodec/aacdec: add support for AAC SBR with 960 frame length

Message ID 14a406d5-5c56-ef89-bebf-18c205cae59e@walliczek.de
State New
Headers show
Series [FFmpeg-devel] avcodec/aacdec: add support for AAC SBR with 960 frame length | expand

Checks

Context Check Description
yinshiyou/configure_loongarch64 warning Failed to apply patch
andriy/configure_x86 warning Failed to apply patch

Commit Message

Matthias Walliczek May 20, 2023, 1:25 p.m. UTC
Supports the european DAB+ digital radio coding

Fixes: https://trac.ffmpeg.org/ticket/1407 "HE-AAC (v2): 960/120 MDCT 
window is not implemented"

Signed-off-by: Matthias Walliczek <matthias@walliczek.de>
---
  libavcodec/aacdec_template.c | 21 ++--------
  libavcodec/aacps.c           | 10 +++--
  libavcodec/aacps.h           |  7 ++--
  libavcodec/aacps_common.c    |  3 +-
  libavcodec/aacsbr.h          |  4 +-
  libavcodec/aacsbr_template.c | 77 ++++++++++++++++++++----------------
  libavcodec/sbr.h             |  4 +-
  7 files changed, 61 insertions(+), 65 deletions(-)

-                     const INTFLOAT X_low[32][40][2], int ch);
+                     const INTFLOAT X_low[32][40][2], int ch, int 
frame_length_short);
      void (*sbr_hf_inverse_filter)(SBRDSPContext *dsp,
                                    INTFLOAT (*alpha0)[2], INTFLOAT 
(*alpha1)[2],
                                    const INTFLOAT X_low[32][40][2], int 
k0);

Comments

Paul B Mahol May 20, 2023, 1:29 p.m. UTC | #1
On 5/20/23, Matthias Walliczek <matthias@walliczek.de> wrote:
> Supports the european DAB+ digital radio coding
>
> Fixes: https://trac.ffmpeg.org/ticket/1407 "HE-AAC (v2): 960/120 MDCT
> window is not implemented"
>
> Signed-off-by: Matthias Walliczek <matthias@walliczek.de>
> ---
>   libavcodec/aacdec_template.c | 21 ++--------
>   libavcodec/aacps.c           | 10 +++--
>   libavcodec/aacps.h           |  7 ++--
>   libavcodec/aacps_common.c    |  3 +-
>   libavcodec/aacsbr.h          |  4 +-
>   libavcodec/aacsbr_template.c | 77 ++++++++++++++++++++----------------
>   libavcodec/sbr.h             |  4 +-
>   7 files changed, 61 insertions(+), 65 deletions(-)
>
> diff --git a/libavcodec/aacdec_template.c b/libavcodec/aacdec_template.c
> index 444dc4fa9d..9f6fd76c6a 100644
> --- a/libavcodec/aacdec_template.c
> +++ b/libavcodec/aacdec_template.c
> @@ -849,12 +849,6 @@ static int decode_ga_specific_config(AACContext
> *ac, AVCodecContext *avctx,
>       int tags = 0;
>        m4ac->frame_length_short = get_bits1(gb);
> -    if (m4ac->frame_length_short && m4ac->sbr == 1) {
> -      avpriv_report_missing_feature(avctx, "SBR with 960 frame length");
> -      if (ac) ac->warned_960_sbr = 1;
> -      m4ac->sbr = 0;
> -      m4ac->ps = 0;
> -    }
>        if (get_bits1(gb))       // dependsOnCoreCoder
>           skip_bits(gb, 14);   // coreCoderDelay
> @@ -1047,10 +1041,10 @@ static int
> decode_audio_specific_config_gb(AACContext *ac,
>       }
>        ff_dlog(avctx,
> -            "AOT %d chan config %d sampling index %d (%d) SBR %d PS %d\n",
> +            "AOT %d chan config %d sampling index %d (%d) SBR %d PS %d
> frame length %d\n",
>               m4ac->object_type, m4ac->chan_config, m4ac->sampling_index,
>               m4ac->sample_rate, m4ac->sbr,
> -            m4ac->ps);
> +            m4ac->ps, m4ac->frame_length_short ? 960 : 1024);
>        return get_bits_count(gb);
>   }
> @@ -2467,13 +2461,6 @@ static int decode_extension_payload(AACContext
> *ac, GetBitContext *gb, int cnt,
>           if (!che) {
>               av_log(ac->avctx, AV_LOG_ERROR, "SBR was found before the
> first channel element.\n");
>               return res;
> -        } else if (ac->oc[1].m4ac.frame_length_short) {
> -            if (!ac->warned_960_sbr)
> -              avpriv_report_missing_feature(ac->avctx,
> -                                            "SBR with 960 frame length");
> -            ac->warned_960_sbr = 1;
> -            skip_bits_long(gb, 8 * cnt - 4);
> -            return res;
>           } else if (!ac->oc[1].m4ac.sbr) {
>               av_log(ac->avctx, AV_LOG_ERROR, "SBR signaled to be
> not-present but was found in the bitstream.\n");
>               skip_bits_long(gb, 8 * cnt - 4);
> @@ -2493,7 +2480,7 @@ static int decode_extension_payload(AACContext
> *ac, GetBitContext *gb, int cnt,
>               ac->oc[1].m4ac.sbr = 1;
>               ac->avctx->profile = FF_PROFILE_AAC_HE;
>           }
> -        res = AAC_RENAME(ff_decode_sbr_extension)(ac, &che->sbr, gb,
> crc_flag, cnt, elem_type);
> +        res = AAC_RENAME(ff_decode_sbr_extension)(ac, &che->sbr, gb,
> crc_flag, cnt, elem_type, ac->oc[1].m4ac.frame_length_short);
>           if (ac->oc[1].m4ac.ps == 1 && !ac->warned_he_aac_mono) {
>               av_log(ac->avctx, AV_LOG_VERBOSE, "Treating HE-AAC mono as
> stereo.\n");
>               ac->warned_he_aac_mono = 1;
> @@ -2974,7 +2961,7 @@ static void spectral_to_sample(AACContext *ac, int
> samples)
>                               ac->update_ltp(ac, &che->ch[1]);
>                       }
>                       if (ac->oc[1].m4ac.sbr > 0) {
> -                        AAC_RENAME(ff_sbr_apply)(ac, &che->sbr, type,
> che->ch[0].ret, che->ch[1].ret);
> +                        AAC_RENAME(ff_sbr_apply)(ac, &che->sbr, type,
> che->ch[0].ret, che->ch[1].ret, ac->oc[1].m4ac.frame_length_short);
>                       }
>                   }
>                   if (type <= TYPE_CCE)
> diff --git a/libavcodec/aacps.c b/libavcodec/aacps.c
> index 655e8fe5b4..52103e97a4 100644
> --- a/libavcodec/aacps.c
> +++ b/libavcodec/aacps.c
> @@ -397,7 +397,7 @@ static void map_val_20_to_34(INTFLOAT
> par[PS_MAX_NR_IIDICC])
>       par[ 1] = AAC_HALF_SUM(par[ 0], par[ 1]);
>   }
>   -static void decorrelation(PSContext *ps, INTFLOAT (*out)[32][2],
> const INTFLOAT (*s)[32][2], int is34)
> +static void decorrelation(PSContext *ps, INTFLOAT (*out)[32][2], const
> INTFLOAT (*s)[32][2], int is34, int frame_length_short)
>   {
>       LOCAL_ALIGNED_16(INTFLOAT, power, [34], [PS_QMF_TIME_SLOTS]);
>       LOCAL_ALIGNED_16(INTFLOAT, transient_gain, [34],
> [PS_QMF_TIME_SLOTS]);
> @@ -414,6 +414,7 @@ static void decorrelation(PSContext *ps, INTFLOAT
> (*out)[32][2], const INTFLOAT
>       int i, k, m, n;
>       int n0 = 0, nL = 32;
>       const INTFLOAT peak_decay_factor = Q31(0.76592833836465f);
> +    int numQMFSlots = frame_length_short ? 30 : 32;
>        memset(power, 0, 34 * sizeof(*power));
>   @@ -717,11 +718,12 @@ static void stereo_processing(PSContext *ps,
> INTFLOAT (*l)[32][2], INTFLOAT (*r)
>       }
>   }
>   -int AAC_RENAME(ff_ps_apply)(AVCodecContext *avctx, PSContext *ps,
> INTFLOAT L[2][38][64], INTFLOAT R[2][38][64], int top)
> +int AAC_RENAME(ff_ps_apply)(AVCodecContext *avctx, PSContext *ps,
> INTFLOAT L[2][38][64], INTFLOAT R[2][38][64], int top,
> +                            int frame_length_short)
>   {
>       INTFLOAT (*Lbuf)[32][2] = ps->Lbuf;
>       INTFLOAT (*Rbuf)[32][2] = ps->Rbuf;
> -    const int len = 32;
> +    const int len = frame_length_short ? 32 : 32;

???

>       int is34 = ps->common.is34bands;
>        top += NR_BANDS[is34] - 64;
> @@ -730,7 +732,7 @@ int AAC_RENAME(ff_ps_apply)(AVCodecContext *avctx,
> PSContext *ps, INTFLOAT L[2][
>           memset(ps->ap_delay + top, 0, (NR_ALLPASS_BANDS[is34] -
> top)*sizeof(ps->ap_delay[0]));
>        hybrid_analysis(&ps->dsp, Lbuf, ps->in_buf, L, is34, len);
> -    decorrelation(ps, Rbuf, (const INTFLOAT (*)[32][2]) Lbuf, is34);
> +    decorrelation(ps, Rbuf, (const INTFLOAT (*)[32][2]) Lbuf, is34,
> frame_length_short);
>       stereo_processing(ps, Lbuf, Rbuf, is34);
>       hybrid_synthesis(&ps->dsp, L, Lbuf, is34, len);
>       hybrid_synthesis(&ps->dsp, R, Rbuf, is34, len);
> diff --git a/libavcodec/aacps.h b/libavcodec/aacps.h
> index 3efa38ad88..c771bfb270 100644
> --- a/libavcodec/aacps.h
> +++ b/libavcodec/aacps.h
> @@ -43,8 +43,6 @@
>                          ///< Baseline implies 10 or 20 stereo bands,
>                          ///< mixing mode A, and no ipd/opd
>   -#define numQMFSlots 32 //numTimeSlots * RATE
> -
>   typedef struct PSCommonContext {
>       int    start;
>       int    enable_iid;
> @@ -96,7 +94,8 @@ void ff_ps_init_common(void);
>   void AAC_RENAME(ff_ps_init)(void);
>   void AAC_RENAME(ff_ps_ctx_init)(PSContext *ps);
>   int ff_ps_read_data(AVCodecContext *avctx, GetBitContext *gb,
> -                     PSCommonContext *ps, int bits_left);
> -int AAC_RENAME(ff_ps_apply)(AVCodecContext *avctx, PSContext *ps,
> INTFLOAT L[2][38][64], INTFLOAT R[2][38][64], int top);
> +                     PSCommonContext *ps, int bits_left, int
> frame_length_short);
> +int AAC_RENAME(ff_ps_apply)(AVCodecContext *avctx, PSContext *ps,
> INTFLOAT L[2][38][64], INTFLOAT R[2][38][64], int top,
> +                            int frame_length_short);
>    #endif /* AVCODEC_AACPS_H */
> diff --git a/libavcodec/aacps_common.c b/libavcodec/aacps_common.c
> index c388d5b9bc..87521c52e3 100644
> --- a/libavcodec/aacps_common.c
> +++ b/libavcodec/aacps_common.c
> @@ -132,13 +132,14 @@ static int ps_read_extension_data(GetBitContext
> *gb, PSCommonContext *ps,
>   }
>    int ff_ps_read_data(AVCodecContext *avctx, GetBitContext *gb_host,
> -                    PSCommonContext *ps, int bits_left)
> +                    PSCommonContext *ps, int bits_left, int
> frame_length_short)
>   {
>       int e;
>       int bit_count_start = get_bits_count(gb_host);
>       int header;
>       int bits_consumed;
>       GetBitContext gbc = *gb_host, *gb = &gbc;
> +    int numQMFSlots = frame_length_short ? 30 : 32;
>        header = get_bits1(gb);
>       if (header) {     //enable_ps_header
> diff --git a/libavcodec/aacsbr.h b/libavcodec/aacsbr.h
> index d70b19e11c..0f4e3d140b 100644
> --- a/libavcodec/aacsbr.h
> +++ b/libavcodec/aacsbr.h
> @@ -86,10 +86,10 @@ int AAC_RENAME(ff_aac_sbr_ctx_init)(AACContext *ac,
> SpectralBandReplication *sbr
>   void AAC_RENAME(ff_aac_sbr_ctx_close)(SpectralBandReplication *sbr);
>   /** Decode one SBR element. */
>   int AAC_RENAME(ff_decode_sbr_extension)(AACContext *ac,
> SpectralBandReplication *sbr,
> -                            GetBitContext *gb, int crc, int cnt, int
> id_aac);
> +                            GetBitContext *gb, int crc, int cnt, int
> id_aac, int frame_length_short);
>   /** Apply one SBR element to one AAC element. */
>   void AAC_RENAME(ff_sbr_apply)(AACContext *ac, SpectralBandReplication
> *sbr, int id_aac,
> -                  INTFLOAT* L, INTFLOAT *R);
> +                  INTFLOAT* L, INTFLOAT *R, int frame_length_short);
>    void ff_aacsbr_func_ptr_init_mips(AACSBRContext *c);
>   diff --git a/libavcodec/aacsbr_template.c b/libavcodec/aacsbr_template.c
> index cdca402f04..adb3c1d56c 100644
> --- a/libavcodec/aacsbr_template.c
> +++ b/libavcodec/aacsbr_template.c
> @@ -643,12 +643,11 @@ static const int8_t ceil_log2[] = {
>   };
>    static int read_sbr_grid(AACContext *ac, SpectralBandReplication *sbr,
> -                         GetBitContext *gb, SBRData *ch_data)
> +                         GetBitContext *gb, SBRData *ch_data, int
> frame_length_short)
>   {
>       int i;
>       int bs_pointer = 0;
> -    // frameLengthFlag ? 15 : 16; 960 sample length frames unsupported;
> this value is numTimeSlots
> -    int abs_bord_trail = 16;
> +    int abs_bord_trail = frame_length_short ? 15 : 16;
>       int num_rel_lead, num_rel_trail;
>       unsigned bs_num_env_old = ch_data->bs_num_env;
>       int bs_frame_class, bs_num_env;
> @@ -963,7 +962,7 @@ static int read_sbr_noise(AACContext *ac,
> SpectralBandReplication *sbr, GetBitCo
>    static void read_sbr_extension(AACContext *ac,
> SpectralBandReplication *sbr,
>                                  GetBitContext *gb,
> -                               int bs_extension_id, int *num_bits_left)
> +                               int bs_extension_id, int *num_bits_left,
> int frame_length_short)
>   {
>       switch (bs_extension_id) {
>       case EXTENSION_ID_PS:
> @@ -972,7 +971,7 @@ static void read_sbr_extension(AACContext *ac,
> SpectralBandReplication *sbr,
>               skip_bits_long(gb, *num_bits_left); // bs_fill_bits
>               *num_bits_left = 0;
>           } else {
> -            *num_bits_left -= ff_ps_read_data(ac->avctx, gb,
> &sbr->ps.common, *num_bits_left);
> +            *num_bits_left -= ff_ps_read_data(ac->avctx, gb,
> &sbr->ps.common, *num_bits_left, frame_length_short);
>               ac->avctx->profile = FF_PROFILE_AAC_HE_V2;
>               // ensure the warning is not printed if PS extension is
> present
>               ac->warned_he_aac_mono = 1;
> @@ -990,14 +989,15 @@ static void read_sbr_extension(AACContext *ac,
> SpectralBandReplication *sbr,
>    static int read_sbr_single_channel_element(AACContext *ac,
>                                               SpectralBandReplication *sbr,
> -                                            GetBitContext *gb)
> +                                            GetBitContext *gb,
> +                                            int frame_length_short)
>   {
>       int ret;
>        if (get_bits1(gb)) // bs_data_extra
>           skip_bits(gb, 4); // bs_reserved
>   -    if (read_sbr_grid(ac, sbr, gb, &sbr->data[0]))
> +    if (read_sbr_grid(ac, sbr, gb, &sbr->data[0], frame_length_short))
>           return -1;
>       read_sbr_dtdf(sbr, gb, &sbr->data[0]);
>       read_sbr_invf(sbr, gb, &sbr->data[0]);
> @@ -1014,7 +1014,8 @@ static int
> read_sbr_single_channel_element(AACContext *ac,
>    static int read_sbr_channel_pair_element(AACContext *ac,
>                                             SpectralBandReplication *sbr,
> -                                          GetBitContext *gb)
> +                                          GetBitContext *gb,
> +                                          int frame_length_short)
>   {
>       int ret;
>   @@ -1022,7 +1023,7 @@ static int
> read_sbr_channel_pair_element(AACContext *ac,
>           skip_bits(gb, 8); // bs_reserved
>        if ((sbr->bs_coupling = get_bits1(gb))) {
> -        if (read_sbr_grid(ac, sbr, gb, &sbr->data[0]))
> +        if (read_sbr_grid(ac, sbr, gb, &sbr->data[0], frame_length_short))
>               return -1;
>           copy_sbr_grid(&sbr->data[1], &sbr->data[0]);
>           read_sbr_dtdf(sbr, gb, &sbr->data[0]);
> @@ -1039,8 +1040,8 @@ static int
> read_sbr_channel_pair_element(AACContext *ac,
>           if((ret = read_sbr_noise(ac, sbr, gb, &sbr->data[1], 1)) < 0)
>               return ret;
>       } else {
> -        if (read_sbr_grid(ac, sbr, gb, &sbr->data[0]) ||
> -            read_sbr_grid(ac, sbr, gb, &sbr->data[1]))
> +        if (read_sbr_grid(ac, sbr, gb, &sbr->data[0],
> frame_length_short) ||
> +            read_sbr_grid(ac, sbr, gb, &sbr->data[1], frame_length_short))
>               return -1;
>           read_sbr_dtdf(sbr, gb, &sbr->data[0]);
>           read_sbr_dtdf(sbr, gb, &sbr->data[1]);
> @@ -1065,7 +1066,7 @@ static int
> read_sbr_channel_pair_element(AACContext *ac,
>   }
>    static unsigned int read_sbr_data(AACContext *ac,
> SpectralBandReplication *sbr,
> -                                  GetBitContext *gb, int id_aac)
> +                                  GetBitContext *gb, int id_aac, int
> frame_length_short)
>   {
>       unsigned int cnt = get_bits_count(gb);
>   @@ -1073,12 +1074,12 @@ static unsigned int read_sbr_data(AACContext
> *ac, SpectralBandReplication *sbr,
>       sbr->ready_for_dequant = 1;
>        if (id_aac == TYPE_SCE || id_aac == TYPE_CCE) {
> -        if (read_sbr_single_channel_element(ac, sbr, gb)) {
> +        if (read_sbr_single_channel_element(ac, sbr, gb,
> frame_length_short)) {
>               sbr_turnoff(sbr);
>               return get_bits_count(gb) - cnt;
>           }
>       } else if (id_aac == TYPE_CPE) {
> -        if (read_sbr_channel_pair_element(ac, sbr, gb)) {
> +        if (read_sbr_channel_pair_element(ac, sbr, gb,
> frame_length_short)) {
>               sbr_turnoff(sbr);
>               return get_bits_count(gb) - cnt;
>           }
> @@ -1096,7 +1097,7 @@ static unsigned int read_sbr_data(AACContext *ac,
> SpectralBandReplication *sbr,
>           num_bits_left <<= 3;
>           while (num_bits_left > 7) {
>               num_bits_left -= 2;
> -            read_sbr_extension(ac, sbr, gb, get_bits(gb, 2),
> &num_bits_left); // bs_extension_id
> +            read_sbr_extension(ac, sbr, gb, get_bits(gb, 2),
> &num_bits_left, frame_length_short); // bs_extension_id
>           }
>           if (num_bits_left < 0) {
>               av_log(ac->avctx, AV_LOG_ERROR, "SBR Extension over
> read.\n");
> @@ -1130,7 +1131,7 @@ static void sbr_reset(AACContext *ac,
> SpectralBandReplication *sbr)
>    * @return  Returns number of bytes consumed from the TYPE_FIL element.
>    */
>   int AAC_RENAME(ff_decode_sbr_extension)(AACContext *ac,
> SpectralBandReplication *sbr,
> -                            GetBitContext *gb_host, int crc, int cnt,
> int id_aac)
> +                            GetBitContext *gb_host, int crc, int cnt,
> int id_aac, int frame_length_short)
>   {
>       unsigned int num_sbr_bits = 0, num_align_bits;
>       unsigned bytes_read;
> @@ -1162,7 +1163,7 @@ int AAC_RENAME(ff_decode_sbr_extension)(AACContext
> *ac, SpectralBandReplication
>           sbr_reset(ac, sbr);
>        if (sbr->start)
> -        num_sbr_bits  += read_sbr_data(ac, sbr, gb, id_aac);
> +        num_sbr_bits  += read_sbr_data(ac, sbr, gb, id_aac,
> frame_length_short);
>        num_align_bits = ((cnt << 3) - 4 - num_sbr_bits) & 7;
>       bytes_read = ((num_sbr_bits + num_align_bits + 4) >> 3);
> @@ -1190,16 +1191,20 @@ static void sbr_qmf_analysis(AVFloatDSPContext
> *dsp, AVTXContext *mdct,
>                                av_tx_fn mdct_fn,
>   #endif /* USE_FIXED */
>                                SBRDSPContext *sbrdsp, const INTFLOAT
> *in, INTFLOAT *x,
> -                             INTFLOAT z[320], INTFLOAT W[2][32][32][2],
> int buf_idx)
> +                             INTFLOAT z[320], INTFLOAT W[2][32][32][2],
> int buf_idx,
> +                             int frame_length_short)
>   {
>       int i;
>   #if USE_FIXED
>       int j;
>   #endif
> -    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
> -                               // are not supported
> +    const int frameLength = frame_length_short ? 960 : 1024;
> +    const int numTimeSlots = frame_length_short ? 15 : 16;
> +    +    memcpy(x    , x+frameLength, (320-32)*sizeof(x[0]));
> +    memcpy(x+288, in,         frameLength*sizeof(x[0]));
> +    +    for (i = 0; i < numTimeSlots*2; i++) { // numTimeSlots*RATE =
> 16*2
>           dsp->vector_fmul_reverse(z, sbr_qmf_window_ds, x, 320);
>           sbrdsp->sum64x5(z);
>           sbrdsp->qmf_pre_shuffle(z);
> @@ -1238,13 +1243,15 @@ static void sbr_qmf_synthesis(AVTXContext *mdct,
> av_tx_fn mdct_fn,
>   #endif /* USE_FIXED */
>                                 INTFLOAT *out, INTFLOAT X[2][38][64],
>                                 INTFLOAT mdct_buf[2][64],
> -                              INTFLOAT *v0, int *v_off, const unsigned
> int div)
> +                              INTFLOAT *v0, int *v_off, const unsigned
> int div,
> +                              int frame_length_short)
>   {
>       int i, n;
>       const INTFLOAT *sbr_qmf_window = div ? sbr_qmf_window_ds :
> sbr_qmf_window_us;
>       const int step = 128 >> div;
> +    const int numTimeSlots = frame_length_short ? 15 : 16;
>       INTFLOAT *v;
> -    for (i = 0; i < 32; i++) {
> +    for (i = 0; i < numTimeSlots*2; i++) {
>           if (*v_off < step) {
>               int saved_samples = (1280 - 128) >> div;
>               memcpy(&v0[SBR_SYNTHESIS_BUF_SIZE - saved_samples], v0,
> saved_samples * sizeof(INTFLOAT));
> @@ -1284,11 +1291,11 @@ static void sbr_qmf_synthesis(AVTXContext *mdct,
> av_tx_fn mdct_fn,
>   /// Generate the subband filtered lowband
>   static int sbr_lf_gen(AACContext *ac, SpectralBandReplication *sbr,
>                         INTFLOAT X_low[32][40][2], const INTFLOAT
> W[2][32][32][2],
> -                      int buf_idx)
> +                      int buf_idx, int frame_length_short)
>   {
>       int i, k;
>       const int t_HFGen = 8;
> -    const int i_f = 32;
> +    const int i_f = frame_length_short ? 30 : 32;
>       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++) {
> @@ -1344,10 +1351,10 @@ static int sbr_hf_gen(AACContext *ac,
> SpectralBandReplication *sbr,
>   /// Generate the subband filtered lowband
>   static int sbr_x_gen(SpectralBandReplication *sbr, INTFLOAT X[2][38][64],
>                        const INTFLOAT Y0[38][64][2], const INTFLOAT
> Y1[38][64][2],
> -                     const INTFLOAT X_low[32][40][2], int ch)
> +                     const INTFLOAT X_low[32][40][2], int ch, int
> frame_length_short)
>   {
>       int k, i;
> -    const int i_f = 32;
> +    const int i_f = frame_length_short ? 30 : 32;
>       const int i_Temp = FFMAX(2*sbr->data[ch].t_env_num_env_old - i_f, 0);
>       memset(X, 0, 2*sizeof(*X));
>       for (k = 0; k < sbr->kx[0]; k++) {
> @@ -1496,7 +1503,7 @@ static void sbr_env_estimate(AAC_FLOAT
> (*e_curr)[48], INTFLOAT X_high[64][40][2]
>   }
>    void AAC_RENAME(ff_sbr_apply)(AACContext *ac, SpectralBandReplication
> *sbr, int id_aac,
> -                  INTFLOAT* L, INTFLOAT* R)
> +                  INTFLOAT* L, INTFLOAT* R, int frame_length_short)
>   {
>       int downsampled = ac->oc[1].m4ac.ext_sample_rate < sbr->sample_rate;
>       int ch;
> @@ -1531,10 +1538,10 @@ void AAC_RENAME(ff_sbr_apply)(AACContext *ac,
> SpectralBandReplication *sbr, int
>           sbr_qmf_analysis(ac->fdsp, sbr->mdct_ana, sbr->mdct_ana_fn,
> &sbr->dsp,
>                            ch ? R : L,
> sbr->data[ch].analysis_filterbank_samples,
>                            (INTFLOAT*)sbr->qmf_filter_scratch,
> -                         sbr->data[ch].W, sbr->data[ch].Ypos);
> +                         sbr->data[ch].W, sbr->data[ch].Ypos,
> frame_length_short);
>           sbr->c.sbr_lf_gen(ac, sbr, sbr->X_low,
>                             (const INTFLOAT (*)[32][32][2])
> sbr->data[ch].W,
> -                          sbr->data[ch].Ypos);
> +                          sbr->data[ch].Ypos, frame_length_short);
>           sbr->data[ch].Ypos ^= 1;
>           if (sbr->start) {
>               sbr->c.sbr_hf_inverse_filter(&sbr->dsp, sbr->alpha0,
> sbr->alpha1,
> @@ -1564,12 +1571,12 @@ void AAC_RENAME(ff_sbr_apply)(AACContext *ac,
> SpectralBandReplication *sbr, int
>           sbr->c.sbr_x_gen(sbr, sbr->X[ch],
>                     (const INTFLOAT (*)[64][2])
> sbr->data[ch].Y[1-sbr->data[ch].Ypos],
>                     (const INTFLOAT (*)[64][2]) sbr->data[ch].Y[
> sbr->data[ch].Ypos],
> -                  (const INTFLOAT (*)[40][2]) sbr->X_low, ch);
> +                  (const INTFLOAT (*)[40][2]) sbr->X_low, ch,
> frame_length_short);
>       }
>        if (ac->oc[1].m4ac.ps == 1) {
>           if (sbr->ps.common.start) {
> -            AAC_RENAME(ff_ps_apply)(ac->avctx, &sbr->ps, sbr->X[0],
> sbr->X[1], sbr->kx[1] + sbr->m[1]);
> +            AAC_RENAME(ff_ps_apply)(ac->avctx, &sbr->ps, sbr->X[0],
> sbr->X[1], sbr->kx[1] + sbr->m[1], frame_length_short);
>           } else {
>               memcpy(sbr->X[1], sbr->X[0], sizeof(sbr->X[0]));
>           }
> @@ -1580,13 +1587,13 @@ void AAC_RENAME(ff_sbr_apply)(AACContext *ac,
> SpectralBandReplication *sbr, int
>                         L, sbr->X[0], sbr->qmf_filter_scratch,
>                         sbr->data[0].synthesis_filterbank_samples,
>                         &sbr->data[0].synthesis_filterbank_samples_offset,
> -                      downsampled);
> +                      downsampled, frame_length_short);
>       if (nch == 2)
>           sbr_qmf_synthesis(sbr->mdct, sbr->mdct_fn, &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);
> +                          downsampled, frame_length_short);
>   }
>    static void aacsbr_func_ptr_init(AACSBRContext *c)
> diff --git a/libavcodec/sbr.h b/libavcodec/sbr.h
> index f949465ef5..aca3a30244 100644
> --- a/libavcodec/sbr.h
> +++ b/libavcodec/sbr.h
> @@ -123,14 +123,14 @@ typedef struct SpectralBandReplication
> SpectralBandReplication;
>   typedef struct AACSBRContext {
>       int (*sbr_lf_gen)(AACContext *ac, SpectralBandReplication *sbr,
>                         INTFLOAT X_low[32][40][2], const INTFLOAT
> W[2][32][32][2],
> -                      int buf_idx);
> +                      int buf_idx, int frame_length_short);
>       void (*sbr_hf_assemble)(INTFLOAT Y1[38][64][2],
>                               const INTFLOAT X_high[64][40][2],
>                               SpectralBandReplication *sbr, SBRData
> *ch_data,
>                               const int e_a[2]);
>       int (*sbr_x_gen)(SpectralBandReplication *sbr, INTFLOAT X[2][38][64],
>                        const INTFLOAT Y0[38][64][2], const INTFLOAT
> Y1[38][64][2],
> -                     const INTFLOAT X_low[32][40][2], int ch);
> +                     const INTFLOAT X_low[32][40][2], int ch, int
> frame_length_short);
>       void (*sbr_hf_inverse_filter)(SBRDSPContext *dsp,
>                                     INTFLOAT (*alpha0)[2], INTFLOAT
> (*alpha1)[2],
>                                     const INTFLOAT X_low[32][40][2], int
> k0);
> --
> 2.36.0.windows.1
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
>
Matthias Walliczek May 20, 2023, 2:06 p.m. UTC | #2
On 20.05.2023 15:29, Paul B Mahol wrote:

> On 5/20/23, Matthias Walliczek <matthias@walliczek.de> wrote:
>> [...]
>> +int AAC_RENAME(ff_ps_apply)(AVCodecContext *avctx, PSContext *ps,
>> INTFLOAT L[2][38][64], INTFLOAT R[2][38][64], int top,
>> +                            int frame_length_short)
>>    {
>>        INTFLOAT (*Lbuf)[32][2] = ps->Lbuf;
>>        INTFLOAT (*Rbuf)[32][2] = ps->Rbuf;
>> -    const int len = 32;
>> +    const int len = frame_length_short ? 32 : 32;
> ???

Sorry, this was a leftover. I will create a new patch without this line.

Best regards,
   Matthias
Lynne May 20, 2023, 2:17 p.m. UTC | #3
May 20, 2023, 15:26 by matthias@walliczek.de:

> Supports the european DAB+ digital radio coding
>
> Fixes: https://trac.ffmpeg.org/ticket/1407 "HE-AAC (v2): 960/120 MDCT window is not implemented"
>
> Signed-off-by: Matthias Walliczek <matthias@walliczek.de>
> ---
>  libavcodec/aacdec_template.c | 21 ++--------
>  libavcodec/aacps.c           | 10 +++--
>  libavcodec/aacps.h           |  7 ++--
>  libavcodec/aacps_common.c    |  3 +-
>  libavcodec/aacsbr.h          |  4 +-
>  libavcodec/aacsbr_template.c | 77 ++++++++++++++++++++----------------
>  libavcodec/sbr.h             |  4 +-
>  7 files changed, 61 insertions(+), 65 deletions(-)
>

Yeah, no, this patch is far from complete.
I have a more complete and correct patch I was working on which had a minor issue I didn't get around to fixing.
I'll see if I have missed changing a constant that you haven't missed.
Matthias Walliczek May 20, 2023, 2:34 p.m. UTC | #4
On 20.05.2023 16:17, Lynne wrote:

> Yeah, no, this patch is far from complete.
> I have a more complete and correct patch I was working on which had a minor issue I didn't get around to fixing.
> I'll see if I have missed changing a constant that you haven't missed.

Your patch looks definitely more complete - but I think there is one 
change missing:

@@ -1190,16 +1191,20 @@ static void sbr_qmf_analysis(AVFloatDSPContext 
*dsp, AVTXContext *mdct,
                               av_tx_fn mdct_fn,
  #endif /* USE_FIXED */
                               SBRDSPContext *sbrdsp, const INTFLOAT 
*in, INTFLOAT *x,
-                             INTFLOAT z[320], INTFLOAT W[2][32][32][2], 
int buf_idx)
+                             INTFLOAT z[320], INTFLOAT W[2][32][32][2], 
int buf_idx,
+                             int frame_length_short)
  {
      int i;
  #if USE_FIXED
      int j;
  #endif
-    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
-                               // are not supported
+    const int frameLength = frame_length_short ? 960 : 1024;
+    const int numTimeSlots = frame_length_short ? 15 : 16;
+
+    memcpy(x    , x+frameLength, (320-32)*sizeof(x[0]));
+    memcpy(x+288, in,         frameLength*sizeof(x[0]));

The adaptation of the memcpy to the changed framelength.

Best regards,
   Matthias
diff mbox series

Patch

diff --git a/libavcodec/aacdec_template.c b/libavcodec/aacdec_template.c
index 444dc4fa9d..9f6fd76c6a 100644
--- a/libavcodec/aacdec_template.c
+++ b/libavcodec/aacdec_template.c
@@ -849,12 +849,6 @@  static int decode_ga_specific_config(AACContext 
*ac, AVCodecContext *avctx,
      int tags = 0;
       m4ac->frame_length_short = get_bits1(gb);
-    if (m4ac->frame_length_short && m4ac->sbr == 1) {
-      avpriv_report_missing_feature(avctx, "SBR with 960 frame length");
-      if (ac) ac->warned_960_sbr = 1;
-      m4ac->sbr = 0;
-      m4ac->ps = 0;
-    }
       if (get_bits1(gb))       // dependsOnCoreCoder
          skip_bits(gb, 14);   // coreCoderDelay
@@ -1047,10 +1041,10 @@  static int 
decode_audio_specific_config_gb(AACContext *ac,
      }
       ff_dlog(avctx,
-            "AOT %d chan config %d sampling index %d (%d) SBR %d PS %d\n",
+            "AOT %d chan config %d sampling index %d (%d) SBR %d PS %d 
frame length %d\n",
              m4ac->object_type, m4ac->chan_config, m4ac->sampling_index,
              m4ac->sample_rate, m4ac->sbr,
-            m4ac->ps);
+            m4ac->ps, m4ac->frame_length_short ? 960 : 1024);
       return get_bits_count(gb);
  }
@@ -2467,13 +2461,6 @@  static int decode_extension_payload(AACContext 
*ac, GetBitContext *gb, int cnt,
          if (!che) {
              av_log(ac->avctx, AV_LOG_ERROR, "SBR was found before the 
first channel element.\n");
              return res;
-        } else if (ac->oc[1].m4ac.frame_length_short) {
-            if (!ac->warned_960_sbr)
-              avpriv_report_missing_feature(ac->avctx,
-                                            "SBR with 960 frame length");
-            ac->warned_960_sbr = 1;
-            skip_bits_long(gb, 8 * cnt - 4);
-            return res;
          } else if (!ac->oc[1].m4ac.sbr) {
              av_log(ac->avctx, AV_LOG_ERROR, "SBR signaled to be 
not-present but was found in the bitstream.\n");
              skip_bits_long(gb, 8 * cnt - 4);
@@ -2493,7 +2480,7 @@  static int decode_extension_payload(AACContext 
*ac, GetBitContext *gb, int cnt,
              ac->oc[1].m4ac.sbr = 1;
              ac->avctx->profile = FF_PROFILE_AAC_HE;
          }
-        res = AAC_RENAME(ff_decode_sbr_extension)(ac, &che->sbr, gb, 
crc_flag, cnt, elem_type);
+        res = AAC_RENAME(ff_decode_sbr_extension)(ac, &che->sbr, gb, 
crc_flag, cnt, elem_type, ac->oc[1].m4ac.frame_length_short);
          if (ac->oc[1].m4ac.ps == 1 && !ac->warned_he_aac_mono) {
              av_log(ac->avctx, AV_LOG_VERBOSE, "Treating HE-AAC mono as 
stereo.\n");
              ac->warned_he_aac_mono = 1;
@@ -2974,7 +2961,7 @@  static void spectral_to_sample(AACContext *ac, int 
samples)
                              ac->update_ltp(ac, &che->ch[1]);
                      }
                      if (ac->oc[1].m4ac.sbr > 0) {
-                        AAC_RENAME(ff_sbr_apply)(ac, &che->sbr, type, 
che->ch[0].ret, che->ch[1].ret);
+                        AAC_RENAME(ff_sbr_apply)(ac, &che->sbr, type, 
che->ch[0].ret, che->ch[1].ret, ac->oc[1].m4ac.frame_length_short);
                      }
                  }
                  if (type <= TYPE_CCE)
diff --git a/libavcodec/aacps.c b/libavcodec/aacps.c
index 655e8fe5b4..52103e97a4 100644
--- a/libavcodec/aacps.c
+++ b/libavcodec/aacps.c
@@ -397,7 +397,7 @@  static void map_val_20_to_34(INTFLOAT 
par[PS_MAX_NR_IIDICC])
      par[ 1] = AAC_HALF_SUM(par[ 0], par[ 1]);
  }
  -static void decorrelation(PSContext *ps, INTFLOAT (*out)[32][2], 
const INTFLOAT (*s)[32][2], int is34)
+static void decorrelation(PSContext *ps, INTFLOAT (*out)[32][2], const 
INTFLOAT (*s)[32][2], int is34, int frame_length_short)
  {
      LOCAL_ALIGNED_16(INTFLOAT, power, [34], [PS_QMF_TIME_SLOTS]);
      LOCAL_ALIGNED_16(INTFLOAT, transient_gain, [34], [PS_QMF_TIME_SLOTS]);
@@ -414,6 +414,7 @@  static void decorrelation(PSContext *ps, INTFLOAT 
(*out)[32][2], const INTFLOAT
      int i, k, m, n;
      int n0 = 0, nL = 32;
      const INTFLOAT peak_decay_factor = Q31(0.76592833836465f);
+    int numQMFSlots = frame_length_short ? 30 : 32;
       memset(power, 0, 34 * sizeof(*power));
  @@ -717,11 +718,12 @@ static void stereo_processing(PSContext *ps, 
INTFLOAT (*l)[32][2], INTFLOAT (*r)
      }
  }
  -int AAC_RENAME(ff_ps_apply)(AVCodecContext *avctx, PSContext *ps, 
INTFLOAT L[2][38][64], INTFLOAT R[2][38][64], int top)
+int AAC_RENAME(ff_ps_apply)(AVCodecContext *avctx, PSContext *ps, 
INTFLOAT L[2][38][64], INTFLOAT R[2][38][64], int top,
+                            int frame_length_short)
  {
      INTFLOAT (*Lbuf)[32][2] = ps->Lbuf;
      INTFLOAT (*Rbuf)[32][2] = ps->Rbuf;
-    const int len = 32;
+    const int len = frame_length_short ? 32 : 32;
      int is34 = ps->common.is34bands;
       top += NR_BANDS[is34] - 64;
@@ -730,7 +732,7 @@  int AAC_RENAME(ff_ps_apply)(AVCodecContext *avctx, 
PSContext *ps, INTFLOAT L[2][
          memset(ps->ap_delay + top, 0, (NR_ALLPASS_BANDS[is34] - 
top)*sizeof(ps->ap_delay[0]));
       hybrid_analysis(&ps->dsp, Lbuf, ps->in_buf, L, is34, len);
-    decorrelation(ps, Rbuf, (const INTFLOAT (*)[32][2]) Lbuf, is34);
+    decorrelation(ps, Rbuf, (const INTFLOAT (*)[32][2]) Lbuf, is34, 
frame_length_short);
      stereo_processing(ps, Lbuf, Rbuf, is34);
      hybrid_synthesis(&ps->dsp, L, Lbuf, is34, len);
      hybrid_synthesis(&ps->dsp, R, Rbuf, is34, len);
diff --git a/libavcodec/aacps.h b/libavcodec/aacps.h
index 3efa38ad88..c771bfb270 100644
--- a/libavcodec/aacps.h
+++ b/libavcodec/aacps.h
@@ -43,8 +43,6 @@ 
                         ///< Baseline implies 10 or 20 stereo bands,
                         ///< mixing mode A, and no ipd/opd
  -#define numQMFSlots 32 //numTimeSlots * RATE
-
  typedef struct PSCommonContext {
      int    start;
      int    enable_iid;
@@ -96,7 +94,8 @@  void ff_ps_init_common(void);
  void AAC_RENAME(ff_ps_init)(void);
  void AAC_RENAME(ff_ps_ctx_init)(PSContext *ps);
  int ff_ps_read_data(AVCodecContext *avctx, GetBitContext *gb,
-                     PSCommonContext *ps, int bits_left);
-int AAC_RENAME(ff_ps_apply)(AVCodecContext *avctx, PSContext *ps, 
INTFLOAT L[2][38][64], INTFLOAT R[2][38][64], int top);
+                     PSCommonContext *ps, int bits_left, int 
frame_length_short);
+int AAC_RENAME(ff_ps_apply)(AVCodecContext *avctx, PSContext *ps, 
INTFLOAT L[2][38][64], INTFLOAT R[2][38][64], int top,
+                            int frame_length_short);
   #endif /* AVCODEC_AACPS_H */
diff --git a/libavcodec/aacps_common.c b/libavcodec/aacps_common.c
index c388d5b9bc..87521c52e3 100644
--- a/libavcodec/aacps_common.c
+++ b/libavcodec/aacps_common.c
@@ -132,13 +132,14 @@  static int ps_read_extension_data(GetBitContext 
*gb, PSCommonContext *ps,
  }
   int ff_ps_read_data(AVCodecContext *avctx, GetBitContext *gb_host,
-                    PSCommonContext *ps, int bits_left)
+                    PSCommonContext *ps, int bits_left, int 
frame_length_short)
  {
      int e;
      int bit_count_start = get_bits_count(gb_host);
      int header;
      int bits_consumed;
      GetBitContext gbc = *gb_host, *gb = &gbc;
+    int numQMFSlots = frame_length_short ? 30 : 32;
       header = get_bits1(gb);
      if (header) {     //enable_ps_header
diff --git a/libavcodec/aacsbr.h b/libavcodec/aacsbr.h
index d70b19e11c..0f4e3d140b 100644
--- a/libavcodec/aacsbr.h
+++ b/libavcodec/aacsbr.h
@@ -86,10 +86,10 @@  int AAC_RENAME(ff_aac_sbr_ctx_init)(AACContext *ac, 
SpectralBandReplication *sbr
  void AAC_RENAME(ff_aac_sbr_ctx_close)(SpectralBandReplication *sbr);
  /** Decode one SBR element. */
  int AAC_RENAME(ff_decode_sbr_extension)(AACContext *ac, 
SpectralBandReplication *sbr,
-                            GetBitContext *gb, int crc, int cnt, int 
id_aac);
+                            GetBitContext *gb, int crc, int cnt, int 
id_aac, int frame_length_short);
  /** Apply one SBR element to one AAC element. */
  void AAC_RENAME(ff_sbr_apply)(AACContext *ac, SpectralBandReplication 
*sbr, int id_aac,
-                  INTFLOAT* L, INTFLOAT *R);
+                  INTFLOAT* L, INTFLOAT *R, int frame_length_short);
   void ff_aacsbr_func_ptr_init_mips(AACSBRContext *c);
  diff --git a/libavcodec/aacsbr_template.c b/libavcodec/aacsbr_template.c
index cdca402f04..adb3c1d56c 100644
--- a/libavcodec/aacsbr_template.c
+++ b/libavcodec/aacsbr_template.c
@@ -643,12 +643,11 @@  static const int8_t ceil_log2[] = {
  };
   static int read_sbr_grid(AACContext *ac, SpectralBandReplication *sbr,
-                         GetBitContext *gb, SBRData *ch_data)
+                         GetBitContext *gb, SBRData *ch_data, int 
frame_length_short)
  {
      int i;
      int bs_pointer = 0;
-    // frameLengthFlag ? 15 : 16; 960 sample length frames unsupported; 
this value is numTimeSlots
-    int abs_bord_trail = 16;
+    int abs_bord_trail = frame_length_short ? 15 : 16;
      int num_rel_lead, num_rel_trail;
      unsigned bs_num_env_old = ch_data->bs_num_env;
      int bs_frame_class, bs_num_env;
@@ -963,7 +962,7 @@  static int read_sbr_noise(AACContext *ac, 
SpectralBandReplication *sbr, GetBitCo
   static void read_sbr_extension(AACContext *ac, 
SpectralBandReplication *sbr,
                                 GetBitContext *gb,
-                               int bs_extension_id, int *num_bits_left)
+                               int bs_extension_id, int *num_bits_left, 
int frame_length_short)
  {
      switch (bs_extension_id) {
      case EXTENSION_ID_PS:
@@ -972,7 +971,7 @@  static void read_sbr_extension(AACContext *ac, 
SpectralBandReplication *sbr,
              skip_bits_long(gb, *num_bits_left); // bs_fill_bits
              *num_bits_left = 0;
          } else {
-            *num_bits_left -= ff_ps_read_data(ac->avctx, gb, 
&sbr->ps.common, *num_bits_left);
+            *num_bits_left -= ff_ps_read_data(ac->avctx, gb, 
&sbr->ps.common, *num_bits_left, frame_length_short);
              ac->avctx->profile = FF_PROFILE_AAC_HE_V2;
              // ensure the warning is not printed if PS extension is 
present
              ac->warned_he_aac_mono = 1;
@@ -990,14 +989,15 @@  static void read_sbr_extension(AACContext *ac, 
SpectralBandReplication *sbr,
   static int read_sbr_single_channel_element(AACContext *ac,
                                              SpectralBandReplication *sbr,
-                                            GetBitContext *gb)
+                                            GetBitContext *gb,
+                                            int frame_length_short)
  {
      int ret;
       if (get_bits1(gb)) // bs_data_extra
          skip_bits(gb, 4); // bs_reserved
  -    if (read_sbr_grid(ac, sbr, gb, &sbr->data[0]))
+    if (read_sbr_grid(ac, sbr, gb, &sbr->data[0], frame_length_short))
          return -1;
      read_sbr_dtdf(sbr, gb, &sbr->data[0]);
      read_sbr_invf(sbr, gb, &sbr->data[0]);
@@ -1014,7 +1014,8 @@  static int 
read_sbr_single_channel_element(AACContext *ac,
   static int read_sbr_channel_pair_element(AACContext *ac,
                                            SpectralBandReplication *sbr,
-                                          GetBitContext *gb)
+                                          GetBitContext *gb,
+                                          int frame_length_short)
  {
      int ret;
  @@ -1022,7 +1023,7 @@ static int 
read_sbr_channel_pair_element(AACContext *ac,
          skip_bits(gb, 8); // bs_reserved
       if ((sbr->bs_coupling = get_bits1(gb))) {
-        if (read_sbr_grid(ac, sbr, gb, &sbr->data[0]))
+        if (read_sbr_grid(ac, sbr, gb, &sbr->data[0], frame_length_short))
              return -1;
          copy_sbr_grid(&sbr->data[1], &sbr->data[0]);
          read_sbr_dtdf(sbr, gb, &sbr->data[0]);
@@ -1039,8 +1040,8 @@  static int 
read_sbr_channel_pair_element(AACContext *ac,
          if((ret = read_sbr_noise(ac, sbr, gb, &sbr->data[1], 1)) < 0)
              return ret;
      } else {
-        if (read_sbr_grid(ac, sbr, gb, &sbr->data[0]) ||
-            read_sbr_grid(ac, sbr, gb, &sbr->data[1]))
+        if (read_sbr_grid(ac, sbr, gb, &sbr->data[0], 
frame_length_short) ||
+            read_sbr_grid(ac, sbr, gb, &sbr->data[1], frame_length_short))
              return -1;
          read_sbr_dtdf(sbr, gb, &sbr->data[0]);
          read_sbr_dtdf(sbr, gb, &sbr->data[1]);
@@ -1065,7 +1066,7 @@  static int 
read_sbr_channel_pair_element(AACContext *ac,
  }
   static unsigned int read_sbr_data(AACContext *ac, 
SpectralBandReplication *sbr,
-                                  GetBitContext *gb, int id_aac)
+                                  GetBitContext *gb, int id_aac, int 
frame_length_short)
  {
      unsigned int cnt = get_bits_count(gb);
  @@ -1073,12 +1074,12 @@ static unsigned int read_sbr_data(AACContext 
*ac, SpectralBandReplication *sbr,
      sbr->ready_for_dequant = 1;
       if (id_aac == TYPE_SCE || id_aac == TYPE_CCE) {
-        if (read_sbr_single_channel_element(ac, sbr, gb)) {
+        if (read_sbr_single_channel_element(ac, sbr, gb, 
frame_length_short)) {
              sbr_turnoff(sbr);
              return get_bits_count(gb) - cnt;
          }
      } else if (id_aac == TYPE_CPE) {
-        if (read_sbr_channel_pair_element(ac, sbr, gb)) {
+        if (read_sbr_channel_pair_element(ac, sbr, gb, 
frame_length_short)) {
              sbr_turnoff(sbr);
              return get_bits_count(gb) - cnt;
          }
@@ -1096,7 +1097,7 @@  static unsigned int read_sbr_data(AACContext *ac, 
SpectralBandReplication *sbr,
          num_bits_left <<= 3;
          while (num_bits_left > 7) {
              num_bits_left -= 2;
-            read_sbr_extension(ac, sbr, gb, get_bits(gb, 2), 
&num_bits_left); // bs_extension_id
+            read_sbr_extension(ac, sbr, gb, get_bits(gb, 2), 
&num_bits_left, frame_length_short); // bs_extension_id
          }
          if (num_bits_left < 0) {
              av_log(ac->avctx, AV_LOG_ERROR, "SBR Extension over read.\n");
@@ -1130,7 +1131,7 @@  static void sbr_reset(AACContext *ac, 
SpectralBandReplication *sbr)
   * @return  Returns number of bytes consumed from the TYPE_FIL element.
   */
  int AAC_RENAME(ff_decode_sbr_extension)(AACContext *ac, 
SpectralBandReplication *sbr,
-                            GetBitContext *gb_host, int crc, int cnt, 
int id_aac)
+                            GetBitContext *gb_host, int crc, int cnt, 
int id_aac, int frame_length_short)
  {
      unsigned int num_sbr_bits = 0, num_align_bits;
      unsigned bytes_read;
@@ -1162,7 +1163,7 @@  int AAC_RENAME(ff_decode_sbr_extension)(AACContext 
*ac, SpectralBandReplication
          sbr_reset(ac, sbr);
       if (sbr->start)
-        num_sbr_bits  += read_sbr_data(ac, sbr, gb, id_aac);
+        num_sbr_bits  += read_sbr_data(ac, sbr, gb, id_aac, 
frame_length_short);
       num_align_bits = ((cnt << 3) - 4 - num_sbr_bits) & 7;
      bytes_read = ((num_sbr_bits + num_align_bits + 4) >> 3);
@@ -1190,16 +1191,20 @@  static void sbr_qmf_analysis(AVFloatDSPContext 
*dsp, AVTXContext *mdct,
                               av_tx_fn mdct_fn,
  #endif /* USE_FIXED */
                               SBRDSPContext *sbrdsp, const INTFLOAT 
*in, INTFLOAT *x,
-                             INTFLOAT z[320], INTFLOAT W[2][32][32][2], 
int buf_idx)
+                             INTFLOAT z[320], INTFLOAT W[2][32][32][2], 
int buf_idx,
+                             int frame_length_short)
  {
      int i;
  #if USE_FIXED
      int j;
  #endif
-    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
-                               // are not supported
+    const int frameLength = frame_length_short ? 960 : 1024;
+    const int numTimeSlots = frame_length_short ? 15 : 16;
+    +    memcpy(x    , x+frameLength, (320-32)*sizeof(x[0]));
+    memcpy(x+288, in,         frameLength*sizeof(x[0]));
+    +    for (i = 0; i < numTimeSlots*2; i++) { // numTimeSlots*RATE = 16*2
          dsp->vector_fmul_reverse(z, sbr_qmf_window_ds, x, 320);
          sbrdsp->sum64x5(z);
          sbrdsp->qmf_pre_shuffle(z);
@@ -1238,13 +1243,15 @@  static void sbr_qmf_synthesis(AVTXContext *mdct, 
av_tx_fn mdct_fn,
  #endif /* USE_FIXED */
                                INTFLOAT *out, INTFLOAT X[2][38][64],
                                INTFLOAT mdct_buf[2][64],
-                              INTFLOAT *v0, int *v_off, const unsigned 
int div)
+                              INTFLOAT *v0, int *v_off, const unsigned 
int div,
+                              int frame_length_short)
  {
      int i, n;
      const INTFLOAT *sbr_qmf_window = div ? sbr_qmf_window_ds : 
sbr_qmf_window_us;
      const int step = 128 >> div;
+    const int numTimeSlots = frame_length_short ? 15 : 16;
      INTFLOAT *v;
-    for (i = 0; i < 32; i++) {
+    for (i = 0; i < numTimeSlots*2; i++) {
          if (*v_off < step) {
              int saved_samples = (1280 - 128) >> div;
              memcpy(&v0[SBR_SYNTHESIS_BUF_SIZE - saved_samples], v0, 
saved_samples * sizeof(INTFLOAT));
@@ -1284,11 +1291,11 @@  static void sbr_qmf_synthesis(AVTXContext *mdct, 
av_tx_fn mdct_fn,
  /// Generate the subband filtered lowband
  static int sbr_lf_gen(AACContext *ac, SpectralBandReplication *sbr,
                        INTFLOAT X_low[32][40][2], const INTFLOAT 
W[2][32][32][2],
-                      int buf_idx)
+                      int buf_idx, int frame_length_short)
  {
      int i, k;
      const int t_HFGen = 8;
-    const int i_f = 32;
+    const int i_f = frame_length_short ? 30 : 32;
      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++) {
@@ -1344,10 +1351,10 @@  static int sbr_hf_gen(AACContext *ac, 
SpectralBandReplication *sbr,
  /// Generate the subband filtered lowband
  static int sbr_x_gen(SpectralBandReplication *sbr, INTFLOAT X[2][38][64],
                       const INTFLOAT Y0[38][64][2], const INTFLOAT 
Y1[38][64][2],
-                     const INTFLOAT X_low[32][40][2], int ch)
+                     const INTFLOAT X_low[32][40][2], int ch, int 
frame_length_short)
  {
      int k, i;
-    const int i_f = 32;
+    const int i_f = frame_length_short ? 30 : 32;
      const int i_Temp = FFMAX(2*sbr->data[ch].t_env_num_env_old - i_f, 0);
      memset(X, 0, 2*sizeof(*X));
      for (k = 0; k < sbr->kx[0]; k++) {
@@ -1496,7 +1503,7 @@  static void sbr_env_estimate(AAC_FLOAT 
(*e_curr)[48], INTFLOAT X_high[64][40][2]
  }
   void AAC_RENAME(ff_sbr_apply)(AACContext *ac, SpectralBandReplication 
*sbr, int id_aac,
-                  INTFLOAT* L, INTFLOAT* R)
+                  INTFLOAT* L, INTFLOAT* R, int frame_length_short)
  {
      int downsampled = ac->oc[1].m4ac.ext_sample_rate < sbr->sample_rate;
      int ch;
@@ -1531,10 +1538,10 @@  void AAC_RENAME(ff_sbr_apply)(AACContext *ac, 
SpectralBandReplication *sbr, int
          sbr_qmf_analysis(ac->fdsp, sbr->mdct_ana, sbr->mdct_ana_fn, 
&sbr->dsp,
                           ch ? R : L, 
sbr->data[ch].analysis_filterbank_samples,
                           (INTFLOAT*)sbr->qmf_filter_scratch,
-                         sbr->data[ch].W, sbr->data[ch].Ypos);
+                         sbr->data[ch].W, sbr->data[ch].Ypos, 
frame_length_short);
          sbr->c.sbr_lf_gen(ac, sbr, sbr->X_low,
                            (const INTFLOAT (*)[32][32][2]) sbr->data[ch].W,
-                          sbr->data[ch].Ypos);
+                          sbr->data[ch].Ypos, frame_length_short);
          sbr->data[ch].Ypos ^= 1;
          if (sbr->start) {
              sbr->c.sbr_hf_inverse_filter(&sbr->dsp, sbr->alpha0, 
sbr->alpha1,
@@ -1564,12 +1571,12 @@  void AAC_RENAME(ff_sbr_apply)(AACContext *ac, 
SpectralBandReplication *sbr, int
          sbr->c.sbr_x_gen(sbr, sbr->X[ch],
                    (const INTFLOAT (*)[64][2]) 
sbr->data[ch].Y[1-sbr->data[ch].Ypos],
                    (const INTFLOAT (*)[64][2]) sbr->data[ch].Y[ 
sbr->data[ch].Ypos],
-                  (const INTFLOAT (*)[40][2]) sbr->X_low, ch);
+                  (const INTFLOAT (*)[40][2]) sbr->X_low, ch, 
frame_length_short);
      }
       if (ac->oc[1].m4ac.ps == 1) {
          if (sbr->ps.common.start) {
-            AAC_RENAME(ff_ps_apply)(ac->avctx, &sbr->ps, sbr->X[0], 
sbr->X[1], sbr->kx[1] + sbr->m[1]);
+            AAC_RENAME(ff_ps_apply)(ac->avctx, &sbr->ps, sbr->X[0], 
sbr->X[1], sbr->kx[1] + sbr->m[1], frame_length_short);
          } else {
              memcpy(sbr->X[1], sbr->X[0], sizeof(sbr->X[0]));
          }
@@ -1580,13 +1587,13 @@  void AAC_RENAME(ff_sbr_apply)(AACContext *ac, 
SpectralBandReplication *sbr, int
                        L, sbr->X[0], sbr->qmf_filter_scratch,
                        sbr->data[0].synthesis_filterbank_samples,
                        &sbr->data[0].synthesis_filterbank_samples_offset,
-                      downsampled);
+                      downsampled, frame_length_short);
      if (nch == 2)
          sbr_qmf_synthesis(sbr->mdct, sbr->mdct_fn, &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);
+                          downsampled, frame_length_short);
  }
   static void aacsbr_func_ptr_init(AACSBRContext *c)
diff --git a/libavcodec/sbr.h b/libavcodec/sbr.h
index f949465ef5..aca3a30244 100644
--- a/libavcodec/sbr.h
+++ b/libavcodec/sbr.h
@@ -123,14 +123,14 @@  typedef struct SpectralBandReplication 
SpectralBandReplication;
  typedef struct AACSBRContext {
      int (*sbr_lf_gen)(AACContext *ac, SpectralBandReplication *sbr,
                        INTFLOAT X_low[32][40][2], const INTFLOAT 
W[2][32][32][2],
-                      int buf_idx);
+                      int buf_idx, int frame_length_short);
      void (*sbr_hf_assemble)(INTFLOAT Y1[38][64][2],
                              const INTFLOAT X_high[64][40][2],
                              SpectralBandReplication *sbr, SBRData 
*ch_data,
                              const int e_a[2]);
      int (*sbr_x_gen)(SpectralBandReplication *sbr, INTFLOAT X[2][38][64],
                       const INTFLOAT Y0[38][64][2], const INTFLOAT 
Y1[38][64][2],