1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * AAC encoder quantizer 3cabdff1aSopenharmony_ci * Copyright (C) 2015 Rostislav Pehlivanov 4cabdff1aSopenharmony_ci * 5cabdff1aSopenharmony_ci * This file is part of FFmpeg. 6cabdff1aSopenharmony_ci * 7cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 8cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 9cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 10cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 11cabdff1aSopenharmony_ci * 12cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 13cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 14cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15cabdff1aSopenharmony_ci * Lesser General Public License for more details. 16cabdff1aSopenharmony_ci * 17cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 18cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 19cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20cabdff1aSopenharmony_ci */ 21cabdff1aSopenharmony_ci 22cabdff1aSopenharmony_ci/** 23cabdff1aSopenharmony_ci * @file 24cabdff1aSopenharmony_ci * AAC encoder quantizer 25cabdff1aSopenharmony_ci * @author Rostislav Pehlivanov ( atomnuker gmail com ) 26cabdff1aSopenharmony_ci */ 27cabdff1aSopenharmony_ci 28cabdff1aSopenharmony_ci#ifndef AVCODEC_AACENC_QUANTIZATION_H 29cabdff1aSopenharmony_ci#define AVCODEC_AACENC_QUANTIZATION_H 30cabdff1aSopenharmony_ci 31cabdff1aSopenharmony_ci#include "aactab.h" 32cabdff1aSopenharmony_ci#include "aacenc.h" 33cabdff1aSopenharmony_ci#include "aacenctab.h" 34cabdff1aSopenharmony_ci#include "aacenc_utils.h" 35cabdff1aSopenharmony_ci 36cabdff1aSopenharmony_ci/** 37cabdff1aSopenharmony_ci * Calculate rate distortion cost for quantizing with given codebook 38cabdff1aSopenharmony_ci * 39cabdff1aSopenharmony_ci * @return quantization distortion 40cabdff1aSopenharmony_ci */ 41cabdff1aSopenharmony_cistatic av_always_inline float quantize_and_encode_band_cost_template( 42cabdff1aSopenharmony_ci struct AACEncContext *s, 43cabdff1aSopenharmony_ci PutBitContext *pb, const float *in, float *out, 44cabdff1aSopenharmony_ci const float *scaled, int size, int scale_idx, 45cabdff1aSopenharmony_ci int cb, const float lambda, const float uplim, 46cabdff1aSopenharmony_ci int *bits, float *energy, int BT_ZERO, int BT_UNSIGNED, 47cabdff1aSopenharmony_ci int BT_PAIR, int BT_ESC, int BT_NOISE, int BT_STEREO, 48cabdff1aSopenharmony_ci const float ROUNDING) 49cabdff1aSopenharmony_ci{ 50cabdff1aSopenharmony_ci const int q_idx = POW_SF2_ZERO - scale_idx + SCALE_ONE_POS - SCALE_DIV_512; 51cabdff1aSopenharmony_ci const float Q = ff_aac_pow2sf_tab [q_idx]; 52cabdff1aSopenharmony_ci const float Q34 = ff_aac_pow34sf_tab[q_idx]; 53cabdff1aSopenharmony_ci const float IQ = ff_aac_pow2sf_tab [POW_SF2_ZERO + scale_idx - SCALE_ONE_POS + SCALE_DIV_512]; 54cabdff1aSopenharmony_ci const float CLIPPED_ESCAPE = 165140.0f*IQ; 55cabdff1aSopenharmony_ci int i, j; 56cabdff1aSopenharmony_ci float cost = 0; 57cabdff1aSopenharmony_ci float qenergy = 0; 58cabdff1aSopenharmony_ci const int dim = BT_PAIR ? 2 : 4; 59cabdff1aSopenharmony_ci int resbits = 0; 60cabdff1aSopenharmony_ci int off; 61cabdff1aSopenharmony_ci 62cabdff1aSopenharmony_ci if (BT_ZERO || BT_NOISE || BT_STEREO) { 63cabdff1aSopenharmony_ci for (i = 0; i < size; i++) 64cabdff1aSopenharmony_ci cost += in[i]*in[i]; 65cabdff1aSopenharmony_ci if (bits) 66cabdff1aSopenharmony_ci *bits = 0; 67cabdff1aSopenharmony_ci if (energy) 68cabdff1aSopenharmony_ci *energy = qenergy; 69cabdff1aSopenharmony_ci if (out) { 70cabdff1aSopenharmony_ci for (i = 0; i < size; i += dim) 71cabdff1aSopenharmony_ci for (j = 0; j < dim; j++) 72cabdff1aSopenharmony_ci out[i+j] = 0.0f; 73cabdff1aSopenharmony_ci } 74cabdff1aSopenharmony_ci return cost * lambda; 75cabdff1aSopenharmony_ci } 76cabdff1aSopenharmony_ci if (!scaled) { 77cabdff1aSopenharmony_ci s->abs_pow34(s->scoefs, in, size); 78cabdff1aSopenharmony_ci scaled = s->scoefs; 79cabdff1aSopenharmony_ci } 80cabdff1aSopenharmony_ci s->quant_bands(s->qcoefs, in, scaled, size, !BT_UNSIGNED, aac_cb_maxval[cb], Q34, ROUNDING); 81cabdff1aSopenharmony_ci if (BT_UNSIGNED) { 82cabdff1aSopenharmony_ci off = 0; 83cabdff1aSopenharmony_ci } else { 84cabdff1aSopenharmony_ci off = aac_cb_maxval[cb]; 85cabdff1aSopenharmony_ci } 86cabdff1aSopenharmony_ci for (i = 0; i < size; i += dim) { 87cabdff1aSopenharmony_ci const float *vec; 88cabdff1aSopenharmony_ci int *quants = s->qcoefs + i; 89cabdff1aSopenharmony_ci int curidx = 0; 90cabdff1aSopenharmony_ci int curbits; 91cabdff1aSopenharmony_ci float quantized, rd = 0.0f; 92cabdff1aSopenharmony_ci for (j = 0; j < dim; j++) { 93cabdff1aSopenharmony_ci curidx *= aac_cb_range[cb]; 94cabdff1aSopenharmony_ci curidx += quants[j] + off; 95cabdff1aSopenharmony_ci } 96cabdff1aSopenharmony_ci curbits = ff_aac_spectral_bits[cb-1][curidx]; 97cabdff1aSopenharmony_ci vec = &ff_aac_codebook_vectors[cb-1][curidx*dim]; 98cabdff1aSopenharmony_ci if (BT_UNSIGNED) { 99cabdff1aSopenharmony_ci for (j = 0; j < dim; j++) { 100cabdff1aSopenharmony_ci float t = fabsf(in[i+j]); 101cabdff1aSopenharmony_ci float di; 102cabdff1aSopenharmony_ci if (BT_ESC && vec[j] == 64.0f) { //FIXME: slow 103cabdff1aSopenharmony_ci if (t >= CLIPPED_ESCAPE) { 104cabdff1aSopenharmony_ci quantized = CLIPPED_ESCAPE; 105cabdff1aSopenharmony_ci curbits += 21; 106cabdff1aSopenharmony_ci } else { 107cabdff1aSopenharmony_ci int c = av_clip_uintp2(quant(t, Q, ROUNDING), 13); 108cabdff1aSopenharmony_ci quantized = c*cbrtf(c)*IQ; 109cabdff1aSopenharmony_ci curbits += av_log2(c)*2 - 4 + 1; 110cabdff1aSopenharmony_ci } 111cabdff1aSopenharmony_ci } else { 112cabdff1aSopenharmony_ci quantized = vec[j]*IQ; 113cabdff1aSopenharmony_ci } 114cabdff1aSopenharmony_ci di = t - quantized; 115cabdff1aSopenharmony_ci if (out) 116cabdff1aSopenharmony_ci out[i+j] = in[i+j] >= 0 ? quantized : -quantized; 117cabdff1aSopenharmony_ci if (vec[j] != 0.0f) 118cabdff1aSopenharmony_ci curbits++; 119cabdff1aSopenharmony_ci qenergy += quantized*quantized; 120cabdff1aSopenharmony_ci rd += di*di; 121cabdff1aSopenharmony_ci } 122cabdff1aSopenharmony_ci } else { 123cabdff1aSopenharmony_ci for (j = 0; j < dim; j++) { 124cabdff1aSopenharmony_ci quantized = vec[j]*IQ; 125cabdff1aSopenharmony_ci qenergy += quantized*quantized; 126cabdff1aSopenharmony_ci if (out) 127cabdff1aSopenharmony_ci out[i+j] = quantized; 128cabdff1aSopenharmony_ci rd += (in[i+j] - quantized)*(in[i+j] - quantized); 129cabdff1aSopenharmony_ci } 130cabdff1aSopenharmony_ci } 131cabdff1aSopenharmony_ci cost += rd * lambda + curbits; 132cabdff1aSopenharmony_ci resbits += curbits; 133cabdff1aSopenharmony_ci if (cost >= uplim) 134cabdff1aSopenharmony_ci return uplim; 135cabdff1aSopenharmony_ci if (pb) { 136cabdff1aSopenharmony_ci put_bits(pb, ff_aac_spectral_bits[cb-1][curidx], ff_aac_spectral_codes[cb-1][curidx]); 137cabdff1aSopenharmony_ci if (BT_UNSIGNED) 138cabdff1aSopenharmony_ci for (j = 0; j < dim; j++) 139cabdff1aSopenharmony_ci if (ff_aac_codebook_vectors[cb-1][curidx*dim+j] != 0.0f) 140cabdff1aSopenharmony_ci put_bits(pb, 1, in[i+j] < 0.0f); 141cabdff1aSopenharmony_ci if (BT_ESC) { 142cabdff1aSopenharmony_ci for (j = 0; j < 2; j++) { 143cabdff1aSopenharmony_ci if (ff_aac_codebook_vectors[cb-1][curidx*2+j] == 64.0f) { 144cabdff1aSopenharmony_ci int coef = av_clip_uintp2(quant(fabsf(in[i+j]), Q, ROUNDING), 13); 145cabdff1aSopenharmony_ci int len = av_log2(coef); 146cabdff1aSopenharmony_ci 147cabdff1aSopenharmony_ci put_bits(pb, len - 4 + 1, (1 << (len - 4 + 1)) - 2); 148cabdff1aSopenharmony_ci put_sbits(pb, len, coef); 149cabdff1aSopenharmony_ci } 150cabdff1aSopenharmony_ci } 151cabdff1aSopenharmony_ci } 152cabdff1aSopenharmony_ci } 153cabdff1aSopenharmony_ci } 154cabdff1aSopenharmony_ci 155cabdff1aSopenharmony_ci if (bits) 156cabdff1aSopenharmony_ci *bits = resbits; 157cabdff1aSopenharmony_ci if (energy) 158cabdff1aSopenharmony_ci *energy = qenergy; 159cabdff1aSopenharmony_ci return cost; 160cabdff1aSopenharmony_ci} 161cabdff1aSopenharmony_ci 162cabdff1aSopenharmony_cistatic inline float quantize_and_encode_band_cost_NONE(struct AACEncContext *s, PutBitContext *pb, 163cabdff1aSopenharmony_ci const float *in, float *quant, const float *scaled, 164cabdff1aSopenharmony_ci int size, int scale_idx, int cb, 165cabdff1aSopenharmony_ci const float lambda, const float uplim, 166cabdff1aSopenharmony_ci int *bits, float *energy) { 167cabdff1aSopenharmony_ci av_assert0(0); 168cabdff1aSopenharmony_ci return 0.0f; 169cabdff1aSopenharmony_ci} 170cabdff1aSopenharmony_ci 171cabdff1aSopenharmony_ci#define QUANTIZE_AND_ENCODE_BAND_COST_FUNC(NAME, BT_ZERO, BT_UNSIGNED, BT_PAIR, BT_ESC, BT_NOISE, BT_STEREO, ROUNDING) \ 172cabdff1aSopenharmony_cistatic float quantize_and_encode_band_cost_ ## NAME( \ 173cabdff1aSopenharmony_ci struct AACEncContext *s, \ 174cabdff1aSopenharmony_ci PutBitContext *pb, const float *in, float *quant, \ 175cabdff1aSopenharmony_ci const float *scaled, int size, int scale_idx, \ 176cabdff1aSopenharmony_ci int cb, const float lambda, const float uplim, \ 177cabdff1aSopenharmony_ci int *bits, float *energy) { \ 178cabdff1aSopenharmony_ci return quantize_and_encode_band_cost_template( \ 179cabdff1aSopenharmony_ci s, pb, in, quant, scaled, size, scale_idx, \ 180cabdff1aSopenharmony_ci BT_ESC ? ESC_BT : cb, lambda, uplim, bits, energy, \ 181cabdff1aSopenharmony_ci BT_ZERO, BT_UNSIGNED, BT_PAIR, BT_ESC, BT_NOISE, BT_STEREO, \ 182cabdff1aSopenharmony_ci ROUNDING); \ 183cabdff1aSopenharmony_ci} 184cabdff1aSopenharmony_ci 185cabdff1aSopenharmony_ciQUANTIZE_AND_ENCODE_BAND_COST_FUNC(ZERO, 1, 0, 0, 0, 0, 0, ROUND_STANDARD) 186cabdff1aSopenharmony_ciQUANTIZE_AND_ENCODE_BAND_COST_FUNC(SQUAD, 0, 0, 0, 0, 0, 0, ROUND_STANDARD) 187cabdff1aSopenharmony_ciQUANTIZE_AND_ENCODE_BAND_COST_FUNC(UQUAD, 0, 1, 0, 0, 0, 0, ROUND_STANDARD) 188cabdff1aSopenharmony_ciQUANTIZE_AND_ENCODE_BAND_COST_FUNC(SPAIR, 0, 0, 1, 0, 0, 0, ROUND_STANDARD) 189cabdff1aSopenharmony_ciQUANTIZE_AND_ENCODE_BAND_COST_FUNC(UPAIR, 0, 1, 1, 0, 0, 0, ROUND_STANDARD) 190cabdff1aSopenharmony_ciQUANTIZE_AND_ENCODE_BAND_COST_FUNC(ESC, 0, 1, 1, 1, 0, 0, ROUND_STANDARD) 191cabdff1aSopenharmony_ciQUANTIZE_AND_ENCODE_BAND_COST_FUNC(ESC_RTZ, 0, 1, 1, 1, 0, 0, ROUND_TO_ZERO) 192cabdff1aSopenharmony_ciQUANTIZE_AND_ENCODE_BAND_COST_FUNC(NOISE, 0, 0, 0, 0, 1, 0, ROUND_STANDARD) 193cabdff1aSopenharmony_ciQUANTIZE_AND_ENCODE_BAND_COST_FUNC(STEREO,0, 0, 0, 0, 0, 1, ROUND_STANDARD) 194cabdff1aSopenharmony_ci 195cabdff1aSopenharmony_cistatic float (*const quantize_and_encode_band_cost_arr[])( 196cabdff1aSopenharmony_ci struct AACEncContext *s, 197cabdff1aSopenharmony_ci PutBitContext *pb, const float *in, float *quant, 198cabdff1aSopenharmony_ci const float *scaled, int size, int scale_idx, 199cabdff1aSopenharmony_ci int cb, const float lambda, const float uplim, 200cabdff1aSopenharmony_ci int *bits, float *energy) = { 201cabdff1aSopenharmony_ci quantize_and_encode_band_cost_ZERO, 202cabdff1aSopenharmony_ci quantize_and_encode_band_cost_SQUAD, 203cabdff1aSopenharmony_ci quantize_and_encode_band_cost_SQUAD, 204cabdff1aSopenharmony_ci quantize_and_encode_band_cost_UQUAD, 205cabdff1aSopenharmony_ci quantize_and_encode_band_cost_UQUAD, 206cabdff1aSopenharmony_ci quantize_and_encode_band_cost_SPAIR, 207cabdff1aSopenharmony_ci quantize_and_encode_band_cost_SPAIR, 208cabdff1aSopenharmony_ci quantize_and_encode_band_cost_UPAIR, 209cabdff1aSopenharmony_ci quantize_and_encode_band_cost_UPAIR, 210cabdff1aSopenharmony_ci quantize_and_encode_band_cost_UPAIR, 211cabdff1aSopenharmony_ci quantize_and_encode_band_cost_UPAIR, 212cabdff1aSopenharmony_ci quantize_and_encode_band_cost_ESC, 213cabdff1aSopenharmony_ci quantize_and_encode_band_cost_NONE, /* CB 12 doesn't exist */ 214cabdff1aSopenharmony_ci quantize_and_encode_band_cost_NOISE, 215cabdff1aSopenharmony_ci quantize_and_encode_band_cost_STEREO, 216cabdff1aSopenharmony_ci quantize_and_encode_band_cost_STEREO, 217cabdff1aSopenharmony_ci}; 218cabdff1aSopenharmony_ci 219cabdff1aSopenharmony_cistatic float (*const quantize_and_encode_band_cost_rtz_arr[])( 220cabdff1aSopenharmony_ci struct AACEncContext *s, 221cabdff1aSopenharmony_ci PutBitContext *pb, const float *in, float *quant, 222cabdff1aSopenharmony_ci const float *scaled, int size, int scale_idx, 223cabdff1aSopenharmony_ci int cb, const float lambda, const float uplim, 224cabdff1aSopenharmony_ci int *bits, float *energy) = { 225cabdff1aSopenharmony_ci quantize_and_encode_band_cost_ZERO, 226cabdff1aSopenharmony_ci quantize_and_encode_band_cost_SQUAD, 227cabdff1aSopenharmony_ci quantize_and_encode_band_cost_SQUAD, 228cabdff1aSopenharmony_ci quantize_and_encode_band_cost_UQUAD, 229cabdff1aSopenharmony_ci quantize_and_encode_band_cost_UQUAD, 230cabdff1aSopenharmony_ci quantize_and_encode_band_cost_SPAIR, 231cabdff1aSopenharmony_ci quantize_and_encode_band_cost_SPAIR, 232cabdff1aSopenharmony_ci quantize_and_encode_band_cost_UPAIR, 233cabdff1aSopenharmony_ci quantize_and_encode_band_cost_UPAIR, 234cabdff1aSopenharmony_ci quantize_and_encode_band_cost_UPAIR, 235cabdff1aSopenharmony_ci quantize_and_encode_band_cost_UPAIR, 236cabdff1aSopenharmony_ci quantize_and_encode_band_cost_ESC_RTZ, 237cabdff1aSopenharmony_ci quantize_and_encode_band_cost_NONE, /* CB 12 doesn't exist */ 238cabdff1aSopenharmony_ci quantize_and_encode_band_cost_NOISE, 239cabdff1aSopenharmony_ci quantize_and_encode_band_cost_STEREO, 240cabdff1aSopenharmony_ci quantize_and_encode_band_cost_STEREO, 241cabdff1aSopenharmony_ci}; 242cabdff1aSopenharmony_ci 243cabdff1aSopenharmony_ci#define quantize_and_encode_band_cost( \ 244cabdff1aSopenharmony_ci s, pb, in, quant, scaled, size, scale_idx, cb, \ 245cabdff1aSopenharmony_ci lambda, uplim, bits, energy, rtz) \ 246cabdff1aSopenharmony_ci ((rtz) ? quantize_and_encode_band_cost_rtz_arr : quantize_and_encode_band_cost_arr)[cb]( \ 247cabdff1aSopenharmony_ci s, pb, in, quant, scaled, size, scale_idx, cb, \ 248cabdff1aSopenharmony_ci lambda, uplim, bits, energy) 249cabdff1aSopenharmony_ci 250cabdff1aSopenharmony_cistatic inline float quantize_band_cost(struct AACEncContext *s, const float *in, 251cabdff1aSopenharmony_ci const float *scaled, int size, int scale_idx, 252cabdff1aSopenharmony_ci int cb, const float lambda, const float uplim, 253cabdff1aSopenharmony_ci int *bits, float *energy, int rtz) 254cabdff1aSopenharmony_ci{ 255cabdff1aSopenharmony_ci return quantize_and_encode_band_cost(s, NULL, in, NULL, scaled, size, scale_idx, 256cabdff1aSopenharmony_ci cb, lambda, uplim, bits, energy, rtz); 257cabdff1aSopenharmony_ci} 258cabdff1aSopenharmony_ci 259cabdff1aSopenharmony_cistatic inline int quantize_band_cost_bits(struct AACEncContext *s, const float *in, 260cabdff1aSopenharmony_ci const float *scaled, int size, int scale_idx, 261cabdff1aSopenharmony_ci int cb, const float lambda, const float uplim, 262cabdff1aSopenharmony_ci int *bits, float *energy, int rtz) 263cabdff1aSopenharmony_ci{ 264cabdff1aSopenharmony_ci int auxbits; 265cabdff1aSopenharmony_ci quantize_and_encode_band_cost(s, NULL, in, NULL, scaled, size, scale_idx, 266cabdff1aSopenharmony_ci cb, 0.0f, uplim, &auxbits, energy, rtz); 267cabdff1aSopenharmony_ci if (bits) { 268cabdff1aSopenharmony_ci *bits = auxbits; 269cabdff1aSopenharmony_ci } 270cabdff1aSopenharmony_ci return auxbits; 271cabdff1aSopenharmony_ci} 272cabdff1aSopenharmony_ci 273cabdff1aSopenharmony_cistatic inline void quantize_and_encode_band(struct AACEncContext *s, PutBitContext *pb, 274cabdff1aSopenharmony_ci const float *in, float *out, int size, int scale_idx, 275cabdff1aSopenharmony_ci int cb, const float lambda, int rtz) 276cabdff1aSopenharmony_ci{ 277cabdff1aSopenharmony_ci quantize_and_encode_band_cost(s, pb, in, out, NULL, size, scale_idx, cb, lambda, 278cabdff1aSopenharmony_ci INFINITY, NULL, NULL, rtz); 279cabdff1aSopenharmony_ci} 280cabdff1aSopenharmony_ci 281cabdff1aSopenharmony_ci#include "aacenc_quantization_misc.h" 282cabdff1aSopenharmony_ci 283cabdff1aSopenharmony_ci#endif /* AVCODEC_AACENC_QUANTIZATION_H */ 284