This is achieved by using function pointers for AAC SBR functions. This unfortunately necessitated to use void* in ff_aac_sbr_apply(_fixed). Fixes ticket #10999. Reviewed-by: Lynne <dev@lynne.ee> Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
1573 lines
58 KiB
C
1573 lines
58 KiB
C
/*
|
|
* AAC Spectral Band Replication decoding functions
|
|
* Copyright (c) 2008-2009 Robert Swain ( rob opendot cl )
|
|
* Copyright (c) 2009-2010 Alex Converse <alex.converse@gmail.com>
|
|
*
|
|
* Fixed point code
|
|
* Copyright (c) 2013
|
|
* MIPS Technologies, Inc., California.
|
|
*
|
|
* This file is part of FFmpeg.
|
|
*
|
|
* FFmpeg is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* FFmpeg is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with FFmpeg; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
/**
|
|
* @file
|
|
* AAC Spectral Band Replication decoding functions
|
|
* @author Robert Swain ( rob opendot cl )
|
|
* @author Stanislav Ocovaj ( stanislav.ocovaj@imgtec.com )
|
|
* @author Zoran Basaric ( zoran.basaric@imgtec.com )
|
|
*/
|
|
|
|
#include "aac/aacdec.h"
|
|
#include "aac/aacdec_tab.h"
|
|
#include "avcodec.h"
|
|
#include "libavutil/qsort.h"
|
|
#include "libavutil/mem.h"
|
|
|
|
typedef struct ExtChannelElement {
|
|
ChannelElement ch;
|
|
PredictorState predictor_state[2][MAX_PREDICTORS];
|
|
SpectralBandReplication sbr;
|
|
} ExtChannelElement;
|
|
|
|
static inline SpectralBandReplication *get_sbr(ChannelElement *ch)
|
|
{
|
|
return &((ExtChannelElement*)ch)->sbr;
|
|
}
|
|
|
|
av_cold void AAC_RENAME(ff_aac_sbr_init)(void)
|
|
{
|
|
AAC_RENAME(ff_ps_init)();
|
|
}
|
|
|
|
/** Places SBR in pure upsampling mode. */
|
|
static void sbr_turnoff(SpectralBandReplication *sbr) {
|
|
sbr->start = 0;
|
|
sbr->ready_for_dequant = 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 int AAC_RENAME(ff_aac_sbr_ctx_alloc_init)(AACDecContext *ac,
|
|
ChannelElement **che, int id_aac)
|
|
{
|
|
SpectralBandReplication *sbr;
|
|
ExtChannelElement *ext = av_mallocz(sizeof(*ext));
|
|
int ret;
|
|
float scale;
|
|
|
|
if (!ext)
|
|
return AVERROR(ENOMEM);
|
|
*che = &ext->ch;
|
|
sbr = &ext->sbr;
|
|
ext->ch.ch[0].AAC_RENAME(predictor_state) = ext->predictor_state[0];
|
|
ext->ch.ch[1].AAC_RENAME(predictor_state) = ext->predictor_state[1];
|
|
|
|
sbr->kx[0] = sbr->kx[1];
|
|
sbr->id_aac = id_aac;
|
|
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. */
|
|
|
|
scale = USE_FIXED ? 1 : 1.0 / (64 * 32768);
|
|
ret = av_tx_init(&sbr->mdct, &sbr->mdct_fn,
|
|
USE_FIXED ? AV_TX_INT32_MDCT : AV_TX_FLOAT_MDCT,
|
|
1, 64, &scale, 0);
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
scale = USE_FIXED ? -1.0 : -2.0 * 32768;
|
|
ret = av_tx_init(&sbr->mdct_ana, &sbr->mdct_ana_fn,
|
|
USE_FIXED ? AV_TX_INT32_MDCT : AV_TX_FLOAT_MDCT,
|
|
1, 64, &scale, 0);
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
AAC_RENAME(ff_ps_ctx_init)(&sbr->ps);
|
|
AAC_RENAME(ff_sbrdsp_init)(&sbr->dsp);
|
|
aacsbr_func_ptr_init(&sbr->c);
|
|
|
|
return 0;
|
|
}
|
|
|
|
av_cold void AAC_RENAME(ff_aac_sbr_ctx_close)(ChannelElement *che)
|
|
{
|
|
SpectralBandReplication *sbr = get_sbr(che);
|
|
av_tx_uninit(&sbr->mdct);
|
|
av_tx_uninit(&sbr->mdct_ana);
|
|
}
|
|
|
|
static int qsort_comparison_function_int16(const void *a, const void *b)
|
|
{
|
|
return *(const int16_t *)a - *(const int16_t *)b;
|
|
}
|
|
|
|
static inline int in_table_int16(const int16_t *table, int last_el, int16_t needle)
|
|
{
|
|
int i;
|
|
for (i = 0; i <= last_el; i++)
|
|
if (table[i] == needle)
|
|
return 1;
|
|
return 0;
|
|
}
|
|
|
|
/// Limiter Frequency Band Table (14496-3 sp04 p198)
|
|
static void sbr_make_f_tablelim(SpectralBandReplication *sbr)
|
|
{
|
|
int k;
|
|
if (sbr->bs_limiter_bands > 0) {
|
|
static const INTFLOAT bands_warped[3] = { Q23(1.32715174233856803909f), //2^(0.49/1.2)
|
|
Q23(1.18509277094158210129f), //2^(0.49/2)
|
|
Q23(1.11987160404675912501f) }; //2^(0.49/3)
|
|
const INTFLOAT lim_bands_per_octave_warped = bands_warped[sbr->bs_limiter_bands - 1];
|
|
int16_t patch_borders[7];
|
|
uint16_t *in = sbr->f_tablelim + 1, *out = sbr->f_tablelim;
|
|
|
|
patch_borders[0] = sbr->kx[1];
|
|
for (k = 1; k <= sbr->num_patches; k++)
|
|
patch_borders[k] = patch_borders[k-1] + sbr->patch_num_subbands[k-1];
|
|
|
|
memcpy(sbr->f_tablelim, sbr->f_tablelow,
|
|
(sbr->n[0] + 1) * sizeof(sbr->f_tablelow[0]));
|
|
if (sbr->num_patches > 1)
|
|
memcpy(sbr->f_tablelim + sbr->n[0] + 1, patch_borders + 1,
|
|
(sbr->num_patches - 1) * sizeof(patch_borders[0]));
|
|
|
|
AV_QSORT(sbr->f_tablelim, sbr->num_patches + sbr->n[0],
|
|
uint16_t,
|
|
qsort_comparison_function_int16);
|
|
|
|
sbr->n_lim = sbr->n[0] + sbr->num_patches - 1;
|
|
while (out < sbr->f_tablelim + sbr->n_lim) {
|
|
#if USE_FIXED
|
|
if ((*in << 23) >= *out * lim_bands_per_octave_warped) {
|
|
#else
|
|
if (*in >= *out * lim_bands_per_octave_warped) {
|
|
#endif /* USE_FIXED */
|
|
*++out = *in++;
|
|
} else if (*in == *out ||
|
|
!in_table_int16(patch_borders, sbr->num_patches, *in)) {
|
|
in++;
|
|
sbr->n_lim--;
|
|
} else if (!in_table_int16(patch_borders, sbr->num_patches, *out)) {
|
|
*out = *in++;
|
|
sbr->n_lim--;
|
|
} else {
|
|
*++out = *in++;
|
|
}
|
|
}
|
|
} else {
|
|
sbr->f_tablelim[0] = sbr->f_tablelow[0];
|
|
sbr->f_tablelim[1] = sbr->f_tablelow[sbr->n[0]];
|
|
sbr->n_lim = 1;
|
|
}
|
|
}
|
|
|
|
static unsigned int read_sbr_header(SpectralBandReplication *sbr, GetBitContext *gb)
|
|
{
|
|
unsigned int cnt = get_bits_count(gb);
|
|
uint8_t bs_header_extra_1;
|
|
uint8_t bs_header_extra_2;
|
|
int old_bs_limiter_bands = sbr->bs_limiter_bands;
|
|
SpectrumParameters old_spectrum_params;
|
|
|
|
sbr->start = 1;
|
|
sbr->ready_for_dequant = 0;
|
|
|
|
// Save last spectrum parameters variables to compare to new ones
|
|
memcpy(&old_spectrum_params, &sbr->spectrum_params, sizeof(SpectrumParameters));
|
|
|
|
sbr->bs_amp_res_header = get_bits1(gb);
|
|
sbr->spectrum_params.bs_start_freq = get_bits(gb, 4);
|
|
sbr->spectrum_params.bs_stop_freq = get_bits(gb, 4);
|
|
sbr->spectrum_params.bs_xover_band = get_bits(gb, 3);
|
|
skip_bits(gb, 2); // bs_reserved
|
|
|
|
bs_header_extra_1 = get_bits1(gb);
|
|
bs_header_extra_2 = get_bits1(gb);
|
|
|
|
if (bs_header_extra_1) {
|
|
sbr->spectrum_params.bs_freq_scale = get_bits(gb, 2);
|
|
sbr->spectrum_params.bs_alter_scale = get_bits1(gb);
|
|
sbr->spectrum_params.bs_noise_bands = get_bits(gb, 2);
|
|
} else {
|
|
sbr->spectrum_params.bs_freq_scale = 2;
|
|
sbr->spectrum_params.bs_alter_scale = 1;
|
|
sbr->spectrum_params.bs_noise_bands = 2;
|
|
}
|
|
|
|
// Check if spectrum parameters changed
|
|
if (memcmp(&old_spectrum_params, &sbr->spectrum_params, sizeof(SpectrumParameters)))
|
|
sbr->reset = 1;
|
|
|
|
if (bs_header_extra_2) {
|
|
sbr->bs_limiter_bands = get_bits(gb, 2);
|
|
sbr->bs_limiter_gains = get_bits(gb, 2);
|
|
sbr->bs_interpol_freq = get_bits1(gb);
|
|
sbr->bs_smoothing_mode = get_bits1(gb);
|
|
} else {
|
|
sbr->bs_limiter_bands = 2;
|
|
sbr->bs_limiter_gains = 2;
|
|
sbr->bs_interpol_freq = 1;
|
|
sbr->bs_smoothing_mode = 1;
|
|
}
|
|
|
|
if (sbr->bs_limiter_bands != old_bs_limiter_bands && !sbr->reset)
|
|
sbr_make_f_tablelim(sbr);
|
|
|
|
return get_bits_count(gb) - cnt;
|
|
}
|
|
|
|
static int array_min_int16(const int16_t *array, int nel)
|
|
{
|
|
int i, min = array[0];
|
|
for (i = 1; i < nel; i++)
|
|
min = FFMIN(array[i], min);
|
|
return min;
|
|
}
|
|
|
|
static int check_n_master(AVCodecContext *avctx, int n_master, int bs_xover_band)
|
|
{
|
|
// Requirements (14496-3 sp04 p205)
|
|
if (n_master <= 0) {
|
|
av_log(avctx, AV_LOG_ERROR, "Invalid n_master: %d\n", n_master);
|
|
return -1;
|
|
}
|
|
if (bs_xover_band >= n_master) {
|
|
av_log(avctx, AV_LOG_ERROR,
|
|
"Invalid bitstream, crossover band index beyond array bounds: %d\n",
|
|
bs_xover_band);
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/// Master Frequency Band Table (14496-3 sp04 p194)
|
|
static int sbr_make_f_master(AACDecContext *ac, SpectralBandReplication *sbr,
|
|
SpectrumParameters *spectrum)
|
|
{
|
|
unsigned int temp, max_qmf_subbands = 0;
|
|
unsigned int start_min, stop_min;
|
|
int k;
|
|
const int8_t *sbr_offset_ptr;
|
|
int16_t stop_dk[13];
|
|
|
|
switch (sbr->sample_rate) {
|
|
case 16000:
|
|
sbr_offset_ptr = sbr_offset[0];
|
|
break;
|
|
case 22050:
|
|
sbr_offset_ptr = sbr_offset[1];
|
|
break;
|
|
case 24000:
|
|
sbr_offset_ptr = sbr_offset[2];
|
|
break;
|
|
case 32000:
|
|
sbr_offset_ptr = sbr_offset[3];
|
|
break;
|
|
case 44100: case 48000: case 64000:
|
|
sbr_offset_ptr = sbr_offset[4];
|
|
break;
|
|
case 88200: case 96000: case 128000: case 176400: case 192000:
|
|
sbr_offset_ptr = sbr_offset[5];
|
|
break;
|
|
default:
|
|
av_log(ac->avctx, AV_LOG_ERROR,
|
|
"Unsupported sample rate for SBR: %d\n", sbr->sample_rate);
|
|
return -1;
|
|
}
|
|
|
|
if (sbr->sample_rate < 32000) {
|
|
temp = 3000;
|
|
} else if (sbr->sample_rate < 64000) {
|
|
temp = 4000;
|
|
} else
|
|
temp = 5000;
|
|
|
|
start_min = ((temp << 7) + (sbr->sample_rate >> 1)) / sbr->sample_rate;
|
|
stop_min = ((temp << 8) + (sbr->sample_rate >> 1)) / sbr->sample_rate;
|
|
|
|
sbr->k[0] = start_min + sbr_offset_ptr[spectrum->bs_start_freq];
|
|
|
|
if (spectrum->bs_stop_freq < 14) {
|
|
sbr->k[2] = stop_min;
|
|
make_bands(stop_dk, stop_min, 64, 13);
|
|
AV_QSORT(stop_dk, 13, int16_t, qsort_comparison_function_int16);
|
|
for (k = 0; k < spectrum->bs_stop_freq; k++)
|
|
sbr->k[2] += stop_dk[k];
|
|
} else if (spectrum->bs_stop_freq == 14) {
|
|
sbr->k[2] = 2*sbr->k[0];
|
|
} else if (spectrum->bs_stop_freq == 15) {
|
|
sbr->k[2] = 3*sbr->k[0];
|
|
} else {
|
|
av_log(ac->avctx, AV_LOG_ERROR,
|
|
"Invalid bs_stop_freq: %d\n", spectrum->bs_stop_freq);
|
|
return -1;
|
|
}
|
|
sbr->k[2] = FFMIN(64, sbr->k[2]);
|
|
|
|
// Requirements (14496-3 sp04 p205)
|
|
if (sbr->sample_rate <= 32000) {
|
|
max_qmf_subbands = 48;
|
|
} else if (sbr->sample_rate == 44100) {
|
|
max_qmf_subbands = 35;
|
|
} else if (sbr->sample_rate >= 48000)
|
|
max_qmf_subbands = 32;
|
|
else
|
|
av_assert0(0);
|
|
|
|
if (sbr->k[2] - sbr->k[0] > max_qmf_subbands) {
|
|
av_log(ac->avctx, AV_LOG_ERROR,
|
|
"Invalid bitstream, too many QMF subbands: %d\n", sbr->k[2] - sbr->k[0]);
|
|
return -1;
|
|
}
|
|
|
|
if (!spectrum->bs_freq_scale) {
|
|
int dk, k2diff;
|
|
|
|
dk = spectrum->bs_alter_scale + 1;
|
|
sbr->n_master = ((sbr->k[2] - sbr->k[0] + (dk&2)) >> dk) << 1;
|
|
if (check_n_master(ac->avctx, sbr->n_master, sbr->spectrum_params.bs_xover_band))
|
|
return -1;
|
|
|
|
for (k = 1; k <= sbr->n_master; k++)
|
|
sbr->f_master[k] = dk;
|
|
|
|
k2diff = sbr->k[2] - sbr->k[0] - sbr->n_master * dk;
|
|
if (k2diff < 0) {
|
|
sbr->f_master[1]--;
|
|
sbr->f_master[2]-= (k2diff < -1);
|
|
} else if (k2diff) {
|
|
sbr->f_master[sbr->n_master]++;
|
|
}
|
|
|
|
sbr->f_master[0] = sbr->k[0];
|
|
for (k = 1; k <= sbr->n_master; k++)
|
|
sbr->f_master[k] += sbr->f_master[k - 1];
|
|
|
|
} else {
|
|
int half_bands = 7 - spectrum->bs_freq_scale; // bs_freq_scale = {1,2,3}
|
|
int two_regions, num_bands_0;
|
|
int vdk0_max, vdk1_min;
|
|
int16_t vk0[49];
|
|
#if USE_FIXED
|
|
int tmp, nz = 0;
|
|
#endif /* USE_FIXED */
|
|
|
|
if (49 * sbr->k[2] > 110 * sbr->k[0]) {
|
|
two_regions = 1;
|
|
sbr->k[1] = 2 * sbr->k[0];
|
|
} else {
|
|
two_regions = 0;
|
|
sbr->k[1] = sbr->k[2];
|
|
}
|
|
|
|
#if USE_FIXED
|
|
tmp = (sbr->k[1] << 23) / sbr->k[0];
|
|
while (tmp < 0x40000000) {
|
|
tmp <<= 1;
|
|
nz++;
|
|
}
|
|
tmp = fixed_log(tmp - 0x80000000);
|
|
tmp = (int)(((int64_t)tmp * CONST_RECIP_LN2 + 0x20000000) >> 30);
|
|
tmp = (((tmp + 0x80) >> 8) + ((8 - nz) << 23)) * half_bands;
|
|
num_bands_0 = ((tmp + 0x400000) >> 23) * 2;
|
|
#else
|
|
num_bands_0 = lrintf(half_bands * log2f(sbr->k[1] / (float)sbr->k[0])) * 2;
|
|
#endif /* USE_FIXED */
|
|
|
|
if (num_bands_0 <= 0) { // Requirements (14496-3 sp04 p205)
|
|
av_log(ac->avctx, AV_LOG_ERROR, "Invalid num_bands_0: %d\n", num_bands_0);
|
|
return -1;
|
|
}
|
|
|
|
vk0[0] = 0;
|
|
|
|
make_bands(vk0+1, sbr->k[0], sbr->k[1], num_bands_0);
|
|
|
|
AV_QSORT(vk0 + 1, num_bands_0, int16_t, qsort_comparison_function_int16);
|
|
vdk0_max = vk0[num_bands_0];
|
|
|
|
vk0[0] = sbr->k[0];
|
|
for (k = 1; k <= num_bands_0; k++) {
|
|
if (vk0[k] <= 0) { // Requirements (14496-3 sp04 p205)
|
|
av_log(ac->avctx, AV_LOG_ERROR, "Invalid vDk0[%d]: %d\n", k, vk0[k]);
|
|
return -1;
|
|
}
|
|
vk0[k] += vk0[k-1];
|
|
}
|
|
|
|
if (two_regions) {
|
|
int16_t vk1[49];
|
|
#if USE_FIXED
|
|
int num_bands_1;
|
|
|
|
tmp = (sbr->k[2] << 23) / sbr->k[1];
|
|
nz = 0;
|
|
while (tmp < 0x40000000) {
|
|
tmp <<= 1;
|
|
nz++;
|
|
}
|
|
tmp = fixed_log(tmp - 0x80000000);
|
|
tmp = (int)(((int64_t)tmp * CONST_RECIP_LN2 + 0x20000000) >> 30);
|
|
tmp = (((tmp + 0x80) >> 8) + ((8 - nz) << 23)) * half_bands;
|
|
if (spectrum->bs_alter_scale)
|
|
tmp = (int)(((int64_t)tmp * CONST_076923 + 0x40000000) >> 31);
|
|
num_bands_1 = ((tmp + 0x400000) >> 23) * 2;
|
|
#else
|
|
float invwarp = spectrum->bs_alter_scale ? 0.76923076923076923077f
|
|
: 1.0f; // bs_alter_scale = {0,1}
|
|
int num_bands_1 = lrintf(half_bands * invwarp *
|
|
log2f(sbr->k[2] / (float)sbr->k[1])) * 2;
|
|
#endif /* USE_FIXED */
|
|
make_bands(vk1+1, sbr->k[1], sbr->k[2], num_bands_1);
|
|
|
|
vdk1_min = array_min_int16(vk1 + 1, num_bands_1);
|
|
|
|
if (vdk1_min < vdk0_max) {
|
|
int change;
|
|
AV_QSORT(vk1 + 1, num_bands_1, int16_t, qsort_comparison_function_int16);
|
|
change = FFMIN(vdk0_max - vk1[1], (vk1[num_bands_1] - vk1[1]) >> 1);
|
|
vk1[1] += change;
|
|
vk1[num_bands_1] -= change;
|
|
}
|
|
|
|
AV_QSORT(vk1 + 1, num_bands_1, int16_t, qsort_comparison_function_int16);
|
|
|
|
vk1[0] = sbr->k[1];
|
|
for (k = 1; k <= num_bands_1; k++) {
|
|
if (vk1[k] <= 0) { // Requirements (14496-3 sp04 p205)
|
|
av_log(ac->avctx, AV_LOG_ERROR, "Invalid vDk1[%d]: %d\n", k, vk1[k]);
|
|
return -1;
|
|
}
|
|
vk1[k] += vk1[k-1];
|
|
}
|
|
|
|
sbr->n_master = num_bands_0 + num_bands_1;
|
|
if (check_n_master(ac->avctx, sbr->n_master, sbr->spectrum_params.bs_xover_band))
|
|
return -1;
|
|
memcpy(&sbr->f_master[0], vk0,
|
|
(num_bands_0 + 1) * sizeof(sbr->f_master[0]));
|
|
memcpy(&sbr->f_master[num_bands_0 + 1], vk1 + 1,
|
|
num_bands_1 * sizeof(sbr->f_master[0]));
|
|
|
|
} else {
|
|
sbr->n_master = num_bands_0;
|
|
if (check_n_master(ac->avctx, sbr->n_master, sbr->spectrum_params.bs_xover_band))
|
|
return -1;
|
|
memcpy(sbr->f_master, vk0, (num_bands_0 + 1) * sizeof(sbr->f_master[0]));
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/// High Frequency Generation - Patch Construction (14496-3 sp04 p216 fig. 4.46)
|
|
static int sbr_hf_calc_npatches(AACDecContext *ac, SpectralBandReplication *sbr)
|
|
{
|
|
int i, k, last_k = -1, last_msb = -1, sb = 0;
|
|
int msb = sbr->k[0];
|
|
int usb = sbr->kx[1];
|
|
int goal_sb = ((1000 << 11) + (sbr->sample_rate >> 1)) / sbr->sample_rate;
|
|
|
|
sbr->num_patches = 0;
|
|
|
|
if (goal_sb < sbr->kx[1] + sbr->m[1]) {
|
|
for (k = 0; sbr->f_master[k] < goal_sb; k++) ;
|
|
} else
|
|
k = sbr->n_master;
|
|
|
|
do {
|
|
int odd = 0;
|
|
if (k == last_k && msb == last_msb) {
|
|
av_log(ac->avctx, AV_LOG_ERROR, "patch construction failed\n");
|
|