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 |
|
3154 |
static void ac3_exponent_min_c(uint8_t *exp, int num_reuse_blocks, int nb_coefs) |
30 |
|
|
{ |
31 |
|
|
int blk, i; |
32 |
|
|
|
33 |
✓✓ |
3154 |
if (!num_reuse_blocks) |
34 |
|
532 |
return; |
35 |
|
|
|
36 |
✓✓ |
673854 |
for (i = 0; i < nb_coefs; i++) { |
37 |
|
671232 |
uint8_t min_exp = *exp; |
38 |
|
671232 |
uint8_t *exp1 = exp + 256; |
39 |
✓✓ |
3493376 |
for (blk = 0; blk < num_reuse_blocks; blk++) { |
40 |
|
2822144 |
uint8_t next_exp = *exp1; |
41 |
✓✓ |
2822144 |
if (next_exp < min_exp) |
42 |
|
430495 |
min_exp = next_exp; |
43 |
|
2822144 |
exp1 += 256; |
44 |
|
|
} |
45 |
|
671232 |
*exp++ = min_exp; |
46 |
|
|
} |
47 |
|
|
} |
48 |
|
|
|
49 |
|
3822 |
static void float_to_fixed24_c(int32_t *dst, const float *src, unsigned int len) |
50 |
|
|
{ |
51 |
|
3822 |
const float scale = 1 << 24; |
52 |
|
|
do { |
53 |
|
327600 |
*dst++ = lrintf(*src++ * scale); |
54 |
|
327600 |
*dst++ = lrintf(*src++ * scale); |
55 |
|
327600 |
*dst++ = lrintf(*src++ * scale); |
56 |
|
327600 |
*dst++ = lrintf(*src++ * scale); |
57 |
|
327600 |
*dst++ = lrintf(*src++ * scale); |
58 |
|
327600 |
*dst++ = lrintf(*src++ * scale); |
59 |
|
327600 |
*dst++ = lrintf(*src++ * scale); |
60 |
|
327600 |
*dst++ = lrintf(*src++ * scale); |
61 |
|
327600 |
len -= 8; |
62 |
✓✓ |
327600 |
} while (len > 0); |
63 |
|
3822 |
} |
64 |
|
|
|
65 |
|
40438 |
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 |
✗✓ |
40438 |
if (snr_offset == -960) { |
74 |
|
|
memset(bap, 0, AC3_MAX_COEFS); |
75 |
|
|
return; |
76 |
|
|
} |
77 |
|
|
|
78 |
|
40438 |
bin = start; |
79 |
|
40438 |
band = ff_ac3_bin_to_band_tab[start]; |
80 |
|
|
do { |
81 |
|
1193445 |
int m = (FFMAX(mask[band] - snr_offset - floor, 0) & 0x1FE0) + floor; |
82 |
|
1193445 |
band_end = ff_ac3_band_start_tab[++band]; |
83 |
|
1193445 |
band_end = FFMIN(band_end, end); |
84 |
|
|
|
85 |
✓✓ |
5530309 |
for (; bin < band_end; bin++) { |
86 |
|
4336864 |
int address = av_clip_uintp2((psd[bin] - m) >> 5, 6); |
87 |
|
4336864 |
bap[bin] = bap_tab[address]; |
88 |
|
|
} |
89 |
✓✓ |
1193445 |
} while (end > band_end); |
90 |
|
|
} |
91 |
|
|
|
92 |
|
120006 |
static void ac3_update_bap_counts_c(uint16_t mant_cnt[16], uint8_t *bap, |
93 |
|
|
int len) |
94 |
|
|
{ |
95 |
✓✓ |
11811264 |
while (len-- > 0) |
96 |
|
11691258 |
mant_cnt[bap[len]]++; |
97 |
|
120006 |
} |
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 |
|
7877 |
static int ac3_compute_mantissa_size_c(uint16_t mant_cnt[6][16]) |
104 |
|
|
{ |
105 |
|
|
int blk, bap; |
106 |
|
7877 |
int bits = 0; |
107 |
|
|
|
108 |
✓✓ |
55139 |
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { |
109 |
|
|
// bap=1 : 3 mantissas in 5 bits |
110 |
|
47262 |
bits += (mant_cnt[blk][1] / 3) * 5; |
111 |
|
|
// bap=2 : 3 mantissas in 7 bits |
112 |
|
|
// bap=4 : 2 mantissas in 7 bits |
113 |
|
47262 |
bits += ((mant_cnt[blk][2] / 3) + (mant_cnt[blk][4] >> 1)) * 7; |
114 |
|
|
// bap=3 : 1 mantissa in 3 bits |
115 |
|
47262 |
bits += mant_cnt[blk][3] * 3; |
116 |
|
|
// bap=5 to 15 : get bits per mantissa from table |
117 |
✓✓ |
567144 |
for (bap = 5; bap < 16; bap++) |
118 |
|
519882 |
bits += mant_cnt[blk][bap] * ff_ac3_bap_bits[bap]; |
119 |
|
|
} |
120 |
|
7877 |
return bits; |
121 |
|
|
} |
122 |
|
|
|
123 |
|
5239 |
static void ac3_extract_exponents_c(uint8_t *exp, int32_t *coef, int nb_coefs) |
124 |
|
|
{ |
125 |
|
|
int i; |
126 |
|
|
|
127 |
✓✓ |
3772855 |
for (i = 0; i < nb_coefs; i++) { |
128 |
|
3767616 |
int v = abs(coef[i]); |
129 |
✓✓ |
3767616 |
exp[i] = v ? 23 - av_log2(v) : 24; |
130 |
|
|
} |
131 |
|
5239 |
} |
132 |
|
|
|
133 |
|
4152 |
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 |
|
4152 |
sum[0] = sum[1] = sum[2] = sum[3] = 0; |
141 |
|
|
|
142 |
✓✓ |
91344 |
for (i = 0; i < len; i++) { |
143 |
|
87192 |
int lt = coef0[i]; |
144 |
|
87192 |
int rt = coef1[i]; |
145 |
|
87192 |
int md = lt + rt; |
146 |
|
87192 |
int sd = lt - rt; |
147 |
|
87192 |
MAC64(sum[0], lt, lt); |
148 |
|
87192 |
MAC64(sum[1], rt, rt); |
149 |
|
87192 |
MAC64(sum[2], md, md); |
150 |
|
87192 |
MAC64(sum[3], sd, sd); |
151 |
|
|
} |
152 |
|
4152 |
} |
153 |
|
|
|
154 |
|
13104 |
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 |
|
13104 |
sum[0] = sum[1] = sum[2] = sum[3] = 0; |
162 |
|
|
|
163 |
✓✓ |
288288 |
for (i = 0; i < len; i++) { |
164 |
|
275184 |
float lt = coef0[i]; |
165 |
|
275184 |
float rt = coef1[i]; |
166 |
|
275184 |
float md = lt + rt; |
167 |
|
275184 |
float sd = lt - rt; |
168 |
|
275184 |
sum[0] += lt * lt; |
169 |
|
275184 |
sum[1] += rt * rt; |
170 |
|
275184 |
sum[2] += md * md; |
171 |
|
275184 |
sum[3] += sd * sd; |
172 |
|
|
} |
173 |
|
13104 |
} |
174 |
|
|
|
175 |
|
342 |
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 |
|
342 |
float front_mix = matrix[0][0]; |
181 |
|
342 |
float center_mix = matrix[0][1]; |
182 |
|
342 |
float surround_mix = matrix[0][3]; |
183 |
|
|
|
184 |
✓✓ |
87894 |
for (i = 0; i < len; i++) { |
185 |
|
87552 |
v0 = samples[0][i] * front_mix + |
186 |
|
87552 |
samples[1][i] * center_mix + |
187 |
|
87552 |
samples[3][i] * surround_mix; |
188 |
|
|
|
189 |
|
87552 |
v1 = samples[1][i] * center_mix + |
190 |
|
87552 |
samples[2][i] * front_mix + |
191 |
|
87552 |
samples[4][i] * surround_mix; |
192 |
|
|
|
193 |
|
87552 |
samples[0][i] = v0; |
194 |
|
87552 |
samples[1][i] = v1; |
195 |
|
|
} |
196 |
|
342 |
} |
197 |
|
|
|
198 |
|
342 |
static void ac3_downmix_5_to_1_symmetric_c(float **samples, float **matrix, |
199 |
|
|
int len) |
200 |
|
|
{ |
201 |
|
|
int i; |
202 |
|
342 |
float front_mix = matrix[0][0]; |
203 |
|
342 |
float center_mix = matrix[0][1]; |
204 |
|
342 |
float surround_mix = matrix[0][3]; |
205 |
|
|
|
206 |
✓✓ |
87894 |
for (i = 0; i < len; i++) { |
207 |
|
87552 |
samples[0][i] = samples[0][i] * front_mix + |
208 |
|
87552 |
samples[1][i] * center_mix + |
209 |
|
87552 |
samples[2][i] * front_mix + |
210 |
|
87552 |
samples[3][i] * surround_mix + |
211 |
|
87552 |
samples[4][i] * surround_mix; |
212 |
|
|
} |
213 |
|
342 |
} |
214 |
|
|
|
215 |
|
764 |
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 |
✓✓ |
764 |
if (out_ch == 2) { |
222 |
✓✓ |
97275 |
for (i = 0; i < len; i++) { |
223 |
|
96896 |
v0 = v1 = 0.0f; |
224 |
✓✓ |
484480 |
for (j = 0; j < in_ch; j++) { |
225 |
|
387584 |
v0 += samples[j][i] * matrix[0][j]; |
226 |
|
387584 |
v1 += samples[j][i] * matrix[1][j]; |
227 |
|
|
} |
228 |
|
96896 |
samples[0][i] = v0; |
229 |
|
96896 |
samples[1][i] = v1; |
230 |
|
|
} |
231 |
✓✗ |
385 |
} else if (out_ch == 1) { |
232 |
✓✓ |
98817 |
for (i = 0; i < len; i++) { |
233 |
|
98432 |
v0 = 0.0f; |
234 |
✓✓ |
492160 |
for (j = 0; j < in_ch; j++) |
235 |
|
393728 |
v0 += samples[j][i] * matrix[0][j]; |
236 |
|
98432 |
samples[0][i] = v0; |
237 |
|
|
} |
238 |
|
|
} |
239 |
|
764 |
} |
240 |
|
|
|
241 |
|
330 |
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 |
|
330 |
int16_t front_mix = matrix[0][0]; |
247 |
|
330 |
int16_t center_mix = matrix[0][1]; |
248 |
|
330 |
int16_t surround_mix = matrix[0][3]; |
249 |
|
|
|
250 |
✓✓ |
84810 |
for (i = 0; i < len; i++) { |
251 |
|
84480 |
v0 = (int64_t)samples[0][i] * front_mix + |
252 |
|
84480 |
(int64_t)samples[1][i] * center_mix + |
253 |
|
84480 |
(int64_t)samples[3][i] * surround_mix; |
254 |
|
|
|
255 |
|
84480 |
v1 = (int64_t)samples[1][i] * center_mix + |
256 |
|
84480 |
(int64_t)samples[2][i] * front_mix + |
257 |
|
84480 |
(int64_t)samples[4][i] * surround_mix; |
258 |
|
|
|
259 |
|
84480 |
samples[0][i] = (v0+2048)>>12; |
260 |
|
84480 |
samples[1][i] = (v1+2048)>>12; |
261 |
|
|
} |
262 |
|
330 |
} |
263 |
|
|
|
264 |
|
330 |
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 |
|
330 |
int16_t front_mix = matrix[0][0]; |
270 |
|
330 |
int16_t center_mix = matrix[0][1]; |
271 |
|
330 |
int16_t surround_mix = matrix[0][3]; |
272 |
|
|
|
273 |
✓✓ |
84810 |
for (i = 0; i < len; i++) { |
274 |
|
84480 |
v0 = (int64_t)samples[0][i] * front_mix + |
275 |
|
84480 |
(int64_t)samples[1][i] * center_mix + |
276 |
|
84480 |
(int64_t)samples[2][i] * front_mix + |
277 |
|
84480 |
(int64_t)samples[3][i] * surround_mix + |
278 |
|
84480 |
(int64_t)samples[4][i] * surround_mix; |
279 |
|
|
|
280 |
|
84480 |
samples[0][i] = (v0+2048)>>12; |
281 |
|
|
} |
282 |
|
330 |
} |
283 |
|
|
|
284 |
|
372 |
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 |
✗✓ |
372 |
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 |
✓✗ |
372 |
} else if (out_ch == 1) { |
300 |
✓✓ |
95476 |
for (i = 0; i < len; i++) { |
301 |
|
95104 |
v0 = 0; |
302 |
✓✓ |
475520 |
for (j = 0; j < in_ch; j++) |
303 |
|
380416 |
v0 += (int64_t)samples[j][i] * matrix[0][j]; |
304 |
|
95104 |
samples[0][i] = (v0+2048)>>12; |
305 |
|
|
} |
306 |
|
|
} |
307 |
|
372 |
} |
308 |
|
|
|
309 |
|
1032 |
void ff_ac3dsp_downmix_fixed(AC3DSPContext *c, int32_t **samples, int16_t **matrix, |
310 |
|
|
int out_ch, int in_ch, int len) |
311 |
|
|
{ |
312 |
✓✓✗✓
|
1032 |
if (c->in_channels != in_ch || c->out_channels != out_ch) { |
313 |
|
3 |
c->in_channels = in_ch; |
314 |
|
3 |
c->out_channels = out_ch; |
315 |
|
3 |
c->downmix_fixed = NULL; |
316 |
|
|
|
317 |
✓✓✓✓
|
3 |
if (in_ch == 5 && out_ch == 2 && |
318 |
|
1 |
!(matrix[1][0] | matrix[0][2] | |
319 |
|
1 |
matrix[1][3] | matrix[0][4] | |
320 |
|
1 |
(matrix[0][1] ^ matrix[1][1]) | |
321 |
✓✗ |
1 |
(matrix[0][0] ^ matrix[1][2]))) { |
322 |
|
1 |
c->downmix_fixed = ac3_downmix_5_to_2_symmetric_c_fixed; |
323 |
✓✓✓✗
|
2 |
} else if (in_ch == 5 && out_ch == 1 && |
324 |
✓✗ |
1 |
matrix[0][0] == matrix[0][2] && |
325 |
✓✗ |
1 |
matrix[0][3] == matrix[0][4]) { |
326 |
|
1 |
c->downmix_fixed = ac3_downmix_5_to_1_symmetric_c_fixed; |
327 |
|
|
} |
328 |
|
|
} |
329 |
|
|
|
330 |
✓✓ |
1032 |
if (c->downmix_fixed) |
331 |
|
660 |
c->downmix_fixed(samples, matrix, len); |
332 |
|
|
else |
333 |
|
372 |
ac3_downmix_c_fixed(samples, matrix, out_ch, in_ch, len); |
334 |
|
1032 |
} |
335 |
|
|
|
336 |
|
1448 |
void ff_ac3dsp_downmix(AC3DSPContext *c, float **samples, float **matrix, |
337 |
|
|
int out_ch, int in_ch, int len) |
338 |
|
|
{ |
339 |
✓✓✗✓
|
1448 |
if (c->in_channels != in_ch || c->out_channels != out_ch) { |
340 |
|
11 |
int **matrix_cmp = (int **)matrix; |
341 |
|
|
|
342 |
|
11 |
c->in_channels = in_ch; |
343 |
|
11 |
c->out_channels = out_ch; |
344 |
|
11 |
c->downmix = NULL; |
345 |
|
|
|
346 |
✓✓✓✓
|
11 |
if (in_ch == 5 && out_ch == 2 && |
347 |
|
3 |
!(matrix_cmp[1][0] | matrix_cmp[0][2] | |
348 |
|
3 |
matrix_cmp[1][3] | matrix_cmp[0][4] | |
349 |
|
3 |
(matrix_cmp[0][1] ^ matrix_cmp[1][1]) | |
350 |
✓✗ |
3 |
(matrix_cmp[0][0] ^ matrix_cmp[1][2]))) { |
351 |
|
3 |
c->downmix = ac3_downmix_5_to_2_symmetric_c; |
352 |
✓✓✓✗
|
8 |
} else if (in_ch == 5 && out_ch == 1 && |
353 |
✓✗ |
3 |
matrix_cmp[0][0] == matrix_cmp[0][2] && |
354 |
✓✗ |
3 |
matrix_cmp[0][3] == matrix_cmp[0][4]) { |
355 |
|
3 |
c->downmix = ac3_downmix_5_to_1_symmetric_c; |
356 |
|
|
} |
357 |
|
|
|
358 |
|
|
if (ARCH_X86) |
359 |
|
11 |
ff_ac3dsp_set_downmix_x86(c); |
360 |
|
|
} |
361 |
|
|
|
362 |
✓✓ |
1448 |
if (c->downmix) |
363 |
|
684 |
c->downmix(samples, matrix, len); |
364 |
|
|
else |
365 |
|
764 |
ac3_downmix_c(samples, matrix, out_ch, in_ch, len); |
366 |
|
1448 |
} |
367 |
|
|
|
368 |
|
61 |
av_cold void ff_ac3dsp_init(AC3DSPContext *c, int bit_exact) |
369 |
|
|
{ |
370 |
|
61 |
c->ac3_exponent_min = ac3_exponent_min_c; |
371 |
|
61 |
c->float_to_fixed24 = float_to_fixed24_c; |
372 |
|
61 |
c->bit_alloc_calc_bap = ac3_bit_alloc_calc_bap_c; |
373 |
|
61 |
c->update_bap_counts = ac3_update_bap_counts_c; |
374 |
|
61 |
c->compute_mantissa_size = ac3_compute_mantissa_size_c; |
375 |
|
61 |
c->extract_exponents = ac3_extract_exponents_c; |
376 |
|
61 |
c->sum_square_butterfly_int32 = ac3_sum_square_butterfly_int32_c; |
377 |
|
61 |
c->sum_square_butterfly_float = ac3_sum_square_butterfly_float_c; |
378 |
|
61 |
c->in_channels = 0; |
379 |
|
61 |
c->out_channels = 0; |
380 |
|
61 |
c->downmix = NULL; |
381 |
|
61 |
c->downmix_fixed = NULL; |
382 |
|
|
|
383 |
|
|
if (ARCH_ARM) |
384 |
|
|
ff_ac3dsp_init_arm(c, bit_exact); |
385 |
|
|
if (ARCH_X86) |
386 |
|
61 |
ff_ac3dsp_init_x86(c, bit_exact); |
387 |
|
|
if (ARCH_MIPS) |
388 |
|
|
ff_ac3dsp_init_mips(c, bit_exact); |
389 |
|
61 |
} |