FFmpeg
ac3dsp.c
Go to the documentation of this file.
1 /*
2  * AC-3 DSP functions
3  * Copyright (c) 2011 Justin Ruggles
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "libavutil/mem_internal.h"
23 
24 #include "avcodec.h"
25 #include "ac3.h"
26 #include "ac3dsp.h"
27 #include "mathops.h"
28 
29 static void ac3_exponent_min_c(uint8_t *exp, int num_reuse_blocks, int nb_coefs)
30 {
31  int blk, i;
32 
33  if (!num_reuse_blocks)
34  return;
35 
36  for (i = 0; i < nb_coefs; i++) {
37  uint8_t min_exp = *exp;
38  uint8_t *exp1 = exp + 256;
39  for (blk = 0; blk < num_reuse_blocks; blk++) {
40  uint8_t next_exp = *exp1;
41  if (next_exp < min_exp)
42  min_exp = next_exp;
43  exp1 += 256;
44  }
45  *exp++ = min_exp;
46  }
47 }
48 
49 static void float_to_fixed24_c(int32_t *dst, const float *src, unsigned int len)
50 {
51  const float scale = 1 << 24;
52  do {
53  *dst++ = lrintf(*src++ * scale);
54  *dst++ = lrintf(*src++ * scale);
55  *dst++ = lrintf(*src++ * scale);
56  *dst++ = lrintf(*src++ * scale);
57  *dst++ = lrintf(*src++ * scale);
58  *dst++ = lrintf(*src++ * scale);
59  *dst++ = lrintf(*src++ * scale);
60  *dst++ = lrintf(*src++ * scale);
61  len -= 8;
62  } while (len > 0);
63 }
64 
65 static void ac3_bit_alloc_calc_bap_c(int16_t *mask, int16_t *psd,
66  int start, int end,
67  int snr_offset, int floor,
68  const uint8_t *bap_tab, uint8_t *bap)
69 {
70  int bin, band, band_end;
71 
72  /* special case, if snr offset is -960, set all bap's to zero */
73  if (snr_offset == -960) {
74  memset(bap, 0, AC3_MAX_COEFS);
75  return;
76  }
77 
78  bin = start;
79  band = ff_ac3_bin_to_band_tab[start];
80  do {
81  int m = (FFMAX(mask[band] - snr_offset - floor, 0) & 0x1FE0) + floor;
82  band_end = ff_ac3_band_start_tab[++band];
83  band_end = FFMIN(band_end, end);
84 
85  for (; bin < band_end; bin++) {
86  int address = av_clip_uintp2((psd[bin] - m) >> 5, 6);
87  bap[bin] = bap_tab[address];
88  }
89  } while (end > band_end);
90 }
91 
92 static void ac3_update_bap_counts_c(uint16_t mant_cnt[16], uint8_t *bap,
93  int len)
94 {
95  while (len-- > 0)
96  mant_cnt[bap[len]]++;
97 }
98 
99 DECLARE_ALIGNED(16, const uint16_t, ff_ac3_bap_bits)[16] = {
100  0, 0, 0, 3, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16
101 };
102 
103 static int ac3_compute_mantissa_size_c(uint16_t mant_cnt[6][16])
104 {
105  int blk, bap;
106  int bits = 0;
107 
108  for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
109  // bap=1 : 3 mantissas in 5 bits
110  bits += (mant_cnt[blk][1] / 3) * 5;
111  // bap=2 : 3 mantissas in 7 bits
112  // bap=4 : 2 mantissas in 7 bits
113  bits += ((mant_cnt[blk][2] / 3) + (mant_cnt[blk][4] >> 1)) * 7;
114  // bap=3 : 1 mantissa in 3 bits
115  bits += mant_cnt[blk][3] * 3;
116  // bap=5 to 15 : get bits per mantissa from table
117  for (bap = 5; bap < 16; bap++)
118  bits += mant_cnt[blk][bap] * ff_ac3_bap_bits[bap];
119  }
120  return bits;
121 }
122 
123 static void ac3_extract_exponents_c(uint8_t *exp, int32_t *coef, int nb_coefs)
124 {
125  int i;
126 
127  for (i = 0; i < nb_coefs; i++) {
128  int v = abs(coef[i]);
129  exp[i] = v ? 23 - av_log2(v) : 24;
130  }
131 }
132 
133 static void ac3_sum_square_butterfly_int32_c(int64_t sum[4],
134  const int32_t *coef0,
135  const int32_t *coef1,
136  int len)
137 {
138  int i;
139 
140  sum[0] = sum[1] = sum[2] = sum[3] = 0;
141 
142  for (i = 0; i < len; i++) {
143  int lt = coef0[i];
144  int rt = coef1[i];
145  int md = lt + rt;
146  int sd = lt - rt;
147  MAC64(sum[0], lt, lt);
148  MAC64(sum[1], rt, rt);
149  MAC64(sum[2], md, md);
150  MAC64(sum[3], sd, sd);
151  }
152 }
153 
154 static void ac3_sum_square_butterfly_float_c(float sum[4],
155  const float *coef0,
156  const float *coef1,
157  int len)
158 {
159  int i;
160 
161  sum[0] = sum[1] = sum[2] = sum[3] = 0;
162 
163  for (i = 0; i < len; i++) {
164  float lt = coef0[i];
165  float rt = coef1[i];
166  float md = lt + rt;
167  float sd = lt - rt;
168  sum[0] += lt * lt;
169  sum[1] += rt * rt;
170  sum[2] += md * md;
171  sum[3] += sd * sd;
172  }
173 }
174 
175 static void ac3_downmix_5_to_2_symmetric_c(float **samples, float **matrix,
176  int len)
177 {
178  int i;
179  float v0, v1;
180  float front_mix = matrix[0][0];
181  float center_mix = matrix[0][1];
182  float surround_mix = matrix[0][3];
183 
184  for (i = 0; i < len; i++) {
185  v0 = samples[0][i] * front_mix +
186  samples[1][i] * center_mix +
187  samples[3][i] * surround_mix;
188 
189  v1 = samples[1][i] * center_mix +
190  samples[2][i] * front_mix +
191  samples[4][i] * surround_mix;
192 
193  samples[0][i] = v0;
194  samples[1][i] = v1;
195  }
196 }
197 
198 static void ac3_downmix_5_to_1_symmetric_c(float **samples, float **matrix,
199  int len)
200 {
201  int i;
202  float front_mix = matrix[0][0];
203  float center_mix = matrix[0][1];
204  float surround_mix = matrix[0][3];
205 
206  for (i = 0; i < len; i++) {
207  samples[0][i] = samples[0][i] * front_mix +
208  samples[1][i] * center_mix +
209  samples[2][i] * front_mix +
210  samples[3][i] * surround_mix +
211  samples[4][i] * surround_mix;
212  }
213 }
214 
215 static void ac3_downmix_c(float **samples, float **matrix,
216  int out_ch, int in_ch, int len)
217 {
218  int i, j;
219  float v0, v1;
220 
221  if (out_ch == 2) {
222  for (i = 0; i < len; i++) {
223  v0 = v1 = 0.0f;
224  for (j = 0; j < in_ch; j++) {
225  v0 += samples[j][i] * matrix[0][j];
226  v1 += samples[j][i] * matrix[1][j];
227  }
228  samples[0][i] = v0;
229  samples[1][i] = v1;
230  }
231  } else if (out_ch == 1) {
232  for (i = 0; i < len; i++) {
233  v0 = 0.0f;
234  for (j = 0; j < in_ch; j++)
235  v0 += samples[j][i] * matrix[0][j];
236  samples[0][i] = v0;
237  }
238  }
239 }
240 
241 static void ac3_downmix_5_to_2_symmetric_c_fixed(int32_t **samples, int16_t **matrix,
242  int len)
243 {
244  int i;
245  int64_t v0, v1;
246  int16_t front_mix = matrix[0][0];
247  int16_t center_mix = matrix[0][1];
248  int16_t surround_mix = matrix[0][3];
249 
250  for (i = 0; i < len; i++) {
251  v0 = (int64_t)samples[0][i] * front_mix +
252  (int64_t)samples[1][i] * center_mix +
253  (int64_t)samples[3][i] * surround_mix;
254 
255  v1 = (int64_t)samples[1][i] * center_mix +
256  (int64_t)samples[2][i] * front_mix +
257  (int64_t)samples[4][i] * surround_mix;
258 
259  samples[0][i] = (v0+2048)>>12;
260  samples[1][i] = (v1+2048)>>12;
261  }
262 }
263 
264 static void ac3_downmix_5_to_1_symmetric_c_fixed(int32_t **samples, int16_t **matrix,
265  int len)
266 {
267  int i;
268  int64_t v0;
269  int16_t front_mix = matrix[0][0];
270  int16_t center_mix = matrix[0][1];
271  int16_t surround_mix = matrix[0][3];
272 
273  for (i = 0; i < len; i++) {
274  v0 = (int64_t)samples[0][i] * front_mix +
275  (int64_t)samples[1][i] * center_mix +
276  (int64_t)samples[2][i] * front_mix +
277  (int64_t)samples[3][i] * surround_mix +
278  (int64_t)samples[4][i] * surround_mix;
279 
280  samples[0][i] = (v0+2048)>>12;
281  }
282 }
283 
284 static void ac3_downmix_c_fixed(int32_t **samples, int16_t **matrix,
285  int out_ch, int in_ch, int len)
286 {
287  int i, j;
288  int64_t v0, v1;
289  if (out_ch == 2) {
290  for (i = 0; i < len; i++) {
291  v0 = v1 = 0;
292  for (j = 0; j < in_ch; j++) {
293  v0 += (int64_t)samples[j][i] * matrix[0][j];
294  v1 += (int64_t)samples[j][i] * matrix[1][j];
295  }
296  samples[0][i] = (v0+2048)>>12;
297  samples[1][i] = (v1+2048)>>12;
298  }
299  } else if (out_ch == 1) {
300  for (i = 0; i < len; i++) {
301  v0 = 0;
302  for (j = 0; j < in_ch; j++)
303  v0 += (int64_t)samples[j][i] * matrix[0][j];
304  samples[0][i] = (v0+2048)>>12;
305  }
306  }
307 }
308 
310  int out_ch, int in_ch, int len)
311 {
312  if (c->in_channels != in_ch || c->out_channels != out_ch) {
313  c->in_channels = in_ch;
314  c->out_channels = out_ch;
315  c->downmix_fixed = NULL;
316 
317  if (in_ch == 5 && out_ch == 2 &&
318  !(matrix[1][0] | matrix[0][2] |
319  matrix[1][3] | matrix[0][4] |
320  (matrix[0][1] ^ matrix[1][1]) |
321  (matrix[0][0] ^ matrix[1][2]))) {
322  c->downmix_fixed = ac3_downmix_5_to_2_symmetric_c_fixed;
323  } else if (in_ch == 5 && out_ch == 1 &&
324  matrix[0][0] == matrix[0][2] &&
325  matrix[0][3] == matrix[0][4]) {
326  c->downmix_fixed = ac3_downmix_5_to_1_symmetric_c_fixed;
327  }
328  }
329 
330  if (c->downmix_fixed)
331  c->downmix_fixed(samples, matrix, len);
332  else
333  ac3_downmix_c_fixed(samples, matrix, out_ch, in_ch, len);
334 }
335 
336 void ff_ac3dsp_downmix(AC3DSPContext *c, float **samples, float **matrix,
337  int out_ch, int in_ch, int len)
338 {
339  if (c->in_channels != in_ch || c->out_channels != out_ch) {
340  int **matrix_cmp = (int **)matrix;
341 
342  c->in_channels = in_ch;
343  c->out_channels = out_ch;
344  c->downmix = NULL;
345 
346  if (in_ch == 5 && out_ch == 2 &&
347  !(matrix_cmp[1][0] | matrix_cmp[0][2] |
348  matrix_cmp[1][3] | matrix_cmp[0][4] |
349  (matrix_cmp[0][1] ^ matrix_cmp[1][1]) |
350  (matrix_cmp[0][0] ^ matrix_cmp[1][2]))) {
352  } else if (in_ch == 5 && out_ch == 1 &&
353  matrix_cmp[0][0] == matrix_cmp[0][2] &&
354  matrix_cmp[0][3] == matrix_cmp[0][4]) {
356  }
357 
358  if (ARCH_X86)
360  }
361 
362  if (c->downmix)
363  c->downmix(samples, matrix, len);
364  else
365  ac3_downmix_c(samples, matrix, out_ch, in_ch, len);
366 }
367 
368 av_cold void ff_ac3dsp_init(AC3DSPContext *c, int bit_exact)
369 {
370  c->ac3_exponent_min = ac3_exponent_min_c;
371  c->float_to_fixed24 = float_to_fixed24_c;
372  c->bit_alloc_calc_bap = ac3_bit_alloc_calc_bap_c;
373  c->update_bap_counts = ac3_update_bap_counts_c;
374  c->compute_mantissa_size = ac3_compute_mantissa_size_c;
375  c->extract_exponents = ac3_extract_exponents_c;
376  c->sum_square_butterfly_int32 = ac3_sum_square_butterfly_int32_c;
377  c->sum_square_butterfly_float = ac3_sum_square_butterfly_float_c;
378  c->in_channels = 0;
379  c->out_channels = 0;
380  c->downmix = NULL;
381  c->downmix_fixed = NULL;
382 
383  if (ARCH_ARM)
384  ff_ac3dsp_init_arm(c, bit_exact);
385  if (ARCH_X86)
386  ff_ac3dsp_init_x86(c, bit_exact);
387  if (ARCH_MIPS)
388  ff_ac3dsp_init_mips(c, bit_exact);
389 }
mem_internal.h
ac3_compute_mantissa_size_c
static int ac3_compute_mantissa_size_c(uint16_t mant_cnt[6][16])
Definition: ac3dsp.c:103
ff_ac3_bin_to_band_tab
const uint8_t ff_ac3_bin_to_band_tab[253]
Map each frequency coefficient bin to the critical band that contains it.
Definition: ac3.c:46
av_clip_uintp2
#define av_clip_uintp2
Definition: common.h:146
md
#define md
Definition: vf_colormatrix.c:103
AC3DSPContext
Definition: ac3dsp.h:33
ff_ac3dsp_init_arm
void ff_ac3dsp_init_arm(AC3DSPContext *c, int bit_exact)
Definition: ac3dsp_init_arm.c:47
AC3_MAX_COEFS
#define AC3_MAX_COEFS
Definition: ac3.h:34
ac3_sum_square_butterfly_float_c
static void ac3_sum_square_butterfly_float_c(float sum[4], const float *coef0, const float *coef1, int len)
Definition: ac3dsp.c:154
AC3_MAX_BLOCKS
#define AC3_MAX_BLOCKS
Definition: ac3.h:36
v0
#define v0
Definition: regdef.h:26
ac3_downmix_c
static void ac3_downmix_c(float **samples, float **matrix, int out_ch, int in_ch, int len)
Definition: ac3dsp.c:215
ac3_update_bap_counts_c
static void ac3_update_bap_counts_c(uint16_t mant_cnt[16], uint8_t *bap, int len)
Definition: ac3dsp.c:92
av_cold
#define av_cold
Definition: attributes.h:90
ff_ac3dsp_set_downmix_x86
void ff_ac3dsp_set_downmix_x86(AC3DSPContext *c)
Definition: ac3dsp_init.c:89
mask
static const uint16_t mask[17]
Definition: lzw.c:38
floor
static __device__ float floor(float a)
Definition: cuda_runtime.h:173
bits
uint8_t bits
Definition: vp3data.h:141
blk
#define blk(i)
Definition: sha.c:185
ff_ac3_band_start_tab
const uint8_t ff_ac3_band_start_tab[AC3_CRITICAL_BANDS+1]
Starting frequency coefficient bin for each critical band.
Definition: ac3.c:35
int32_t
int32_t
Definition: audio_convert.c:194
bap_tab
static const uint8_t bap_tab[64]
Definition: dolby_e.c:589
NULL
#define NULL
Definition: coverity.c:32
ff_ac3dsp_init_mips
void ff_ac3dsp_init_mips(AC3DSPContext *c, int bit_exact)
Definition: ac3dsp_mips.c:403
src
#define src
Definition: vp8dsp.c:255
mathops.h
ac3dsp.h
ff_ac3_bap_bits
const uint16_t ff_ac3_bap_bits[16]
Number of mantissa bits written for each bap value.
Definition: ac3dsp.c:99
ac3_extract_exponents_c
static void ac3_extract_exponents_c(uint8_t *exp, int32_t *coef, int nb_coefs)
Definition: ac3dsp.c:123
abs
#define abs(x)
Definition: cuda_runtime.h:35
exp
int8_t exp
Definition: eval.c:72
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
ac3_downmix_5_to_1_symmetric_c_fixed
static void ac3_downmix_5_to_1_symmetric_c_fixed(int32_t **samples, int16_t **matrix, int len)
Definition: ac3dsp.c:264
FFMAX
#define FFMAX(a, b)
Definition: common.h:103
float_to_fixed24_c
static void float_to_fixed24_c(int32_t *dst, const float *src, unsigned int len)
Definition: ac3dsp.c:49
FFMIN
#define FFMIN(a, b)
Definition: common.h:105
ac3_downmix_5_to_2_symmetric_c
static void ac3_downmix_5_to_2_symmetric_c(float **samples, float **matrix, int len)
Definition: ac3dsp.c:175
ac3_sum_square_butterfly_int32_c
static void ac3_sum_square_butterfly_int32_c(int64_t sum[4], const int32_t *coef0, const int32_t *coef1, int len)
Definition: ac3dsp.c:133
ac3_bit_alloc_calc_bap_c
static void ac3_bit_alloc_calc_bap_c(int16_t *mask, int16_t *psd, int start, int end, int snr_offset, int floor, const uint8_t *bap_tab, uint8_t *bap)
Definition: ac3dsp.c:65
DECLARE_ALIGNED
#define DECLARE_ALIGNED(n, t, v)
Definition: mem.h:117
i
int i
Definition: input.c:407
lrintf
#define lrintf(x)
Definition: libm_mips.h:70
ac3_downmix_5_to_2_symmetric_c_fixed
static void ac3_downmix_5_to_2_symmetric_c_fixed(int32_t **samples, int16_t **matrix, int len)
Definition: ac3dsp.c:241
ff_ac3dsp_init_x86
void ff_ac3dsp_init_x86(AC3DSPContext *c, int bit_exact)
Definition: ac3dsp_init.c:42
uint8_t
uint8_t
Definition: audio_convert.c:194
len
int len
Definition: vorbis_enc_data.h:452
avcodec.h
ff_ac3dsp_downmix
void ff_ac3dsp_downmix(AC3DSPContext *c, float **samples, float **matrix, int out_ch, int in_ch, int len)
Definition: ac3dsp.c:336
ff_ac3dsp_downmix_fixed
void ff_ac3dsp_downmix_fixed(AC3DSPContext *c, int32_t **samples, int16_t **matrix, int out_ch, int in_ch, int len)
Definition: ac3dsp.c:309
samples
Filter the word “frame” indicates either a video frame or a group of audio samples
Definition: filter_design.txt:8
ff_ac3dsp_init
av_cold void ff_ac3dsp_init(AC3DSPContext *c, int bit_exact)
Definition: ac3dsp.c:368
MAC64
#define MAC64(d, a, b)
Definition: mathops.h:74
ac3.h
ac3_downmix_5_to_1_symmetric_c
static void ac3_downmix_5_to_1_symmetric_c(float **samples, float **matrix, int len)
Definition: ac3dsp.c:198
ac3_exponent_min_c
static void ac3_exponent_min_c(uint8_t *exp, int num_reuse_blocks, int nb_coefs)
Definition: ac3dsp.c:29
ac3_downmix_c_fixed
static void ac3_downmix_c_fixed(int32_t **samples, int16_t **matrix, int out_ch, int in_ch, int len)
Definition: ac3dsp.c:284
av_log2
int av_log2(unsigned v)
Definition: intmath.c:26