mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-01-24 13:56:33 +02: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 \
|
tableprint_vlc.h \
|
||||||
aaccoder_twoloop.h \
|
aaccoder_twoloop.h \
|
||||||
aaccoder_trellis.h \
|
aaccoder_trellis.h \
|
||||||
|
aacenc_quantization.h \
|
||||||
|
aacenc_quantization_misc.h \
|
||||||
$(ARCH)/vp56_arith.h \
|
$(ARCH)/vp56_arith.h \
|
||||||
|
|
||||||
SKIPHEADERS-$(CONFIG_D3D11VA) += d3d11va.h dxva2_internal.h
|
SKIPHEADERS-$(CONFIG_D3D11VA) += d3d11va.h dxva2_internal.h
|
||||||
|
@ -287,6 +287,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
|
|||||||
if (!allz)
|
if (!allz)
|
||||||
return;
|
return;
|
||||||
abs_pow34_v(s->scoefs, sce->coeffs, 1024);
|
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]) {
|
for (w = 0; w < sce->ics.num_windows; w += sce->ics.group_len[w]) {
|
||||||
start = w*128;
|
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++) {
|
for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) {
|
||||||
int b;
|
int b;
|
||||||
float sqenergy;
|
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,
|
scaled + w2*128,
|
||||||
sce->ics.swb_sizes[g],
|
sce->ics.swb_sizes[g],
|
||||||
sce->sf_idx[w*16+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++) {
|
for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) {
|
||||||
int b;
|
int b;
|
||||||
float sqenergy;
|
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,
|
scaled + w2*128,
|
||||||
sce->ics.swb_sizes[g],
|
sce->ics.swb_sizes[g],
|
||||||
sce->sf_idx[w*16+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++) {
|
for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) {
|
||||||
int b;
|
int b;
|
||||||
float sqenergy;
|
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,
|
scaled + w2*128,
|
||||||
sce->ics.swb_sizes[g],
|
sce->ics.swb_sizes[g],
|
||||||
sce->sf_idx[w*16+g]-1,
|
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++) {
|
for (w2 = 0; w2 < sce->ics.group_len[w]; w2++) {
|
||||||
int b;
|
int b;
|
||||||
float sqenergy;
|
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,
|
scaled + w2*128,
|
||||||
sce->ics.swb_sizes[g],
|
sce->ics.swb_sizes[g],
|
||||||
sce->sf_idx[w*16+g]+1,
|
sce->sf_idx[w*16+g]+1,
|
||||||
|
@ -71,6 +71,16 @@ static void put_audio_specific_config(AVCodecContext *avctx)
|
|||||||
flush_put_bits(&pb);
|
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) \
|
#define WINDOW_FUNC(type) \
|
||||||
static void apply_ ##type ##_window(AVFloatDSPContext *fdsp, \
|
static void apply_ ##type ##_window(AVFloatDSPContext *fdsp, \
|
||||||
SingleChannelElement *sce, \
|
SingleChannelElement *sce, \
|
||||||
|
@ -75,6 +75,15 @@ typedef struct AACCoefficientsEncoder {
|
|||||||
|
|
||||||
extern AACCoefficientsEncoder ff_aac_coders[];
|
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
|
* AAC encoder context
|
||||||
*/
|
*/
|
||||||
@ -109,11 +118,15 @@ typedef struct AACEncContext {
|
|||||||
DECLARE_ALIGNED(16, int, qcoefs)[96]; ///< quantized coefficients
|
DECLARE_ALIGNED(16, int, qcoefs)[96]; ///< quantized coefficients
|
||||||
DECLARE_ALIGNED(32, float, scoefs)[1024]; ///< scaled coefficients
|
DECLARE_ALIGNED(32, float, scoefs)[1024]; ///< scaled coefficients
|
||||||
|
|
||||||
|
AACQuantizeBandCostCacheEntry quantize_band_cost_cache[256][128]; ///< memoization area for quantize_band_cost
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
float *samples;
|
float *samples;
|
||||||
} buffer;
|
} buffer;
|
||||||
} AACEncContext;
|
} AACEncContext;
|
||||||
|
|
||||||
void ff_aac_coder_init_mips(AACEncContext *c);
|
void ff_aac_coder_init_mips(AACEncContext *c);
|
||||||
|
void ff_quantize_band_cost_cache_init(struct AACEncContext *s);
|
||||||
|
|
||||||
|
|
||||||
#endif /* AVCODEC_AACENC_H */
|
#endif /* AVCODEC_AACENC_H */
|
||||||
|
@ -278,4 +278,6 @@ static inline void quantize_and_encode_band(struct AACEncContext *s, PutBitConte
|
|||||||
INFINITY, NULL, NULL, rtz);
|
INFINITY, NULL, NULL, rtz);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include "aacenc_quantization_misc.h"
|
||||||
|
|
||||||
#endif /* AVCODEC_AACENC_QUANTIZATION_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);
|
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) {
|
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_size = 1.0f / swb_size;
|
||||||
const float iswb_sizem1 = 1.0f / (swb_size - 1);
|
const float iswb_sizem1 = 1.0f / (swb_size - 1);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user