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