1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * AAC encoder utilities 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 utilities 25cabdff1aSopenharmony_ci * @author Rostislav Pehlivanov ( atomnuker gmail com ) 26cabdff1aSopenharmony_ci */ 27cabdff1aSopenharmony_ci 28cabdff1aSopenharmony_ci#ifndef AVCODEC_AACENC_UTILS_H 29cabdff1aSopenharmony_ci#define AVCODEC_AACENC_UTILS_H 30cabdff1aSopenharmony_ci 31cabdff1aSopenharmony_ci#include "libavutil/ffmath.h" 32cabdff1aSopenharmony_ci#include "aac.h" 33cabdff1aSopenharmony_ci#include "aacenctab.h" 34cabdff1aSopenharmony_ci#include "aactab.h" 35cabdff1aSopenharmony_ci 36cabdff1aSopenharmony_ci#define ROUND_STANDARD 0.4054f 37cabdff1aSopenharmony_ci#define ROUND_TO_ZERO 0.1054f 38cabdff1aSopenharmony_ci#define C_QUANT 0.4054f 39cabdff1aSopenharmony_ci 40cabdff1aSopenharmony_cistatic inline void abs_pow34_v(float *out, const float *in, const int size) 41cabdff1aSopenharmony_ci{ 42cabdff1aSopenharmony_ci int i; 43cabdff1aSopenharmony_ci for (i = 0; i < size; i++) { 44cabdff1aSopenharmony_ci float a = fabsf(in[i]); 45cabdff1aSopenharmony_ci out[i] = sqrtf(a * sqrtf(a)); 46cabdff1aSopenharmony_ci } 47cabdff1aSopenharmony_ci} 48cabdff1aSopenharmony_ci 49cabdff1aSopenharmony_cistatic inline float pos_pow34(float a) 50cabdff1aSopenharmony_ci{ 51cabdff1aSopenharmony_ci return sqrtf(a * sqrtf(a)); 52cabdff1aSopenharmony_ci} 53cabdff1aSopenharmony_ci 54cabdff1aSopenharmony_ci/** 55cabdff1aSopenharmony_ci * Quantize one coefficient. 56cabdff1aSopenharmony_ci * @return absolute value of the quantized coefficient 57cabdff1aSopenharmony_ci * @see 3GPP TS26.403 5.6.2 "Scalefactor determination" 58cabdff1aSopenharmony_ci */ 59cabdff1aSopenharmony_cistatic inline int quant(float coef, const float Q, const float rounding) 60cabdff1aSopenharmony_ci{ 61cabdff1aSopenharmony_ci float a = coef * Q; 62cabdff1aSopenharmony_ci return sqrtf(a * sqrtf(a)) + rounding; 63cabdff1aSopenharmony_ci} 64cabdff1aSopenharmony_ci 65cabdff1aSopenharmony_cistatic inline void quantize_bands(int *out, const float *in, const float *scaled, 66cabdff1aSopenharmony_ci int size, int is_signed, int maxval, const float Q34, 67cabdff1aSopenharmony_ci const float rounding) 68cabdff1aSopenharmony_ci{ 69cabdff1aSopenharmony_ci int i; 70cabdff1aSopenharmony_ci for (i = 0; i < size; i++) { 71cabdff1aSopenharmony_ci float qc = scaled[i] * Q34; 72cabdff1aSopenharmony_ci int tmp = (int)FFMIN(qc + rounding, (float)maxval); 73cabdff1aSopenharmony_ci if (is_signed && in[i] < 0.0f) { 74cabdff1aSopenharmony_ci tmp = -tmp; 75cabdff1aSopenharmony_ci } 76cabdff1aSopenharmony_ci out[i] = tmp; 77cabdff1aSopenharmony_ci } 78cabdff1aSopenharmony_ci} 79cabdff1aSopenharmony_ci 80cabdff1aSopenharmony_cistatic inline float find_max_val(int group_len, int swb_size, const float *scaled) 81cabdff1aSopenharmony_ci{ 82cabdff1aSopenharmony_ci float maxval = 0.0f; 83cabdff1aSopenharmony_ci int w2, i; 84cabdff1aSopenharmony_ci for (w2 = 0; w2 < group_len; w2++) { 85cabdff1aSopenharmony_ci for (i = 0; i < swb_size; i++) { 86cabdff1aSopenharmony_ci maxval = FFMAX(maxval, scaled[w2*128+i]); 87cabdff1aSopenharmony_ci } 88cabdff1aSopenharmony_ci } 89cabdff1aSopenharmony_ci return maxval; 90cabdff1aSopenharmony_ci} 91cabdff1aSopenharmony_ci 92cabdff1aSopenharmony_cistatic inline int find_min_book(float maxval, int sf) 93cabdff1aSopenharmony_ci{ 94cabdff1aSopenharmony_ci float Q34 = ff_aac_pow34sf_tab[POW_SF2_ZERO - sf + SCALE_ONE_POS - SCALE_DIV_512]; 95cabdff1aSopenharmony_ci int qmaxval, cb; 96cabdff1aSopenharmony_ci qmaxval = maxval * Q34 + C_QUANT; 97cabdff1aSopenharmony_ci if (qmaxval >= (FF_ARRAY_ELEMS(aac_maxval_cb))) 98cabdff1aSopenharmony_ci cb = 11; 99cabdff1aSopenharmony_ci else 100cabdff1aSopenharmony_ci cb = aac_maxval_cb[qmaxval]; 101cabdff1aSopenharmony_ci return cb; 102cabdff1aSopenharmony_ci} 103cabdff1aSopenharmony_ci 104cabdff1aSopenharmony_cistatic inline float find_form_factor(int group_len, int swb_size, float thresh, 105cabdff1aSopenharmony_ci const float *scaled, float nzslope) { 106cabdff1aSopenharmony_ci const float iswb_size = 1.0f / swb_size; 107cabdff1aSopenharmony_ci const float iswb_sizem1 = 1.0f / (swb_size - 1); 108cabdff1aSopenharmony_ci const float ethresh = thresh; 109cabdff1aSopenharmony_ci float form = 0.0f, weight = 0.0f; 110cabdff1aSopenharmony_ci int w2, i; 111cabdff1aSopenharmony_ci for (w2 = 0; w2 < group_len; w2++) { 112cabdff1aSopenharmony_ci float e = 0.0f, e2 = 0.0f, var = 0.0f, maxval = 0.0f; 113cabdff1aSopenharmony_ci float nzl = 0; 114cabdff1aSopenharmony_ci for (i = 0; i < swb_size; i++) { 115cabdff1aSopenharmony_ci float s = fabsf(scaled[w2*128+i]); 116cabdff1aSopenharmony_ci maxval = FFMAX(maxval, s); 117cabdff1aSopenharmony_ci e += s; 118cabdff1aSopenharmony_ci e2 += s *= s; 119cabdff1aSopenharmony_ci /* We really don't want a hard non-zero-line count, since 120cabdff1aSopenharmony_ci * even below-threshold lines do add up towards band spectral power. 121cabdff1aSopenharmony_ci * So, fall steeply towards zero, but smoothly 122cabdff1aSopenharmony_ci */ 123cabdff1aSopenharmony_ci if (s >= ethresh) { 124cabdff1aSopenharmony_ci nzl += 1.0f; 125cabdff1aSopenharmony_ci } else { 126cabdff1aSopenharmony_ci if (nzslope == 2.f) 127cabdff1aSopenharmony_ci nzl += (s / ethresh) * (s / ethresh); 128cabdff1aSopenharmony_ci else 129cabdff1aSopenharmony_ci nzl += ff_fast_powf(s / ethresh, nzslope); 130cabdff1aSopenharmony_ci } 131cabdff1aSopenharmony_ci } 132cabdff1aSopenharmony_ci if (e2 > thresh) { 133cabdff1aSopenharmony_ci float frm; 134cabdff1aSopenharmony_ci e *= iswb_size; 135cabdff1aSopenharmony_ci 136cabdff1aSopenharmony_ci /** compute variance */ 137cabdff1aSopenharmony_ci for (i = 0; i < swb_size; i++) { 138cabdff1aSopenharmony_ci float d = fabsf(scaled[w2*128+i]) - e; 139cabdff1aSopenharmony_ci var += d*d; 140cabdff1aSopenharmony_ci } 141cabdff1aSopenharmony_ci var = sqrtf(var * iswb_sizem1); 142cabdff1aSopenharmony_ci 143cabdff1aSopenharmony_ci e2 *= iswb_size; 144cabdff1aSopenharmony_ci frm = e / FFMIN(e+4*var,maxval); 145cabdff1aSopenharmony_ci form += e2 * sqrtf(frm) / FFMAX(0.5f,nzl); 146cabdff1aSopenharmony_ci weight += e2; 147cabdff1aSopenharmony_ci } 148cabdff1aSopenharmony_ci } 149cabdff1aSopenharmony_ci if (weight > 0) { 150cabdff1aSopenharmony_ci return form / weight; 151cabdff1aSopenharmony_ci } else { 152cabdff1aSopenharmony_ci return 1.0f; 153cabdff1aSopenharmony_ci } 154cabdff1aSopenharmony_ci} 155cabdff1aSopenharmony_ci 156cabdff1aSopenharmony_ci/** Return the minimum scalefactor where the quantized coef does not clip. */ 157cabdff1aSopenharmony_cistatic inline uint8_t coef2minsf(float coef) 158cabdff1aSopenharmony_ci{ 159cabdff1aSopenharmony_ci return av_clip_uint8(log2f(coef)*4 - 69 + SCALE_ONE_POS - SCALE_DIV_512); 160cabdff1aSopenharmony_ci} 161cabdff1aSopenharmony_ci 162cabdff1aSopenharmony_ci/** Return the maximum scalefactor where the quantized coef is not zero. */ 163cabdff1aSopenharmony_cistatic inline uint8_t coef2maxsf(float coef) 164cabdff1aSopenharmony_ci{ 165cabdff1aSopenharmony_ci return av_clip_uint8(log2f(coef)*4 + 6 + SCALE_ONE_POS - SCALE_DIV_512); 166cabdff1aSopenharmony_ci} 167cabdff1aSopenharmony_ci 168cabdff1aSopenharmony_ci/* 169cabdff1aSopenharmony_ci * Returns the closest possible index to an array of float values, given a value. 170cabdff1aSopenharmony_ci */ 171cabdff1aSopenharmony_cistatic inline int quant_array_idx(const float val, const float *arr, const int num) 172cabdff1aSopenharmony_ci{ 173cabdff1aSopenharmony_ci int i, index = 0; 174cabdff1aSopenharmony_ci float quant_min_err = INFINITY; 175cabdff1aSopenharmony_ci for (i = 0; i < num; i++) { 176cabdff1aSopenharmony_ci float error = (val - arr[i])*(val - arr[i]); 177cabdff1aSopenharmony_ci if (error < quant_min_err) { 178cabdff1aSopenharmony_ci quant_min_err = error; 179cabdff1aSopenharmony_ci index = i; 180cabdff1aSopenharmony_ci } 181cabdff1aSopenharmony_ci } 182cabdff1aSopenharmony_ci return index; 183cabdff1aSopenharmony_ci} 184cabdff1aSopenharmony_ci 185cabdff1aSopenharmony_ci/** 186cabdff1aSopenharmony_ci * approximates exp10f(-3.0f*(0.5f + 0.5f * cosf(FFMIN(b,15.5f) / 15.5f))) 187cabdff1aSopenharmony_ci */ 188cabdff1aSopenharmony_cistatic av_always_inline float bval2bmax(float b) 189cabdff1aSopenharmony_ci{ 190cabdff1aSopenharmony_ci return 0.001f + 0.0035f * (b*b*b) / (15.5f*15.5f*15.5f); 191cabdff1aSopenharmony_ci} 192cabdff1aSopenharmony_ci 193cabdff1aSopenharmony_ci/* 194cabdff1aSopenharmony_ci * Compute a nextband map to be used with SF delta constraint utilities. 195cabdff1aSopenharmony_ci * The nextband array should contain 128 elements, and positions that don't 196cabdff1aSopenharmony_ci * map to valid, nonzero bands of the form w*16+g (with w being the initial 197cabdff1aSopenharmony_ci * window of the window group, only) are left indetermined. 198cabdff1aSopenharmony_ci */ 199cabdff1aSopenharmony_cistatic inline void ff_init_nextband_map(const SingleChannelElement *sce, uint8_t *nextband) 200cabdff1aSopenharmony_ci{ 201cabdff1aSopenharmony_ci unsigned char prevband = 0; 202cabdff1aSopenharmony_ci int w, g; 203cabdff1aSopenharmony_ci /** Just a safe default */ 204cabdff1aSopenharmony_ci for (g = 0; g < 128; g++) 205cabdff1aSopenharmony_ci nextband[g] = g; 206cabdff1aSopenharmony_ci 207cabdff1aSopenharmony_ci /** Now really navigate the nonzero band chain */ 208cabdff1aSopenharmony_ci for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) { 209cabdff1aSopenharmony_ci for (g = 0; g < sce->ics.num_swb; g++) { 210cabdff1aSopenharmony_ci if (!sce->zeroes[w*16+g] && sce->band_type[w*16+g] < RESERVED_BT) 211cabdff1aSopenharmony_ci prevband = nextband[prevband] = w*16+g; 212cabdff1aSopenharmony_ci } 213cabdff1aSopenharmony_ci } 214cabdff1aSopenharmony_ci nextband[prevband] = prevband; /* terminate */ 215cabdff1aSopenharmony_ci} 216cabdff1aSopenharmony_ci 217cabdff1aSopenharmony_ci/* 218cabdff1aSopenharmony_ci * Updates nextband to reflect a removed band (equivalent to 219cabdff1aSopenharmony_ci * calling ff_init_nextband_map after marking a band as zero) 220cabdff1aSopenharmony_ci */ 221cabdff1aSopenharmony_cistatic inline void ff_nextband_remove(uint8_t *nextband, int prevband, int band) 222cabdff1aSopenharmony_ci{ 223cabdff1aSopenharmony_ci nextband[prevband] = nextband[band]; 224cabdff1aSopenharmony_ci} 225cabdff1aSopenharmony_ci 226cabdff1aSopenharmony_ci/* 227cabdff1aSopenharmony_ci * Checks whether the specified band could be removed without inducing 228cabdff1aSopenharmony_ci * scalefactor delta that violates SF delta encoding constraints. 229cabdff1aSopenharmony_ci * prev_sf has to be the scalefactor of the previous nonzero, nonspecial 230cabdff1aSopenharmony_ci * band, in encoding order, or negative if there was no such band. 231cabdff1aSopenharmony_ci */ 232cabdff1aSopenharmony_cistatic inline int ff_sfdelta_can_remove_band(const SingleChannelElement *sce, 233cabdff1aSopenharmony_ci const uint8_t *nextband, int prev_sf, int band) 234cabdff1aSopenharmony_ci{ 235cabdff1aSopenharmony_ci return prev_sf >= 0 236cabdff1aSopenharmony_ci && sce->sf_idx[nextband[band]] >= (prev_sf - SCALE_MAX_DIFF) 237cabdff1aSopenharmony_ci && sce->sf_idx[nextband[band]] <= (prev_sf + SCALE_MAX_DIFF); 238cabdff1aSopenharmony_ci} 239cabdff1aSopenharmony_ci 240cabdff1aSopenharmony_ci/* 241cabdff1aSopenharmony_ci * Checks whether the specified band's scalefactor could be replaced 242cabdff1aSopenharmony_ci * with another one without violating SF delta encoding constraints. 243cabdff1aSopenharmony_ci * prev_sf has to be the scalefactor of the previous nonzero, nonsepcial 244cabdff1aSopenharmony_ci * band, in encoding order, or negative if there was no such band. 245cabdff1aSopenharmony_ci */ 246cabdff1aSopenharmony_cistatic inline int ff_sfdelta_can_replace(const SingleChannelElement *sce, 247cabdff1aSopenharmony_ci const uint8_t *nextband, int prev_sf, int new_sf, int band) 248cabdff1aSopenharmony_ci{ 249cabdff1aSopenharmony_ci return new_sf >= (prev_sf - SCALE_MAX_DIFF) 250cabdff1aSopenharmony_ci && new_sf <= (prev_sf + SCALE_MAX_DIFF) 251cabdff1aSopenharmony_ci && sce->sf_idx[nextband[band]] >= (new_sf - SCALE_MAX_DIFF) 252cabdff1aSopenharmony_ci && sce->sf_idx[nextband[band]] <= (new_sf + SCALE_MAX_DIFF); 253cabdff1aSopenharmony_ci} 254cabdff1aSopenharmony_ci 255cabdff1aSopenharmony_ci/** 256cabdff1aSopenharmony_ci * linear congruential pseudorandom number generator 257cabdff1aSopenharmony_ci * 258cabdff1aSopenharmony_ci * @param previous_val pointer to the current state of the generator 259cabdff1aSopenharmony_ci * 260cabdff1aSopenharmony_ci * @return Returns a 32-bit pseudorandom integer 261cabdff1aSopenharmony_ci */ 262cabdff1aSopenharmony_cistatic av_always_inline int lcg_random(unsigned previous_val) 263cabdff1aSopenharmony_ci{ 264cabdff1aSopenharmony_ci union { unsigned u; int s; } v = { previous_val * 1664525u + 1013904223 }; 265cabdff1aSopenharmony_ci return v.s; 266cabdff1aSopenharmony_ci} 267cabdff1aSopenharmony_ci 268cabdff1aSopenharmony_ci#define ERROR_IF(cond, ...) \ 269cabdff1aSopenharmony_ci if (cond) { \ 270cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, __VA_ARGS__); \ 271cabdff1aSopenharmony_ci return AVERROR(EINVAL); \ 272cabdff1aSopenharmony_ci } 273cabdff1aSopenharmony_ci 274cabdff1aSopenharmony_ci#define WARN_IF(cond, ...) \ 275cabdff1aSopenharmony_ci if (cond) { \ 276cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_WARNING, __VA_ARGS__); \ 277cabdff1aSopenharmony_ci } 278cabdff1aSopenharmony_ci 279cabdff1aSopenharmony_ci#endif /* AVCODEC_AACENC_UTILS_H */ 280