]> git.sesse.net Git - ffmpeg/blob - libavcodec/ac3enc_template.c
de6eba71d88977dddeee11a5562bbc30bba19b23
[ffmpeg] / libavcodec / ac3enc_template.c
1 /*
2  * AC-3 encoder float/fixed template
3  * Copyright (c) 2000 Fabrice Bellard
4  * Copyright (c) 2006-2011 Justin Ruggles <justin.ruggles@gmail.com>
5  * Copyright (c) 2006-2010 Prakash Punnoor <prakash@punnoor.de>
6  *
7  * This file is part of FFmpeg.
8  *
9  * FFmpeg is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * FFmpeg is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with FFmpeg; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  */
23
24 /**
25  * @file
26  * AC-3 encoder float/fixed template
27  */
28
29 #include <stdint.h>
30
31 #include "libavutil/attributes.h"
32 #include "libavutil/internal.h"
33 #include "libavutil/mem_internal.h"
34
35 #include "audiodsp.h"
36 #include "internal.h"
37 #include "ac3enc.h"
38 #include "eac3enc.h"
39
40
41 static int allocate_sample_buffers(AC3EncodeContext *s)
42 {
43     int ch;
44
45     if (!FF_ALLOC_TYPED_ARRAY(s->windowed_samples, AC3_WINDOW_SIZE) ||
46         !FF_ALLOCZ_TYPED_ARRAY(s->planar_samples,  s->channels))
47         return AVERROR(ENOMEM);
48
49     for (ch = 0; ch < s->channels; ch++) {
50         if (!(s->planar_samples[ch] = av_mallocz((AC3_FRAME_SIZE + AC3_BLOCK_SIZE) *
51                                                   sizeof(**s->planar_samples))))
52             return AVERROR(ENOMEM);
53     }
54     return 0;
55 }
56
57
58 /*
59  * Copy input samples.
60  * Channels are reordered from FFmpeg's default order to AC-3 order.
61  */
62 static void copy_input_samples(AC3EncodeContext *s, SampleType **samples)
63 {
64     int ch;
65
66     /* copy and remap input samples */
67     for (ch = 0; ch < s->channels; ch++) {
68         /* copy last 256 samples of previous frame to the start of the current frame */
69         memcpy(&s->planar_samples[ch][0], &s->planar_samples[ch][AC3_BLOCK_SIZE * s->num_blocks],
70                AC3_BLOCK_SIZE * sizeof(s->planar_samples[0][0]));
71
72         /* copy new samples for current frame */
73         memcpy(&s->planar_samples[ch][AC3_BLOCK_SIZE],
74                samples[s->channel_map[ch]],
75                AC3_BLOCK_SIZE * s->num_blocks * sizeof(s->planar_samples[0][0]));
76     }
77 }
78
79
80 /*
81  * Apply the MDCT to input samples to generate frequency coefficients.
82  * This applies the KBD window and normalizes the input to reduce precision
83  * loss due to fixed-point calculations.
84  */
85 static void apply_mdct(AC3EncodeContext *s)
86 {
87     int blk, ch;
88
89     for (ch = 0; ch < s->channels; ch++) {
90         for (blk = 0; blk < s->num_blocks; blk++) {
91             AC3Block *block = &s->blocks[blk];
92             const SampleType *input_samples = &s->planar_samples[ch][blk * AC3_BLOCK_SIZE];
93
94             s->fdsp->vector_fmul(s->windowed_samples, input_samples,
95                                  s->mdct_window, AC3_WINDOW_SIZE);
96
97             s->mdct.mdct_calc(&s->mdct, block->mdct_coef[ch+1],
98                               s->windowed_samples);
99         }
100     }
101 }
102
103
104 /*
105  * Calculate coupling channel and coupling coordinates.
106  */
107 static void apply_channel_coupling(AC3EncodeContext *s)
108 {
109     LOCAL_ALIGNED_16(CoefType, cpl_coords,      [AC3_MAX_BLOCKS], [AC3_MAX_CHANNELS][16]);
110 #if AC3ENC_FLOAT
111     LOCAL_ALIGNED_16(int32_t, fixed_cpl_coords, [AC3_MAX_BLOCKS], [AC3_MAX_CHANNELS][16]);
112 #else
113     int32_t (*fixed_cpl_coords)[AC3_MAX_CHANNELS][16] = cpl_coords;
114 #endif
115     int av_uninit(blk), ch, bnd, i, j;
116     CoefSumType energy[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][16] = {{{0}}};
117     int cpl_start, num_cpl_coefs;
118
119     memset(cpl_coords,       0, AC3_MAX_BLOCKS * sizeof(*cpl_coords));
120 #if AC3ENC_FLOAT
121     memset(fixed_cpl_coords, 0, AC3_MAX_BLOCKS * sizeof(*cpl_coords));
122 #endif
123
124     /* align start to 16-byte boundary. align length to multiple of 32.
125         note: coupling start bin % 4 will always be 1 */
126     cpl_start     = s->start_freq[CPL_CH] - 1;
127     num_cpl_coefs = FFALIGN(s->num_cpl_subbands * 12 + 1, 32);
128     cpl_start     = FFMIN(256, cpl_start + num_cpl_coefs) - num_cpl_coefs;
129
130     /* calculate coupling channel from fbw channels */
131     for (blk = 0; blk < s->num_blocks; blk++) {
132         AC3Block *block = &s->blocks[blk];
133         CoefType *cpl_coef = &block->mdct_coef[CPL_CH][cpl_start];
134         if (!block->cpl_in_use)
135             continue;
136         memset(cpl_coef, 0, num_cpl_coefs * sizeof(*cpl_coef));
137         for (ch = 1; ch <= s->fbw_channels; ch++) {
138             CoefType *ch_coef = &block->mdct_coef[ch][cpl_start];
139             if (!block->channel_in_cpl[ch])
140                 continue;
141             for (i = 0; i < num_cpl_coefs; i++)
142                 cpl_coef[i] += ch_coef[i];
143         }
144
145         /* coefficients must be clipped in order to be encoded */
146         clip_coefficients(&s->adsp, cpl_coef, num_cpl_coefs);
147     }
148
149     /* calculate energy in each band in coupling channel and each fbw channel */
150     /* TODO: possibly use SIMD to speed up energy calculation */
151     bnd = 0;
152     i = s->start_freq[CPL_CH];
153     while (i < s->cpl_end_freq) {
154         int band_size = s->cpl_band_sizes[bnd];
155         for (ch = CPL_CH; ch <= s->fbw_channels; ch++) {
156             for (blk = 0; blk < s->num_blocks; blk++) {
157                 AC3Block *block = &s->blocks[blk];
158                 if (!block->cpl_in_use || (ch > CPL_CH && !block->channel_in_cpl[ch]))
159                     continue;
160                 for (j = 0; j < band_size; j++) {
161                     CoefType v = block->mdct_coef[ch][i+j];
162                     MAC_COEF(energy[blk][ch][bnd], v, v);
163                 }
164             }
165         }
166         i += band_size;
167         bnd++;
168     }
169
170     /* calculate coupling coordinates for all blocks for all channels */
171     for (blk = 0; blk < s->num_blocks; blk++) {
172         AC3Block *block  = &s->blocks[blk];
173         if (!block->cpl_in_use)
174             continue;
175         for (ch = 1; ch <= s->fbw_channels; ch++) {
176             if (!block->channel_in_cpl[ch])
177                 continue;
178             for (bnd = 0; bnd < s->num_cpl_bands; bnd++) {
179                 cpl_coords[blk][ch][bnd] = calc_cpl_coord(energy[blk][ch][bnd],
180                                                           energy[blk][CPL_CH][bnd]);
181             }
182         }
183     }
184
185     /* determine which blocks to send new coupling coordinates for */
186     for (blk = 0; blk < s->num_blocks; blk++) {
187         AC3Block *block  = &s->blocks[blk];
188         AC3Block *block0 = blk ? &s->blocks[blk-1] : NULL;
189
190         memset(block->new_cpl_coords, 0, sizeof(block->new_cpl_coords));
191
192         if (block->cpl_in_use) {
193             /* send new coordinates if this is the first block, if previous
194              * block did not use coupling but this block does, the channels
195              * using coupling has changed from the previous block, or the
196              * coordinate difference from the last block for any channel is
197              * greater than a threshold value. */
198             if (blk == 0 || !block0->cpl_in_use) {
199                 for (ch = 1; ch <= s->fbw_channels; ch++)
200                     block->new_cpl_coords[ch] = 1;
201             } else {
202                 for (ch = 1; ch <= s->fbw_channels; ch++) {
203                     if (!block->channel_in_cpl[ch])
204                         continue;
205                     if (!block0->channel_in_cpl[ch]) {
206                         block->new_cpl_coords[ch] = 1;
207                     } else {
208                         CoefSumType coord_diff = 0;
209                         for (bnd = 0; bnd < s->num_cpl_bands; bnd++) {
210                             coord_diff += FFABS(cpl_coords[blk-1][ch][bnd] -
211                                                 cpl_coords[blk  ][ch][bnd]);
212                         }
213                         coord_diff /= s->num_cpl_bands;
214                         if (coord_diff > NEW_CPL_COORD_THRESHOLD)
215                             block->new_cpl_coords[ch] = 1;
216                     }
217                 }
218             }
219         }
220     }
221
222     /* calculate final coupling coordinates, taking into account reusing of
223        coordinates in successive blocks */
224     for (bnd = 0; bnd < s->num_cpl_bands; bnd++) {
225         blk = 0;
226         while (blk < s->num_blocks) {
227             int av_uninit(blk1);
228             AC3Block *block  = &s->blocks[blk];
229
230             if (!block->cpl_in_use) {
231                 blk++;
232                 continue;
233             }
234
235             for (ch = 1; ch <= s->fbw_channels; ch++) {
236                 CoefSumType energy_ch, energy_cpl;
237                 if (!block->channel_in_cpl[ch])
238                     continue;
239                 energy_cpl = energy[blk][CPL_CH][bnd];
240                 energy_ch = energy[blk][ch][bnd];
241                 blk1 = blk+1;
242                 while (blk1 < s->num_blocks && !s->blocks[blk1].new_cpl_coords[ch]) {
243                     if (s->blocks[blk1].cpl_in_use) {
244                         energy_cpl += energy[blk1][CPL_CH][bnd];
245                         energy_ch += energy[blk1][ch][bnd];
246                     }
247                     blk1++;
248                 }
249                 cpl_coords[blk][ch][bnd] = calc_cpl_coord(energy_ch, energy_cpl);
250             }
251             blk = blk1;
252         }
253     }
254
255     /* calculate exponents/mantissas for coupling coordinates */
256     for (blk = 0; blk < s->num_blocks; blk++) {
257         AC3Block *block = &s->blocks[blk];
258         if (!block->cpl_in_use)
259             continue;
260
261 #if AC3ENC_FLOAT
262         s->ac3dsp.float_to_fixed24(fixed_cpl_coords[blk][1],
263                                    cpl_coords[blk][1],
264                                    s->fbw_channels * 16);
265 #endif
266         s->ac3dsp.extract_exponents(block->cpl_coord_exp[1],
267                                     fixed_cpl_coords[blk][1],
268                                     s->fbw_channels * 16);
269
270         for (ch = 1; ch <= s->fbw_channels; ch++) {
271             int bnd, min_exp, max_exp, master_exp;
272
273             if (!block->new_cpl_coords[ch])
274                 continue;
275
276             /* determine master exponent */
277             min_exp = max_exp = block->cpl_coord_exp[ch][0];
278             for (bnd = 1; bnd < s->num_cpl_bands; bnd++) {
279                 int exp = block->cpl_coord_exp[ch][bnd];
280                 min_exp = FFMIN(exp, min_exp);
281                 max_exp = FFMAX(exp, max_exp);
282             }
283             master_exp = ((max_exp - 15) + 2) / 3;
284             master_exp = FFMAX(master_exp, 0);
285             while (min_exp < master_exp * 3)
286                 master_exp--;
287             for (bnd = 0; bnd < s->num_cpl_bands; bnd++) {
288                 block->cpl_coord_exp[ch][bnd] = av_clip(block->cpl_coord_exp[ch][bnd] -
289                                                         master_exp * 3, 0, 15);
290             }
291             block->cpl_master_exp[ch] = master_exp;
292
293             /* quantize mantissas */
294             for (bnd = 0; bnd < s->num_cpl_bands; bnd++) {
295                 int cpl_exp  = block->cpl_coord_exp[ch][bnd];
296                 int cpl_mant = (fixed_cpl_coords[blk][ch][bnd] << (5 + cpl_exp + master_exp * 3)) >> 24;
297                 if (cpl_exp == 15)
298                     cpl_mant >>= 1;
299                 else
300                     cpl_mant -= 16;
301
302                 block->cpl_coord_mant[ch][bnd] = cpl_mant;
303             }
304         }
305     }
306
307     if (AC3ENC_FLOAT && CONFIG_EAC3_ENCODER && s->eac3)
308         ff_eac3_set_cpl_states(s);
309 }
310
311
312 /*
313  * Determine rematrixing flags for each block and band.
314  */
315 static void compute_rematrixing_strategy(AC3EncodeContext *s)
316 {
317     int nb_coefs;
318     int blk, bnd;
319     AC3Block *block, *block0 = NULL;
320
321     if (s->channel_mode != AC3_CHMODE_STEREO)
322         return;
323
324     for (blk = 0; blk < s->num_blocks; blk++) {
325         block = &s->blocks[blk];
326         block->new_rematrixing_strategy = !blk;
327
328         block->num_rematrixing_bands = 4;
329         if (block->cpl_in_use) {
330             block->num_rematrixing_bands -= (s->start_freq[CPL_CH] <= 61);
331             block->num_rematrixing_bands -= (s->start_freq[CPL_CH] == 37);
332             if (blk && block->num_rematrixing_bands != block0->num_rematrixing_bands)
333                 block->new_rematrixing_strategy = 1;
334         }
335         nb_coefs = FFMIN(block->end_freq[1], block->end_freq[2]);
336
337         if (!s->rematrixing_enabled) {
338             block0 = block;
339             continue;
340         }
341
342         for (bnd = 0; bnd < block->num_rematrixing_bands; bnd++) {
343             /* calculate sum of squared coeffs for one band in one block */
344             int start = ff_ac3_rematrix_band_tab[bnd];
345             int end   = FFMIN(nb_coefs, ff_ac3_rematrix_band_tab[bnd+1]);
346             CoefSumType sum[4];
347             sum_square_butterfly(s, sum, block->mdct_coef[1] + start,
348                                  block->mdct_coef[2] + start, end - start);
349
350             /* compare sums to determine if rematrixing will be used for this band */
351             if (FFMIN(sum[2], sum[3]) < FFMIN(sum[0], sum[1]))
352                 block->rematrixing_flags[bnd] = 1;
353             else
354                 block->rematrixing_flags[bnd] = 0;
355
356             /* determine if new rematrixing flags will be sent */
357             if (blk &&
358                 block->rematrixing_flags[bnd] != block0->rematrixing_flags[bnd]) {
359                 block->new_rematrixing_strategy = 1;
360             }
361         }
362         block0 = block;
363     }
364 }
365
366
367 int AC3_NAME(encode_frame)(AVCodecContext *avctx, AVPacket *avpkt,
368                            const AVFrame *frame, int *got_packet_ptr)
369 {
370     AC3EncodeContext *s = avctx->priv_data;
371     int ret;
372
373     if (s->options.allow_per_frame_metadata) {
374         ret = ff_ac3_validate_metadata(s);
375         if (ret)
376             return ret;
377     }
378
379     if (s->bit_alloc.sr_code == 1 || (AC3ENC_FLOAT && s->eac3))
380         ff_ac3_adjust_frame_size(s);
381
382     copy_input_samples(s, (SampleType **)frame->extended_data);
383
384     apply_mdct(s);
385
386     clip_coefficients(&s->adsp, s->blocks[0].mdct_coef[1],
387                       AC3_MAX_COEFS * s->num_blocks * s->channels);
388
389     s->cpl_on = s->cpl_enabled;
390     ff_ac3_compute_coupling_strategy(s);
391
392     if (s->cpl_on)
393         apply_channel_coupling(s);
394
395     compute_rematrixing_strategy(s);
396
397 #if AC3ENC_FLOAT
398     scale_coefficients(s);
399 #endif
400
401     return ff_ac3_encode_frame_common_end(avctx, avpkt, frame, got_packet_ptr);
402 }