tbits += bits; start += sce->ics.swb_sizes[g]; prev = sce->sf_idx[w*16+g]; } } if (tbits > destbits) { for (i = 0; i < 128; i++) if (sce->sf_idx[i] < 218 - qstep) sce->sf_idx[i] += qstep; } else { for (i = 0; i < 128; i++) if (sce->sf_idx[i] > 60 - qstep) sce->sf_idx[i] -= qstep; } qstep >>= 1; if (!qstep && tbits > destbits*1.02 && sce->sf_idx[0] < 217) qstep = 1; } while (qstep); fflag = 0; minscaler = av_clip(minscaler, 60, 255 - SCALE_MAX_DIFF); for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { for (g = 0; g < sce->ics.num_swb; g++) { int prevsc = sce->sf_idx[w*16+g]; if (dists[w*16+g] > uplims[w*16+g] && sce->sf_idx[w*16+g] > 60) { if (find_min_book(maxvals[w*16+g], sce->sf_idx[w*16+g]-1)) sce->sf_idx[w*16+g]--; else //Try to make sure there is some energy in every band sce->sf_idx[w*16+g]-=2; } sce->sf_idx[w*16+g] = av_clip(sce->sf_idx[w*16+g], minscaler, minscaler + SCALE_MAX_DIFF); sce->sf_idx[w*16+g] = FFMIN(sce->sf_idx[w*16+g], 219); if (sce->sf_idx[w*16+g] != prevsc) fflag = 1; sce->band_type[w*16+g] = find_min_book(maxvals[w*16+g], sce->sf_idx[w*16+g]); } } its++; } while (fflag && its < 10);} static void search_for_pns(AACEncContext *s, AVCodecContext *avctx, SingleChannelElement *sce){ FFPsyBand *band; int w, g, w2, i; int wlen = 1024 / sce->ics.num_windows; 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); const float spread_threshold = FFMIN(0.75f, NOISE_SPREAD_THRESHOLD*FFMAX(0.5f, lambda/100.f)); const float dist_bias = av_clipf(4.f * 120 / lambda, 0.25f, 4.0f); const float pns_transient_energy_r = FFMIN(0.7f, lambda / 140.f); int refbits = avctx->bit_rate * 1024.0 / avctx->sample_rate / ((avctx->flags & AV_CODEC_FLAG_QSCALE) ? 2.0f : avctx->channels) * (lambda / 120.f); /** 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 & AV_CODEC_FLAG_QSCALE) ? (refbits * rate_bandwidth_multiplier * avctx->sample_rate / 1024) : (avctx->bit_rate / avctx->channels); frame_bit_rate *= 1.15f; if (avctx->cutoff > 0) { bandwidth = avctx->cutoff; } else { bandwidth = FFMAX(3000, AAC_CUTOFF_FROM_BITRATE(frame_bit_rate, 1, avctx->sample_rate)); } 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++) { int noise_sfi; float dist1 = 0.0f, dist2 = 0.0f, noise_amp; float pns_energy = 0.0f, pns_tgt_energy, energy_ratio, dist_thresh; float sfb_energy = 0.0f, threshold = 0.0f, spread = 2.0f; float min_energy = -1.0f, max_energy = 0.0f; const int start = wstart+sce->ics.swb_offset[g]; const float freq = (start-wstart)*freq_mult; const float freq_boost = FFMAX(0.88f*freq/NOISE_LOW_LIMIT, 1.0f); if (freq < NOISE_LOW_LIMIT || (start-wstart) >= cutoff) { 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++) { band = &s->psy.ch[s->cur_channel].psy_bands[(w+w2)*16+g]; sfb_energy += band->energy; spread = FFMIN(spread, band->spread); threshold += band->threshold; if (!w2) { min_energy = max_energy = band->energy; } else { min_energy = FFMIN(min_energy, band->energy); max_energy = FFMAX(max_energy, band->energy); } } /* Ramps down at ~8000Hz and loosens the dist threshold */ dist_thresh = av_clipf(2.5f*NOISE_LOW_LIMIT/freq, 0.5f, 2.5f) * dist_bias; /* PNS is acceptable when all of these are true: * 1. high spread energy (noise-like band) * 2. near-threshold energy (high PE means the random nature of PNS content will be noticed) * 3. on short window groups, all windows have similar energy (variations in energy would be destroyed by PNS) * * 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] && !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]; band = &s->psy.ch[s->cur_channel].psy_bands[(w+w2)*16+g]; for (i = 0; i < sce->ics.swb_sizes[g]; i++) { s->random_state = lcg_random(s->random_state); PNS[i] = s->random_state; } band_energy = s->fdsp->scalarproduct_float(PNS, PNS, sce->ics.swb_sizes[g]); scale = noise_amp/sqrtf(band_energy); s->fdsp->vector_fmul_scalar(PNS, PNS, scale, sce->ics.swb_sizes[g]); pns_senergy = s->fdsp->scalarproduct_float(PNS, PNS, sce->ics.swb_sizes[g]); pns_energy += pns_senergy; s->abs_pow34(NOR34, &sce->coeffs[start_c], sce->ics.swb_sizes[g]); s->abs_pow34(PNS34, PNS, sce->ics.swb_sizes[g]); dist1 += quantize_band_cost(s, &sce->coeffs[start_c], NOR34, sce->ics.swb_sizes[g], sce->sf_idx[(w+w2)*16+g], sce->band_alt[(w+w2)*16+g], lambda/band->threshold, INFINITY, NULL, NULL, 0); /* Estimate rd on average as 5 bits for SF, 4 for the CB, plus spread energy * lambda/thr */ dist2 += band->energy/(band->spread*band->spread)*lambda*dist_thresh/band->threshold; } if (g && sce->band_type[w*16+g-1] == NOISE_BT) { dist2 += 5; } else { dist2 += 9; } energy_ratio = pns_tgt_energy/pns_energy; /* Compensates for quantization error */ sce->pns_ener[w*16+g] = energy_ratio*pns_tgt_energy; 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; } else { if (!sce->zeroes[w*16+g]) prev_sf = sce->sf_idx[w*16+g]; } } }} static void mark_pns(AACEncContext *s, AVCodecContext *avctx, SingleChannelElement *sce){ FFPsyBand *band; int w, g, w2; int wlen = 1024 / sce->ics.num_windows; int bandwidth, cutoff; const float lambda = s->lambda; const float freq_mult = avctx->sample_rate*0.5f/wlen; const float spread_threshold = FFMIN(0.75f, NOISE_SPREAD_THRESHOLD*FFMAX(0.5f, lambda/100.f)); const float pns_transient_energy_r = FFMIN(0.7f, lambda / 140.f); int refbits = avctx->bit_rate * 1024.0 / avctx->sample_rate / ((avctx->flags & AV_CODEC_FLAG_QSCALE) ? 2.0f : avctx->channels) * (lambda / 120.f); /** Keep this in sync with twoloop's cutoff selection */ float rate_bandwidth_multiplier = 1.5f; int frame_bit_rate = (avctx->flags & AV_CODEC_FLAG_QSCALE) ? (refbits * rate_bandwidth_multiplier * avctx->sample_rate / 1024) : (avctx->bit_rate / avctx->channels); frame_bit_rate *= 1.15f; if (avctx->cutoff > 0) { bandwidth = avctx->cutoff; } else { bandwidth = FFMAX(3000, AAC_CUTOFF_FROM_BITRATE(frame_bit_rate, 1, avctx->sample_rate)); } cutoff = bandwidth * 2 * wlen / avctx->sample_rate; memcpy(sce->band_alt, sce->band_type, sizeof(sce->band_type)); for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { for (g = 0; g < sce->ics.num_swb; g++) { float sfb_energy = 0.0f, threshold = 0.0f, spread = 2.0f; float min_energy = -1.0f, max_energy = 0.0f; const int start = sce->ics.swb_offset[g]; const float freq = start*freq_mult; const float freq_boost = FFMAX(0.88f*freq/NOISE_LOW_LIMIT, 1.0f); if (freq < NOISE_LOW_LIMIT || start >= cutoff) { sce->can_pns[w*16+g] = 0; continue; } for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) { band = &s->psy.ch[s->cur_channel].psy_bands[(w+w2)*16+g]; sfb_energy += band->energy; spread = FFMIN(spread, band->spread); threshold += band->threshold; if (!w2) { min_energy = max_energy = band->energy; } else { min_energy = FFMIN(min_energy, band->energy); max_energy = FFMAX(max_energy, band->energy); } } /* PNS is acceptable when all of these are true: * 1. high spread energy (noise-like band) * 2. near-threshold energy (high PE means the random nature of PNS content will be noticed) * 3. on short window groups, all windows have similar energy (variations in energy would be destroyed by PNS) */ sce->pns_ener[w*16+g] = sfb_energy; if (sfb_energy < threshold*sqrtf(1.5f/freq_boost) || spread < spread_threshold || min_energy < pns_transient_energy_r * max_energy) { sce->can_pns[w*16+g] = 0; } else { sce->can_pns[w*16+g] = 1; } } }} static void search_for_ms(AACEncContext *s, ChannelElement *cpe){ int start = 0, i, w, w2, g, sid_sf_boost, prev_mid, prev_side; uint8_t nextband0[128], nextband1[128]; float *M = s->scoefs + 128*0, *S = s->scoefs + 128*1; float *L34 = s->scoefs + 128*2, *R34 = s->scoefs + 128*3; float *M34 = s->scoefs + 128*4, *S34 = s->scoefs + 128*5; const float lambda = s->lambda; const float mslambda = FFMIN(1.0f, lambda / 120.f); SingleChannelElement *sce0 = &cpe->ch[0]; SingleChannelElement *sce1 = &cpe->ch[1]; if (!cpe->common_window) return; /** 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; if (!cpe->is_mask[w*16+g]) cpe->ms_mask[w*16+g] = 0; if (!sce0->zeroes[w*16+g] && !sce1->zeroes[w*16+g] && !cpe->is_mask[w*16+g]) { float Mmax = 0.0f, Smax = 0.0f; /* Must compute mid/side SF and book for the whole window group */ for (w2 = 0; w2 < sce0->ics.group_len[w]; w2++) { for (i = 0; i < sce0->ics.swb_sizes[g]; i++) { M[i] = (sce0->coeffs[start+(w+w2)*128+i] + sce1->coeffs[start+(w+w2)*128+i]) * 0.5; S[i] = M[i] - sce1->coeffs[start+(w+w2)*128+i]; } s->abs_pow34(M34, M, sce0->ics.swb_sizes[g]); s->abs_pow34(S34, S, sce0->ics.swb_sizes[g]); for (i = 0; i < sce0->ics.swb_sizes[g]; i++ ) { Mmax = FFMAX(Mmax, M34[i]); Smax = FFMAX(Smax, S34[i]); } } for (sid_sf_boost = 0; sid_sf_boost < 4; sid_sf_boost++) { float dist1 = 0.0f, dist2 = 0.0f; int B0 = 0, B1 = 0; int minidx; int mididx, sididx; int midcb, sidcb; minidx = FFMIN(sce0->sf_idx[w*16+g], sce1->sf_idx[w*16+g]); 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 (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); for (w2 = 0; w2 < sce0->ics.group_len[w]; w2++) { FFPsyBand *band0 = &s->psy.ch[s->cur_channel+0].psy_bands[(w+w2)*16+g]; FFPsyBand *band1 = &s->psy.ch[s->cur_channel+1].psy_bands[(w+w2)*16+g]; float minthr = FFMIN(band0->threshold, band1->threshold); int b1,b2,b3,b4; for (i = 0; i < sce0->ics.swb_sizes[g]; i++) { M[i] = (sce0->coeffs[start+(w+w2)*128+i] + sce1->coeffs[start+(w+w2)*128+i]) * 0.5; S[i] = M[i] - sce1->coeffs[start+(w+w2)*128+i]; } s->abs_pow34(L34, sce0->coeffs+start+(w+w2)*128, sce0->ics.swb_sizes[g]); s->abs_pow34(R34, sce1->coeffs+start+(w+w2)*128, sce0->ics.swb_sizes[g]); s->abs_pow34(M34, M, sce0->ics.swb_sizes[g]); s->abs_pow34(S34, S, sce0->ics.swb_sizes[g]); dist1 += quantize_band_cost(s, &sce0->coeffs[start + (w+w2)*128], L34, sce0->ics.swb_sizes[g], sce0->sf_idx[w*16+g], sce0->band_type[w*16+g], lambda / band0->threshold, INFINITY, &b1, NULL, 0); dist1 += quantize_band_cost(s, &sce1->coeffs[start + (w+w2)*128], R34, sce1->ics.swb_sizes[g], sce1->sf_idx[w*16+g], sce1->band_type[w*16+g], lambda / band1->threshold, INFINITY, &b2, NULL, 0); dist2 += quantize_band_cost(s, M, M34, sce0->ics.swb_sizes[g], mididx, midcb, lambda / minthr, INFINITY, &b3, NULL, 0); dist2 += quantize_band_cost(s, S, S34, sce1->ics.swb_sizes[g], sididx, sidcb, mslambda / (minthr * bmax), INFINITY, &b4, NULL, 0); B0 += b1+b2; B1 += b3+b4; dist1 -= b1+b2; dist2 -= b3+b4; } cpe->ms_mask[w*16+g] = dist2 <= dist1 && B1 < B0; if (cpe->ms_mask[w*16+g]) { if (sce0->band_type[w*16+g] != NOISE_BT && sce1->band_type[w*16+g] != NOISE_BT) { sce0->sf_idx[w*16+g] = mididx; sce1->sf_idx[w*16+g] = sididx; sce0->band_type[w*16+g] = midcb; sce1->band_type[w*16+g] = sidcb; } else if ((sce0->band_type[w*16+g] != NOISE_BT) ^ (sce1->band_type[w*16+g] != NOISE_BT)) { /* ms_mask unneeded, and it confuses some decoders */ cpe->ms_mask[w*16+g] = 0; } break; } else if (B1 > B0) { /* More boost won't fix this */ break; } } } 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]; } }} AACCoefficientsEncoder ff_aac_coders[AAC_CODER_NB] = { [AAC_CODER_ANMR] = { search_for_quantizers_anmr, encode_window_bands_info, quantize_and_encode_band, ff_aac_encode_tns_info, ff_aac_encode_ltp_info, ff_aac_encode_main_pred, ff_aac_adjust_common_pred, ff_aac_adjust_common_ltp, ff_aac_apply_main_pred, ff_aac_apply_tns, ff_aac_update_ltp, ff_aac_ltp_insert_new_frame, set_special_band_scalefactors, search_for_pns, mark_pns, ff_aac_search_for_tns, ff_aac_search_for_ltp, search_for_ms, ff_aac_search_for_is, ff_aac_search_for_pred, }, [AAC_CODER_TWOLOOP] = { search_for_quantizers_twoloop, codebook_trellis_rate, quantize_and_encode_band, ff_aac_encode_tns_info, ff_aac_encode_ltp_info, ff_aac_encode_main_pred, ff_aac_adjust_common_pred, ff_aac_adjust_common_ltp, ff_aac_apply_main_pred, ff_aac_apply_tns, ff_aac_update_ltp, ff_aac_ltp_insert_new_frame, set_special_band_scalefactors, search_for_pns, mark_pns, ff_aac_search_for_tns, ff_aac_search_for_ltp, search_for_ms, ff_aac_search_for_is, ff_aac_search_for_pred, }, [AAC_CODER_FAST] = { search_for_quantizers_fast, codebook_trellis_rate, quantize_and_encode_band, ff_aac_encode_tns_info, ff_aac_encode_ltp_info, ff_aac_encode_main_pred, ff_aac_adjust_common_pred, ff_aac_adjust_common_ltp, ff_aac_apply_main_pred, ff_aac_apply_tns, ff_aac_update_ltp, ff_aac_ltp_insert_new_frame, set_special_band_scalefactors, search_for_pns, mark_pns, ff_aac_search_for_tns, ff_aac_search_for_ltp, search_for_ms, ff_aac_search_for_is, ff_aac_search_for_pred, },};Lines 501–964 of 964. Previous lines
tbits += bits; start += sce->ics.swb_sizes[g]; prev = sce->sf_idx[w*16+g]; } } if (tbits > destbits) { for (i = 0; i < 128; i++) if (sce->sf_idx[i] < 218 - qstep) sce->sf_idx[i] += qstep; } else { for (i = 0; i < 128; i++) if (sce->sf_idx[i] > 60 - qstep) sce->sf_idx[i] -= qstep; } qstep >>= 1; if (!qstep && tbits > destbits*1.02 && sce->sf_idx[0] < 217) qstep = 1; } while (qstep); fflag = 0; minscaler = av_clip(minscaler, 60, 255 - SCALE_MAX_DIFF); for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { for (g = 0; g < sce->ics.num_swb; g++) { int prevsc = sce->sf_idx[w*16+g]; if (dists[w*16+g] > uplims[w*16+g] && sce->sf_idx[w*16+g] > 60) { if (find_min_book(maxvals[w*16+g], sce->sf_idx[w*16+g]-1)) sce->sf_idx[w*16+g]--; else //Try to make sure there is some energy in every band sce->sf_idx[w*16+g]-=2; } sce->sf_idx[w*16+g] = av_clip(sce->sf_idx[w*16+g], minscaler, minscaler + SCALE_MAX_DIFF); sce->sf_idx[w*16+g] = FFMIN(sce->sf_idx[w*16+g], 219); if (sce->sf_idx[w*16+g] != prevsc) fflag = 1; sce->band_type[w*16+g] = find_min_book(maxvals[w*16+g], sce->sf_idx[w*16+g]); } } its++; } while (fflag && its < 10); } static void search_for_pns(AACEncContext *s, AVCodecContext *avctx, SingleChannelElement *sce) { FFPsyBand *band; int w, g, w2, i; int wlen = 1024 / sce->ics.num_windows; 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); const float spread_threshold = FFMIN(0.75f, NOISE_SPREAD_THRESHOLD*FFMAX(0.5f, lambda/100.f)); const float dist_bias = av_clipf(4.f * 120 / lambda, 0.25f, 4.0f); const float pns_transient_energy_r = FFMIN(0.7f, lambda / 140.f); int refbits = avctx->bit_rate * 1024.0 / avctx->sample_rate / ((avctx->flags & AV_CODEC_FLAG_QSCALE) ? 2.0f : avctx->channels) * (lambda / 120.f); /** 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 & AV_CODEC_FLAG_QSCALE) ? (refbits * rate_bandwidth_multiplier * avctx->sample_rate / 1024) : (avctx->bit_rate / avctx->channels); frame_bit_rate *= 1.15f; if (avctx->cutoff > 0) { bandwidth = avctx->cutoff; } else { bandwidth = FFMAX(3000, AAC_CUTOFF_FROM_BITRATE(frame_bit_rate, 1, avctx->sample_rate)); } 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++) { int noise_sfi; float dist1 = 0.0f, dist2 = 0.0f, noise_amp; float pns_energy = 0.0f, pns_tgt_energy, energy_ratio, dist_thresh; float sfb_energy = 0.0f, threshold = 0.0f, spread = 2.0f; float min_energy = -1.0f, max_energy = 0.0f; const int start = wstart+sce->ics.swb_offset[g]; const float freq = (start-wstart)*freq_mult; const float freq_boost = FFMAX(0.88f*freq/NOISE_LOW_LIMIT, 1.0f); if (freq < NOISE_LOW_LIMIT || (start-wstart) >= cutoff) { 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++) { band = &s->psy.ch[s->cur_channel].psy_bands[(w+w2)*16+g]; sfb_energy += band->energy; spread = FFMIN(spread, band->spread); threshold += band->threshold; if (!w2) { min_energy = max_energy = band->energy; } else { min_energy = FFMIN(min_energy, band->energy); max_energy = FFMAX(max_energy, band->energy); } } /* Ramps down at ~8000Hz and loosens the dist threshold */ dist_thresh = av_clipf(2.5f*NOISE_LOW_LIMIT/freq, 0.5f, 2.5f) * dist_bias; /* PNS is acceptable when all of these are true: * 1. high spread energy (noise-like band) * 2. near-threshold energy (high PE means the random nature of PNS content will be noticed) * 3. on short window groups, all windows have similar energy (variations in energy would be destroyed by PNS) * * 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] && !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]; band = &s->psy.ch[s->cur_channel].psy_bands[(w+w2)*16+g]; for (i = 0; i < sce->ics.swb_sizes[g]; i++) { s->random_state = lcg_random(s->random_state); PNS[i] = s->random_state; } band_energy = s->fdsp->scalarproduct_float(PNS, PNS, sce->ics.swb_sizes[g]); scale = noise_amp/sqrtf(band_energy); s->fdsp->vector_fmul_scalar(PNS, PNS, scale, sce->ics.swb_sizes[g]); pns_senergy = s->fdsp->scalarproduct_float(PNS, PNS, sce->ics.swb_sizes[g]); pns_energy += pns_senergy; s->abs_pow34(NOR34, &sce->coeffs[start_c], sce->ics.swb_sizes[g]); s->abs_pow34(PNS34, PNS, sce->ics.swb_sizes[g]); dist1 += quantize_band_cost(s, &sce->coeffs[start_c], NOR34, sce->ics.swb_sizes[g], sce->sf_idx[(w+w2)*16+g], sce->band_alt[(w+w2)*16+g], lambda/band->threshold, INFINITY, NULL, NULL, 0); /* Estimate rd on average as 5 bits for SF, 4 for the CB, plus spread energy * lambda/thr */ dist2 += band->energy/(band->spread*band->spread)*lambda*dist_thresh/band->threshold; } if (g && sce->band_type[w*16+g-1] == NOISE_BT) { dist2 += 5; } else { dist2 += 9; } energy_ratio = pns_tgt_energy/pns_energy; /* Compensates for quantization error */ sce->pns_ener[w*16+g] = energy_ratio*pns_tgt_energy; 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; } else { if (!sce->zeroes[w*16+g]) prev_sf = sce->sf_idx[w*16+g]; } } } } static void mark_pns(AACEncContext *s, AVCodecContext *avctx, SingleChannelElement *sce) { FFPsyBand *band; int w, g, w2; int wlen = 1024 / sce->ics.num_windows; int bandwidth, cutoff; const float lambda = s->lambda; const float freq_mult = avctx->sample_rate*0.5f/wlen; const float spread_threshold = FFMIN(0.75f, NOISE_SPREAD_THRESHOLD*FFMAX(0.5f, lambda/100.f)); const float pns_transient_energy_r = FFMIN(0.7f, lambda / 140.f); int refbits = avctx->bit_rate * 1024.0 / avctx->sample_rate / ((avctx->flags & AV_CODEC_FLAG_QSCALE) ? 2.0f : avctx->channels) * (lambda / 120.f); /** Keep this in sync with twoloop's cutoff selection */ float rate_bandwidth_multiplier = 1.5f; int frame_bit_rate = (avctx->flags & AV_CODEC_FLAG_QSCALE) ? (refbits * rate_bandwidth_multiplier * avctx->sample_rate / 1024) : (avctx->bit_rate / avctx->channels); frame_bit_rate *= 1.15f; if (avctx->cutoff > 0) { bandwidth = avctx->cutoff; } else { bandwidth = FFMAX(3000, AAC_CUTOFF_FROM_BITRATE(frame_bit_rate, 1, avctx->sample_rate)); } cutoff = bandwidth * 2 * wlen / avctx->sample_rate; memcpy(sce->band_alt, sce->band_type, sizeof(sce->band_type)); for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { for (g = 0; g < sce->ics.num_swb; g++) { float sfb_energy = 0.0f, threshold = 0.0f, spread = 2.0f; float min_energy = -1.0f, max_energy = 0.0f; const int start = sce->ics.swb_offset[g]; const float freq = start*freq_mult; const float freq_boost = FFMAX(0.88f*freq/NOISE_LOW_LIMIT, 1.0f); if (freq < NOISE_LOW_LIMIT || start >= cutoff) { sce->can_pns[w*16+g] = 0; continue; } for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) { band = &s->psy.ch[s->cur_channel].psy_bands[(w+w2)*16+g]; sfb_energy += band->energy; spread = FFMIN(spread, band->spread); threshold += band->threshold; if (!w2) { min_energy = max_energy = band->energy; } else { min_energy = FFMIN(min_energy, band->energy); max_energy = FFMAX(max_energy, band->energy); } } /* PNS is acceptable when all of these are true: * 1. high spread energy (noise-like band) * 2. near-threshold energy (high PE means the random nature of PNS content will be noticed) * 3. on short window groups, all windows have similar energy (variations in energy would be destroyed by PNS) */ sce->pns_ener[w*16+g] = sfb_energy; if (sfb_energy < threshold*sqrtf(1.5f/freq_boost) || spread < spread_threshold || min_energy < pns_transient_energy_r * max_energy) { sce->can_pns[w*16+g] = 0; } else { sce->can_pns[w*16+g] = 1; } } } } static void search_for_ms(AACEncContext *s, ChannelElement *cpe) { int start = 0, i, w, w2, g, sid_sf_boost, prev_mid, prev_side; uint8_t nextband0[128], nextband1[128]; float *M = s->scoefs + 128*0, *S = s->scoefs + 128*1; float *L34 = s->scoefs + 128*2, *R34 = s->scoefs + 128*3; float *M34 = s->scoefs + 128*4, *S34 = s->scoefs + 128*5; const float lambda = s->lambda; const float mslambda = FFMIN(1.0f, lambda / 120.f); SingleChannelElement *sce0 = &cpe->ch[0]; SingleChannelElement *sce1 = &cpe->ch[1]; if (!cpe->common_window) return; /** 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; if (!cpe->is_mask[w*16+g]) cpe->ms_mask[w*16+g] = 0; if (!sce0->zeroes[w*16+g] && !sce1->zeroes[w*16+g] && !cpe->is_mask[w*16+g]) { float Mmax = 0.0f, Smax = 0.0f; /* Must compute mid/side SF and book for the whole window group */ for (w2 = 0; w2 < sce0->ics.group_len[w]; w2++) { for (i = 0; i < sce0->ics.swb_sizes[g]; i++) { M[i] = (sce0->coeffs[start+(w+w2)*128+i] + sce1->coeffs[start+(w+w2)*128+i]) * 0.5; S[i] = M[i] - sce1->coeffs[start+(w+w2)*128+i]; } s->abs_pow34(M34, M, sce0->ics.swb_sizes[g]); s->abs_pow34(S34, S, sce0->ics.swb_sizes[g]); for (i = 0; i < sce0->ics.swb_sizes[g]; i++ ) { Mmax = FFMAX(Mmax, M34[i]); Smax = FFMAX(Smax, S34[i]); } } for (sid_sf_boost = 0; sid_sf_boost < 4; sid_sf_boost++) { float dist1 = 0.0f, dist2 = 0.0f; int B0 = 0, B1 = 0; int minidx; int mididx, sididx; int midcb, sidcb; minidx = FFMIN(sce0->sf_idx[w*16+g], sce1->sf_idx[w*16+g]); 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 (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); for (w2 = 0; w2 < sce0->ics.group_len[w]; w2++) { FFPsyBand *band0 = &s->psy.ch[s->cur_channel+0].psy_bands[(w+w2)*16+g]; FFPsyBand *band1 = &s->psy.ch[s->cur_channel+1].psy_bands[(w+w2)*16+g]; float minthr = FFMIN(band0->threshold, band1->threshold); int b1,b2,b3,b4; for (i = 0; i < sce0->ics.swb_sizes[g]; i++) { M[i] = (sce0->coeffs[start+(w+w2)*128+i] + sce1->coeffs[start+(w+w2)*128+i]) * 0.5; S[i] = M[i] - sce1->coeffs[start+(w+w2)*128+i]; } s->abs_pow34(L34, sce0->coeffs+start+(w+w2)*128, sce0->ics.swb_sizes[g]); s->abs_pow34(R34, sce1->coeffs+start+(w+w2)*128, sce0->ics.swb_sizes[g]); s->abs_pow34(M34, M, sce0->ics.swb_sizes[g]); s->abs_pow34(S34, S, sce0->ics.swb_sizes[g]); dist1 += quantize_band_cost(s, &sce0->coeffs[start + (w+w2)*128], L34, sce0->ics.swb_sizes[g], sce0->sf_idx[w*16+g], sce0->band_type[w*16+g], lambda / band0->threshold, INFINITY, &b1, NULL, 0); dist1 += quantize_band_cost(s, &sce1->coeffs[start + (w+w2)*128], R34, sce1->ics.swb_sizes[g], sce1->sf_idx[w*16+g], sce1->band_type[w*16+g], lambda / band1->threshold, INFINITY, &b2, NULL, 0); dist2 += quantize_band_cost(s, M, M34, sce0->ics.swb_sizes[g], mididx, midcb, lambda / minthr, INFINITY, &b3, NULL, 0); dist2 += quantize_band_cost(s, S, S34, sce1->ics.swb_sizes[g], sididx, sidcb, mslambda / (minthr * bmax), INFINITY, &b4, NULL, 0); B0 += b1+b2; B1 += b3+b4; dist1 -= b1+b2; dist2 -= b3+b4; } cpe->ms_mask[w*16+g] = dist2 <= dist1 && B1 < B0; if (cpe->ms_mask[w*16+g]) { if (sce0->band_type[w*16+g] != NOISE_BT && sce1->band_type[w*16+g] != NOISE_BT) { sce0->sf_idx[w*16+g] = mididx; sce1->sf_idx[w*16+g] = sididx; sce0->band_type[w*16+g] = midcb; sce1->band_type[w*16+g] = sidcb; } else if ((sce0->band_type[w*16+g] != NOISE_BT) ^ (sce1->band_type[w*16+g] != NOISE_BT)) { /* ms_mask unneeded, and it confuses some decoders */ cpe->ms_mask[w*16+g] = 0; } break; } else if (B1 > B0) { /* More boost won't fix this */ break; } } } 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]; } } } AACCoefficientsEncoder ff_aac_coders[AAC_CODER_NB] = { [AAC_CODER_ANMR] = { search_for_quantizers_anmr, encode_window_bands_info, quantize_and_encode_band, ff_aac_encode_tns_info, ff_aac_encode_ltp_info, ff_aac_encode_main_pred, ff_aac_adjust_common_pred, ff_aac_adjust_common_ltp, ff_aac_apply_main_pred, ff_aac_apply_tns, ff_aac_update_ltp, ff_aac_ltp_insert_new_frame, set_special_band_scalefactors, search_for_pns, mark_pns, ff_aac_search_for_tns, ff_aac_search_for_ltp, search_for_ms, ff_aac_search_for_is, ff_aac_search_for_pred, }, [AAC_CODER_TWOLOOP] = { search_for_quantizers_twoloop, codebook_trellis_rate, quantize_and_encode_band, ff_aac_encode_tns_info, ff_aac_encode_ltp_info, ff_aac_encode_main_pred, ff_aac_adjust_common_pred, ff_aac_adjust_common_ltp, ff_aac_apply_main_pred, ff_aac_apply_tns, ff_aac_update_ltp, ff_aac_ltp_insert_new_frame, set_special_band_scalefactors, search_for_pns, mark_pns, ff_aac_search_for_tns, ff_aac_search_for_ltp, search_for_ms, ff_aac_search_for_is, ff_aac_search_for_pred, }, [AAC_CODER_FAST] = { search_for_quantizers_fast, codebook_trellis_rate, quantize_and_encode_band, ff_aac_encode_tns_info, ff_aac_encode_ltp_info, ff_aac_encode_main_pred, ff_aac_adjust_common_pred, ff_aac_adjust_common_ltp, ff_aac_apply_main_pred, ff_aac_apply_tns, ff_aac_update_ltp, ff_aac_ltp_insert_new_frame, set_special_band_scalefactors, search_for_pns, mark_pns, ff_aac_search_for_tns, ff_aac_search_for_ltp, search_for_ms, ff_aac_search_for_is, ff_aac_search_for_pred, }, };