From 71ea26811cbd8345cb10ab29406594e1fc19204e Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Thu, 22 Mar 2012 11:50:48 -0700 Subject: [PATCH 1/6] aacsbr: handle m_max values smaller than 4. Prevents a signflip in the counter, and a subsequent crash because of overreads/overwrites. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org --- libavcodec/x86/sbrdsp.asm | 1 + 1 file changed, 1 insertion(+) diff --git a/libavcodec/x86/sbrdsp.asm b/libavcodec/x86/sbrdsp.asm index 31a1c8b76f..6f66327088 100644 --- a/libavcodec/x86/sbrdsp.asm +++ b/libavcodec/x86/sbrdsp.asm @@ -81,6 +81,7 @@ cglobal sbr_hf_g_filt, 5, 6, 5 lea r2, [r2 + r3*4] lea r0, [r0 + r3*8] neg r3 + jz .loop1 .loop4: movlps m0, [r2 + 4*r3 + 0] movlps m1, [r2 + 4*r3 + 8] From 7beec7e29df051ce586e519861ac3203d36d8cf5 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Thu, 22 Mar 2012 12:13:24 -0700 Subject: [PATCH 2/6] fate: add wmalossless test. --- tests/fate/lossless-audio.mak | 3 +++ tests/ref/fate/lossless-wma | 1 + 2 files changed, 4 insertions(+) create mode 100644 tests/ref/fate/lossless-wma diff --git a/tests/fate/lossless-audio.mak b/tests/fate/lossless-audio.mak index f35d659264..44d6f094d2 100644 --- a/tests/fate/lossless-audio.mak +++ b/tests/fate/lossless-audio.mak @@ -12,3 +12,6 @@ fate-lossless-shorten: CMD = md5 -i $(SAMPLES)/lossless-audio/luckynight-partial FATE_TESTS += fate-lossless-tta fate-lossless-tta: CMD = crc -i $(SAMPLES)/lossless-audio/inside.tta + +FATE_TESTS += fate-lossless-wma +fate-lossless-wma: CMD = md5 -i $(SAMPLES)/lossless-audio/luckynight-partial.wma -f s16le diff --git a/tests/ref/fate/lossless-wma b/tests/ref/fate/lossless-wma new file mode 100644 index 0000000000..5bea19b219 --- /dev/null +++ b/tests/ref/fate/lossless-wma @@ -0,0 +1 @@ +35dc840f91cbcece02178d03c8f2fe26 From a237b38021cd3009cc78eeb974b596085f2fe393 Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Wed, 21 Mar 2012 10:11:02 -0700 Subject: [PATCH 3/6] aac: Reset PS parameters on header decode failure. If the next header frame codes zero envelopes the previous frame's values will be used. Consequently the invalid values must be cleared. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org --- libavcodec/aacps.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libavcodec/aacps.c b/libavcodec/aacps.c index 3da912c6c7..6c9dcf2f1b 100644 --- a/libavcodec/aacps.c +++ b/libavcodec/aacps.c @@ -275,6 +275,10 @@ int ff_ps_read_data(AVCodecContext *avctx, GetBitContext *gb_host, PSContext *ps err: ps->start = 0; 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; } From 0cb93dacee45d3d767b4470e6a9b43b17e5220c4 Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Wed, 21 Mar 2012 12:00:56 -0700 Subject: [PATCH 4/6] aac: Reset some state variables when turning SBR off This makes sure the reset flag gets set when SBR gets turned back on and sets control variables for unguided mode back to their defaults. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org --- libavcodec/aacsbr.c | 33 ++++++++++++++++++++++++++------- libavcodec/sbr.h | 1 + 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/libavcodec/aacsbr.c b/libavcodec/aacsbr.c index f5ac30f17e..f39806e30f 100644 --- a/libavcodec/aacsbr.c +++ b/libavcodec/aacsbr.c @@ -127,11 +127,22 @@ av_cold void ff_aac_sbr_init(void) 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) { float mdct_scale; - sbr->kx[0] = sbr->kx[1] = 32; //Typo in spec, kx' inits to 32 - sbr->data[0].e_a[1] = sbr->data[1].e_a[1] = -1; + sbr->kx[0] = sbr->kx[1]; + 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. @@ -994,18 +1005,18 @@ static unsigned int read_sbr_data(AACContext *ac, SpectralBandReplication *sbr, if (id_aac == TYPE_SCE || id_aac == TYPE_CCE) { if (read_sbr_single_channel_element(ac, sbr, gb)) { - sbr->start = 0; + sbr_turnoff(sbr); return get_bits_count(gb) - cnt; } } else if (id_aac == TYPE_CPE) { if (read_sbr_channel_pair_element(ac, sbr, gb)) { - sbr->start = 0; + sbr_turnoff(sbr); return get_bits_count(gb) - cnt; } } else { av_log(ac->avctx, AV_LOG_ERROR, "Invalid bitstream - cannot apply SBR to element type %d\n", id_aac); - sbr->start = 0; + sbr_turnoff(sbr); return get_bits_count(gb) - cnt; } if (get_bits1(gb)) { // bs_extended_data @@ -1037,7 +1048,7 @@ static void sbr_reset(AACContext *ac, SpectralBandReplication *sbr) if (err < 0) { av_log(ac->avctx, AV_LOG_ERROR, "SBR reset failed. Switching SBR to pure upsampling mode.\n"); - sbr->start = 0; + sbr_turnoff(sbr); } } @@ -1072,6 +1083,7 @@ int ff_decode_sbr_extension(AACContext *ac, SpectralBandReplication *sbr, //Save some state from the previous frame. sbr->kx[0] = sbr->kx[1]; sbr->m[0] = sbr->m[1]; + sbr->kx_and_m_pushed = 1; num_sbr_bits++; if (get_bits1(gb)) // bs_header_flag @@ -1633,6 +1645,13 @@ void ff_sbr_apply(AACContext *ac, SpectralBandReplication *sbr, int id_aac, int ch; int nch = (id_aac == TYPE_CPE) ? 2 : 1; + 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) { sbr_dequant(sbr, id_aac); } @@ -1642,6 +1661,7 @@ void ff_sbr_apply(AACContext *ac, SpectralBandReplication *sbr, int id_aac, (float*)sbr->qmf_filter_scratch, sbr->data[ch].W); sbr_lf_gen(ac, sbr, sbr->X_low, sbr->data[ch].W); + sbr->data[ch].Ypos ^= 1; if (sbr->start) { sbr_hf_inverse_filter(&sbr->dsp, sbr->alpha0, sbr->alpha1, sbr->X_low, sbr->k[0]); sbr_chirp(sbr, &sbr->data[ch]); @@ -1653,7 +1673,6 @@ void ff_sbr_apply(AACContext *ac, SpectralBandReplication *sbr, int id_aac, 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]); sbr_gain_calc(ac, sbr, &sbr->data[ch], sbr->data[ch].e_a); - sbr->data[ch].Ypos ^= 1; sbr_hf_assemble(sbr->data[ch].Y[sbr->data[ch].Ypos], sbr->X_high, sbr, &sbr->data[ch], sbr->data[ch].e_a); diff --git a/libavcodec/sbr.h b/libavcodec/sbr.h index 8da8e570f3..459ee9c436 100644 --- a/libavcodec/sbr.h +++ b/libavcodec/sbr.h @@ -133,6 +133,7 @@ typedef struct { unsigned kx[2]; ///M' and M respectively, M is the number of QMF subbands that use SBR. unsigned m[2]; + unsigned kx_and_m_pushed; ///The number of frequency bands in f_master unsigned n_master; SBRData data[2]; From b00307ecd04f80d8021c50f9fa76fd452e54a3d1 Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Wed, 21 Mar 2012 12:20:58 -0700 Subject: [PATCH 5/6] aacsbr: Add a debug check to sbr_mapping. There have been multiple bugs caused by inconsistencies here. Based on an idea from Michael Niedermayer. CC: libav-stable@libav.org --- libavcodec/aacsbr.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/libavcodec/aacsbr.c b/libavcodec/aacsbr.c index f39806e30f..c71cfa00e1 100644 --- a/libavcodec/aacsbr.c +++ b/libavcodec/aacsbr.c @@ -1399,7 +1399,7 @@ static int sbr_x_gen(SpectralBandReplication *sbr, float X[2][38][64], /** High Frequency Adjustment (14496-3 sp04 p217) and Mapping * (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]) { int e, i, m; @@ -1410,6 +1410,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; int k; + 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 (m = table[i]; m < table[i + 1]; m++) sbr->e_origmapped[e][m - sbr->kx[1]] = ch_data->env_facs[e+1][i]; @@ -1444,6 +1450,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])); + return 0; } /// Estimation of current envelope (14496-3 sp04 p218) @@ -1644,6 +1651,7 @@ void ff_sbr_apply(AACContext *ac, SpectralBandReplication *sbr, int id_aac, int downsampled = ac->m4ac.ext_sample_rate < sbr->sample_rate; int ch; int nch = (id_aac == TYPE_CPE) ? 2 : 1; + int err; if (!sbr->kx_and_m_pushed) { sbr->kx[0] = sbr->kx[1]; @@ -1670,12 +1678,14 @@ void ff_sbr_apply(AACContext *ac, SpectralBandReplication *sbr, int id_aac, sbr->data[ch].bs_num_env); // hf_adj - 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]); - 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->X_high, sbr, &sbr->data[ch], - sbr->data[ch].e_a); + err = sbr_mapping(ac, sbr, &sbr->data[ch], sbr->data[ch].e_a); + if (!err) { + sbr_env_estimate(sbr->e_curr, sbr->X_high, sbr, &sbr->data[ch]); + 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->X_high, sbr, &sbr->data[ch], + sbr->data[ch].e_a); + } } /* synthesis */ From cb7190cd2c691fd93e4d3664f3fce6c19ee001dd Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Fri, 23 Mar 2012 22:30:38 +0100 Subject: [PATCH 6/6] rv34: error out on size changes with frame threading --- libavcodec/rv34.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libavcodec/rv34.c b/libavcodec/rv34.c index f9ea40d6c8..da5d437b07 100644 --- a/libavcodec/rv34.c +++ b/libavcodec/rv34.c @@ -1662,6 +1662,13 @@ int ff_rv34_decode_frame(AVCodecContext *avctx, if (s->width != si.width || s->height != si.height) { 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", si.width, si.height); ff_MPV_common_end(s);