diff options
Diffstat (limited to 'libavcodec/aaccoder.c')
-rw-r--r-- | libavcodec/aaccoder.c | 60 |
1 files changed, 41 insertions, 19 deletions
diff --git a/libavcodec/aaccoder.c b/libavcodec/aaccoder.c index 2a66045c8e..2a0cb1f6b5 100644 --- a/libavcodec/aaccoder.c +++ b/libavcodec/aaccoder.c @@ -54,7 +54,7 @@ /* Parameter of f(x) = a*(lambda/100), defines the maximum fourier spread * beyond which no PNS is used (since the SFBs contain tone rather than noise) */ -#define NOISE_SPREAD_THRESHOLD 0.5073f +#define NOISE_SPREAD_THRESHOLD 0.9f /* Parameter of f(x) = a*(100/lambda), defines how much PNS is allowed to * replace low energy non zero bands */ @@ -591,6 +591,7 @@ static void search_for_pns(AACEncContext *s, AVCodecContext *avctx, SingleChanne int bandwidth, cutoff; float *PNS = &s->scoefs[0*128], *PNS34 = &s->scoefs[1*128]; float *NOR34 = &s->scoefs[3*128]; + uint8_t nextband[128]; const float lambda = s->lambda; const float freq_mult = avctx->sample_rate*0.5f/wlen; const float thr_mult = NOISE_LAMBDA_REPLACE*(100.0f/lambda); @@ -604,6 +605,7 @@ static void search_for_pns(AACEncContext *s, AVCodecContext *avctx, SingleChanne /** Keep this in sync with twoloop's cutoff selection */ float rate_bandwidth_multiplier = 1.5f; + int prev = -1000, prev_sf = -1; int frame_bit_rate = (avctx->flags & CODEC_FLAG_QSCALE) ? (refbits * rate_bandwidth_multiplier * avctx->sample_rate / 1024) : (avctx->bit_rate / avctx->channels); @@ -619,6 +621,7 @@ static void search_for_pns(AACEncContext *s, AVCodecContext *avctx, SingleChanne cutoff = bandwidth * 2 * wlen / avctx->sample_rate; memcpy(sce->band_alt, sce->band_type, sizeof(sce->band_type)); + ff_init_nextband_map(sce, nextband); for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { int wstart = w*128; for (g = 0; g < sce->ics.num_swb; g++) { @@ -655,16 +658,27 @@ static void search_for_pns(AACEncContext *s, AVCodecContext *avctx, SingleChanne * * At this stage, point 2 is relaxed for zeroed bands near the noise threshold (hole avoidance is more important) */ - if (((sce->zeroes[w*16+g] || !sce->band_alt[w*16+g]) && sfb_energy < threshold*sqrtf(1.5f/freq_boost)) || spread < spread_threshold || + if ((!sce->zeroes[w*16+g] && !ff_sfdelta_can_remove_band(sce, nextband, prev_sf, w*16+g)) || + ((sce->zeroes[w*16+g] || !sce->band_alt[w*16+g]) && sfb_energy < threshold*sqrtf(1.0f/freq_boost)) || spread < spread_threshold || (!sce->zeroes[w*16+g] && sce->band_alt[w*16+g] && sfb_energy > threshold*thr_mult*freq_boost) || min_energy < pns_transient_energy_r * max_energy ) { sce->pns_ener[w*16+g] = sfb_energy; + if (!sce->zeroes[w*16+g]) + prev_sf = sce->sf_idx[w*16+g]; continue; } pns_tgt_energy = sfb_energy*FFMIN(1.0f, spread*spread); noise_sfi = av_clip(roundf(log2f(pns_tgt_energy)*2), -100, 155); /* Quantize */ noise_amp = -ff_aac_pow2sf_tab[noise_sfi + POW_SF2_ZERO]; /* Dequantize */ + if (prev != -1000) { + int noise_sfdiff = noise_sfi - prev + SCALE_DIFF_ZERO; + if (noise_sfdiff < 0 || noise_sfdiff > 2*SCALE_MAX_DIFF) { + if (!sce->zeroes[w*16+g]) + prev_sf = sce->sf_idx[w*16+g]; + continue; + } + } for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) { float band_energy, scale, pns_senergy; const int start_c = (w+w2)*128+sce->ics.swb_offset[g]; @@ -697,7 +711,10 @@ static void search_for_pns(AACEncContext *s, AVCodecContext *avctx, SingleChanne if (sce->zeroes[w*16+g] || !sce->band_alt[w*16+g] || (energy_ratio > 0.85f && energy_ratio < 1.25f && dist2 < dist1)) { sce->band_type[w*16+g] = NOISE_BT; sce->zeroes[w*16+g] = 0; + prev = noise_sfi; } + if (!sce->zeroes[w*16+g]) + prev_sf = sce->sf_idx[w*16+g]; } } } @@ -775,7 +792,8 @@ static void mark_pns(AACEncContext *s, AVCodecContext *avctx, SingleChannelEleme static void search_for_ms(AACEncContext *s, ChannelElement *cpe) { - int start = 0, i, w, w2, g, sid_sf_boost; + int start = 0, i, w, w2, g, sid_sf_boost, prev_mid, prev_side; + uint8_t nextband0[128], nextband1[128]; float M[128], S[128]; float *L34 = s->scoefs, *R34 = s->scoefs + 128, *M34 = s->scoefs + 128*2, *S34 = s->scoefs + 128*3; const float lambda = s->lambda; @@ -784,21 +802,19 @@ static void search_for_ms(AACEncContext *s, ChannelElement *cpe) SingleChannelElement *sce1 = &cpe->ch[1]; if (!cpe->common_window) return; - for (w = 0; w < sce0->ics.num_windows; w += sce0->ics.group_len[w]) { - int min_sf_idx_mid = SCALE_MAX_POS; - int min_sf_idx_side = SCALE_MAX_POS; - for (g = 0; g < sce0->ics.num_swb; g++) { - if (!sce0->zeroes[w*16+g] && sce0->band_type[w*16+g] < RESERVED_BT) - min_sf_idx_mid = FFMIN(min_sf_idx_mid, sce0->sf_idx[w*16+g]); - if (!sce1->zeroes[w*16+g] && sce1->band_type[w*16+g] < RESERVED_BT) - min_sf_idx_side = FFMIN(min_sf_idx_side, sce1->sf_idx[w*16+g]); - } + /** Scout out next nonzero bands */ + ff_init_nextband_map(sce0, nextband0); + ff_init_nextband_map(sce1, nextband1); + + prev_mid = sce0->sf_idx[0]; + prev_side = sce1->sf_idx[0]; + for (w = 0; w < sce0->ics.num_windows; w += sce0->ics.group_len[w]) { start = 0; for (g = 0; g < sce0->ics.num_swb; g++) { float bmax = bval2bmax(g * 17.0f / sce0->ics.num_swb) / 0.0045f; cpe->ms_mask[w*16+g] = 0; - if (!cpe->ch[0].zeroes[w*16+g] && !cpe->ch[1].zeroes[w*16+g]) { + if (!sce0->zeroes[w*16+g] && !sce1->zeroes[w*16+g]) { float Mmax = 0.0f, Smax = 0.0f; /* Must compute mid/side SF and book for the whole window group */ @@ -825,16 +841,18 @@ static void search_for_ms(AACEncContext *s, ChannelElement *cpe) int midcb, sidcb; minidx = FFMIN(sce0->sf_idx[w*16+g], sce1->sf_idx[w*16+g]); - mididx = av_clip(minidx, min_sf_idx_mid, min_sf_idx_mid + SCALE_MAX_DIFF); - sididx = av_clip(minidx - sid_sf_boost * 3, min_sf_idx_side, min_sf_idx_side + SCALE_MAX_DIFF); - midcb = find_min_book(Mmax, mididx); - sidcb = find_min_book(Smax, sididx); - - if ((mididx > minidx) || (sididx > minidx)) { + mididx = av_clip(minidx, 0, SCALE_MAX_POS - SCALE_DIV_512); + sididx = av_clip(minidx - sid_sf_boost * 3, 0, SCALE_MAX_POS - SCALE_DIV_512); + if (!cpe->is_mask[w*16+g] && sce0->band_type[w*16+g] != NOISE_BT && sce1->band_type[w*16+g] != NOISE_BT + && ( !ff_sfdelta_can_replace(sce0, nextband0, prev_mid, mididx, w*16+g) + || !ff_sfdelta_can_replace(sce1, nextband1, prev_side, sididx, w*16+g))) { /* scalefactor range violation, bad stuff, will decrease quality unacceptably */ continue; } + midcb = find_min_book(Mmax, mididx); + sidcb = find_min_book(Smax, sididx); + /* No CB can be zero */ midcb = FFMAX(1,midcb); sidcb = FFMAX(1,sidcb); @@ -900,6 +918,10 @@ static void search_for_ms(AACEncContext *s, ChannelElement *cpe) } } } + if (!sce0->zeroes[w*16+g] && sce0->band_type[w*16+g] < RESERVED_BT) + prev_mid = sce0->sf_idx[w*16+g]; + if (!sce1->zeroes[w*16+g] && !cpe->is_mask[w*16+g] && sce1->band_type[w*16+g] < RESERVED_BT) + prev_side = sce1->sf_idx[w*16+g]; start += sce0->ics.swb_sizes[g]; } } |