mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2024-12-18 21:45:10 +00:00
AAC encoder: memoize quantize_band_cost
The bulk of calls to quantize_band_cost are replaced by a call to a version that memoizes, greatly improving performance, since during coefficient search there is a great deal of repeat work. Memoization cannot always be applied, so do this in a different function, and leave the original as-is.
This commit is contained in:
parent
ce0834bdd6
commit
b629c67ddf
@ -915,6 +915,8 @@ SKIPHEADERS += %_tablegen.h \
|
||||
tableprint_vlc.h \
|
||||
aaccoder_twoloop.h \
|
||||
aaccoder_trellis.h \
|
||||
aacenc_quantization.h \
|
||||
aacenc_quantization_misc.h \
|
||||
$(ARCH)/vp56_arith.h \
|
||||
|
||||
SKIPHEADERS-$(CONFIG_D3D11VA) += d3d11va.h dxva2_internal.h
|
||||
|
@ -287,6 +287,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
|
||||
if (!allz)
|
||||
return;
|
||||
abs_pow34_v(s->scoefs, sce->coeffs, 1024);
|
||||
ff_quantize_band_cost_cache_init(s);
|
||||
|
||||
for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
|
||||
start = w*128;
|
||||
@ -380,7 +381,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
|
||||
for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) {
|
||||
int b;
|
||||
float sqenergy;
|
||||
dist += quantize_band_cost(s, coefs + w2*128,
|
||||
dist += quantize_band_cost_cached(s, w + w2, g, coefs + w2*128,
|
||||
scaled + w2*128,
|
||||
sce->ics.swb_sizes[g],
|
||||
sce->sf_idx[w*16+g],
|
||||
@ -460,7 +461,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
|
||||
for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) {
|
||||
int b;
|
||||
float sqenergy;
|
||||
dist += quantize_band_cost(s, coefs + w2*128,
|
||||
dist += quantize_band_cost_cached(s, w + w2, g, coefs + w2*128,
|
||||
scaled + w2*128,
|
||||
sce->ics.swb_sizes[g],
|
||||
sce->sf_idx[w*16+g],
|
||||
@ -588,7 +589,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
|
||||
for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) {
|
||||
int b;
|
||||
float sqenergy;
|
||||
dist += quantize_band_cost(s, coefs + w2*128,
|
||||
dist += quantize_band_cost_cached(s, w + w2, g, coefs + w2*128,
|
||||
scaled + w2*128,
|
||||
sce->ics.swb_sizes[g],
|
||||
sce->sf_idx[w*16+g]-1,
|
||||
@ -625,7 +626,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
|
||||
for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) {
|
||||
int b;
|
||||
float sqenergy;
|
||||
dist += quantize_band_cost(s, coefs + w2*128,
|
||||
dist += quantize_band_cost_cached(s, w + w2, g, coefs + w2*128,
|
||||
scaled + w2*128,
|
||||
sce->ics.swb_sizes[g],
|
||||
sce->sf_idx[w*16+g]+1,
|
||||
|
@ -71,6 +71,16 @@ static void put_audio_specific_config(AVCodecContext *avctx)
|
||||
flush_put_bits(&pb);
|
||||
}
|
||||
|
||||
void ff_quantize_band_cost_cache_init(struct AACEncContext *s)
|
||||
{
|
||||
int sf, g;
|
||||
for (sf = 0; sf < 256; sf++) {
|
||||
for (g = 0; g < 128; g++) {
|
||||
s->quantize_band_cost_cache[sf][g].bits = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define WINDOW_FUNC(type) \
|
||||
static void apply_ ##type ##_window(AVFloatDSPContext *fdsp, \
|
||||
SingleChannelElement *sce, \
|
||||
|
@ -75,6 +75,15 @@ typedef struct AACCoefficientsEncoder {
|
||||
|
||||
extern AACCoefficientsEncoder ff_aac_coders[];
|
||||
|
||||
typedef struct AACQuantizeBandCostCacheEntry {
|
||||
float rd;
|
||||
float energy;
|
||||
int bits; ///< -1 means uninitialized entry
|
||||
char cb;
|
||||
char rtz;
|
||||
char padding[2]; ///< Keeps the entry size a multiple of 32 bits
|
||||
} AACQuantizeBandCostCacheEntry;
|
||||
|
||||
/**
|
||||
* AAC encoder context
|
||||
*/
|
||||
@ -109,11 +118,15 @@ typedef struct AACEncContext {
|
||||
DECLARE_ALIGNED(16, int, qcoefs)[96]; ///< quantized coefficients
|
||||
DECLARE_ALIGNED(32, float, scoefs)[1024]; ///< scaled coefficients
|
||||
|
||||
AACQuantizeBandCostCacheEntry quantize_band_cost_cache[256][128]; ///< memoization area for quantize_band_cost
|
||||
|
||||
struct {
|
||||
float *samples;
|
||||
} buffer;
|
||||
} AACEncContext;
|
||||
|
||||
void ff_aac_coder_init_mips(AACEncContext *c);
|
||||
void ff_quantize_band_cost_cache_init(struct AACEncContext *s);
|
||||
|
||||
|
||||
#endif /* AVCODEC_AACENC_H */
|
||||
|
@ -278,4 +278,6 @@ static inline void quantize_and_encode_band(struct AACEncContext *s, PutBitConte
|
||||
INFINITY, NULL, NULL, rtz);
|
||||
}
|
||||
|
||||
#include "aacenc_quantization_misc.h"
|
||||
|
||||
#endif /* AVCODEC_AACENC_QUANTIZATION_H */
|
||||
|
52
libavcodec/aacenc_quantization_misc.h
Normal file
52
libavcodec/aacenc_quantization_misc.h
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* AAC encoder quantization
|
||||
* Copyright (C) 2015 Claudio Freire
|
||||
*
|
||||
* 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 quantization misc reusable function templates
|
||||
* @author Claudio Freire ( klaussfreire gmail com )
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_AACENC_QUANTIZATION_MISC_H
|
||||
#define AVCODEC_AACENC_QUANTIZATION_MISC_H
|
||||
|
||||
static inline float quantize_band_cost_cached(struct AACEncContext *s, int w, int g, const float *in,
|
||||
const float *scaled, int size, int scale_idx,
|
||||
int cb, const float lambda, const float uplim,
|
||||
int *bits, float *energy, int rtz)
|
||||
{
|
||||
AACQuantizeBandCostCacheEntry *entry;
|
||||
av_assert1(scale_idx >= 0 && scale_idx < 256);
|
||||
entry = &s->quantize_band_cost_cache[scale_idx][w*16+g];
|
||||
if (entry->bits < 0 || entry->cb != cb || entry->rtz != rtz) {
|
||||
entry->rd = quantize_band_cost(s, in, scaled, size, scale_idx,
|
||||
cb, lambda, uplim, &entry->bits, &entry->energy, rtz);
|
||||
entry->cb = cb;
|
||||
entry->rtz = rtz;
|
||||
}
|
||||
if (bits)
|
||||
*bits = entry->bits;
|
||||
if (energy)
|
||||
*energy = entry->energy;
|
||||
return entry->rd;
|
||||
}
|
||||
|
||||
#endif /* AVCODEC_AACENC_QUANTIZATION_MISC_H */
|
@ -2388,6 +2388,8 @@ static float quantize_band_cost(struct AACEncContext *s, const float *in,
|
||||
return get_band_cost(s, NULL, in, scaled, size, scale_idx, cb, lambda, uplim, bits, energy);
|
||||
}
|
||||
|
||||
#include "libavcodec/aacenc_quantization_misc.h"
|
||||
|
||||
static 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);
|
||||
|
Loading…
Reference in New Issue
Block a user