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 <math.h>
23 #include <stdlib.h>
24 #include <string.h>
25 
26 #include "config.h"
27 #include "libavutil/attributes.h"
28 #include "libavutil/common.h"
29 #include "libavutil/intmath.h"
30 #include "libavutil/mem_internal.h"
31 
32 #include "ac3.h"
33 #include "ac3dsp.h"
34 #include "mathops.h"
35 
36 static void ac3_exponent_min_c(uint8_t *exp, int num_reuse_blocks, int nb_coefs)
37 {
38  int blk, i;
39 
40  if (!num_reuse_blocks)
41  return;
42 
43  for (i = 0; i < nb_coefs; i++) {
44  uint8_t min_exp = *exp;
45  uint8_t *exp1 = exp + 256;
46  for (blk = 0; blk < num_reuse_blocks; blk++) {
47  uint8_t next_exp = *exp1;
48  if (next_exp < min_exp)
49  min_exp = next_exp;
50  exp1 += 256;
51  }
52  *exp++ = min_exp;
53  }
54 }
55 
56 static void float_to_fixed24_c(int32_t *dst, const float *src, unsigned int len)
57 {
58  const float scale = 1 << 24;
59  do {
60  *dst++ = lrintf(*src++ * scale);
61  *dst++ = lrintf(*src++ * scale);
62  *dst++ = lrintf(*src++ * scale);
63  *dst++ = lrintf(*src++ * scale);
64  *dst++ = lrintf(*src++ * scale);
65  *dst++ = lrintf(*src++ * scale);
66  *dst++ = lrintf(*src++ * scale);
67  *dst++ = lrintf(*src++ * scale);
68  len -= 8;
69  } while (len > 0);
70 }
71 
72 static void ac3_bit_alloc_calc_bap_c(int16_t *mask, int16_t *psd,
73  int start, int end,
74  int snr_offset, int floor,
75  const uint8_t *bap_tab, uint8_t *bap)
76 {
77  int bin, band, band_end;
78 
79  /* special case, if snr offset is -960, set all bap's to zero */
80  if (snr_offset == -960) {
81  memset(bap, 0, AC3_MAX_COEFS);
82  return;
83  }
84 
85  bin = start;
86  band = ff_ac3_bin_to_band_tab[start];
87  do {
88  int m = (FFMAX(mask[band] - snr_offset - floor, 0) & 0x1FE0) + floor;
89  band_end = ff_ac3_band_start_tab[++band];
90  band_end = FFMIN(band_end, end);
91 
92  for (; bin < band_end; bin++) {
93  int address = av_clip_uintp2((psd[bin] - m) >> 5, 6);
94  bap[bin] = bap_tab[address];
95  }
96  } while (end > band_end);
97 }
98 
99 static void ac3_update_bap_counts_c(uint16_t mant_cnt[16], uint8_t *bap,
100  int len)
101 {
102  while (len-- > 0)
103  mant_cnt[bap[len]]++;
104 }
105 
106 DECLARE_ALIGNED(16, const uint16_t, ff_ac3_bap_bits)[16] = {
107  0, 0, 0, 3, 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16
108 };
109 
110 static int ac3_compute_mantissa_size_c(uint16_t mant_cnt[6][16])
111 {
112  int blk, bap;
113  int bits = 0;
114 
115  for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
116  // bap=1 : 3 mantissas in 5 bits
117  bits += (mant_cnt[blk][1] / 3) * 5;
118  // bap=2 : 3 mantissas in 7 bits
119  // bap=4 : 2 mantissas in 7 bits
120  bits += ((mant_cnt[blk][2] / 3) + (mant_cnt[blk][4] >> 1)) * 7;
121  // bap=3 : 1 mantissa in 3 bits
122  bits += mant_cnt[blk][3] * 3;
123  // bap=5 to 15 : get bits per mantissa from table
124  for (bap = 5; bap < 16; bap++)
125  bits += mant_cnt[blk][bap] * ff_ac3_bap_bits[bap];
126  }
127  return bits;
128 }
129 
130 static void ac3_extract_exponents_c(uint8_t *exp, int32_t *coef, int nb_coefs)
131 {
132  int i;
133 
134  for (i = 0; i < nb_coefs; i++) {
135  int v = abs(coef[i]);
136  exp[i] = v ? 23 - av_log2(v) : 24;
137  }
138 }
139 
140 static void ac3_sum_square_butterfly_int32_c(int64_t sum[4],
141  const int32_t *coef0,
142  const int32_t *coef1,
143  int len)
144 {
145  int i;
146 
147  sum[0] = sum[1] = sum[2] = sum[3] = 0;
148 
149  for (i = 0; i < len; i++) {
150  int lt = coef0[i];
151  int rt = coef1[i];
152  int md = lt + rt;
153  int sd = lt - rt;
154  MAC64(sum[0], lt, lt);
155  MAC64(sum[1], rt, rt);
156  MAC64(sum[2], md, md);
157  MAC64(sum[3], sd, sd);
158  }
159 }
160 
161 static void ac3_sum_square_butterfly_float_c(float sum[4],
162  const float *coef0,
163  const float *coef1,
164  int len)
165 {
166  int i;
167 
168  sum[0] = sum[1] = sum[2] = sum[3] = 0;
169 
170  for (i = 0; i < len; i++) {
171  float lt = coef0[i];
172  float rt = coef1[i];
173  float md = lt + rt;
174  float sd = lt - rt;
175  sum[0] += lt * lt;
176  sum[1] += rt * rt;
177  sum[2] += md * md;
178  sum[3] += sd * sd;
179  }
180 }
181 
182 static void ac3_downmix_5_to_2_symmetric_c(float **samples, float **matrix,
183  int len)
184 {
185  int i;
186  float v0, v1;
187  float front_mix = matrix[0][0];
188  float center_mix = matrix[0][1];
189  float surround_mix = matrix[0][3];
190 
191  for (i = 0; i < len; i++) {
192  v0 = samples[0][i] * front_mix +
193  samples[1][i] * center_mix +
194  samples[3][i] * surround_mix;
195 
196  v1 = samples[1][i] * center_mix +
197  samples[2][i] * front_mix +
198  samples[4][i] * surround_mix;
199 
200  samples[0][i] = v0;
201  samples[1][i] = v1;
202  }
203 }
204 
205 static void ac3_downmix_5_to_1_symmetric_c(float **samples, float **matrix,
206  int len)
207 {
208  int i;
209  float front_mix = matrix[0][0];
210  float center_mix = matrix[0][1];
211  float surround_mix = matrix[0][3];
212 
213  for (i = 0; i < len; i++) {
214  samples[0][i] = samples[0][i] * front_mix +
215  samples[1][i] * center_mix +
216  samples[2][i] * front_mix +
217  samples[3][i] * surround_mix +
218  samples[4][i] * surround_mix;
219  }
220 }
221 
222 static void ac3_downmix_c(float **samples, float **matrix,
223  int out_ch, int in_ch, int len)
224 {
225  int i, j;
226  float v0, v1;
227 
228  if (out_ch == 2) {
229  for (i = 0; i < len; i++) {
230  v0 = v1 = 0.0f;
231  for (j = 0; j < in_ch; j++) {
232  v0 += samples[j][i] * matrix[0][j];
233  v1 += samples[j][i] * matrix[1][j];
234  }
235  samples[0][i] = v0;
236  samples[1][i] = v1;
237  }
238  } else if (out_ch == 1) {
239  for (i = 0; i < len; i++) {
240  v0 = 0.0f;
241  for (j = 0; j < in_ch; j++)
242  v0 += samples[j][i] * matrix[0][j];
243  samples[0][i] = v0;
244  }
245  }
246 }
247 
248 static void ac3_downmix_5_to_2_symmetric_c_fixed(int32_t **samples, int16_t **matrix,
249  int len)
250 {
251  int i;
252  int64_t v0, v1;
253  int16_t front_mix = matrix[0][0];
254  int16_t center_mix = matrix[0][1];
255  int16_t surround_mix = matrix[0][3];
256 
257  for (i = 0; i < len; i++) {
258  v0 = (int64_t)samples[0][i] * front_mix +
259  (int64_t)samples[1][i] * center_mix +
260  (int64_t)samples[3][i] * surround_mix;
261 
262  v1 = (int64_t)samples[1][i] * center_mix +
263  (int64_t)samples[2][i] * front_mix +
264  (int64_t)samples[4][i] * surround_mix;
265 
266  samples[0][i] = (v0+2048)>>12;
267  samples[1][i] = (v1+2048)>>12;
268  }
269 }
270 
271 static void ac3_downmix_5_to_1_symmetric_c_fixed(int32_t **samples, int16_t **matrix,
272  int len)
273 {
274  int i;
275  int64_t v0;
276  int16_t front_mix = matrix[0][0];
277  int16_t center_mix = matrix[0][1];
278  int16_t surround_mix = matrix[0][3];
279 
280  for (i = 0; i < len; i++) {
281  v0 = (int64_t)samples[0][i] * front_mix +
282  (int64_t)samples[1][i] * center_mix +
283  (int64_t)samples[2][i] * front_mix +
284  (int64_t)samples[3][i] * surround_mix +
285  (int64_t)samples[4][i] * surround_mix;
286 
287  samples[0][i] = (v0+2048)>>12;
288  }
289 }
290 
291 static void ac3_downmix_c_fixed(int32_t **samples, int16_t **matrix,
292  int out_ch, int in_ch, int len)
293 {
294  int i, j;
295  int64_t v0, v1;
296  if (out_ch == 2) {
297  for (i = 0; i < len; i++) {
298  v0 = v1 = 0;
299  for (j = 0; j < in_ch; j++) {
300  v0 += (int64_t)samples[j][i] * matrix[0][j];
301  v1 += (int64_t)samples[j][i] * matrix[1][j];
302  }
303  samples[0][i] = (v0+2048)>>12;
304  samples[1][i] = (v1+2048)>>12;
305  }
306  } else if (out_ch == 1) {
307  for (i = 0; i < len; i++) {
308  v0 = 0;
309  for (j = 0; j < in_ch; j++)
310  v0 += (int64_t)samples[j][i] * matrix[0][j];
311  samples[0][i] = (v0+2048)>>12;
312  }
313  }
314 }
315 
317  int out_ch, int in_ch, int len)
318 {
319  if (c->in_channels != in_ch || c->out_channels != out_ch) {
320  c->in_channels = in_ch;
321  c->out_channels = out_ch;
322  c->downmix_fixed = NULL;
323 
324  if (in_ch == 5 && out_ch == 2 &&
325  !(matrix[1][0] | matrix[0][2] |
326  matrix[1][3] | matrix[0][4] |
327  (matrix[0][1] ^ matrix[1][1]) |
328  (matrix[0][0] ^ matrix[1][2]))) {
329  c->downmix_fixed = ac3_downmix_5_to_2_symmetric_c_fixed;
330  } else if (in_ch == 5 && out_ch == 1 &&
331  matrix[0][0] == matrix[0][2] &&
332  matrix[0][3] == matrix[0][4]) {
333  c->downmix_fixed = ac3_downmix_5_to_1_symmetric_c_fixed;
334  }
335  }
336 
337  if (c->downmix_fixed)
338  c->downmix_fixed(samples, matrix, len);
339  else
340  ac3_downmix_c_fixed(samples, matrix, out_ch, in_ch, len);
341 }
342 
343 void ff_ac3dsp_downmix(AC3DSPContext *c, float **samples, float **matrix,
344  int out_ch, int in_ch, int len)
345 {
346  if (c->in_channels != in_ch || c->out_channels != out_ch) {
347  int **matrix_cmp = (int **)matrix;
348 
349  c->in_channels = in_ch;
350  c->out_channels = out_ch;
351  c->downmix = NULL;
352 
353  if (in_ch == 5 && out_ch == 2 &&
354  !(matrix_cmp[1][0] | matrix_cmp[0][2] |
355  matrix_cmp[1][3] | matrix_cmp[0][4] |
356  (matrix_cmp[0][1] ^ matrix_cmp[1][1]) |
357  (matrix_cmp[0][0] ^ matrix_cmp[1][2]))) {
359  } else if (in_ch == 5 && out_ch == 1 &&
360  matrix_cmp[0][0] == matrix_cmp[0][2] &&
361  matrix_cmp[0][3] == matrix_cmp[0][4]) {
363  }
364 
365  if (ARCH_X86)
367  }
368 
369  if (c->downmix)
370  c->downmix(samples, matrix, len);
371  else
372  ac3_downmix_c(samples, matrix, out_ch, in_ch, len);
373 }
374 
375 av_cold void ff_ac3dsp_init(AC3DSPContext *c, int bit_exact)
376 {
377  c->ac3_exponent_min = ac3_exponent_min_c;
378  c->float_to_fixed24 = float_to_fixed24_c;
379  c->bit_alloc_calc_bap = ac3_bit_alloc_calc_bap_c;
380  c->update_bap_counts = ac3_update_bap_counts_c;
381  c->compute_mantissa_size = ac3_compute_mantissa_size_c;
382  c->extract_exponents = ac3_extract_exponents_c;
383  c->sum_square_butterfly_int32 = ac3_sum_square_butterfly_int32_c;
384  c->sum_square_butterfly_float = ac3_sum_square_butterfly_float_c;
385  c->in_channels = 0;
386  c->out_channels = 0;
387  c->downmix = NULL;
388  c->downmix_fixed = NULL;
389 
390  if (ARCH_ARM)
391  ff_ac3dsp_init_arm(c, bit_exact);
392  if (ARCH_X86)
393  ff_ac3dsp_init_x86(c, bit_exact);
394  if (ARCH_MIPS)
395  ff_ac3dsp_init_mips(c, bit_exact);
396 }
nb_coefs
static int nb_coefs(int length, int level, uint64_t sn)
Definition: af_afwtdn.c:532
mem_internal.h
ac3_compute_mantissa_size_c
static int ac3_compute_mantissa_size_c(uint16_t mant_cnt[6][16])
Definition: ac3dsp.c:110
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:45
av_clip_uintp2
#define av_clip_uintp2
Definition: common.h:120
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:37
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
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:161
AC3_MAX_BLOCKS
#define AC3_MAX_BLOCKS
Definition: ac3.h:39
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:222
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:99
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:88
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:34
bap_tab
static const uint8_t bap_tab[64]
Definition: dolby_e.c:590
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:106
ac3_extract_exponents_c
static void ac3_extract_exponents_c(uint8_t *exp, int32_t *coef, int nb_coefs)
Definition: ac3dsp.c:130
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:271
float_to_fixed24_c
static void float_to_fixed24_c(int32_t *dst, const float *src, unsigned int len)
Definition: ac3dsp.c:56
attributes.h
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:182
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:140
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:72
DECLARE_ALIGNED
#define DECLARE_ALIGNED(n, t, v)
Definition: mem.h:116
i
int i
Definition: input.c:406
lrintf
#define lrintf(x)
Definition: libm_mips.h:72
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:248
ff_ac3dsp_init_x86
void ff_ac3dsp_init_x86(AC3DSPContext *c, int bit_exact)
Definition: ac3dsp_init.c:41
common.h
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
len
int len
Definition: vorbis_enc_data.h:426
ff_ac3dsp_downmix
void ff_ac3dsp_downmix(AC3DSPContext *c, float **samples, float **matrix, int out_ch, int in_ch, int len)
Definition: ac3dsp.c:343
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:316
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:375
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:205
int32_t
int32_t
Definition: audioconvert.c:56
ac3_exponent_min_c
static void ac3_exponent_min_c(uint8_t *exp, int num_reuse_blocks, int nb_coefs)
Definition: ac3dsp.c:36
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:291
av_log2
int av_log2(unsigned v)
Definition: intmath.c:26
intmath.h