Michael NiedermayerMerge remote branch 'qatar/master'066519915 years agoHistory
1126 lines · 43.2 KB · C
RawDownload
/* * AAC coefficients encoder * 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 coefficients encoder */ /*********************************** *              TODOs: * speedup quantizer selection * add sane pulse detection ***********************************/ #include <float.h>#include <math.h>#include "avcodec.h"#include "put_bits.h"#include "aac.h"#include "aacenc.h"#include "aactab.h"#include "libavutil/libm.h" /** bits needed to code codebook run value for long windows */static const uint8_t run_value_bits_long[64] = {     5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,     5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5, 10,    10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,    10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 15}; /** bits needed to code codebook run value for short windows */static const uint8_t run_value_bits_short[16] = {    3, 3, 3, 3, 3, 3, 3, 6, 6, 6, 6, 6, 6, 6, 6, 9}; static const uint8_t *run_value_bits[2] = {    run_value_bits_long, run_value_bits_short};  /** * Quantize one coefficient. * @return absolute value of the quantized coefficient * @see 3GPP TS26.403 5.6.2 "Scalefactor determination" */static av_always_inline int quant(float coef, const float Q){    float a = coef * Q;    return sqrtf(a * sqrtf(a)) + 0.4054;} static void quantize_bands(int *out, const float *in, const float *scaled,                           int size, float Q34, int is_signed, int maxval){    int i;    double qc;    for (i = 0; i < size; i++) {        qc = scaled[i] * Q34;        out[i] = (int)FFMIN(qc + 0.4054, (double)maxval);        if (is_signed && in[i] < 0.0f) {            out[i] = -out[i];        }    }} static void abs_pow34_v(float *out, const float *in, const int size){#ifndef USE_REALLY_FULL_SEARCH    int i;    for (i = 0; i < size; i++) {        float a = fabsf(in[i]);        out[i] = sqrtf(a * sqrtf(a));    }#endif /* USE_REALLY_FULL_SEARCH */} static const uint8_t aac_cb_range [12] = {0, 3, 3, 3, 3, 9, 9, 8, 8, 13, 13, 17};static const uint8_t aac_cb_maxval[12] = {0, 1, 1, 2, 2, 4, 4, 7, 7, 12, 12, 16}; /** * Calculate rate distortion cost for quantizing with given codebook * * @return quantization distortion */static av_always_inline float quantize_and_encode_band_cost_template(                                struct AACEncContext *s,                                PutBitContext *pb, const float *in,                                const float *scaled, int size, int scale_idx,                                int cb, const float lambda, const float uplim,                                int *bits, int BT_ZERO, int BT_UNSIGNED,                                int BT_PAIR, int BT_ESC){    const float IQ = ff_aac_pow2sf_tab[POW_SF2_ZERO + scale_idx - SCALE_ONE_POS + SCALE_DIV_512];    const float  Q = ff_aac_pow2sf_tab[POW_SF2_ZERO - scale_idx + SCALE_ONE_POS - SCALE_DIV_512];    const float CLIPPED_ESCAPE = 165140.0f*IQ;    int i, j;    float cost = 0;    const int dim = BT_PAIR ? 2 : 4;    int resbits = 0;    const float  Q34 = sqrtf(Q * sqrtf(Q));    const int range  = aac_cb_range[cb];    const int maxval = aac_cb_maxval[cb];    int off;     if (BT_ZERO) {        for (i = 0; i < size; i++)            cost += in[i]*in[i];        if (bits)            *bits = 0;        return cost * lambda;    }    if (!scaled) {        abs_pow34_v(s->scoefs, in, size);        scaled = s->scoefs;    }    quantize_bands(s->qcoefs, in, scaled, size, Q34, !BT_UNSIGNED, maxval);    if (BT_UNSIGNED) {        off = 0;    } else {        off = maxval;    }    for (i = 0; i < size; i += dim) {        const float *vec;        int *quants = s->qcoefs + i;        int curidx = 0;        int curbits;        float rd = 0.0f;        for (j = 0; j < dim; j++) {            curidx *= range;            curidx += quants[j] + off;        }        curbits =  ff_aac_spectral_bits[cb-1][curidx];        vec     = &ff_aac_codebook_vectors[cb-1][curidx*dim];        if (BT_UNSIGNED) {            for (j = 0; j < dim; j++) {                float t = fabsf(in[i+j]);                float di;                if (BT_ESC && vec[j] == 64.0f) { //FIXME: slow                    if (t >= CLIPPED_ESCAPE) {                        di = t - CLIPPED_ESCAPE;                        curbits += 21;                    } else {                        int c = av_clip(quant(t, Q), 0, 8191);                        di = t - c*cbrtf(c)*IQ;                        curbits += av_log2(c)*2 - 4 + 1;                    }                } else {                    di = t - vec[j]*IQ;                }                if (vec[j] != 0.0f)                    curbits++;                rd += di*di;            }        } else {            for (j = 0; j < dim; j++) {                float di = in[i+j] - vec[j]*IQ;                rd += di*di;            }        }        cost    += rd * lambda + curbits;        resbits += curbits;        if (cost >= uplim)            return uplim;        if (pb) {            put_bits(pb, ff_aac_spectral_bits[cb-1][curidx], ff_aac_spectral_codes[cb-1][curidx]);            if (BT_UNSIGNED)                for (j = 0; j < dim; j++)                    if (ff_aac_codebook_vectors[cb-1][curidx*dim+j] != 0.0f)                        put_bits(pb, 1, in[i+j] < 0.0f);            if (BT_ESC) {                for (j = 0; j < 2; j++) {                    if (ff_aac_codebook_vectors[cb-1][curidx*2+j] == 64.0f) {                        int coef = av_clip(quant(fabsf(in[i+j]), Q), 0, 8191);                        int len = av_log2(coef);                         put_bits(pb, len - 4 + 1, (1 << (len - 4 + 1)) - 2);                        put_bits(pb, len, coef & ((1 << len) - 1));                    }                }            }        }    }     if (bits)        *bits = resbits;    return cost;} #define QUANTIZE_AND_ENCODE_BAND_COST_FUNC(NAME, BT_ZERO, BT_UNSIGNED, BT_PAIR, BT_ESC) \static float quantize_and_encode_band_cost_ ## NAME(                                        \                                struct AACEncContext *s,                                \                                PutBitContext *pb, const float *in,                     \                                const float *scaled, int size, int scale_idx,           \                                int cb, const float lambda, const float uplim,          \                                int *bits) {                                            \    return quantize_and_encode_band_cost_template(                                      \                                s, pb, in, scaled, size, scale_idx,                     \                                BT_ESC ? ESC_BT : cb, lambda, uplim, bits,              \                                BT_ZERO, BT_UNSIGNED, BT_PAIR, BT_ESC);                 \} QUANTIZE_AND_ENCODE_BAND_COST_FUNC(ZERO,  1, 0, 0, 0)QUANTIZE_AND_ENCODE_BAND_COST_FUNC(SQUAD, 0, 0, 0, 0)QUANTIZE_AND_ENCODE_BAND_COST_FUNC(UQUAD, 0, 1, 0, 0)QUANTIZE_AND_ENCODE_BAND_COST_FUNC(SPAIR, 0, 0, 1, 0)QUANTIZE_AND_ENCODE_BAND_COST_FUNC(UPAIR, 0, 1, 1, 0)QUANTIZE_AND_ENCODE_BAND_COST_FUNC(ESC,   0, 1, 1, 1) static float (*const quantize_and_encode_band_cost_arr[])(                                struct AACEncContext *s,                                PutBitContext *pb, const float *in,                                const float *scaled, int size, int scale_idx,                                int cb, const float lambda, const float uplim,                                int *bits) = {    quantize_and_encode_band_cost_ZERO,    quantize_and_encode_band_cost_SQUAD,    quantize_and_encode_band_cost_SQUAD,    quantize_and_encode_band_cost_UQUAD,    quantize_and_encode_band_cost_UQUAD,    quantize_and_encode_band_cost_SPAIR,    quantize_and_encode_band_cost_SPAIR,    quantize_and_encode_band_cost_UPAIR,    quantize_and_encode_band_cost_UPAIR,    quantize_and_encode_band_cost_UPAIR,    quantize_and_encode_band_cost_UPAIR,    quantize_and_encode_band_cost_ESC,}; #define quantize_and_encode_band_cost(                                  \                                s, pb, in, scaled, size, scale_idx, cb, \                                lambda, uplim, bits)                    \    quantize_and_encode_band_cost_arr[cb](                              \                                s, pb, in, scaled, size, scale_idx, cb, \                                lambda, uplim, bits) static float quantize_band_cost(struct AACEncContext *s, const float *in,                                const float *scaled, int size, int scale_idx,                                int cb, const float lambda, const float uplim,                                int *bits){    return quantize_and_encode_band_cost(s, NULL, in, scaled, size, scale_idx,                                         cb, lambda, uplim, bits);} static void quantize_and_encode_band(struct AACEncContext *s, PutBitContext *pb,                                     const float *in, int size, int scale_idx,                                     int cb, const float lambda){    quantize_and_encode_band_cost(s, pb, in, NULL, size, scale_idx, cb, lambda,                                  INFINITY, NULL);} static float find_max_val(int group_len, int swb_size, const float *scaled) {    float maxval = 0.0f;    int w2, i;    for (w2 = 0; w2 < group_len; w2++) {        for (i = 0; i < swb_size; i++) {            maxval = FFMAX(maxval, scaled[w2*128+i]);        }    }    return maxval;} static 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));    int qmaxval, cb;    qmaxval = maxval * Q34 + 0.4054f;    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;    return cb;} /** * structure used in optimal codebook search */typedef struct BandCodingPath {    int prev_idx; ///< pointer to the previous path point    float cost;   ///< path cost    int run;} BandCodingPath; /** * Encode band info for single window group bands. */static void encode_window_bands_info(AACEncContext *s, SingleChannelElement *sce,                                     int win, int group_len, const float lambda){    BandCodingPath path[120][12];    int w, swb, cb, start, start2, size;    int i, j;    const int max_sfb  = sce->ics.max_sfb;    const int run_bits = sce->ics.num_windows == 1 ? 5 : 3;    const int run_esc  = (1 << run_bits) - 1;    int idx, ppos, count;    int stackrun[120], stackcb[120], stack_len;    float next_minrd = INFINITY;    int next_mincb = 0;     abs_pow34_v(s->scoefs, sce->coeffs, 1024);    start = win*128;    for (cb = 0; cb < 12; cb++) {        path[0][cb].cost     = 0.0f;        path[0][cb].prev_idx = -1;        path[0][cb].run      = 0;    }    for (swb = 0; swb < max_sfb; swb++) {        start2 = start;        size = sce->ics.swb_sizes[swb];        if (sce->zeroes[win*16 + swb]) {            for (cb = 0; cb < 12; cb++) {                path[swb+1][cb].prev_idx = cb;                path[swb+1][cb].cost     = path[swb][cb].cost;                path[swb+1][cb].run      = path[swb][cb].run + 1;            }        } else {            float minrd = next_minrd;            int mincb = next_mincb;            next_minrd = INFINITY;            next_mincb = 0;            for (cb = 0; cb < 12; cb++) {                float cost_stay_here, cost_get_here;                float rd = 0.0f;                for (w = 0; w < group_len; w++) {                    FFPsyBand *band = &s->psy.psy_bands[s->cur_channel*PSY_MAX_BANDS+(win+w)*16+swb];                    rd += quantize_band_cost(s, sce->coeffs + start + w*128,                                             s->scoefs + start + w*128, size,                                             sce->sf_idx[(win+w)*16+swb], cb,                                             lambda / band->threshold, INFINITY, NULL);                }                cost_stay_here = path[swb][cb].cost + rd;                cost_get_here  = minrd              + rd + run_bits + 4;                if (   run_value_bits[sce->ics.num_windows == 8][path[swb][cb].run]                    != run_value_bits[sce->ics.num_windows == 8][path[swb][cb].run+1])                    cost_stay_here += run_bits;                if (cost_get_here < cost_stay_here) {                    path[swb+1][cb].prev_idx = mincb;                    path[swb+1][cb].cost     = cost_get_here;                    path[swb+1][cb].run      = 1;                } else {                    path[swb+1][cb].prev_idx = cb;                    path[swb+1][cb].cost     = cost_stay_here;                    path[swb+1][cb].run      = path[swb][cb].run + 1;                }                if (path[swb+1][cb].cost < next_minrd) {                    next_minrd = path[swb+1][cb].cost;                    next_mincb = cb;                }            }        }        start += sce->ics.swb_sizes[swb];    }     //convert resulting path from backward-linked list    stack_len = 0;    idx       = 0;    for (cb = 1; cb < 12; cb++)        if (path[max_sfb][cb].cost < path[max_sfb][idx].cost)            idx = cb;    ppos = max_sfb;    while (ppos > 0) {        cb = idx;        stackrun[stack_len] = path[ppos][cb].run;        stackcb [stack_len] = cb;        idx = path[ppos-path[ppos][cb].run+1][cb].prev_idx;        ppos -= path[ppos][cb].run;        stack_len++;    }    //perform actual band info encoding    start = 0;    for (i = stack_len - 1; i >= 0; i--) {        put_bits(&s->pb, 4, stackcb[i]);        count = stackrun[i];        memset(sce->zeroes + win*16 + start, !stackcb[i], count);        //XXX: memset when band_type is also uint8_t        for (j = 0; j < count; j++) {            sce->band_type[win*16 + start] =  stackcb[i];            start++;        }        while (count >= run_esc) {            put_bits(&s->pb, run_bits, run_esc);            count -= run_esc;        }        put_bits(&s->pb, run_bits, count);    }} static void codebook_trellis_rate(AACEncContext *s, SingleChannelElement *sce,                                  int win, int group_len, const float lambda){    BandCodingPath path[120][12];    int w, swb, cb, start, start2, size;    int i, j;    const int max_sfb  = sce->ics.max_sfb;    const int run_bits = sce->ics.num_windows == 1 ? 5 : 3;    const int run_esc  = (1 << run_bits) - 1;    int idx, ppos, count;    int stackrun[120], stackcb[120], stack_len;    float next_minrd = INFINITY;    int next_mincb = 0;     abs_pow34_v(s->scoefs, sce->coeffs, 1024);    start = win*128;    for (cb = 0; cb < 12; cb++) {        path[0][cb].cost     = run_bits+4;        path[0][cb].prev_idx = -1;        path[0][cb].run      = 0;    }    for (swb = 0; swb < max_sfb; swb++) {        start2 = start;        size = sce->ics.swb_sizes[swb];        if (sce->zeroes[win*16 + swb]) {            for (cb = 0; cb < 12; cb++) {                path[swb+1][cb].prev_idx = cb;                path[swb+1][cb].cost     = path[swb][cb].cost;                path[swb+1][cb].run      = path[swb][cb].run + 1;            }        } else {            float minrd = next_minrd;            int mincb = next_mincb;            int startcb = sce->band_type[win*16+swb];            next_minrd = INFINITY;            next_mincb = 0;            for (cb = 0; cb < startcb; cb++) {                path[swb+1][cb].cost = 61450;                path[swb+1][cb].prev_idx = -1;                path[swb+1][cb].run = 0;            }            for (cb = startcb; cb < 12; cb++) {                float cost_stay_here, cost_get_here;                float rd = 0.0f;                for (w = 0; w < group_len; w++) {                    rd += quantize_band_cost(s, sce->coeffs + start + w*128,                                             s->scoefs + start + w*128, size,                                             sce->sf_idx[(win+w)*16+swb], cb,                                             0, INFINITY, NULL);                }                cost_stay_here = path[swb][cb].cost + rd;                cost_get_here  = minrd              + rd + run_bits + 4;                if (   run_value_bits[sce->ics.num_windows == 8][path[swb][cb].run]                    != run_value_bits[sce->ics.num_windows == 8][path[swb][cb].run+1])                    cost_stay_here += run_bits;                if (cost_get_here < cost_stay_here) {                    path[swb+1][cb].prev_idx = mincb;                    path[swb+1][cb].cost     = cost_get_here;                    path[swb+1][cb].run      = 1;                } else {                    path[swb+1][cb].prev_idx = cb;                    path[swb+1][cb].cost     = cost_stay_here;                    path[swb+1][cb].run      = path[swb][cb].run + 1;                }                if (path[swb+1][cb].cost < next_minrd) {                    next_minrd = path[swb+1][cb].cost;                    next_mincb = cb;                }            }        }        start += sce->ics.swb_sizes[swb];    }     //convert resulting path from backward-linked list    stack_len = 0;    idx       = 0;    for (cb = 1; cb < 12; cb++)        if (path[max_sfb][cb].cost < path[max_sfb][idx].cost)            idx = cb;    ppos = max_sfb;    while (ppos > 0) {        assert(idx >= 0);        cb = idx;        stackrun[stack_len] = path[ppos][cb].run;        stackcb [stack_len] = cb;        idx = path[ppos-path[ppos][cb].run+1][cb].prev_idx;        ppos -= path[ppos][cb].run;        stack_len++;    }

Lines 1–500 of 1126.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t