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