mirror of https://git.ffmpeg.org/ffmpeg.git
avcodec/ac3enc: Avoid copying samples
Only the last 256 samples of each frame are used;
the encoder currently uses a buffer for 1536 + 256 samples
whose first 256 samples contain are the last 256 samples
from the last frame and the next 1536 are the samples
of the current frame.
Yet since 238b2d4155
all the
DSP functions only need 256 contiguous samples and this can
be achieved by only retaining the last 256 samples of each
frame. Doing so saves 6KiB per channel.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This commit is contained in:
parent
da460fb95c
commit
7f35c999f6
|
@ -503,28 +503,6 @@ static void ac3_adjust_frame_size(AC3EncodeContext *s)
|
||||||
s->samples_written += AC3_BLOCK_SIZE * s->num_blocks;
|
s->samples_written += AC3_BLOCK_SIZE * s->num_blocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Copy input samples.
|
|
||||||
* Channels are reordered from FFmpeg's default order to AC-3 order.
|
|
||||||
*/
|
|
||||||
static void copy_input_samples(AC3EncodeContext *s, uint8_t * const *samples)
|
|
||||||
{
|
|
||||||
const unsigned sampletype_size = SAMPLETYPE_SIZE(s);
|
|
||||||
|
|
||||||
/* copy and remap input samples */
|
|
||||||
for (int ch = 0; ch < s->channels; ch++) {
|
|
||||||
/* copy last 256 samples of previous frame to the start of the current frame */
|
|
||||||
memcpy(&s->planar_samples[ch][0],
|
|
||||||
s->planar_samples[ch] + AC3_BLOCK_SIZE * sampletype_size * s->num_blocks,
|
|
||||||
AC3_BLOCK_SIZE * sampletype_size);
|
|
||||||
|
|
||||||
/* copy new samples for current frame */
|
|
||||||
memcpy(s->planar_samples[ch] + AC3_BLOCK_SIZE * sampletype_size,
|
|
||||||
samples[s->channel_map[ch]],
|
|
||||||
sampletype_size * AC3_BLOCK_SIZE * s->num_blocks);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the initial coupling strategy parameters prior to coupling analysis.
|
* Set the initial coupling strategy parameters prior to coupling analysis.
|
||||||
*
|
*
|
||||||
|
@ -2018,9 +1996,7 @@ int ff_ac3_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
|
||||||
if (s->bit_alloc.sr_code == 1 || s->eac3)
|
if (s->bit_alloc.sr_code == 1 || s->eac3)
|
||||||
ac3_adjust_frame_size(s);
|
ac3_adjust_frame_size(s);
|
||||||
|
|
||||||
copy_input_samples(s, frame->extended_data);
|
s->encode_frame(s, frame->extended_data);
|
||||||
|
|
||||||
s->encode_frame(s);
|
|
||||||
|
|
||||||
ac3_apply_rematrixing(s);
|
ac3_apply_rematrixing(s);
|
||||||
|
|
||||||
|
@ -2442,8 +2418,7 @@ static av_cold int allocate_buffers(AC3EncodeContext *s)
|
||||||
const unsigned sampletype_size = SAMPLETYPE_SIZE(s);
|
const unsigned sampletype_size = SAMPLETYPE_SIZE(s);
|
||||||
|
|
||||||
for (int ch = 0; ch < s->channels; ch++) {
|
for (int ch = 0; ch < s->channels; ch++) {
|
||||||
s->planar_samples[ch] = av_mallocz((AC3_FRAME_SIZE + AC3_BLOCK_SIZE) *
|
s->planar_samples[ch] = av_mallocz(AC3_BLOCK_SIZE * sampletype_size);
|
||||||
sampletype_size);
|
|
||||||
if (!s->planar_samples[ch])
|
if (!s->planar_samples[ch])
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
}
|
}
|
||||||
|
|
|
@ -253,7 +253,7 @@ typedef struct AC3EncodeContext {
|
||||||
int ref_bap_set; ///< indicates if ref_bap pointers have been set
|
int ref_bap_set; ///< indicates if ref_bap pointers have been set
|
||||||
|
|
||||||
/** fixed vs. float function pointers */
|
/** fixed vs. float function pointers */
|
||||||
void (*encode_frame)(struct AC3EncodeContext *s);
|
void (*encode_frame)(struct AC3EncodeContext *s, uint8_t * const *samples);
|
||||||
|
|
||||||
/* AC-3 vs. E-AC-3 function pointers */
|
/* AC-3 vs. E-AC-3 function pointers */
|
||||||
void (*output_frame_header)(struct AC3EncodeContext *s);
|
void (*output_frame_header)(struct AC3EncodeContext *s);
|
||||||
|
|
|
@ -48,25 +48,33 @@
|
||||||
* This applies the KBD window and normalizes the input to reduce precision
|
* This applies the KBD window and normalizes the input to reduce precision
|
||||||
* loss due to fixed-point calculations.
|
* loss due to fixed-point calculations.
|
||||||
*/
|
*/
|
||||||
static void apply_mdct(AC3EncodeContext *s)
|
static void apply_mdct(AC3EncodeContext *s, uint8_t * const *samples)
|
||||||
{
|
{
|
||||||
int blk, ch;
|
int blk, ch;
|
||||||
|
|
||||||
for (ch = 0; ch < s->channels; ch++) {
|
for (ch = 0; ch < s->channels; ch++) {
|
||||||
|
const SampleType *input_samples0 = (const SampleType*)s->planar_samples[ch];
|
||||||
|
/* Reorder channels from native order to AC-3 order. */
|
||||||
|
const SampleType *input_samples1 = (const SampleType*)samples[s->channel_map[ch]];
|
||||||
|
|
||||||
for (blk = 0; blk < s->num_blocks; blk++) {
|
for (blk = 0; blk < s->num_blocks; blk++) {
|
||||||
AC3Block *block = &s->blocks[blk];
|
AC3Block *block = &s->blocks[blk];
|
||||||
const SampleType *input_samples = (SampleType*)s->planar_samples[ch] + blk * AC3_BLOCK_SIZE;
|
|
||||||
SampleType *windowed_samples = s->RENAME(windowed_samples);
|
SampleType *windowed_samples = s->RENAME(windowed_samples);
|
||||||
|
|
||||||
s->fdsp->vector_fmul(windowed_samples, input_samples,
|
s->fdsp->vector_fmul(windowed_samples, input_samples0,
|
||||||
s->RENAME(mdct_window), AC3_BLOCK_SIZE);
|
s->RENAME(mdct_window), AC3_BLOCK_SIZE);
|
||||||
s->fdsp->vector_fmul_reverse(windowed_samples + AC3_BLOCK_SIZE,
|
s->fdsp->vector_fmul_reverse(windowed_samples + AC3_BLOCK_SIZE,
|
||||||
&input_samples[AC3_BLOCK_SIZE],
|
input_samples1,
|
||||||
s->RENAME(mdct_window), AC3_BLOCK_SIZE);
|
s->RENAME(mdct_window), AC3_BLOCK_SIZE);
|
||||||
|
|
||||||
s->tx_fn(s->tx, block->mdct_coef[ch+1],
|
s->tx_fn(s->tx, block->mdct_coef[ch+1],
|
||||||
windowed_samples, sizeof(*windowed_samples));
|
windowed_samples, sizeof(*windowed_samples));
|
||||||
|
input_samples0 = input_samples1;
|
||||||
|
input_samples1 += AC3_BLOCK_SIZE;
|
||||||
}
|
}
|
||||||
|
/* Store last 256 samples of current frame */
|
||||||
|
memcpy(s->planar_samples[ch], input_samples0,
|
||||||
|
AC3_BLOCK_SIZE * sizeof(*input_samples0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -336,9 +344,9 @@ static void compute_rematrixing_strategy(AC3EncodeContext *s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void encode_frame(AC3EncodeContext *s)
|
static void encode_frame(AC3EncodeContext *s, uint8_t * const *samples)
|
||||||
{
|
{
|
||||||
apply_mdct(s);
|
apply_mdct(s, samples);
|
||||||
|
|
||||||
s->cpl_on = s->cpl_enabled;
|
s->cpl_on = s->cpl_enabled;
|
||||||
ff_ac3_compute_coupling_strategy(s);
|
ff_ac3_compute_coupling_strategy(s);
|
||||||
|
|
Loading…
Reference in New Issue