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->mdct.mdct_calc(&s->mdct, block->mdct_coef[ch+1],
102  s->windowed_samples);
103  }
104  }
105 }
106 
107 
108 /*
109  * Calculate coupling channel and coupling coordinates.
110  */
112 {
114 #if AC3ENC_FLOAT
115  LOCAL_ALIGNED_16(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  /* calculate final coupling coordinates, taking into account reusing of
227  coordinates in successive blocks */
228  for (bnd = 0; bnd < s->num_cpl_bands; bnd++) {
229  blk = 0;
230  while (blk < s->num_blocks) {
231  int av_uninit(blk1);
232  AC3Block *block = &s->blocks[blk];
233 
234  if (!block->cpl_in_use) {
235  blk++;
236  continue;
237  }
238 
239  for (ch = 1; ch <= s->fbw_channels; ch++) {
240  CoefSumType energy_ch, energy_cpl;
241  if (!block->channel_in_cpl[ch])
242  continue;
243  energy_cpl = energy[blk][CPL_CH][bnd];
244  energy_ch = energy[blk][ch][bnd];
245  blk1 = blk+1;
246  while (blk1 < s->num_blocks && !s->blocks[blk1].new_cpl_coords[ch]) {
247  if (s->blocks[blk1].cpl_in_use) {
248  energy_cpl += energy[blk1][CPL_CH][bnd];
249  energy_ch += energy[blk1][ch][bnd];
250  }
251  blk1++;
252  }
253  cpl_coords[blk][ch][bnd] = calc_cpl_coord(energy_ch, energy_cpl);
254  }
255  blk = blk1;
256  }
257  }
258 
259  /* calculate exponents/mantissas for coupling coordinates */
260  for (blk = 0; blk < s->num_blocks; blk++) {
261  AC3Block *block = &s->blocks[blk];
262  if (!block->cpl_in_use)
263  continue;
264 
265 #if AC3ENC_FLOAT
266  s->ac3dsp.float_to_fixed24(fixed_cpl_coords[blk][1],
267  cpl_coords[blk][1],
268  s->fbw_channels * 16);
269 #endif
270  s->ac3dsp.extract_exponents(block->cpl_coord_exp[1],
271  fixed_cpl_coords[blk][1],
272  s->fbw_channels * 16);
273 
274  for (ch = 1; ch <= s->fbw_channels; ch++) {
275  int bnd, min_exp, max_exp, master_exp;
276 
277  if (!block->new_cpl_coords[ch])
278  continue;
279 
280  /* determine master exponent */
281  min_exp = max_exp = block->cpl_coord_exp[ch][0];
282  for (bnd = 1; bnd < s->num_cpl_bands; bnd++) {
283  int exp = block->cpl_coord_exp[ch][bnd];
284  min_exp = FFMIN(exp, min_exp);
285  max_exp = FFMAX(exp, max_exp);
286  }
287  master_exp = ((max_exp - 15) + 2) / 3;
288  master_exp = FFMAX(master_exp, 0);
289  while (min_exp < master_exp * 3)
290  master_exp--;
291  for (bnd = 0; bnd < s->num_cpl_bands; bnd++) {
292  block->cpl_coord_exp[ch][bnd] = av_clip(block->cpl_coord_exp[ch][bnd] -
293  master_exp * 3, 0, 15);
294  }
295  block->cpl_master_exp[ch] = master_exp;
296 
297  /* quantize mantissas */
298  for (bnd = 0; bnd < s->num_cpl_bands; bnd++) {
299  int cpl_exp = block->cpl_coord_exp[ch][bnd];
300  int cpl_mant = (fixed_cpl_coords[blk][ch][bnd] << (5 + cpl_exp + master_exp * 3)) >> 24;
301  if (cpl_exp == 15)
302  cpl_mant >>= 1;
303  else
304  cpl_mant -= 16;
305 
306  block->cpl_coord_mant[ch][bnd] = cpl_mant;
307  }
308  }
309  }
310 
311  if (AC3ENC_FLOAT && CONFIG_EAC3_ENCODER && s->eac3)
313 }
314 
315 
316 /*
317  * Determine rematrixing flags for each block and band.
318  */
320 {
321  int nb_coefs;
322  int blk, bnd;
323  AC3Block *block, *block0 = NULL;
324 
325  if (s->channel_mode != AC3_CHMODE_STEREO)
326  return;
327 
328  for (blk = 0; blk < s->num_blocks; blk++) {
329  block = &s->blocks[blk];
330  block->new_rematrixing_strategy = !blk;
331 
332  block->num_rematrixing_bands = 4;
333  if (block->cpl_in_use) {
334  block->num_rematrixing_bands -= (s->start_freq[CPL_CH] <= 61);
335  block->num_rematrixing_bands -= (s->start_freq[CPL_CH] == 37);
336  if (blk && block->num_rematrixing_bands != block0->num_rematrixing_bands)
337  block->new_rematrixing_strategy = 1;
338  }
339  nb_coefs = FFMIN(block->end_freq[1], block->end_freq[2]);
340 
341  if (!s->rematrixing_enabled) {
342  block0 = block;
343  continue;
344  }
345 
346  for (bnd = 0; bnd < block->num_rematrixing_bands; bnd++) {
347  /* calculate sum of squared coeffs for one band in one block */
348  int start = ff_ac3_rematrix_band_tab[bnd];
349  int end = FFMIN(nb_coefs, ff_ac3_rematrix_band_tab[bnd+1]);
350  CoefSumType sum[4];
351  sum_square_butterfly(s, sum, block->mdct_coef[1] + start,
352  block->mdct_coef[2] + start, end - start);
353 
354  /* compare sums to determine if rematrixing will be used for this band */
355  if (FFMIN(sum[2], sum[3]) < FFMIN(sum[0], sum[1]))
356  block->rematrixing_flags[bnd] = 1;
357  else
358  block->rematrixing_flags[bnd] = 0;
359 
360  /* determine if new rematrixing flags will be sent */
361  if (blk &&
362  block->rematrixing_flags[bnd] != block0->rematrixing_flags[bnd]) {
363  block->new_rematrixing_strategy = 1;
364  }
365  }
366  block0 = block;
367  }
368 }
369 
370 
372  const AVFrame *frame, int *got_packet_ptr)
373 {
375  int ret;
376 
377  if (s->options.allow_per_frame_metadata) {
379  if (ret)
380  return ret;
381  }
382 
383  if (s->bit_alloc.sr_code == 1 || (AC3ENC_FLOAT && s->eac3))
385 
386  copy_input_samples(s, (SampleType **)frame->extended_data);
387 
388  apply_mdct(s);
389 
390  s->cpl_on = s->cpl_enabled;
392 
393  if (s->cpl_on)
395 
397 
398 #if AC3ENC_FLOAT
400 #endif
401 
402  return ff_ac3_encode_frame_common_end(avctx, avpkt, frame, got_packet_ptr);
403 }
FF_ALLOCZ_TYPED_ARRAY
#define FF_ALLOCZ_TYPED_ARRAY(p, nelem)
Definition: internal.h:97
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:95
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:324
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:145
SampleType
int32_t SampleType
Definition: ac3enc.h:66
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:325
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:371
ff_ac3_validate_metadata
int ff_ac3_validate_metadata(AC3EncodeContext *s)
Validate metadata options as set by AVOption system.
Definition: ac3enc.c:1985
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:96
AC3_WINDOW_SIZE
#define AC3_WINDOW_SIZE
Definition: ac3defs.h:33
s
#define s(width, name)
Definition: cbs_vp9.c:256
LOCAL_ALIGNED_16
#define LOCAL_ALIGNED_16(t, v,...)
Definition: mem_internal.h:131
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:64
NULL
#define NULL
Definition: coverity.c:32
AC3_FRAME_SIZE
#define AC3_FRAME_SIZE
Definition: ac3defs.h:32
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:72
AC3Block
Data for a single audio block.
Definition: ac3enc.h:129
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:306
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:47
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:57
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:61
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:269
internal.h
AC3Block::rematrixing_flags
uint8_t rematrixing_flags[4]
rematrixing flags
Definition: ac3enc.h:142
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
compute_rematrixing_strategy
static void compute_rematrixing_strategy(AC3EncodeContext *s)
Definition: ac3enc_template.c:319
AC3EncodeContext::num_blocks
int num_blocks
number of blocks per frame
Definition: ac3enc.h:184
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:264
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:37
av_uninit
#define av_uninit(x)
Definition: attributes.h:154
ret
ret
Definition: filter_design.txt:187
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:264
AC3EncodeContext::cpl_end_freq
int cpl_end_freq
coupling channel end frequency bin
Definition: ac3enc.h:211
AC3Block::num_rematrixing_bands
int num_rematrixing_bands
number of rematrixing bands
Definition: ac3enc.h:141
AVCodecContext
main external API structure.
Definition: avcodec.h:398
apply_mdct
static void apply_mdct(AC3EncodeContext *s)
Definition: ac3enc_template.c:86
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
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:425
AVPacket
This structure stores compressed data.
Definition: packet.h:351
AC3EncodeContext::avctx
AVCodecContext * avctx
parent AVCodecContext
Definition: ac3enc.h:160
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:1796
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:46
AC3Block::cpl_in_use
int cpl_in_use
coupling in use for this block (cplinu)
Definition: ac3enc.h:144
NEW_CPL_COORD_THRESHOLD
#define NEW_CPL_COORD_THRESHOLD
Definition: ac3enc.h:65