Merge remote-tracking branch 'qatar/master'

* qatar/master:
  rv34: error out on size changes with frame threading
  aacsbr: Add a debug check to sbr_mapping.
  aac: Reset some state variables when turning SBR off
  aac: Reset PS parameters on header decode failure.
  fate: add wmalossless test.
  aacsbr: handle m_max values smaller than 4.

Conflicts:
	libavcodec/aacsbr.c
	tests/fate/lossless-audio.mak

Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
Michael Niedermayer 2012-03-24 10:59:43 +01:00
commit f58f75dd92
7 changed files with 60 additions and 15 deletions

View File

@ -275,6 +275,10 @@ int ff_ps_read_data(AVCodecContext *avctx, GetBitContext *gb_host, PSContext *ps
err: err:
ps->start = 0; ps->start = 0;
skip_bits_long(gb_host, bits_left); skip_bits_long(gb_host, bits_left);
memset(ps->iid_par, 0, sizeof(ps->iid_par));
memset(ps->icc_par, 0, sizeof(ps->icc_par));
memset(ps->ipd_par, 0, sizeof(ps->ipd_par));
memset(ps->opd_par, 0, sizeof(ps->opd_par));
return bits_left; return bits_left;
} }

View File

@ -129,13 +129,24 @@ av_cold void ff_aac_sbr_init(void)
ff_ps_init(); ff_ps_init();
} }
/** Places SBR in pure upsampling mode. */
static void sbr_turnoff(SpectralBandReplication *sbr) {
sbr->start = 0;
// Init defults used in pure upsampling mode
sbr->kx[1] = 32; //Typo in spec, kx' inits to 32
sbr->m[1] = 0;
// Reset values for first SBR header
sbr->data[0].e_a[1] = sbr->data[1].e_a[1] = -1;
memset(&sbr->spectrum_params, -1, sizeof(SpectrumParameters));
}
av_cold void ff_aac_sbr_ctx_init(AACContext *ac, SpectralBandReplication *sbr) av_cold void ff_aac_sbr_ctx_init(AACContext *ac, SpectralBandReplication *sbr)
{ {
float mdct_scale; float mdct_scale;
if(sbr->mdct.mdct_bits) if(sbr->mdct.mdct_bits)
return; return;
sbr->kx[0] = sbr->kx[1] = 32; //Typo in spec, kx' inits to 32 sbr->kx[0] = sbr->kx[1];
sbr->data[0].e_a[1] = sbr->data[1].e_a[1] = -1; sbr_turnoff(sbr);
sbr->data[0].synthesis_filterbank_samples_offset = SBR_SYNTHESIS_BUF_SIZE - (1280 - 128); 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->data[1].synthesis_filterbank_samples_offset = SBR_SYNTHESIS_BUF_SIZE - (1280 - 128);
/* SBR requires samples to be scaled to +/-32768.0 to work correctly. /* SBR requires samples to be scaled to +/-32768.0 to work correctly.
@ -998,18 +1009,18 @@ static unsigned int read_sbr_data(AACContext *ac, SpectralBandReplication *sbr,
if (id_aac == TYPE_SCE || id_aac == TYPE_CCE) { 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)) {
sbr->start = 0; sbr_turnoff(sbr);
return get_bits_count(gb) - cnt; return get_bits_count(gb) - cnt;
} }
} else if (id_aac == TYPE_CPE) { } else if (id_aac == TYPE_CPE) {
if (read_sbr_channel_pair_element(ac, sbr, gb)) { if (read_sbr_channel_pair_element(ac, sbr, gb)) {
sbr->start = 0; sbr_turnoff(sbr);
return get_bits_count(gb) - cnt; return get_bits_count(gb) - cnt;
} }
} else { } else {
av_log(ac->avctx, AV_LOG_ERROR, av_log(ac->avctx, AV_LOG_ERROR,
"Invalid bitstream - cannot apply SBR to element type %d\n", id_aac); "Invalid bitstream - cannot apply SBR to element type %d\n", id_aac);
sbr->start = 0; sbr_turnoff(sbr);
return get_bits_count(gb) - cnt; return get_bits_count(gb) - cnt;
} }
if (get_bits1(gb)) { // bs_extended_data if (get_bits1(gb)) { // bs_extended_data
@ -1041,7 +1052,7 @@ static void sbr_reset(AACContext *ac, SpectralBandReplication *sbr)
if (err < 0) { if (err < 0) {
av_log(ac->avctx, AV_LOG_ERROR, av_log(ac->avctx, AV_LOG_ERROR,
"SBR reset failed. Switching SBR to pure upsampling mode.\n"); "SBR reset failed. Switching SBR to pure upsampling mode.\n");
sbr->start = 0; sbr_turnoff(sbr);
} }
} }
@ -1076,6 +1087,7 @@ int ff_decode_sbr_extension(AACContext *ac, SpectralBandReplication *sbr,
//Save some state from the previous frame. //Save some state from the previous frame.
sbr->kx[0] = sbr->kx[1]; sbr->kx[0] = sbr->kx[1];
sbr->m[0] = sbr->m[1]; sbr->m[0] = sbr->m[1];
sbr->kx_and_m_pushed = 1;
num_sbr_bits++; num_sbr_bits++;
if (get_bits1(gb)) // bs_header_flag if (get_bits1(gb)) // bs_header_flag
@ -1391,7 +1403,7 @@ static int sbr_x_gen(SpectralBandReplication *sbr, float X[2][38][64],
/** High Frequency Adjustment (14496-3 sp04 p217) and Mapping /** High Frequency Adjustment (14496-3 sp04 p217) and Mapping
* (14496-3 sp04 p217) * (14496-3 sp04 p217)
*/ */
static void sbr_mapping(AACContext *ac, SpectralBandReplication *sbr, static int sbr_mapping(AACContext *ac, SpectralBandReplication *sbr,
SBRData *ch_data, int e_a[2]) SBRData *ch_data, int e_a[2])
{ {
int e, i, m; int e, i, m;
@ -1402,7 +1414,12 @@ static void sbr_mapping(AACContext *ac, SpectralBandReplication *sbr,
uint16_t *table = ch_data->bs_freq_res[e + 1] ? sbr->f_tablehigh : sbr->f_tablelow; uint16_t *table = ch_data->bs_freq_res[e + 1] ? sbr->f_tablehigh : sbr->f_tablelow;
int k; int k;
av_assert0(sbr->kx[1] <= table[0]); if (sbr->kx[1] != table[0]) {
av_log(ac->avctx, AV_LOG_ERROR, "kx != f_table{high,low}[0]. "
"Derived frequency tables were not regenerated.\n");
sbr_turnoff(sbr);
return AVERROR_BUG;
}
for (i = 0; i < ilim; i++) for (i = 0; i < ilim; i++)
for (m = table[i]; m < table[i + 1]; m++) for (m = table[i]; m < table[i + 1]; m++)
sbr->e_origmapped[e][m - sbr->kx[1]] = ch_data->env_facs[e+1][i]; sbr->e_origmapped[e][m - sbr->kx[1]] = ch_data->env_facs[e+1][i];
@ -1437,6 +1454,7 @@ static void sbr_mapping(AACContext *ac, SpectralBandReplication *sbr,
} }
memcpy(ch_data->s_indexmapped[0], ch_data->s_indexmapped[ch_data->bs_num_env], sizeof(ch_data->s_indexmapped[0])); memcpy(ch_data->s_indexmapped[0], ch_data->s_indexmapped[ch_data->bs_num_env], sizeof(ch_data->s_indexmapped[0]));
return 0;
} }
/// Estimation of current envelope (14496-3 sp04 p218) /// Estimation of current envelope (14496-3 sp04 p218)
@ -1637,6 +1655,14 @@ void ff_sbr_apply(AACContext *ac, SpectralBandReplication *sbr, int id_aac,
int downsampled = ac->m4ac.ext_sample_rate < sbr->sample_rate; int downsampled = ac->m4ac.ext_sample_rate < sbr->sample_rate;
int ch; int ch;
int nch = (id_aac == TYPE_CPE) ? 2 : 1; int nch = (id_aac == TYPE_CPE) ? 2 : 1;
int err;
if (!sbr->kx_and_m_pushed) {
sbr->kx[0] = sbr->kx[1];
sbr->m[0] = sbr->m[1];
} else {
sbr->kx_and_m_pushed = 0;
}
if (sbr->start) { if (sbr->start) {
sbr_dequant(sbr, id_aac); sbr_dequant(sbr, id_aac);
@ -1647,6 +1673,7 @@ void ff_sbr_apply(AACContext *ac, SpectralBandReplication *sbr, int id_aac,
(float*)sbr->qmf_filter_scratch, (float*)sbr->qmf_filter_scratch,
sbr->data[ch].W); sbr->data[ch].W);
sbr_lf_gen(ac, sbr, sbr->X_low, sbr->data[ch].W); sbr_lf_gen(ac, sbr, sbr->X_low, sbr->data[ch].W);
sbr->data[ch].Ypos ^= 1;
if (sbr->start) { if (sbr->start) {
sbr_hf_inverse_filter(&sbr->dsp, sbr->alpha0, sbr->alpha1, sbr->X_low, sbr->k[0]); sbr_hf_inverse_filter(&sbr->dsp, sbr->alpha0, sbr->alpha1, sbr->X_low, sbr->k[0]);
sbr_chirp(sbr, &sbr->data[ch]); sbr_chirp(sbr, &sbr->data[ch]);
@ -1655,13 +1682,14 @@ void ff_sbr_apply(AACContext *ac, SpectralBandReplication *sbr, int id_aac,
sbr->data[ch].bs_num_env); sbr->data[ch].bs_num_env);
// hf_adj // hf_adj
sbr_mapping(ac, sbr, &sbr->data[ch], sbr->data[ch].e_a); err = sbr_mapping(ac, sbr, &sbr->data[ch], sbr->data[ch].e_a);
sbr_env_estimate(sbr->e_curr, sbr->X_high, sbr, &sbr->data[ch]); if (!err) {
sbr_gain_calc(ac, sbr, &sbr->data[ch], sbr->data[ch].e_a); sbr_env_estimate(sbr->e_curr, sbr->X_high, sbr, &sbr->data[ch]);
sbr->data[ch].Ypos ^= 1; sbr_gain_calc(ac, sbr, &sbr->data[ch], sbr->data[ch].e_a);
sbr_hf_assemble(sbr->data[ch].Y[sbr->data[ch].Ypos], sbr_hf_assemble(sbr->data[ch].Y[sbr->data[ch].Ypos],
sbr->X_high, sbr, &sbr->data[ch], sbr->X_high, sbr, &sbr->data[ch],
sbr->data[ch].e_a); sbr->data[ch].e_a);
}
} }
/* synthesis */ /* synthesis */

View File

@ -1666,6 +1666,13 @@ int ff_rv34_decode_frame(AVCodecContext *avctx,
if (s->width != si.width || s->height != si.height) { if (s->width != si.width || s->height != si.height) {
int err; int err;
if (HAVE_THREADS &&
(s->avctx->active_thread_type & FF_THREAD_FRAME)) {
av_log_missing_feature(s->avctx, "Width/height changing with "
"frame threading is", 0);
return AVERROR_PATCHWELCOME;
}
av_log(s->avctx, AV_LOG_WARNING, "Changing dimensions to %dx%d\n", av_log(s->avctx, AV_LOG_WARNING, "Changing dimensions to %dx%d\n",
si.width, si.height); si.width, si.height);
ff_MPV_common_end(s); ff_MPV_common_end(s);

View File

@ -133,6 +133,7 @@ typedef struct {
unsigned kx[2]; unsigned kx[2];
///M' and M respectively, M is the number of QMF subbands that use SBR. ///M' and M respectively, M is the number of QMF subbands that use SBR.
unsigned m[2]; unsigned m[2];
unsigned kx_and_m_pushed;
///The number of frequency bands in f_master ///The number of frequency bands in f_master
unsigned n_master; unsigned n_master;
SBRData data[2]; SBRData data[2];

View File

@ -81,6 +81,7 @@ cglobal sbr_hf_g_filt, 5, 6, 5
lea r2, [r2 + r3*4] lea r2, [r2 + r3*4]
lea r0, [r0 + r3*8] lea r0, [r0 + r3*8]
neg r3 neg r3
jz .loop1
.loop4: .loop4:
movlps m0, [r2 + 4*r3 + 0] movlps m0, [r2 + 4*r3 + 0]
movlps m1, [r2 + 4*r3 + 8] movlps m1, [r2 + 4*r3 + 8]

View File

@ -13,6 +13,9 @@ fate-lossless-shorten: CMD = md5 -i $(SAMPLES)/lossless-audio/luckynight-partial
FATE_LOSSLESS_AUDIO += fate-lossless-tta FATE_LOSSLESS_AUDIO += fate-lossless-tta
fate-lossless-tta: CMD = crc -i $(SAMPLES)/lossless-audio/inside.tta fate-lossless-tta: CMD = crc -i $(SAMPLES)/lossless-audio/inside.tta
FATE_LOSSLESS_AUDIO += fate-lossless-wma
fate-lossless-wma: CMD = md5 -i $(SAMPLES)/lossless-audio/luckynight-partial.wma -f s16le
FATE_TESTS += $(FATE_LOSSLESS_AUDIO) FATE_TESTS += $(FATE_LOSSLESS_AUDIO)
fate-lossless-audio: $(FATE_LOSSLESS_AUDIO) fate-lossless-audio: $(FATE_LOSSLESS_AUDIO)

View File

@ -0,0 +1 @@
35dc840f91cbcece02178d03c8f2fe26