---
 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

Reply via email to