/* * AAC encoder twoloop coder * Copyright (C) 2008-2009 Konstantin Shishkov * * 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 encoder twoloop coder * @author Konstantin Shishkov */ /** * This file contains a template for the twoloop coder function. * It needs to be provided, externally, as an already included declaration, * the following functions from aacenc_quantization/util.h. They're not included * explicitly here to make it possible to provide alternative implementations: * - quantize_band_cost * - abs_pow34_v * - find_max_val * - find_min_book */ #ifndef AVCODEC_AACCODER_TWOLOOP_H #define AVCODEC_AACCODER_TWOLOOP_H #include #include "libavutil/mathematics.h" #include "avcodec.h" #include "put_bits.h" #include "aac.h" #include "aacenc.h" #include "aactab.h" #include "aacenctab.h" #include "aac_tablegen_decl.h" /** * two-loop quantizers search taken from ISO 13818-7 Appendix C */ static void search_for_quantizers_twoloop(AVCodecContext *avctx, AACEncContext *s, SingleChannelElement *sce, const float lambda) { int start = 0, i, w, w2, g; int destbits = avctx->bit_rate * 1024.0 / avctx->sample_rate / avctx->channels * (lambda / 120.f); float dists[128] = { 0 }, uplims[128] = { 0 }; float maxvals[128]; int fflag, minscaler; int its = 0; int allz = 0; float minthr = INFINITY; // for values above this the decoder might end up in an endless loop // due to always having more bits than what can be encoded. destbits = FFMIN(destbits, 5800); //XXX: some heuristic to determine initial quantizers will reduce search time //determine zero bands and upper limits for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { for (g = 0; g < sce->ics.num_swb; g++) { int nz = 0; float uplim = 0.0f, energy = 0.0f; for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) { FFPsyBand *band = &s->psy.ch[s->cur_channel].psy_bands[(w+w2)*16+g]; uplim += band->threshold; energy += band->energy; if (band->energy <= band->threshold || band->threshold == 0.0f) { sce->zeroes[(w+w2)*16+g] = 1; continue; } nz = 1; } uplims[w*16+g] = uplim *512; sce->zeroes[w*16+g] = !nz; if (nz) minthr = FFMIN(minthr, uplim); allz |= nz; } } for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { for (g = 0; g < sce->ics.num_swb; g++) { if (sce->zeroes[w*16+g]) { sce->sf_idx[w*16+g] = SCALE_ONE_POS; continue; } sce->sf_idx[w*16+g] = SCALE_ONE_POS + FFMIN(log2f(uplims[w*16+g]/minthr)*4,59); } } if (!allz) return; abs_pow34_v(s->scoefs, sce->coeffs, 1024); for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { start = w*128; for (g = 0; g < sce->ics.num_swb; g++) { const float *scaled = s->scoefs + start; maxvals[w*16+g] = find_max_val(sce->ics.group_len[w], sce->ics.swb_sizes[g], scaled); start += sce->ics.swb_sizes[g]; } } //perform two-loop search //outer loop - improve quality do { int tbits, qstep; minscaler = sce->sf_idx[0]; //inner loop - quantize spectrum to fit into given number of bits qstep = its ? 1 : 32; do { int prev = -1; tbits = 0; for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { start = w*128; for (g = 0; g < sce->ics.num_swb; g++) { const float *coefs = &sce->coeffs[start]; const float *scaled = &s->scoefs[start]; int bits = 0; int cb; float dist = 0.0f; if (sce->zeroes[w*16+g] || sce->sf_idx[w*16+g] >= 218) { start += sce->ics.swb_sizes[g]; continue; } minscaler = FFMIN(minscaler, sce->sf_idx[w*16+g]); cb = find_min_book(maxvals[w*16+g], sce->sf_idx[w*16+g]); for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) { int b; dist += quantize_band_cost(s, coefs + w2*128, scaled + w2*128, sce->ics.swb_sizes[g], sce->sf_idx[w*16+g], cb, 1.0f, INFINITY, &b, 0); bits += b; } dists[w*16+g] = dist - bits; if (prev != -1) { bits += ff_aac_scalefactor_bits[sce->sf_idx[w*16+g] - prev + SCALE_DIFF_ZERO]; } 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); } #endif /* AVCODEC_AACCODER_TWOLOOP_H */