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/internal.h"
35 #include "libavutil/mem_internal.h"
36 
37 #include "audiodsp.h"
38 #include "ac3enc.h"
39 #include "eac3enc.h"
40 
41 
43 {
44  int ch;
45 
46  if (!FF_ALLOC_TYPED_ARRAY(s->windowed_samples, AC3_WINDOW_SIZE) ||
47  !FF_ALLOCZ_TYPED_ARRAY(s->planar_samples, s->channels))
48  return AVERROR(ENOMEM);
49 
50  for (ch = 0; ch < s->channels; ch++) {
51  if (!(s->planar_samples[ch] = av_mallocz((AC3_FRAME_SIZE + AC3_BLOCK_SIZE) *
52  sizeof(**s->planar_samples))))
53  return AVERROR(ENOMEM);
54  }
55  return 0;
56 }
57 
58 
59 /*
60  * Copy input samples.
61  * Channels are reordered from FFmpeg's default order to AC-3 order.
62  */
64 {
65  int ch;
66 
67  /* copy and remap input samples */
68  for (ch = 0; ch < s->channels; ch++) {
69  /* copy last 256 samples of previous frame to the start of the current frame */
70  memcpy(&s->planar_samples[ch][0], &s->planar_samples[ch][AC3_BLOCK_SIZE * s->num_blocks],
71  AC3_BLOCK_SIZE * sizeof(s->planar_samples[0][0]));
72 
73  /* copy new samples for current frame */
74  memcpy(&s->planar_samples[ch][AC3_BLOCK_SIZE],
75  samples[s->channel_map[ch]],
76  AC3_BLOCK_SIZE * s->num_blocks * sizeof(s->planar_samples[0][0]));
77  }
78 }
79 
80 
81 /*
82  * Apply the MDCT to input samples to generate frequency coefficients.
83  * This applies the KBD window and normalizes the input to reduce precision
84  * loss due to fixed-point calculations.
85  */
87 {
88  int blk, ch;
89 
90  for (ch = 0; ch < s->channels; ch++) {
91  for (blk = 0; blk < s->num_blocks; blk++) {
92  AC3Block *block = &s->blocks[blk];
93  const SampleType *input_samples = &s->planar_samples[ch][blk * AC3_BLOCK_SIZE];
94 
95  s->fdsp->vector_fmul(s->windowed_samples, input_samples,
96  s->mdct_window, AC3_BLOCK_SIZE);
97  s->fdsp->vector_fmul_reverse(s->windowed_samples + AC3_BLOCK_SIZE,
98  &input_samples[AC3_BLOCK_SIZE],
99  s->mdct_window, AC3_BLOCK_SIZE);
100 
101  s->tx_fn(s->tx, block->mdct_coef[ch+1],
102  s->windowed_samples, sizeof(float));
103  }
104  }
105 }
106 
107 
108 /*
109  * Calculate coupling channel and coupling coordinates.
110  */
112 {
114 #if AC3ENC_FLOAT
115  LOCAL_ALIGNED_32(int32_t, fixed_cpl_coords, [AC3_MAX_BLOCKS], [AC3_MAX_CHANNELS][16]);
116 #else
117  int32_t (*fixed_cpl_coords)[AC3_MAX_CHANNELS][16] = cpl_coords;
118 #endif
119  int av_uninit(blk), ch, bnd, i, j;
120  CoefSumType energy[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][16] = {{{0}}};
121  int cpl_start, num_cpl_coefs;
122 
123  memset(cpl_coords, 0, AC3_MAX_BLOCKS * sizeof(*cpl_coords));
124 #if AC3ENC_FLOAT
125  memset(fixed_cpl_coords, 0, AC3_MAX_BLOCKS * sizeof(*cpl_coords));
126 #endif
127 
128  /* align start to 16-byte boundary. align length to multiple of 32.
129  note: coupling start bin % 4 will always be 1 */
130  cpl_start = s->start_freq[CPL_CH] - 1;
131  num_cpl_coefs = FFALIGN(s->num_cpl_subbands * 12 + 1, 32);
132  cpl_start = FFMIN(256, cpl_start + num_cpl_coefs) - num_cpl_coefs;
133 
134  /* calculate coupling channel from fbw channels */
135  for (blk = 0; blk < s->num_blocks; blk++) {
136  AC3Block *block = &s->blocks[blk];
137  CoefType *cpl_coef = &block->mdct_coef[CPL_CH][cpl_start];
138  if (!block->cpl_in_use)
139  continue;
140  memset(cpl_coef, 0, num_cpl_coefs * sizeof(*cpl_coef));
141  for (ch = 1; ch <= s->fbw_channels; ch++) {
142  CoefType *ch_coef = &block->mdct_coef[ch][cpl_start];
143  if (!block->channel_in_cpl[ch])
144  continue;
145  for (i = 0; i < num_cpl_coefs; i++)
146  cpl_coef[i] += ch_coef[i];
147  }
148 
149  /* coefficients must be clipped in order to be encoded */
150  clip_coefficients(&s->adsp, cpl_coef, num_cpl_coefs);
151  }
152 
153  /* calculate energy in each band in coupling channel and each fbw channel */
154  /* TODO: possibly use SIMD to speed up energy calculation */
155  bnd = 0;
156  i = s->start_freq[CPL_CH];
157  while (i < s->cpl_end_freq) {
158  int band_size = s->cpl_band_sizes[bnd];
159  for (ch = CPL_CH; ch <= s->fbw_channels; ch++) {
160  for (blk = 0; blk < s->num_blocks; blk++) {
161  AC3Block *block = &s->blocks[blk];
162  if (!block->cpl_in_use || (ch > CPL_CH && !block->channel_in_cpl[ch]))
163  continue;
164  for (j = 0; j < band_size; j++) {
165  CoefType v = block->mdct_coef[ch][i+j];
166  MAC_COEF(energy[blk][ch][bnd], v, v);
167  }
168  }
169  }
170  i += band_size;
171  bnd++;
172  }
173 
174  /* calculate coupling coordinates for all blocks for all channels */
175  for (blk = 0; blk < s->num_blocks; blk++) {
176  AC3Block *block = &s->blocks[blk];
177  if (!block->cpl_in_use)
178  continue;
179  for (ch = 1; ch <= s->fbw_channels; ch++) {
180  if (!block->channel_in_cpl[ch])
181  continue;
182  for (bnd = 0; bnd < s->num_cpl_bands; bnd++) {
183  cpl_coords[blk][ch][bnd] = calc_cpl_coord(energy[blk][ch][bnd],
184  energy[blk][CPL_CH][bnd]);
185  }
186  }
187  }
188 
189  /* determine which blocks to send new coupling coordinates for */
190  for (blk = 0; blk < s->num_blocks; blk++) {
191  AC3Block *block = &s->blocks[blk];
192  AC3Block *block0 = blk ? &s->blocks[blk-1] : NULL;
193 
194  memset(block->new_cpl_coords, 0, sizeof(block->new_cpl_coords));
195 
196  if (block->cpl_in_use) {
197  /* send new coordinates if this is the first block, if previous
198  * block did not use coupling but this block does, the channels
199  * using coupling has changed from the previous block, or the
200  * coordinate difference from the last block for any channel is
201  * greater than a threshold value. */
202  if (blk == 0 || !block0->cpl_in_use) {
203  for (ch = 1; ch <= s->fbw_channels; ch++)
204  block->new_cpl_coords[ch] = 1;
205  } else {
206  for (ch = 1; ch <= s->fbw_channels; ch++) {
207  if (!block->channel_in_cpl[ch])
208  continue;
209  if (!block0->channel_in_cpl[ch]) {
210  block->new_cpl_coords[ch] = 1;
211  } else {
212  CoefSumType coord_diff = 0;
213  for (bnd = 0; bnd < s->num_cpl_bands; bnd++) {
214  coord_diff += FFABS(cpl_coords[blk-1][ch][bnd] -
215  cpl_coords[blk ][ch][bnd]);
216  }
217  coord_diff /= s->num_cpl_bands;
218  if (coord_diff > NEW_CPL_COORD_THRESHOLD)
219  block->new_cpl_coords[ch] = 1;
220  }
221  }
222  }
223  }
224  }
225 
226  av_assert1(s->fbw_channels > 0);
227 
228  /* calculate final coupling coordinates, taking into account reusing of
229  coordinates in successive blocks */
230  for (bnd = 0; bnd < s->num_cpl_bands; bnd++) {
231  blk = 0;
232  while (blk < s->num_blocks) {
233  int av_uninit(blk1);
234  AC3Block *block = &s->blocks[blk];
235 
236  if (!block->cpl_in_use) {
237  blk++;
238  continue;
239  }
240 
241  for (ch = 1; ch <= s->fbw_channels; ch++) {
242  CoefSumType energy_ch, energy_cpl;
243  if (!block->channel_in_cpl[ch])
244  continue;
245  energy_cpl = energy[blk][CPL_CH][bnd];
246  energy_ch = energy[blk][ch][bnd];
247  blk1 = blk+1;
248  while (blk1 < s->num_blocks && !s->blocks[blk1].new_cpl_coords[ch]) {
249  if (s->blocks[blk1].cpl_in_use) {
250  energy_cpl += energy[blk1][CPL_CH][bnd];
251  energy_ch += energy[blk1][ch][bnd];
252  }
253  blk1++;
254  }
255  cpl_coords[blk][ch][bnd] = calc_cpl_coord(energy_ch, energy_cpl);
256  }
257  blk = blk1;
258  }
259  }
260 
261  /* calculate exponents/mantissas for coupling coordinates */
262  for (blk = 0; blk < s->num_blocks; blk++) {
263  AC3Block *block = &s->blocks[blk];
264  if (!block->cpl_in_use)
265  continue;
266 
267 #if AC3ENC_FLOAT
268  s->ac3dsp.float_to_fixed24(fixed_cpl_coords[blk][1],
269  cpl_coords[blk][1],
270  s->fbw_channels * 16);
271 #endif
272  s->ac3dsp.extract_exponents(block->cpl_coord_exp[1],
273  fixed_cpl_coords[blk][1],
274  s->fbw_channels * 16);
275 
276  for (ch = 1; ch <= s->fbw_channels; ch++) {
277  int bnd, min_exp, max_exp, master_exp;
278 
279  if (!block->new_cpl_coords[ch])
280  continue;
281 
282  /* determine master exponent */
283  min_exp = max_exp = block->cpl_coord_exp[ch][0];
284  for (bnd = 1; bnd < s->num_cpl_bands; bnd++) {
285  int exp = block->cpl_coord_exp[ch][bnd];
286  min_exp = FFMIN(exp, min_exp);
287  max_exp = FFMAX(exp, max_exp);
288  }
289  master_exp = ((max_exp - 15) + 2) / 3;
290  master_exp = FFMAX(master_exp, 0);
291  while (min_exp < master_exp * 3)
292  master_exp--;
293  for (bnd = 0; bnd < s->num_cpl_bands; bnd++) {
294  block->cpl_coord_exp[ch][bnd] = av_clip(block->cpl_coord_exp[ch][bnd] -
295  master_exp * 3, 0, 15);
296  }
297  block->cpl_master_exp[ch] = master_exp;
298 
299  /* quantize mantissas */
300  for (bnd = 0; bnd < s->num_cpl_bands; bnd++) {
301  int cpl_exp = block->cpl_coord_exp[ch][bnd];
302  int cpl_mant = (fixed_cpl_coords[blk][ch][bnd] << (5 + cpl_exp + master_exp * 3)) >> 24;
303  if (cpl_exp == 15)
304  cpl_mant >>= 1;
305  else
306  cpl_mant -= 16;
307 
308  block->cpl_coord_mant[ch][bnd] = cpl_mant;
309  }
310  }
311  }
312 
313  if (AC3ENC_FLOAT && CONFIG_EAC3_ENCODER && s->eac3)
315 }
316 
317 
318 /*
319  * Determine rematrixing flags for each block and band.
320  */
322 {
323  int nb_coefs;
324  int blk, bnd;
325  AC3Block *block, *block0 = NULL;
326 
327  if (s->channel_mode != AC3_CHMODE_STEREO)
328  return;
329 
330  for (blk = 0; blk < s->num_blocks; blk++) {
331  block = &s->blocks[blk];
332  block->new_rematrixing_strategy = !blk;
333 
334  block->num_rematrixing_bands = 4;
335  if (block->cpl_in_use) {
336  block->num_rematrixing_bands -= (s->start_freq[CPL_CH] <= 61);
337  block->num_rematrixing_bands -= (s->start_freq[CPL_CH] == 37);
338  if (blk && block->num_rematrixing_bands != block0->num_rematrixing_bands)
339  block->new_rematrixing_strategy = 1;
340  }
341  nb_coefs = FFMIN(block->end_freq[1], block->end_freq[2]);
342 
343  if (!s->rematrixing_enabled) {
344  block0 = block;
345  continue;
346  }
347 
348  for (bnd = 0; bnd < block->num_rematrixing_bands; bnd++) {
349  /* calculate sum of squared coeffs for one band in one block */
350  int start = ff_ac3_rematrix_band_tab[bnd];
351  int end = FFMIN(nb_coefs, ff_ac3_rematrix_band_tab[bnd+1]);
352  CoefSumType sum[4];
353  sum_square_butterfly(s, sum, block->mdct_coef[1] + start,
354  block->mdct_coef[2] + start, end - start);
355 
356  /* compare sums to determine if rematrixing will be used for this band */
357  if (FFMIN(sum[2], sum[3]) < FFMIN(sum[0], sum[1]))
358  block->rematrixing_flags[bnd] = 1;
359  else
360  block->rematrixing_flags[bnd] = 0;
361 
362  /* determine if new rematrixing flags will be sent */
363  if (blk &&
364  block->rematrixing_flags[bnd] != block0->rematrixing_flags[bnd]) {
365  block->new_rematrixing_strategy = 1;
366  }
367  }
368  block0 = block;
369  }
370 }
371 
372 
374  const AVFrame *frame, int *got_packet_ptr)
375 {
377  int ret;
378 
379  if (s->options.allow_per_frame_metadata) {
381  if (ret)
382  return ret;
383  }
384 
385  if (s->bit_alloc.sr_code == 1 || (AC3ENC_FLOAT && s->eac3))
387 
389 
390  apply_mdct(s);
391 
392  s->cpl_on = s->cpl_enabled;
394 
395  if (s->cpl_on)
397 
399 
400 #if AC3ENC_FLOAT
402 #endif
403 
404  return ff_ac3_encode_frame_common_end(avctx, avpkt, frame, got_packet_ptr);
405 }
FF_ALLOCZ_TYPED_ARRAY
#define FF_ALLOCZ_TYPED_ARRAY(p, nelem)
Definition: internal.h:88
nb_coefs
static int nb_coefs(int length, int level, uint64_t sn)
Definition: af_afwtdn.c:514
av_clip
#define av_clip
Definition: common.h:98
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
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:300
copy_input_samples
static void copy_input_samples(AC3EncodeContext *s, SampleType **samples)
Definition: ac3enc_template.c:63
AC3Block::channel_in_cpl
uint8_t channel_in_cpl[AC3_MAX_CHANNELS]
channel in coupling (chincpl)
Definition: ac3enc.h:146
SampleType
int32_t SampleType
Definition: ac3enc.h:67
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:340
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
encode_frame
int AC3_NAME() encode_frame(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, int *got_packet_ptr)
Definition: ac3enc_template.c:373
ff_ac3_validate_metadata
int ff_ac3_validate_metadata(AC3EncodeContext *s)
Validate metadata options as set by AVOption system.
Definition: ac3enc.c:1961
allocate_sample_buffers
static int allocate_sample_buffers(AC3EncodeContext *s)
Definition: ac3enc_template.c:42
ff_eac3_set_cpl_states
void ff_eac3_set_cpl_states(AC3EncodeContext *s)
Set coupling states.
Definition: eac3enc.c:93
FF_ALLOC_TYPED_ARRAY
#define FF_ALLOC_TYPED_ARRAY(p, nelem)
Definition: internal.h:87
AC3_WINDOW_SIZE
#define AC3_WINDOW_SIZE
Definition: ac3defs.h:33
s
#define s(width, name)
Definition: cbs_vp9.c:198
blk
#define blk(i)
Definition: sha.c:186
frame
static AVFrame * frame
Definition: demux_decode.c:54
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:72
NULL
#define NULL
Definition: coverity.c:32
AC3_FRAME_SIZE
#define AC3_FRAME_SIZE
Definition: ac3defs.h:32
LOCAL_ALIGNED_32
#define LOCAL_ALIGNED_32(t, v,...)
Definition: mem_internal.h:156
ac3enc.h
CoefSumType
int64_t CoefSumType
Definition: ac3enc.h:69
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:74
AC3Block
Data for a single audio block.
Definition: ac3enc.h:130
ff_ac3_adjust_frame_size
void ff_ac3_adjust_frame_size(AC3EncodeContext *s)
Adjust the frame size to make the average bit rate match the target bit rate.
Definition: ac3enc.c:282
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:111
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
AC3_NAME
#define AC3_NAME(x)
Definition: ac3enc.h:62
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:255
internal.h
AVFrame::extended_data
uint8_t ** extended_data
pointers to the data planes/channels.
Definition: frame.h:401
AC3Block::rematrixing_flags
uint8_t rematrixing_flags[4]
rematrixing flags
Definition: ac3enc.h:143
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:321
AC3EncodeContext::num_blocks
int num_blocks
number of blocks per frame
Definition: ac3enc.h:186
AC3_MAX_BLOCKS
#define AC3_MAX_BLOCKS
Definition: ac3defs.h:31
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:254
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
ret
ret
Definition: filter_design.txt:187
AC3EncodeContext::cpl_end_freq
int cpl_end_freq
coupling channel end frequency bin
Definition: ac3enc.h:213
AC3Block::num_rematrixing_bands
int num_rematrixing_bands
number of rematrixing bands
Definition: ac3enc.h:142
AVCodecContext
main external API structure.
Definition: avcodec.h:445
apply_mdct
static void apply_mdct(AC3EncodeContext *s)
Definition: ac3enc_template.c:86
CoefType
int32_t CoefType
Definition: ac3enc.h:68
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:63
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:472
AVPacket
This structure stores compressed data.
Definition: packet.h:499
AC3EncodeContext::avctx
AVCodecContext * avctx
parent AVCodecContext
Definition: ac3enc.h:161
int32_t
int32_t
Definition: audioconvert.c:56
ff_ac3_encode_frame_common_end
int ff_ac3_encode_frame_common_end(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame, int *got_packet_ptr)
Definition: ac3enc.c:1772
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:145
NEW_CPL_COORD_THRESHOLD
#define NEW_CPL_COORD_THRESHOLD
Definition: ac3enc.h:66