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 
350 {
351  int end = frame ? frame->nb_samples : 0;
352 
353  /* copy new samples and zero any remaining samples */
354  if (frame) {
355  av_samples_copy(s->input_samples, frame->extended_data, 0, 0,
356  frame->nb_samples, s->channels,
357  s->avctx->sample_fmt);
358  }
359  av_samples_set_silence(s->input_samples, end,
360  s->avctx->frame_size - end,
361  s->channels, s->avctx->sample_fmt);
362 }
363 
365 {
366  uint8_t **samples;
367 
368  if (!frame || frame->nb_samples < s->avctx->frame_size) {
370  samples = s->input_samples;
371  } else
372  samples = frame->extended_data;
373 
374  apply_mdct(s, samples);
375 
376  s->cpl_on = s->cpl_enabled;
378 
379  if (s->cpl_on)
381 
383 
384 #if AC3ENC_FLOAT
386 #endif
387 }
copy_input_samples
static void copy_input_samples(AC3EncodeContext *s, const AVFrame *frame)
Definition: ac3enc_template.c:349
av_samples_copy
int av_samples_copy(uint8_t *const *dst, uint8_t *const *src, int dst_offset, int src_offset, int nb_samples, int nb_channels, enum AVSampleFormat sample_fmt)
Copy samples from src to dst.
Definition: samplefmt.c:222
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:100
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:507
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
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:466
av_samples_set_silence
int av_samples_set_silence(uint8_t *const *audio_data, int offset, int nb_samples, int nb_channels, enum AVSampleFormat sample_fmt)
Fill an audio buffer with silence.
Definition: samplefmt.c:246
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
avassert.h
encode_frame
static void encode_frame(AC3EncodeContext *s, const AVFrame *frame)
Definition: ac3enc_template.c:364
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:74
NULL
#define NULL
Definition: coverity.c:32
LOCAL_ALIGNED_32
#define LOCAL_ALIGNED_32(t, v,...)
Definition: mem_internal.h:132
ac3enc.h
CoefSumType
int64_t CoefSumType
Definition: ac3enc.h:68
attributes.h
AC3EncodeContext
AC-3 encoder private context.
Definition: ac3enc.h:159
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:76
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:70
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
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
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
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:108
CPL_CH
#define CPL_CH
coupling channel index
Definition: ac3defs.h:27
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:58
s
uint8_t s
Definition: llvidencdsp.c:39
av_uninit
#define av_uninit(x)
Definition: attributes.h:187
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
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:265
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