FFmpeg
ac3enc_template.c
Go to the documentation of this file.
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 "config_components.h"
30 
31 #include <stdint.h>
32 
33 #include "libavutil/attributes.h"
34 #include "libavutil/mem_internal.h"
35 
36 #include "audiodsp.h"
37 #include "ac3enc.h"
38 #include "eac3enc.h"
39 
40 #if AC3ENC_FLOAT
41 #define RENAME(element) element ## _float
42 #else
43 #define RENAME(element) element ## _fixed
44 #endif
45 
46 /*
47  * Apply the MDCT to input samples to generate frequency coefficients.
48  * This applies the KBD window and normalizes the input to reduce precision
49  * loss due to fixed-point calculations.
50  */
51 static void apply_mdct(AC3EncodeContext *s, uint8_t * const *samples)
52 {
53  int blk, ch;
54 
55  for (ch = 0; ch < s->channels; ch++) {
56  const SampleType *input_samples0 = (const SampleType*)s->planar_samples[ch];
57  /* Reorder channels from native order to AC-3 order. */
58  const SampleType *input_samples1 = (const SampleType*)samples[s->channel_map[ch]];
59 
60  for (blk = 0; blk < s->num_blocks; blk++) {
61  AC3Block *block = &s->blocks[blk];
62  SampleType *windowed_samples = s->RENAME(windowed_samples);
63 
64  s->fdsp->vector_fmul(windowed_samples, input_samples0,
65  s->RENAME(mdct_window), AC3_BLOCK_SIZE);
66  s->fdsp->vector_fmul_reverse(windowed_samples + AC3_BLOCK_SIZE,
67  input_samples1,
68  s->RENAME(mdct_window), AC3_BLOCK_SIZE);
69 
70  s->tx_fn(s->tx, block->mdct_coef[ch+1],
71  windowed_samples, sizeof(*windowed_samples));
72  input_samples0 = input_samples1;
73  input_samples1 += AC3_BLOCK_SIZE;
74  }
75  /* Store last 256 samples of current frame */
76  memcpy(s->planar_samples[ch], input_samples0,
77  AC3_BLOCK_SIZE * sizeof(*input_samples0));
78  }
79 }
80 
81 
82 /*
83  * Calculate coupling channel and coupling coordinates.
84  */
86 {
88 #if AC3ENC_FLOAT
89  LOCAL_ALIGNED_32(int32_t, fixed_cpl_coords, [AC3_MAX_BLOCKS], [AC3_MAX_CHANNELS][16]);
90 #else
91  int32_t (*fixed_cpl_coords)[AC3_MAX_CHANNELS][16] = cpl_coords;
92 #endif
93  int av_uninit(blk), ch, bnd, i, j;
94  CoefSumType energy[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][16] = {{{0}}};
95  int cpl_start, num_cpl_coefs;
96 
97  memset(cpl_coords, 0, AC3_MAX_BLOCKS * sizeof(*cpl_coords));
98 #if AC3ENC_FLOAT
99  memset(fixed_cpl_coords, 0, AC3_MAX_BLOCKS * sizeof(*cpl_coords));
100 #endif
101 
102  /* align start to 16-byte boundary. align length to multiple of 32.
103  note: coupling start bin % 4 will always be 1 */
104  cpl_start = s->start_freq[CPL_CH] - 1;
105  num_cpl_coefs = FFALIGN(s->num_cpl_subbands * 12 + 1, 32);
106  cpl_start = FFMIN(256, cpl_start + num_cpl_coefs) - num_cpl_coefs;
107 
108  /* calculate coupling channel from fbw channels */
109  for (blk = 0; blk < s->num_blocks; blk++) {
110  AC3Block *block = &s->blocks[blk];
111  CoefType *cpl_coef = &block->mdct_coef[CPL_CH][cpl_start];
112  if (!block->cpl_in_use)
113  continue;
114  memset(cpl_coef, 0, num_cpl_coefs * sizeof(*cpl_coef));
115  for (ch = 1; ch <= s->fbw_channels; ch++) {
116  CoefType *ch_coef = &block->mdct_coef[ch][cpl_start];
117  if (!block->channel_in_cpl[ch])
118  continue;
119  for (i = 0; i < num_cpl_coefs; i++)
120  cpl_coef[i] += ch_coef[i];
121  }
122 
123  /* coefficients must be clipped in order to be encoded */
124  clip_coefficients(&s->adsp, cpl_coef, num_cpl_coefs);
125  }
126 
127  /* calculate energy in each band in coupling channel and each fbw channel */
128  /* TODO: possibly use SIMD to speed up energy calculation */
129  bnd = 0;
130  i = s->start_freq[CPL_CH];
131  while (i < s->cpl_end_freq) {
132  int band_size = s->cpl_band_sizes[bnd];
133  for (ch = CPL_CH; ch <= s->fbw_channels; ch++) {
134  for (blk = 0; blk < s->num_blocks; blk++) {
135  AC3Block *block = &s->blocks[blk];
136  if (!block->cpl_in_use || (ch > CPL_CH && !block->channel_in_cpl[ch]))
137  continue;
138  for (j = 0; j < band_size; j++) {
139  CoefType v = block->mdct_coef[ch][i+j];
140  MAC_COEF(energy[blk][ch][bnd], v, v);
141  }
142  }
143  }
144  i += band_size;
145  bnd++;
146  }
147 
148  /* calculate coupling coordinates for all blocks for all channels */
149  for (blk = 0; blk < s->num_blocks; blk++) {
150  AC3Block *block = &s->blocks[blk];
151  if (!block->cpl_in_use)
152  continue;
153  for (ch = 1; ch <= s->fbw_channels; ch++) {
154  if (!block->channel_in_cpl[ch])
155  continue;
156  for (bnd = 0; bnd < s->num_cpl_bands; bnd++) {
157  cpl_coords[blk][ch][bnd] = calc_cpl_coord(energy[blk][ch][bnd],
158  energy[blk][CPL_CH][bnd]);
159  }
160  }
161  }
162 
163  /* determine which blocks to send new coupling coordinates for */
164  for (blk = 0; blk < s->num_blocks; blk++) {
165  AC3Block *block = &s->blocks[blk];
166  AC3Block *block0 = blk ? &s->blocks[blk-1] : NULL;
167 
168  memset(block->new_cpl_coords, 0, sizeof(block->new_cpl_coords));
169 
170  if (block->cpl_in_use) {
171  /* send new coordinates if this is the first block, if previous
172  * block did not use coupling but this block does, the channels
173  * using coupling has changed from the previous block, or the
174  * coordinate difference from the last block for any channel is
175  * greater than a threshold value. */
176  if (blk == 0 || !block0->cpl_in_use) {
177  for (ch = 1; ch <= s->fbw_channels; ch++)
178  block->new_cpl_coords[ch] = 1;
179  } else {
180  for (ch = 1; ch <= s->fbw_channels; ch++) {
181  if (!block->channel_in_cpl[ch])
182  continue;
183  if (!block0->channel_in_cpl[ch]) {
184  block->new_cpl_coords[ch] = 1;
185  } else {
186  CoefSumType coord_diff = 0;
187  for (bnd = 0; bnd < s->num_cpl_bands; bnd++) {
188  coord_diff += FFABS(cpl_coords[blk-1][ch][bnd] -
189  cpl_coords[blk ][ch][bnd]);
190  }
191  coord_diff /= s->num_cpl_bands;
192  if (coord_diff > NEW_CPL_COORD_THRESHOLD)
193  block->new_cpl_coords[ch] = 1;
194  }
195  }
196  }
197  }
198  }
199 
200  av_assert1(s->fbw_channels > 0);
201 
202  /* calculate final coupling coordinates, taking into account reusing of
203  coordinates in successive blocks */
204  for (bnd = 0; bnd < s->num_cpl_bands; bnd++) {
205  blk = 0;
206  while (blk < s->num_blocks) {
207  int av_uninit(blk1);
208  AC3Block *block = &s->blocks[blk];
209 
210  if (!block->cpl_in_use) {
211  blk++;
212  continue;
213  }
214 
215  for (ch = 1; ch <= s->fbw_channels; ch++) {
216  CoefSumType energy_ch, energy_cpl;
217  if (!block->channel_in_cpl[ch])
218  continue;
219  energy_cpl = energy[blk][CPL_CH][bnd];
220  energy_ch = energy[blk][ch][bnd];
221  blk1 = blk+1;
222  while (blk1 < s->num_blocks && !s->blocks[blk1].new_cpl_coords[ch]) {
223  if (s->blocks[blk1].cpl_in_use) {
224  energy_cpl += energy[blk1][CPL_CH][bnd];
225  energy_ch += energy[blk1][ch][bnd];
226  }
227  blk1++;
228  }
229  cpl_coords[blk][ch][bnd] = calc_cpl_coord(energy_ch, energy_cpl);
230  }
231  blk = blk1;
232  }
233  }
234 
235  /* calculate exponents/mantissas for coupling coordinates */
236  for (blk = 0; blk < s->num_blocks; blk++) {
237  AC3Block *block = &s->blocks[blk];
238  if (!block->cpl_in_use)
239  continue;
240 
241 #if AC3ENC_FLOAT
242  s->ac3dsp.float_to_fixed24(fixed_cpl_coords[blk][1],
243  cpl_coords[blk][1],
244  s->fbw_channels * 16);
245 #endif
246  s->ac3dsp.extract_exponents(block->cpl_coord_exp[1],
247  fixed_cpl_coords[blk][1],
248  s->fbw_channels * 16);
249 
250  for (ch = 1; ch <= s->fbw_channels; ch++) {
251  int bnd, min_exp, max_exp, master_exp;
252 
253  if (!block->new_cpl_coords[ch])
254  continue;
255 
256  /* determine master exponent */
257  min_exp = max_exp = block->cpl_coord_exp[ch][0];
258  for (bnd = 1; bnd < s->num_cpl_bands; bnd++) {
259  int exp = block->cpl_coord_exp[ch][bnd];
260  min_exp = FFMIN(exp, min_exp);
261  max_exp = FFMAX(exp, max_exp);
262  }
263  master_exp = ((max_exp - 15) + 2) / 3;
264  master_exp = FFMAX(master_exp, 0);
265  while (min_exp < master_exp * 3)
266  master_exp--;
267  for (bnd = 0; bnd < s->num_cpl_bands; bnd++) {
268  block->cpl_coord_exp[ch][bnd] = av_clip(block->cpl_coord_exp[ch][bnd] -
269  master_exp * 3, 0, 15);
270  }
271  block->cpl_master_exp[ch] = master_exp;
272 
273  /* quantize mantissas */
274  for (bnd = 0; bnd < s->num_cpl_bands; bnd++) {
275  int cpl_exp = block->cpl_coord_exp[ch][bnd];
276  int cpl_mant = (fixed_cpl_coords[blk][ch][bnd] << (5 + cpl_exp + master_exp * 3)) >> 24;
277  if (cpl_exp == 15)
278  cpl_mant >>= 1;
279  else
280  cpl_mant -= 16;
281 
282  block->cpl_coord_mant[ch][bnd] = cpl_mant;
283  }
284  }
285  }
286 
287  if (AC3ENC_FLOAT && CONFIG_EAC3_ENCODER && s->eac3)
289 }
290 
291 
292 /*
293  * Determine rematrixing flags for each block and band.
294  */
296 {
297  int nb_coefs;
298  int blk, bnd;
299  AC3Block *block, *block0 = NULL;
300 
301  if (s->channel_mode != AC3_CHMODE_STEREO)
302  return;
303 
304  for (blk = 0; blk < s->num_blocks; blk++) {
305  block = &s->blocks[blk];
306  block->new_rematrixing_strategy = !blk;
307 
308  block->num_rematrixing_bands = 4;
309  if (block->cpl_in_use) {
310  block->num_rematrixing_bands -= (s->start_freq[CPL_CH] <= 61);
311  block->num_rematrixing_bands -= (s->start_freq[CPL_CH] == 37);
312  if (blk && block->num_rematrixing_bands != block0->num_rematrixing_bands)
313  block->new_rematrixing_strategy = 1;
314  }
315  nb_coefs = FFMIN(block->end_freq[1], block->end_freq[2]);
316 
317  if (!s->rematrixing_enabled) {
318  block0 = block;
319  continue;
320  }
321 
322  for (bnd = 0; bnd < block->num_rematrixing_bands; bnd++) {
323  /* calculate sum of squared coeffs for one band in one block */
324  int start = ff_ac3_rematrix_band_tab[bnd];
325  int end = FFMIN(nb_coefs, ff_ac3_rematrix_band_tab[bnd+1]);
326  CoefSumType sum[4];
327  sum_square_butterfly(s, sum, block->mdct_coef[1] + start,
328  block->mdct_coef[2] + start, end - start);
329 
330  /* compare sums to determine if rematrixing will be used for this band */
331  if (FFMIN(sum[2], sum[3]) < FFMIN(sum[0], sum[1]))
332  block->rematrixing_flags[bnd] = 1;
333  else
334  block->rematrixing_flags[bnd] = 0;
335 
336  /* determine if new rematrixing flags will be sent */
337  if (blk &&
338  block->rematrixing_flags[bnd] != block0->rematrixing_flags[bnd]) {
339  block->new_rematrixing_strategy = 1;
340  }
341  }
342  block0 = block;
343  }
344 }
345 
346 
347 static void encode_frame(AC3EncodeContext *s, uint8_t * const *samples)
348 {
349  apply_mdct(s, samples);
350 
351  s->cpl_on = s->cpl_enabled;
353 
354  if (s->cpl_on)
356 
358 
359 #if AC3ENC_FLOAT
361 #endif
362 }
nb_coefs
static int nb_coefs(int length, int level, uint64_t sn)
Definition: af_afwtdn.c:515
av_clip
#define av_clip
Definition: common.h:99
mem_internal.h
ff_ac3_compute_coupling_strategy
void ff_ac3_compute_coupling_strategy(AC3EncodeContext *s)
Set the initial coupling strategy parameters prior to coupling analysis.
Definition: ac3enc.c:511
AC3Block::channel_in_cpl
uint8_t channel_in_cpl[AC3_MAX_CHANNELS]
channel in coupling (chincpl)
Definition: ac3enc.h:145
SampleType
int32_t SampleType
Definition: ac3enc.h:66
apply_mdct
static void apply_mdct(AC3EncodeContext *s, uint8_t *const *samples)
Definition: ac3enc_template.c:51
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
ff_eac3_set_cpl_states
void ff_eac3_set_cpl_states(AC3EncodeContext *s)
Set coupling states.
Definition: eac3enc.c:97
encode_frame
static void encode_frame(AC3EncodeContext *s, uint8_t *const *samples)
Definition: ac3enc_template.c:347
s
#define s(width, name)
Definition: cbs_vp9.c:198
blk
#define blk(i)
Definition: sha.c:186
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:73
NULL
#define NULL
Definition: coverity.c:32
LOCAL_ALIGNED_32
#define LOCAL_ALIGNED_32(t, v,...)
Definition: mem_internal.h:156
ac3enc.h
CoefSumType
int64_t CoefSumType
Definition: ac3enc.h:68
AC3EncodeContext
AC-3 encoder private context.
Definition: ac3enc.h:157
AC3_MAX_CHANNELS
#define AC3_MAX_CHANNELS
maximum number of channels, including coupling channel
Definition: ac3defs.h:26
exp
int8_t exp
Definition: eval.c:73
AC3Block
Data for a single audio block.
Definition: ac3enc.h:129
scale_coefficients
static void scale_coefficients(AC3EncodeContext *s)
Definition: ac3enc_float.c:40
AC3_CHMODE_STEREO
@ AC3_CHMODE_STEREO
Definition: ac3defs.h:57
clip_coefficients
static void clip_coefficients(AudioDSPContext *adsp, int32_t *coef, unsigned int len)
Definition: ac3enc_fixed.c:46
AC3_BLOCK_SIZE
#define AC3_BLOCK_SIZE
Definition: ac3defs.h:30
apply_channel_coupling
static void apply_channel_coupling(AC3EncodeContext *s)
Definition: ac3enc_template.c:85
calc_cpl_coord
static CoefType calc_cpl_coord(CoefSumType energy_ch, CoefSumType energy_cpl)
Definition: ac3enc_fixed.c:56
attributes.h
eac3enc.h
ff_ac3_rematrix_band_tab
const uint8_t ff_ac3_rematrix_band_tab[5]
Table of bin locations for rematrixing bands reference: Section 7.5.2 Rematrixing : Frequency Band De...
Definition: ac3tab.c:107
CPL_CH
#define CPL_CH
coupling channel index
Definition: ac3defs.h:27
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
AC3Block::rematrixing_flags
uint8_t rematrixing_flags[4]
rematrixing flags
Definition: ac3enc.h:142
av_assert1
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition: avassert.h:56
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
compute_rematrixing_strategy
static void compute_rematrixing_strategy(AC3EncodeContext *s)
Definition: ac3enc_template.c:295
AC3_MAX_BLOCKS
#define AC3_MAX_BLOCKS
Definition: ac3defs.h:31
sum_square_butterfly
static void sum_square_butterfly(AC3EncodeContext *s, int64_t sum[4], const int32_t *coef0, const int32_t *coef1, int len)
Definition: ac3enc_fixed.c:36
av_uninit
#define av_uninit(x)
Definition: attributes.h:154
AC3Block::num_rematrixing_bands
int num_rematrixing_bands
number of rematrixing bands
Definition: ac3enc.h:141
CoefType
int32_t CoefType
Definition: ac3enc.h:67
samples
Filter the word “frame” indicates either a video frame or a group of audio samples
Definition: filter_design.txt:8
audiodsp.h
MAC_COEF
#define MAC_COEF(d, a, b)
Definition: ac3enc.h:62
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
int32_t
int32_t
Definition: audioconvert.c:56
block
The exact code depends on how similar the blocks are and how related they are to the block
Definition: filter_design.txt:207
AC3ENC_FLOAT
#define AC3ENC_FLOAT
Definition: ac3enc.h:48
AC3Block::cpl_in_use
int cpl_in_use
coupling in use for this block (cplinu)
Definition: ac3enc.h:144
mdct_window
static float mdct_window[MDCT_SIZE]
Definition: atrac3.c:125
NEW_CPL_COORD_THRESHOLD
#define NEW_CPL_COORD_THRESHOLD
Definition: ac3enc.h:65