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