---
libavcodec/ac3enc.c | 73 +++++++++++++++++++++++++++++++++++---------------
1 files changed, 51 insertions(+), 22 deletions(-)
diff --git libavcodec/ac3enc.c libavcodec/ac3enc.c
index fc8ae06..0b32b36 100644
--- libavcodec/ac3enc.c
+++ libavcodec/ac3enc.c
@@ -73,7 +73,8 @@ typedef struct AC3EncodeContext {
/* mantissa encoding */
int mant1_cnt, mant2_cnt, mant4_cnt; ///< matissa counts for bap=1,2,4
- int16_t last_samples[AC3_MAX_CHANNELS][AC3_BLOCK_SIZE]; ///< last 256 samples from previous frame
+ int16_t *windowed_samples; ///< windowed samples for the current block
+ int16_t *planar_samples[AC3_MAX_CHANNELS]; ///< full input frame, deinterleaved
} AC3EncodeContext;
/**
@@ -747,10 +748,22 @@ static av_cold int AC3_encode_init(AVCodecContext *avctx)
exponent_group_tab[1][7] =
exponent_group_tab[2][7] = 2;
+ /* allocate context arrays */
+ FF_ALLOC_OR_GOTO(avctx, s->windowed_samples,
+ AC3_BLOCK_SIZE*2 * sizeof(*s->windowed_samples),
+ alloc_fail);
+ for (ch = 0; ch < s->channels; ch++) {
+ FF_ALLOCZ_OR_GOTO(avctx, s->planar_samples[ch],
+ (AC3_FRAME_SIZE+AC3_BLOCK_SIZE) * sizeof(*s->planar_samples[0]),
+ alloc_fail)
+ }
+
avctx->coded_frame = avcodec_alloc_frame();
avctx->coded_frame->key_frame= 1;
return 0;
+alloc_fail:
+ return AVERROR(ENOMEM);
}
/* output the AC-3 frame header */
@@ -1146,13 +1159,32 @@ static int output_frame_end(AC3EncodeContext *s)
return frame_size * 2;
}
+static void deinterleave_samples(AC3EncodeContext *s, const int16_t *samples)
+{
+ int ch, i;
+ const int16_t *smp;
+
+ /* copy last 256 samples of previous frame to the start of the current frame */
+ for (ch = 0; ch < s->channels; ch++) {
+ memcpy(&s->planar_samples[ch][0], &s->planar_samples[ch][AC3_FRAME_SIZE],
+ AC3_BLOCK_SIZE * sizeof(int16_t));
+ }
+
+ /* deinterleave and remap input samples */
+ for (ch = 0; ch < s->channels; ch++) {
+ smp = samples + s->channel_map[ch];
+ for (i = AC3_BLOCK_SIZE; i < AC3_FRAME_SIZE+AC3_BLOCK_SIZE; i++) {
+ s->planar_samples[ch][i] = *smp;
+ smp += s->channels;
+ }
+ }
+}
+
static int AC3_encode_frame(AVCodecContext *avctx,
unsigned char *frame, int buf_size, void *data)
{
AC3EncodeContext *s = avctx->priv_data;
- const int16_t *samples = data;
int i, j, k, v, ch;
- int16_t input_samples[AC3_BLOCK_SIZE*2];
int32_t mdct_coef[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][AC3_MAX_COEFS];
uint8_t exp[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][AC3_MAX_COEFS];
uint8_t exp_strategy[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS];
@@ -1160,41 +1192,30 @@ static int AC3_encode_frame(AVCodecContext *avctx,
int8_t exp_samples[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS];
int frame_bits;
+ deinterleave_samples(s, data);
+
frame_bits = 0;
for (ch = 0; ch < s->channels; ch++) {
- int ich = s->channel_map[ch];
/* fixed mdct to the six sub blocks & exponent computation */
for (i = 0; i < AC3_MAX_BLOCKS; i++) {
- const int16_t *sptr;
- int sinc;
-
- /* compute input samples */
- memcpy(input_samples, s->last_samples[ich], AC3_BLOCK_SIZE * sizeof(int16_t));
- sinc = s->channels;
- sptr = samples + (sinc * AC3_BLOCK_SIZE * i) + ich;
- for (j = 0; j < AC3_BLOCK_SIZE; j++) {
- v = *sptr;
- input_samples[j + AC3_BLOCK_SIZE] = v;
- s->last_samples[ich][j] = v;
- sptr += sinc;
- }
+ int16_t *input_samples = &s->planar_samples[ch][i * AC3_BLOCK_SIZE];
/* apply the MDCT window */
for (j = 0; j < AC3_BLOCK_SIZE; j++) {
- input_samples[j] = MUL16(input_samples[j],
+ s->windowed_samples[j] = MUL16(input_samples[j],
ff_ac3_window[j]) >> 15;
- input_samples[AC3_BLOCK_SIZE*2-j-1] = MUL16(input_samples[AC3_BLOCK_SIZE*2-j-1],
+ s->windowed_samples[AC3_BLOCK_SIZE*2-j-1] = MUL16(input_samples[AC3_BLOCK_SIZE*2-j-1],
ff_ac3_window[j]) >> 15;
}
/* Normalize the samples to use the maximum available precision */
- v = 14 - log2_tab(input_samples, AC3_BLOCK_SIZE*2);
+ v = 14 - log2_tab(s->windowed_samples, AC3_BLOCK_SIZE*2);
v = FFMAX(0, v);
exp_samples[i][ch] = v - 9;
- lshift_tab(input_samples, AC3_BLOCK_SIZE*2, v);
+ lshift_tab(s->windowed_samples, AC3_BLOCK_SIZE*2, v);
/* do the MDCT */
- mdct512(mdct_coef[i][ch], input_samples);
+ mdct512(mdct_coef[i][ch], s->windowed_samples);
/* compute "exponents". We take into account the normalization there */
for (j = 0; j < AC3_MAX_COEFS; j++) {
@@ -1258,6 +1279,14 @@ static int AC3_encode_frame(AVCodecContext *avctx,
static av_cold int AC3_encode_close(AVCodecContext *avctx)
{
+ AC3EncodeContext *s = avctx->priv_data;
+ int ch;
+
+ av_freep(&s->windowed_samples);
+ for (ch = 0; ch < s->channels; ch++) {
+ av_freep(&s->planar_samples[ch]);
+ }
+
av_freep(&avctx->coded_frame);
return 0;
}
_______________________________________________
FFmpeg-soc mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/ffmpeg-soc