123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254 |
- $OpenBSD: patch-libavcodec_aacenc_utils_h,v 1.11 2016/10/17 07:51:00 ajacoutot Exp $
- aacenc: copy PRNG from the decoder
- AAC encoder: simplify and speed up find_min_book
- AAC encoder: Extensive improvements
- aacenc_utils: add 'inline' flag to find_form_factor, silence warning
- aacenc: add support for changing options based on a profile
- aacenc_utils: fit find_form_factor() below 80 chars per line
- aacenc: partially revert previous commits to set options via a profile
- avcodec/aac_tablegen: get rid of hardcoded tables entirely
- AAC encoder: improve SF range utilization
- aacenc: switch to using the RNG from libavutil
- avcodec/aacenc_is: replace pow(x, 0.75) by x/sqrtf(sqrtf(x))
- lavc/aacenc_utils: replace sqrtf(Q*sqrtf(Q)) by precomputed value
- aacenc: avoid double in quantize_bands.
- aacenc_utils: Use temporary variable.
- lavc/aacenc_utils: replace powf(x,y) by expf(logf(x), y)
- aacenc: use the decoder's lcg PRNG
- --- libavcodec/aacenc_utils.h.orig Sat Aug 27 22:51:19 2016
- +++ libavcodec/aacenc_utils.h Sat Oct 15 18:51:24 2016
- @@ -28,9 +28,10 @@
- #ifndef AVCODEC_AACENC_UTILS_H
- #define AVCODEC_AACENC_UTILS_H
-
- +#include "libavutil/internal.h"
- #include "aac.h"
- -#include "aac_tablegen_decl.h"
- #include "aacenctab.h"
- +#include "aactab.h"
-
- #define ROUND_STANDARD 0.4054f
- #define ROUND_TO_ZERO 0.1054f
- @@ -45,6 +46,11 @@ static inline void abs_pow34_v(float *out, const float
- }
- }
-
- +static inline float pos_pow34(float a)
- +{
- + return sqrtf(a * sqrtf(a));
- +}
- +
- /**
- * Quantize one coefficient.
- * @return absolute value of the quantized coefficient
- @@ -61,13 +67,13 @@ static inline void quantize_bands(int *out, const floa
- const float rounding)
- {
- int i;
- - double qc;
- for (i = 0; i < size; i++) {
- - qc = scaled[i] * Q34;
- - out[i] = (int)FFMIN(qc + rounding, (double)maxval);
- + float qc = scaled[i] * Q34;
- + int tmp = (int)FFMIN(qc + rounding, (float)maxval);
- if (is_signed && in[i] < 0.0f) {
- - out[i] = -out[i];
- + tmp = -tmp;
- }
- + out[i] = tmp;
- }
- }
-
- @@ -85,20 +91,68 @@ static inline float find_max_val(int group_len, int sw
-
- static inline int find_min_book(float maxval, int sf)
- {
- - float Q = ff_aac_pow2sf_tab[POW_SF2_ZERO - sf + SCALE_ONE_POS - SCALE_DIV_512];
- - float Q34 = sqrtf(Q * sqrtf(Q));
- + float Q34 = ff_aac_pow34sf_tab[POW_SF2_ZERO - sf + SCALE_ONE_POS - SCALE_DIV_512];
- int qmaxval, cb;
- qmaxval = maxval * Q34 + C_QUANT;
- - if (qmaxval == 0) cb = 0;
- - else if (qmaxval == 1) cb = 1;
- - else if (qmaxval == 2) cb = 3;
- - else if (qmaxval <= 4) cb = 5;
- - else if (qmaxval <= 7) cb = 7;
- - else if (qmaxval <= 12) cb = 9;
- - else cb = 11;
- + if (qmaxval >= (FF_ARRAY_ELEMS(aac_maxval_cb)))
- + cb = 11;
- + else
- + cb = aac_maxval_cb[qmaxval];
- return cb;
- }
-
- +static inline float find_form_factor(int group_len, int swb_size, float thresh,
- + const float *scaled, float nzslope) {
- + const float iswb_size = 1.0f / swb_size;
- + const float iswb_sizem1 = 1.0f / (swb_size - 1);
- + const float ethresh = thresh;
- + float form = 0.0f, weight = 0.0f;
- + int w2, i;
- + for (w2 = 0; w2 < group_len; w2++) {
- + float e = 0.0f, e2 = 0.0f, var = 0.0f, maxval = 0.0f;
- + float nzl = 0;
- + for (i = 0; i < swb_size; i++) {
- + float s = fabsf(scaled[w2*128+i]);
- + maxval = FFMAX(maxval, s);
- + e += s;
- + e2 += s *= s;
- + /* We really don't want a hard non-zero-line count, since
- + * even below-threshold lines do add up towards band spectral power.
- + * So, fall steeply towards zero, but smoothly
- + */
- + if (s >= ethresh) {
- + nzl += 1.0f;
- + } else {
- + if (nzslope == 2.f)
- + nzl += (s / ethresh) * (s / ethresh);
- + else
- + nzl += ff_fast_powf(s / ethresh, nzslope);
- + }
- + }
- + if (e2 > thresh) {
- + float frm;
- + e *= iswb_size;
- +
- + /** compute variance */
- + for (i = 0; i < swb_size; i++) {
- + float d = fabsf(scaled[w2*128+i]) - e;
- + var += d*d;
- + }
- + var = sqrtf(var * iswb_sizem1);
- +
- + e2 *= iswb_size;
- + frm = e / FFMIN(e+4*var,maxval);
- + form += e2 * sqrtf(frm) / FFMAX(0.5f,nzl);
- + weight += e2;
- + }
- + }
- + if (weight > 0) {
- + return form / weight;
- + } else {
- + return 1.0f;
- + }
- +}
- +
- /** Return the minimum scalefactor where the quantized coef does not clip. */
- static inline uint8_t coef2minsf(float coef)
- {
- @@ -128,6 +182,89 @@ static inline int quant_array_idx(const float val, con
- return index;
- }
-
- +/**
- + * approximates exp10f(-3.0f*(0.5f + 0.5f * cosf(FFMIN(b,15.5f) / 15.5f)))
- + */
- +static av_always_inline float bval2bmax(float b)
- +{
- + return 0.001f + 0.0035f * (b*b*b) / (15.5f*15.5f*15.5f);
- +}
- +
- +/*
- + * Compute a nextband map to be used with SF delta constraint utilities.
- + * The nextband array should contain 128 elements, and positions that don't
- + * map to valid, nonzero bands of the form w*16+g (with w being the initial
- + * window of the window group, only) are left indetermined.
- + */
- +static inline void ff_init_nextband_map(const SingleChannelElement *sce, uint8_t *nextband)
- +{
- + unsigned char prevband = 0;
- + int w, g;
- + /** Just a safe default */
- + for (g = 0; g < 128; g++)
- + nextband[g] = g;
- +
- + /** Now really navigate the nonzero band chain */
- + 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->band_type[w*16+g] < RESERVED_BT)
- + prevband = nextband[prevband] = w*16+g;
- + }
- + }
- + nextband[prevband] = prevband; /* terminate */
- +}
- +
- +/*
- + * Updates nextband to reflect a removed band (equivalent to
- + * calling ff_init_nextband_map after marking a band as zero)
- + */
- +static inline void ff_nextband_remove(uint8_t *nextband, int prevband, int band)
- +{
- + nextband[prevband] = nextband[band];
- +}
- +
- +/*
- + * Checks whether the specified band could be removed without inducing
- + * scalefactor delta that violates SF delta encoding constraints.
- + * prev_sf has to be the scalefactor of the previous nonzero, nonspecial
- + * band, in encoding order, or negative if there was no such band.
- + */
- +static inline int ff_sfdelta_can_remove_band(const SingleChannelElement *sce,
- + const uint8_t *nextband, int prev_sf, int band)
- +{
- + return prev_sf >= 0
- + && sce->sf_idx[nextband[band]] >= (prev_sf - SCALE_MAX_DIFF)
- + && sce->sf_idx[nextband[band]] <= (prev_sf + SCALE_MAX_DIFF);
- +}
- +
- +/*
- + * Checks whether the specified band's scalefactor could be replaced
- + * with another one without violating SF delta encoding constraints.
- + * prev_sf has to be the scalefactor of the previous nonzero, nonsepcial
- + * band, in encoding order, or negative if there was no such band.
- + */
- +static inline int ff_sfdelta_can_replace(const SingleChannelElement *sce,
- + const uint8_t *nextband, int prev_sf, int new_sf, int band)
- +{
- + return new_sf >= (prev_sf - SCALE_MAX_DIFF)
- + && new_sf <= (prev_sf + SCALE_MAX_DIFF)
- + && sce->sf_idx[nextband[band]] >= (new_sf - SCALE_MAX_DIFF)
- + && sce->sf_idx[nextband[band]] <= (new_sf + SCALE_MAX_DIFF);
- +}
- +
- +/**
- + * linear congruential pseudorandom number generator
- + *
- + * @param previous_val pointer to the current state of the generator
- + *
- + * @return Returns a 32-bit pseudorandom integer
- + */
- +static av_always_inline int lcg_random(unsigned previous_val)
- +{
- + union { unsigned u; int s; } v = { previous_val * 1664525u + 1013904223 };
- + return v.s;
- +}
- +
- #define ERROR_IF(cond, ...) \
- if (cond) { \
- av_log(avctx, AV_LOG_ERROR, __VA_ARGS__); \
- @@ -138,6 +275,5 @@ static inline int quant_array_idx(const float val, con
- if (cond) { \
- av_log(avctx, AV_LOG_WARNING, __VA_ARGS__); \
- }
- -
-
- #endif /* AVCODEC_AACENC_UTILS_H */
|