FFmpeg
Loading...
Searching...
No Matches
rematrix.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2011-2012 Michael Niedermayer (michaelni@gmx.at)
3 *
4 * This file is part of libswresample
5 *
6 * libswresample is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * libswresample is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with libswresample; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21#include "swresample_internal.h"
22#include "libavutil/avassert.h"
24#include "libavutil/mem.h"
25
26#define TEMPLATE_REMATRIX_FLT
27#include "rematrix_template.c"
28#undef TEMPLATE_REMATRIX_FLT
29
30#define TEMPLATE_REMATRIX_DBL
31#include "rematrix_template.c"
32#undef TEMPLATE_REMATRIX_DBL
33
34#define TEMPLATE_REMATRIX_S16
35#include "rematrix_template.c"
36#define TEMPLATE_CLIP
37#include "rematrix_template.c"
38#undef TEMPLATE_CLIP
39#undef TEMPLATE_REMATRIX_S16
40
41#define TEMPLATE_REMATRIX_S32
42#include "rematrix_template.c"
43#undef TEMPLATE_REMATRIX_S32
44
45#define FRONT_LEFT 0
46#define FRONT_RIGHT 1
47#define FRONT_CENTER 2
48#define LOW_FREQUENCY 3
49#define BACK_LEFT 4
50#define BACK_RIGHT 5
51#define FRONT_LEFT_OF_CENTER 6
52#define FRONT_RIGHT_OF_CENTER 7
53#define BACK_CENTER 8
54#define SIDE_LEFT 9
55#define SIDE_RIGHT 10
56#define TOP_CENTER 11
57#define TOP_FRONT_LEFT 12
58#define TOP_FRONT_CENTER 13
59#define TOP_FRONT_RIGHT 14
60#define TOP_BACK_LEFT 15
61#define TOP_BACK_CENTER 16
62#define TOP_BACK_RIGHT 17
63#define LOW_FREQUENCY_2 35
64#define TOP_SIDE_LEFT 36
65#define TOP_SIDE_RIGHT 37
66#define BOTTOM_FRONT_CENTER 38
67#define BOTTOM_FRONT_LEFT 39
68#define BOTTOM_FRONT_RIGHT 40
69#define NUM_NAMED_CHANNELS 41
70
71int swr_set_matrix(struct SwrContext *s, const double *matrix, int stride)
72{
73 int nb_in, nb_out, in, out;
74
75 if (!s || s->in_convert || // s needs to be allocated but not initialized
76 swri_check_chlayout(s, &s->user_in_chlayout , "input") ||
77 swri_check_chlayout(s, &s->user_out_chlayout, "output")
78 )
79 return AVERROR(EINVAL);
80 memset(s->matrix, 0, sizeof(s->matrix));
81
82 nb_in = s->user_in_chlayout.nb_channels;
83 nb_out = s->user_out_chlayout.nb_channels;
84 for (out = 0; out < nb_out; out++) {
85 for (in = 0; in < nb_in; in++)
86 s->matrix[out][in] = matrix[in];
87 matrix += stride;
88 }
89 s->rematrix_custom = 1;
90 return 0;
91}
92
93static int even(int64_t layout){
94 if(!layout) return 1;
95 if(layout&(layout-1)) return 1;
96 return 0;
97}
98
99static int clean_layout(AVChannelLayout *out, const AVChannelLayout *in, void *s)
100{
101 int used = in->nb_channels, idx = 0;
102
103 if (in->order == AV_CHANNEL_ORDER_CUSTOM && in->nb_channels > 1) {
104 used = 0;
105 for (int i = 0; i < in->nb_channels; i++) {
106 if (in->u.map[i].id != AV_CHAN_UNUSED) {
107 idx = i;
108 used++;
109 }
110 }
111 }
112
113 if (used != 1 ||
115 return av_channel_layout_copy(out, in);
116
117 char buf[128];
118 av_channel_layout_describe(in, buf, sizeof(buf));
119 av_log(s, AV_LOG_VERBOSE, "Treating %s as mono\n", buf);
120
121 if (in->nb_channels == 1) {
123 return 0;
124 }
125
126 /* the channel keeps its place among the unused ones */
127 int ret = av_channel_layout_copy(out, in);
128 if (ret < 0)
129 return ret;
130 out->u.map[idx].id = AV_CHAN_FRONT_CENTER;
131
132 return 0;
133}
134
135/**
136 * Stereo downmix channels are mixed like stereo, unless the other layout has
137 * such channels as well. The channels keep their places.
138 */
139static void clean_downmix(AVChannelLayout *ch_layout, const AVChannelLayout *other)
140{
141 if (av_channel_layout_subset(ch_layout, ~(uint64_t)0) != AV_CH_LAYOUT_STEREO_DOWNMIX ||
143 return;
144
145 if (ch_layout->order == AV_CHANNEL_ORDER_NATIVE) {
146 ch_layout->u.mask = AV_CH_LAYOUT_STEREO;
147 } else if (ch_layout->order == AV_CHANNEL_ORDER_CUSTOM) {
148 for (int i = 0; i < ch_layout->nb_channels; i++) {
149 if (ch_layout->u.map[i].id == AV_CHAN_STEREO_LEFT)
150 ch_layout->u.map[i].id = AV_CHAN_FRONT_LEFT;
151 else if (ch_layout->u.map[i].id == AV_CHAN_STEREO_RIGHT)
152 ch_layout->u.map[i].id = AV_CHAN_FRONT_RIGHT;
153 }
154 }
155}
156
157static int sane_layout(const AVChannelLayout *ch_layout, int mixed) {
158 if(ch_layout->nb_channels > SWR_CH_MAX)
159 return 0;
160 if(ch_layout->order == AV_CHANNEL_ORDER_CUSTOM)
161 for (int i = 0; i < ch_layout->nb_channels; i++) {
162 enum AVChannel id = ch_layout->u.map[i].id;
163
164 if (id == AV_CHAN_UNUSED)
165 continue;
166 if (id >= 64)
167 return 0;
168 }
169 else if (ch_layout->order != AV_CHANNEL_ORDER_NATIVE)
170 return 0;
171 if (!mixed)
172 return 1;
173 uint64_t mask = av_channel_layout_subset(ch_layout, ~(uint64_t)0);
174 if(!(mask & AV_CH_LAYOUT_SURROUND)) // at least 1 front speaker
175 return 0;
176 if (!even(mask & (AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT))) // no asymmetric front
177 return 0;
178 if (!even(mask & (AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT))) // no asymmetric side
179 return 0;
181 return 0;
183 return 0;
185 return 0;
187 return 0;
189 return 0;
191 return 0;
192
193 return 1;
194}
195
196static void build_matrix(const AVChannelLayout *in_ch_layout, const AVChannelLayout *out_ch_layout,
197 double center_mix_level, double surround_mix_level,
198 double lfe_mix_level, double maxval, double rematrix_volume, double *matrix_param,
199 ptrdiff_t stride, enum AVMatrixEncoding matrix_encoding)
200{
202 uint64_t in_mask = av_channel_layout_subset(in_ch_layout, ~(uint64_t)0);
203 uint64_t out_mask = av_channel_layout_subset(out_ch_layout, ~(uint64_t)0);
204 uint64_t unaccounted = in_mask & ~out_mask;
205 double maxcoef=0;
206 int i, j;
207
208 if (in_ch_layout->order == AV_CHANNEL_ORDER_CUSTOM) {
209 for (j = 0; j < in_ch_layout->nb_channels; j++) {
210 if (in_ch_layout->u.map[j].id == AV_CHAN_UNUSED) {
211 /* the named-channel loop below cannot visit AV_CHAN_UNUSED.
212 * explicitly clear its column so callers may reuse a matrix. */
213 for (i = 0; i < out_ch_layout->nb_channels; i++)
214 matrix_param[stride * i + j] = 0.0;
215 }
216 }
217 }
218
219 if (out_ch_layout->order == AV_CHANNEL_ORDER_CUSTOM) {
220 for (i = 0; i < out_ch_layout->nb_channels; i++) {
221 if (out_ch_layout->u.map[i].id == AV_CHAN_UNUSED) {
222 /* the named-channel loop below cannot visit AV_CHAN_UNUSED.
223 * explicitly clear its row so callers may reuse a matrix. */
224 for (j = 0; j < in_ch_layout->nb_channels; j++)
225 matrix_param[stride * i + j] = 0.0;
226 }
227 }
228 }
229
230 for(i=0; i<FF_ARRAY_ELEMS(matrix); i++){
231 if (in_mask & out_mask & (1ULL << i))
232 matrix[i][i]= 1.0;
233 }
234
235//FIXME implement dolby surround
236//FIXME implement full ac3
237
238 if(unaccounted & AV_CH_FRONT_CENTER){
239 if ((out_mask & AV_CH_LAYOUT_STEREO) == AV_CH_LAYOUT_STEREO) {
240 if (in_mask & AV_CH_LAYOUT_STEREO) {
241 matrix[ FRONT_LEFT][FRONT_CENTER]+= center_mix_level;
242 matrix[FRONT_RIGHT][FRONT_CENTER]+= center_mix_level;
243 } else {
246 }
247 }else
248 av_assert0(0);
249 }
250 if(unaccounted & AV_CH_LAYOUT_STEREO){
251 if (out_mask & AV_CH_FRONT_CENTER) {
254 if (in_mask & AV_CH_FRONT_CENTER)
255 matrix[FRONT_CENTER][ FRONT_CENTER] = center_mix_level*sqrt(2);
256 }else
257 av_assert0(0);
258 }
259
260 if(unaccounted & AV_CH_BACK_CENTER){
261 if (out_mask & AV_CH_BACK_LEFT) {
264 } else if (out_mask & AV_CH_SIDE_LEFT) {
267 } else if (out_mask & AV_CH_FRONT_LEFT) {
268 if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY ||
269 matrix_encoding == AV_MATRIX_ENCODING_DPLII) {
270 if (unaccounted & (AV_CH_BACK_LEFT | AV_CH_SIDE_LEFT)) {
271 matrix[FRONT_LEFT ][BACK_CENTER] -= surround_mix_level * M_SQRT1_2;
272 matrix[FRONT_RIGHT][BACK_CENTER] += surround_mix_level * M_SQRT1_2;
273 } else {
274 matrix[FRONT_LEFT ][BACK_CENTER] -= surround_mix_level;
275 matrix[FRONT_RIGHT][BACK_CENTER] += surround_mix_level;
276 }
277 } else {
278 matrix[ FRONT_LEFT][BACK_CENTER]+= surround_mix_level * M_SQRT1_2;
279 matrix[FRONT_RIGHT][BACK_CENTER]+= surround_mix_level * M_SQRT1_2;
280 }
281 } else if (out_mask & AV_CH_FRONT_CENTER) {
282 matrix[ FRONT_CENTER][BACK_CENTER]+= surround_mix_level * M_SQRT1_2;
283 }else
284 av_assert0(0);
285 }
286 if(unaccounted & AV_CH_BACK_LEFT){
287 if (out_mask & AV_CH_BACK_CENTER) {
290 } else if (out_mask & AV_CH_SIDE_LEFT) {
291 if (in_mask & AV_CH_SIDE_LEFT) {
294 }else{
295 matrix[ SIDE_LEFT][ BACK_LEFT]+= 1.0;
297 }
298 } else if (out_mask & AV_CH_FRONT_LEFT) {
299 if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY) {
300 matrix[FRONT_LEFT ][BACK_LEFT ] -= surround_mix_level * M_SQRT1_2;
301 matrix[FRONT_LEFT ][BACK_RIGHT] -= surround_mix_level * M_SQRT1_2;
302 matrix[FRONT_RIGHT][BACK_LEFT ] += surround_mix_level * M_SQRT1_2;
303 matrix[FRONT_RIGHT][BACK_RIGHT] += surround_mix_level * M_SQRT1_2;
304 } else if (matrix_encoding == AV_MATRIX_ENCODING_DPLII) {
305 matrix[FRONT_LEFT ][BACK_LEFT ] -= surround_mix_level * SQRT3_2;
306 matrix[FRONT_LEFT ][BACK_RIGHT] -= surround_mix_level * M_SQRT1_2;
307 matrix[FRONT_RIGHT][BACK_LEFT ] += surround_mix_level * M_SQRT1_2;
308 matrix[FRONT_RIGHT][BACK_RIGHT] += surround_mix_level * SQRT3_2;
309 } else {
310 matrix[ FRONT_LEFT][ BACK_LEFT] += surround_mix_level;
311 matrix[FRONT_RIGHT][BACK_RIGHT] += surround_mix_level;
312 }
313 } else if (out_mask & AV_CH_FRONT_CENTER) {
314 matrix[ FRONT_CENTER][BACK_LEFT ]+= surround_mix_level*M_SQRT1_2;
315 matrix[ FRONT_CENTER][BACK_RIGHT]+= surround_mix_level*M_SQRT1_2;
316 }else
317 av_assert0(0);
318 }
319
320 if(unaccounted & AV_CH_SIDE_LEFT){
321 if (out_mask & AV_CH_BACK_LEFT) {
322 /* if back channels do not exist in the input, just copy side
323 channels to back channels, otherwise mix side into back */
324 if (in_mask & AV_CH_BACK_LEFT) {
327 } else {
328 matrix[BACK_LEFT ][SIDE_LEFT ] += 1.0;
330 }
331 } else if (out_mask & AV_CH_BACK_CENTER) {
334 } else if (out_mask & AV_CH_FRONT_LEFT) {
335 if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY) {
336 matrix[FRONT_LEFT ][SIDE_LEFT ] -= surround_mix_level * M_SQRT1_2;
337 matrix[FRONT_LEFT ][SIDE_RIGHT] -= surround_mix_level * M_SQRT1_2;
338 matrix[FRONT_RIGHT][SIDE_LEFT ] += surround_mix_level * M_SQRT1_2;
339 matrix[FRONT_RIGHT][SIDE_RIGHT] += surround_mix_level * M_SQRT1_2;
340 } else if (matrix_encoding == AV_MATRIX_ENCODING_DPLII) {
341 matrix[FRONT_LEFT ][SIDE_LEFT ] -= surround_mix_level * SQRT3_2;
342 matrix[FRONT_LEFT ][SIDE_RIGHT] -= surround_mix_level * M_SQRT1_2;
343 matrix[FRONT_RIGHT][SIDE_LEFT ] += surround_mix_level * M_SQRT1_2;
344 matrix[FRONT_RIGHT][SIDE_RIGHT] += surround_mix_level * SQRT3_2;
345 } else {
346 matrix[ FRONT_LEFT][ SIDE_LEFT] += surround_mix_level;
347 matrix[FRONT_RIGHT][SIDE_RIGHT] += surround_mix_level;
348 }
349 } else if (out_mask & AV_CH_FRONT_CENTER) {
350 matrix[ FRONT_CENTER][SIDE_LEFT ]+= surround_mix_level * M_SQRT1_2;
351 matrix[ FRONT_CENTER][SIDE_RIGHT]+= surround_mix_level * M_SQRT1_2;
352 }else
353 av_assert0(0);
354 }
355
356 if(unaccounted & AV_CH_FRONT_LEFT_OF_CENTER){
357 if (out_mask & AV_CH_FRONT_LEFT) {
360 } else if (out_mask & AV_CH_FRONT_CENTER) {
363 }else
364 av_assert0(0);
365 }
366
367 if (unaccounted & AV_CH_TOP_FRONT_LEFT) {
368 if (out_mask & AV_CH_TOP_FRONT_CENTER) {
371 if (in_mask & AV_CH_TOP_FRONT_CENTER)
372 matrix[TOP_FRONT_CENTER][TOP_FRONT_CENTER] = center_mix_level * sqrt(2);
373 } else if (out_mask & AV_CH_FRONT_LEFT) {
374 /* U+030 -> M+030 in ITU-R BS.2127-1, Table 16. */
377 } else if (out_mask & AV_CH_FRONT_CENTER) {
380 } else
381 av_assert0(0);
382 }
383
384 if (unaccounted & AV_CH_TOP_FRONT_CENTER) {
385 if (out_mask & AV_CH_TOP_FRONT_LEFT) {
386 /* U+030 = U-030 = sqrt(1/2) */
389 } else if (out_mask & AV_CH_FRONT_CENTER) {
390 /* M+000 = 1 */
392 } else if (out_mask & AV_CH_FRONT_LEFT) {
393 /* M+030 = M-030 = sqrt(1/2) */
394 matrix[FRONT_LEFT ][TOP_FRONT_CENTER] += center_mix_level;
395 matrix[FRONT_RIGHT][TOP_FRONT_CENTER] += center_mix_level;
396 } else
397 av_assert0(0);
398 }
399
400 if (unaccounted & AV_CH_TOP_BACK_LEFT) {
401 if (out_mask & AV_CH_TOP_BACK_CENTER) {
404 } else if (out_mask & AV_CH_TOP_FRONT_LEFT) {
405 /* IAMF v1.1.0, Section 7.3.2.1.1. */
408 } else if (out_mask & AV_CH_BACK_LEFT) {
409 matrix[BACK_LEFT ][TOP_BACK_LEFT ] += 1.0;
411 } else if (out_mask & AV_CH_SIDE_LEFT) {
412 matrix[SIDE_LEFT ][TOP_BACK_LEFT ] += 1.0;
414 } else if (out_mask & AV_CH_FRONT_LEFT) {
415 matrix[FRONT_LEFT ][TOP_BACK_LEFT ] += surround_mix_level;
416 matrix[FRONT_RIGHT][TOP_BACK_RIGHT] += surround_mix_level;
417 } else if (out_mask & AV_CH_FRONT_CENTER) {
418 matrix[FRONT_CENTER][TOP_BACK_LEFT ] += surround_mix_level*M_SQRT1_2;
419 matrix[FRONT_CENTER][TOP_BACK_RIGHT] += surround_mix_level*M_SQRT1_2;
420 } else
421 av_assert0(0);
422 }
423
424 /* BS.2127-1 maps U+180 to rear outputs before front outputs. */
425 if (unaccounted & AV_CH_TOP_BACK_CENTER) {
426 if (out_mask & AV_CH_TOP_BACK_LEFT) {
429 } else if (out_mask & AV_CH_BACK_LEFT) {
432 } else if (out_mask & AV_CH_SIDE_LEFT) {
435 } else if (out_mask & AV_CH_FRONT_LEFT) {
438 } else if (out_mask & AV_CH_FRONT_CENTER)
440 else
441 av_assert0(0);
442 }
443
444
445 if (unaccounted & AV_CH_TOP_SIDE_LEFT) {
446 if ((out_mask & (AV_CH_TOP_FRONT_LEFT|AV_CH_TOP_BACK_CENTER)) ==
448 /* UH+180 = sqrt(1/3); U±045 = sqrt(2/3)*/
453 } else if ((out_mask & (AV_CH_TOP_FRONT_LEFT|AV_CH_TOP_BACK_LEFT)) ==
455 /* U±030 = U±110 = sqrt(1/2) */
460 } else if (out_mask & AV_CH_TOP_FRONT_LEFT &&
461 (out_mask & (AV_CH_BACK_LEFT|AV_CH_SIDE_LEFT))) {
462 /* U±030 = M±110 = sqrt(1/2) */
465 if (out_mask & AV_CH_BACK_LEFT) {
468 } else if (out_mask & AV_CH_SIDE_LEFT) {
471 }
472 } else if (out_mask & AV_CH_SIDE_LEFT) {
473 /* M±090 = 1 */
474 matrix[SIDE_LEFT ][TOP_SIDE_LEFT ] += 1.0;
476 } else if (out_mask & AV_CH_FRONT_LEFT) {
477 /* M±030 = M±110 = sqrt(1/2) */
478 matrix[FRONT_LEFT ][TOP_SIDE_LEFT ] += surround_mix_level;
479 matrix[FRONT_RIGHT][TOP_SIDE_RIGHT] += surround_mix_level;
480 if (out_mask & AV_CH_BACK_LEFT) {
483 }
484 } else if (out_mask & AV_CH_FRONT_CENTER) {
485 matrix[FRONT_CENTER][TOP_SIDE_LEFT ] += surround_mix_level*M_SQRT1_2;
486 matrix[FRONT_CENTER][TOP_SIDE_RIGHT] += surround_mix_level*M_SQRT1_2;
487 } else
488 av_assert0(0);
489 }
490
491 if (unaccounted & AV_CH_TOP_CENTER) {
492 if ((out_mask & (AV_CH_TOP_FRONT_LEFT|AV_CH_TOP_BACK_LEFT)) ==
494 /* U+045 = U-045 = U+135 = U-135 = sqrt(1/4) */
499 } else if ((out_mask & (AV_CH_TOP_FRONT_LEFT|AV_CH_TOP_BACK_CENTER)) ==
501 /* U+045 = U-045 = UH+180 = sqrt(1/3) */
505 } else if (out_mask & AV_CH_TOP_FRONT_LEFT &&
506 out_mask & (AV_CH_BACK_LEFT|AV_CH_SIDE_LEFT)) {
507 /* U+045 = U-045 = M+135 = M-135 = sqrt(1/4) *
508 * U+030 = U-030 = M+110 = M-110 = sqrt(1/4) */
511 if (out_mask & AV_CH_BACK_LEFT) {
512 matrix[BACK_LEFT ][TOP_CENTER] += 0.5;
514 } else if (out_mask & AV_CH_SIDE_LEFT) {
515 matrix[SIDE_LEFT ][TOP_CENTER] += 0.5;
517 }
518 } else if (out_mask & AV_CH_FRONT_LEFT) {
519 /* M+030 = M-030 = M+135 = M-135 = sqrt(1/4) */
520 /* M+030 = M-030 = sqrt(1/4) */
521 matrix[FRONT_LEFT ][TOP_CENTER] += 0.5;
523 if (out_mask & AV_CH_BACK_LEFT) {
524 matrix[BACK_LEFT ][TOP_CENTER] += 0.5;
526 } else if (out_mask & AV_CH_SIDE_LEFT) {
527 matrix[SIDE_LEFT ][TOP_CENTER] += 0.5;
529 }
530 } else if (out_mask & AV_CH_FRONT_CENTER) {
532 } else
533 av_assert0(0);
534 }
535
536 if (unaccounted & AV_CH_BOTTOM_FRONT_CENTER) {
537 if (out_mask & AV_CH_FRONT_CENTER) {
539 } else if (out_mask & AV_CH_FRONT_LEFT) {
540 matrix[FRONT_LEFT ][BOTTOM_FRONT_CENTER] += center_mix_level;
541 matrix[FRONT_RIGHT][BOTTOM_FRONT_CENTER] += center_mix_level;
542 } else
543 av_assert0(0);
544 }
545
546 if (unaccounted & AV_CH_BOTTOM_FRONT_LEFT) {
547 if (out_mask & AV_CH_BOTTOM_FRONT_CENTER) {
550 if (in_mask & AV_CH_BOTTOM_FRONT_CENTER)
551 matrix[BOTTOM_FRONT_CENTER][BOTTOM_FRONT_CENTER] = center_mix_level * sqrt(2);
552 } else if (out_mask & AV_CH_FRONT_LEFT) {
553 /* M±030 = 1 */
556 } else if (out_mask & AV_CH_FRONT_CENTER) {
559 } else
560 av_assert0(0);
561 }
562
563 /* mix LFE into front left/right or center */
564 if (unaccounted & AV_CH_LOW_FREQUENCY) {
565 if (out_mask & AV_CH_FRONT_CENTER) {
566 matrix[FRONT_CENTER][LOW_FREQUENCY] += lfe_mix_level;
567 } else if (out_mask & AV_CH_FRONT_LEFT) {
568 matrix[FRONT_LEFT ][LOW_FREQUENCY] += lfe_mix_level * M_SQRT1_2;
569 matrix[FRONT_RIGHT][LOW_FREQUENCY] += lfe_mix_level * M_SQRT1_2;
570 } else
571 av_assert0(0);
572 }
573
574 /* mix LFE2 into LFE, front left/right or center */
575 if (unaccounted & AV_CH_LOW_FREQUENCY_2) {
576 if (out_mask & AV_CH_LOW_FREQUENCY) {
578 } else if (out_mask & AV_CH_FRONT_CENTER) {
579 matrix[FRONT_CENTER][LOW_FREQUENCY_2] += lfe_mix_level;
580 } else if (out_mask & AV_CH_FRONT_LEFT) {
581 matrix[FRONT_LEFT ][LOW_FREQUENCY_2] += lfe_mix_level * M_SQRT1_2;
582 matrix[FRONT_RIGHT][LOW_FREQUENCY_2] += lfe_mix_level * M_SQRT1_2;
583 } else
584 av_assert0(0);
585 }
586
587
588 for (i = 0; i < 64; i++) {
589 double sum=0;
590 int out_i = av_channel_layout_index_from_channel(out_ch_layout, i);
591 if (out_i < 0)
592 continue;
593 for(j=0; j<64; j++){
594 int in_i = av_channel_layout_index_from_channel(in_ch_layout, j);
595 if (in_i < 0)
596 continue;
597 if (i < FF_ARRAY_ELEMS(matrix) && j < FF_ARRAY_ELEMS(matrix[0]))
598 matrix_param[stride*out_i + in_i] = matrix[i][j];
599 else
600 matrix_param[stride*out_i + in_i] = i == j && (in_mask & out_mask & (1ULL << i));
601 sum += fabs(matrix_param[stride*out_i + in_i]);
602 }
603 maxcoef= FFMAX(maxcoef, sum);
604 }
605 if(rematrix_volume < 0)
606 maxcoef = -rematrix_volume;
607
608 if(maxcoef > maxval || rematrix_volume < 0){
609 maxcoef /= maxval;
610 for(i=0; i<SWR_CH_MAX; i++)
611 for(j=0; j<SWR_CH_MAX; j++){
612 matrix_param[stride*i + j] /= maxcoef;
613 }
614 }
615}
616
617av_cold int swr_build_matrix2(const AVChannelLayout *in_layout, const AVChannelLayout *out_layout,
618 double center_mix_level, double surround_mix_level,
619 double lfe_mix_level, double maxval,
620 double rematrix_volume, double *matrix_param,
621 ptrdiff_t stride, enum AVMatrixEncoding matrix_encoding, void *log_context)
622{
623 int i, j, ret, mixed;
624 AVChannelLayout in_ch_layout = { 0 }, out_ch_layout = { 0 };
625 char buf[128];
626
627 ret = clean_layout(&in_ch_layout, in_layout, log_context);
628 ret |= clean_layout(&out_ch_layout, out_layout, log_context);
629 if (ret < 0)
630 goto fail;
631
632 clean_downmix(&out_ch_layout, &in_ch_layout);
633 clean_downmix(&in_ch_layout, &out_ch_layout);
634
635 /* the same channels on both sides change their places at most */
636 mixed = av_channel_layout_subset(&in_ch_layout, ~(uint64_t)0) !=
637 av_channel_layout_subset(&out_ch_layout, ~(uint64_t)0);
638
639 if(!av_channel_layout_check(&in_ch_layout)) {
640 av_log(log_context, AV_LOG_ERROR, "Input channel layout is invalid\n");
641 ret = AVERROR(EINVAL);
642 goto fail;
643 }
644 if(!sane_layout(&in_ch_layout, mixed)) {
645 av_channel_layout_describe(&in_ch_layout, buf, sizeof(buf));
646 av_log(log_context, AV_LOG_ERROR, "Input channel layout '%s' is not supported\n", buf);
647 ret = AVERROR(EINVAL);
648 goto fail;
649 }
650
651 if(!av_channel_layout_check(&out_ch_layout)) {
652 av_log(log_context, AV_LOG_ERROR, "Output channel layout is invalid\n");
653 ret = AVERROR(EINVAL);
654 goto fail;
655 }
656 if(!sane_layout(&out_ch_layout, mixed)) {
657 av_channel_layout_describe(&out_ch_layout, buf, sizeof(buf));
658 av_log(log_context, AV_LOG_ERROR, "Output channel layout '%s' is not supported\n", buf);
659 ret = AVERROR(EINVAL);
660 goto fail;
661 }
662
663 build_matrix(&in_ch_layout, &out_ch_layout, center_mix_level,
664 surround_mix_level, lfe_mix_level, maxval, rematrix_volume,
665 matrix_param, stride, matrix_encoding);
666
667 if(rematrix_volume > 0){
668 for(i=0; i<SWR_CH_MAX; i++)
669 for(j=0; j<SWR_CH_MAX; j++){
670 matrix_param[stride*i + j] *= rematrix_volume;
671 }
672 }
673
674 av_log(log_context, AV_LOG_DEBUG, "Matrix coefficients:\n");
675 for (i = 0; i < out_ch_layout.nb_channels; i++){
676 av_channel_name(buf, sizeof(buf), av_channel_layout_channel_from_index(&out_ch_layout, i));
677 av_log(log_context, AV_LOG_DEBUG, "%s: ", buf);
678 for (j = 0; j < in_ch_layout.nb_channels; j++){
679 av_channel_name(buf, sizeof(buf), av_channel_layout_channel_from_index(&in_ch_layout, j));
680 av_log(log_context, AV_LOG_DEBUG, "%s:%f ", buf, matrix_param[stride*i + j]);
681 }
682 av_log(log_context, AV_LOG_DEBUG, "\n");
683 }
684
685 ret = 0;
686fail:
687 av_channel_layout_uninit(&in_ch_layout);
688 av_channel_layout_uninit(&out_ch_layout);
689
690 return ret;
691}
692
694{
695 double maxval;
696
697 if (s->rematrix_maxval > 0) {
698 maxval = s->rematrix_maxval;
699 } else if ( av_get_packed_sample_fmt(s->out_sample_fmt) < AV_SAMPLE_FMT_FLT
700 || (s->user_int_sample_fmt != AV_SAMPLE_FMT_NONE &&
701 av_get_packed_sample_fmt(s->user_int_sample_fmt) < AV_SAMPLE_FMT_FLT)) {
702 maxval = 1.0;
703 } else
704 maxval = INT_MAX;
705
706 memset(s->matrix, 0, sizeof(s->matrix));
707 return swr_build_matrix2(&s->in_ch_layout, &s->out_ch_layout,
708 s->clev, s->slev, s->lfe_mix_level,
709 maxval, s->rematrix_volume, (double*)s->matrix,
710 s->matrix[1] - s->matrix[0], s->matrix_encoding, s);
711}
712
714{
715 int i, j;
716 int nb_in = s->used_ch_layout.nb_channels;
717 int nb_out = s->out.ch_count;
718
719 if (!s->rematrix_custom) {
720 int r = auto_matrix(s);
721 if (r)
722 return r;
723 } else {
724 char buf[128];
725 av_log(s, AV_LOG_DEBUG, "Custom matrix coefficients:\n");
726 double *matrix_param = (double*)s->matrix;
727 ptrdiff_t stride = s->matrix[1] - s->matrix[0];
728 for (i = 0; i < s->out_ch_layout.nb_channels; i++) {
729 av_channel_name(buf, sizeof(buf), av_channel_layout_channel_from_index(&s->out_ch_layout, i));
730 av_log(s, AV_LOG_DEBUG, "%s: ", buf);
731 for (j = 0; j < s->in_ch_layout.nb_channels; j++){
732 av_channel_name(buf, sizeof(buf), av_channel_layout_channel_from_index(&s->in_ch_layout, j));
733 av_log(s, AV_LOG_DEBUG, "%s:%f ", buf, matrix_param[stride*i + j]);
734 }
735 av_log(s, AV_LOG_DEBUG, "\n");
736 }
737 }
738
739 /* a channel that is one channel of the input, or silent, is not mixed */
740 for (i = 0; i < nb_out; i++) {
741 int sources = 0;
742 for (j = 0; j < nb_in; j++) {
743 if (s->matrix[i][j] == 0.0)
744 continue;
745 if (s->matrix[i][j] != 1.0 || sources++)
746 return 1;
747 }
748 }
749
750 return 0;
751}
752
754 int i, j;
755 int nb_in = s->used_ch_layout.nb_channels;
756 int nb_out = s->out.ch_count;
757
758 s->mix_any_f = NULL;
759
760 /* a matrix that is applied was built by swri_rematrix_build() */
761 if (!s->rematrix) {
762 int r = auto_matrix(s);
763 if (r)
764 return r;
765 }
766 if (s->midbuf.fmt == AV_SAMPLE_FMT_S16P){
767 int maxsum = 0;
768 s->native_matrix = av_calloc(nb_in * nb_out, sizeof(int));
769 if (!s->native_matrix)
770 return AVERROR(ENOMEM);
771 for (i = 0; i < nb_out; i++) {
772 double rem = 0;
773 int sum = 0;
774
775 for (j = 0; j < nb_in; j++) {
776 double target = s->matrix[i][j] * 32768 + rem;
777 ((int*)s->native_matrix)[i * nb_in + j] = lrintf(target);
778 rem += target - ((int*)s->native_matrix)[i * nb_in + j];
779 sum += FFABS(((int*)s->native_matrix)[i * nb_in + j]);
780 }
781 maxsum = FFMAX(maxsum, sum);
782 }
783 s->native_one.i = 32768;
784 if (maxsum <= 32768) {
785 s->mix_1_1_f = copy_s16;
786 s->mix_2_1_f = sum2_s16;
787 s->mix_any_f = get_mix_any_func_s16(s);
788 } else {
789 s->mix_1_1_f = copy_clip_s16;
790 s->mix_2_1_f = sum2_clip_s16;
791 s->mix_any_f = get_mix_any_func_clip_s16(s);
792 }
793 }else if(s->midbuf.fmt == AV_SAMPLE_FMT_FLTP){
794 s->native_matrix = av_calloc(nb_in * nb_out, sizeof(float));
795 if (!s->native_matrix)
796 return AVERROR(ENOMEM);
797 for (i = 0; i < nb_out; i++)
798 for (j = 0; j < nb_in; j++)
799 ((float*)s->native_matrix)[i * nb_in + j] = s->matrix[i][j];
800 s->native_one.f = 1.0;
801 s->mix_1_1_f = copy_float;
802 s->mix_2_1_f = sum2_float;
803 s->mix_any_f = get_mix_any_func_float(s);
804 }else if(s->midbuf.fmt == AV_SAMPLE_FMT_DBLP){
805 s->native_matrix = av_calloc(nb_in * nb_out, sizeof(double));
806 if (!s->native_matrix)
807 return AVERROR(ENOMEM);
808 for (i = 0; i < nb_out; i++)
809 for (j = 0; j < nb_in; j++)
810 ((double*)s->native_matrix)[i * nb_in + j] = s->matrix[i][j];
811 s->native_one.d = 1.0;
812 s->mix_1_1_f = copy_double;
813 s->mix_2_1_f = sum2_double;
814 s->mix_any_f = get_mix_any_func_double(s);
815 }else if(s->midbuf.fmt == AV_SAMPLE_FMT_S32P){
816 s->native_matrix = av_calloc(nb_in * nb_out, sizeof(int));
817 if (!s->native_matrix)
818 return AVERROR(ENOMEM);
819 for (i = 0; i < nb_out; i++) {
820 double rem = 0;
821
822 for (j = 0; j < nb_in; j++) {
823 double target = s->matrix[i][j] * 32768 + rem;
824 ((int*)s->native_matrix)[i * nb_in + j] = lrintf(target);
825 rem += target - ((int*)s->native_matrix)[i * nb_in + j];
826 }
827 }
828 s->native_one.i = 32768;
829 s->mix_1_1_f = copy_s32;
830 s->mix_2_1_f = sum2_s32;
831 s->mix_any_f = get_mix_any_func_s32(s);
832 }else
833 av_assert0(0);
834 //FIXME quantize for integeres
835 for (i = 0; i < SWR_CH_MAX; i++) {
836 int ch_in=0;
837 for (j = 0; j < SWR_CH_MAX; j++) {
838 const double coeff = s->matrix[i][j];
839 if (coeff)
840 s->matrix_ch[i][++ch_in]= j;
841 switch (s->int_sample_fmt) {
843 s->matrix_flt[i][j] = coeff;
844 break;
846 break;
847 default:
848 s->matrix32[i][j] = lrintf(coeff * 32768);
849 break;
850 }
851 }
852 s->matrix_ch[i][0]= ch_in;
853 }
854
855#if ARCH_X86 && HAVE_X86ASM
857#endif
858
859 return 0;
860}
861
863 av_freep(&s->native_matrix);
864 av_freep(&s->native_simd_matrix);
865}
866
867int swri_rematrix(SwrContext *s, AudioData *out, AudioData *in, int len, int mustcopy){
868 int out_i, in_i, i, j;
869 int len1 = 0;
870 int off = 0;
871
872 if(s->mix_any_f) {
873 s->mix_any_f(out->ch, (const uint8_t *const *)in->ch, s->native_matrix, len);
874 return 0;
875 }
876
877 if(s->mix_2_1_simd || s->mix_1_1_simd){
878 len1= len&~15;
879 off = len1 * out->bps;
880 }
881
882 av_assert0(s->out_ch_layout.order == AV_CHANNEL_ORDER_UNSPEC || out->ch_count == s->out_ch_layout.nb_channels);
883 av_assert0(s-> in_ch_layout.order == AV_CHANNEL_ORDER_UNSPEC || in ->ch_count == s->in_ch_layout.nb_channels);
884
885 for(out_i=0; out_i<out->ch_count; out_i++){
886 switch(s->matrix_ch[out_i][0]){
887 case 0:
888 if(mustcopy)
889 memset(out->ch[out_i], 0, len * av_get_bytes_per_sample(s->int_sample_fmt));
890 break;
891 case 1:
892 in_i= s->matrix_ch[out_i][1];
893 if(s->matrix[out_i][in_i]!=1.0){
894 if(s->mix_1_1_simd && len1)
895 s->mix_1_1_simd(out->ch[out_i] , in->ch[in_i] , s->native_simd_matrix, in->ch_count*out_i + in_i, len1);
896 if(len != len1)
897 s->mix_1_1_f (out->ch[out_i]+off, in->ch[in_i]+off, s->native_matrix, in->ch_count*out_i + in_i, len-len1);
898 }else if(mustcopy){
899 memcpy(out->ch[out_i], in->ch[in_i], len*out->bps);
900 }else{
901 out->ch[out_i]= in->ch[in_i];
902 }
903 break;
904 case 2: {
905 int in_i1 = s->matrix_ch[out_i][1];
906 int in_i2 = s->matrix_ch[out_i][2];
907 if(s->mix_2_1_simd && len1)
908 s->mix_2_1_simd(out->ch[out_i] , in->ch[in_i1] , in->ch[in_i2] , s->native_simd_matrix, in->ch_count*out_i + in_i1, in->ch_count*out_i + in_i2, len1);
909 else
910 s->mix_2_1_f (out->ch[out_i] , in->ch[in_i1] , in->ch[in_i2] , s->native_matrix, in->ch_count*out_i + in_i1, in->ch_count*out_i + in_i2, len1);
911 if(len != len1)
912 s->mix_2_1_f (out->ch[out_i]+off, in->ch[in_i1]+off, in->ch[in_i2]+off, s->native_matrix, in->ch_count*out_i + in_i1, in->ch_count*out_i + in_i2, len-len1);
913 break;}
914 default:
915 if(s->int_sample_fmt == AV_SAMPLE_FMT_FLTP){
916 for(i=0; i<len; i++){
917 float v=0;
918 for(j=0; j<s->matrix_ch[out_i][0]; j++){
919 in_i= s->matrix_ch[out_i][1+j];
920 v+= ((float*)in->ch[in_i])[i] * s->matrix_flt[out_i][in_i];
921 }
922 ((float*)out->ch[out_i])[i]= v;
923 }
924 }else if(s->int_sample_fmt == AV_SAMPLE_FMT_DBLP){
925 for(i=0; i<len; i++){
926 double v=0;
927 for(j=0; j<s->matrix_ch[out_i][0]; j++){
928 in_i= s->matrix_ch[out_i][1+j];
929 v+= ((double*)in->ch[in_i])[i] * s->matrix[out_i][in_i];
930 }
931 ((double*)out->ch[out_i])[i]= v;
932 }
933 }else{
934 for(i=0; i<len; i++){
935 int v=0;
936 for(j=0; j<s->matrix_ch[out_i][0]; j++){
937 in_i= s->matrix_ch[out_i][1+j];
938 v+= ((int16_t*)in->ch[in_i])[i] * s->matrix32[out_i][in_i];
939 }
940 ((int16_t*)out->ch[out_i])[i]= (v + 16384)>>15;
941 }
942 }
943 }
944 }
945 return 0;
946}
#define SWR_CH_MAX
Definition af_amerge.c:37
static FILE * out
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define s(width, name)
Definition cbs_vp9.c:198
Public libavutil channel layout APIs header.
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition common.h:74
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
static __device__ float fabs(float a)
#define fail
Definition test.h:479
#define AV_CH_LAYOUT_STEREO_DOWNMIX
#define AV_CH_LAYOUT_SURROUND
#define AV_CH_LAYOUT_STEREO
#define AV_CH_SIDE_LEFT
#define AV_CH_TOP_FRONT_LEFT
#define AV_CH_FRONT_RIGHT
#define AV_CH_TOP_BACK_CENTER
#define AV_CH_BOTTOM_FRONT_CENTER
#define AV_CH_FRONT_RIGHT_OF_CENTER
#define AV_CH_BACK_CENTER
#define AV_CH_TOP_FRONT_CENTER
#define AV_CH_FRONT_LEFT_OF_CENTER
#define AV_CH_LOW_FREQUENCY_2
#define AV_CH_BACK_RIGHT
#define AV_CH_TOP_SIDE_RIGHT
#define AV_CH_FRONT_CENTER
#define AV_CH_TOP_BACK_RIGHT
#define AV_CH_TOP_CENTER
#define AV_CH_SIDE_RIGHT
#define AV_CH_BACK_LEFT
#define AV_CH_TOP_SIDE_LEFT
#define AV_CH_TOP_BACK_LEFT
#define AV_CH_LOW_FREQUENCY
#define AV_CH_BOTTOM_FRONT_RIGHT
#define AV_CH_TOP_FRONT_RIGHT
#define AV_CH_BOTTOM_FRONT_LEFT
#define AV_CH_FRONT_LEFT
int av_channel_layout_index_from_channel(const AVChannelLayout *channel_layout, enum AVChannel channel)
Get the index of a given channel in a channel layout.
int av_channel_name(char *buf, size_t buf_size, enum AVChannel channel_id)
Get a human readable string in an abbreviated form describing a given channel.
#define AV_CHANNEL_LAYOUT_MONO
enum AVChannel av_channel_layout_channel_from_index(const AVChannelLayout *channel_layout, unsigned int idx)
Get the channel with the given index in a channel layout.
void av_channel_layout_uninit(AVChannelLayout *channel_layout)
Free any allocated data in the channel layout and reset the channel count to 0.
AVChannel
AVMatrixEncoding
int av_channel_layout_describe(const AVChannelLayout *channel_layout, char *buf, size_t buf_size)
Get a human-readable string describing the channel layout properties.
int av_channel_layout_check(const AVChannelLayout *channel_layout)
Check whether a channel layout is valid, i.e.
int av_channel_layout_copy(AVChannelLayout *dst, const AVChannelLayout *src)
Make a copy of a channel layout.
uint64_t av_channel_layout_subset(const AVChannelLayout *channel_layout, uint64_t mask)
Find out what channels from a given set are present in a channel layout, without regard for their pos...
@ AV_CHANNEL_ORDER_NATIVE
The native channel order, i.e.
@ AV_CHANNEL_ORDER_CUSTOM
The channel order does not correspond to any other predefined order and is stored as an explicit map.
@ AV_CHANNEL_ORDER_UNSPEC
Only the channel count is specified, without any further information about the channel order.
@ AV_CHAN_UNUSED
Channel is empty can be safely skipped.
@ AV_CHAN_FRONT_LEFT
@ AV_CHAN_FRONT_RIGHT
@ AV_CHAN_FRONT_CENTER
@ AV_CHAN_STEREO_RIGHT
See above.
@ AV_CHAN_STEREO_LEFT
Stereo downmix.
@ AV_MATRIX_ENCODING_DOLBY
@ AV_MATRIX_ENCODING_DPLII
#define AVERROR(e)
Definition error.h:45
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition log.h:231
#define AV_LOG_VERBOSE
Detailed information.
Definition log.h:226
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt)
Return number of bytes per sample.
Definition samplefmt.c:109
enum AVSampleFormat av_get_packed_sample_fmt(enum AVSampleFormat sample_fmt)
Get the packed alternative form of the given sample format.
Definition samplefmt.c:78
@ AV_SAMPLE_FMT_FLTP
float, planar
Definition samplefmt.h:66
@ AV_SAMPLE_FMT_S16P
signed 16 bits, planar
Definition samplefmt.h:64
@ AV_SAMPLE_FMT_FLT
float
Definition samplefmt.h:60
@ AV_SAMPLE_FMT_S32P
signed 32 bits, planar
Definition samplefmt.h:65
@ AV_SAMPLE_FMT_NONE
Definition samplefmt.h:56
@ AV_SAMPLE_FMT_DBLP
double, planar
Definition samplefmt.h:67
av_cold int swr_build_matrix2(const AVChannelLayout *in_layout, const AVChannelLayout *out_layout, double center_mix_level, double surround_mix_level, double lfe_mix_level, double maxval, double rematrix_volume, double *matrix_param, ptrdiff_t stride, enum AVMatrixEncoding matrix_encoding, void *log_context)
Generate a channel mixing matrix.
Definition rematrix.c:617
int swr_set_matrix(struct SwrContext *s, const double *matrix, int stride)
Set a customized remix matrix.
Definition rematrix.c:71
#define r
Definition input.c:42
#define av_cold
Definition attributes.h:117
#define lrintf(x)
Definition libm_mips.h:74
static const uint16_t mask[17]
Definition lzw.c:38
#define FFMAX(a, b)
Definition macros.h:47
#define M_SQRT1_2
uint64_t layout
void * av_calloc(size_t nmemb, size_t size)
Definition mem.c:370
Memory handling functions.
#define TOP_CENTER
Definition movtextdec.c:51
int swri_rematrix(SwrContext *s, AudioData *out, AudioData *in, int len, int mustcopy)
Definition rematrix.c:867
#define BOTTOM_FRONT_LEFT
Definition rematrix.c:67
#define TOP_BACK_RIGHT
Definition rematrix.c:62
static int sane_layout(const AVChannelLayout *ch_layout, int mixed)
Definition rematrix.c:157
av_cold int swri_rematrix_init(SwrContext *s)
Definition rematrix.c:753
#define FRONT_LEFT_OF_CENTER
Definition rematrix.c:51
static int even(int64_t layout)
Definition rematrix.c:93
static void build_matrix(const AVChannelLayout *in_ch_layout, const AVChannelLayout *out_ch_layout, double center_mix_level, double surround_mix_level, double lfe_mix_level, double maxval, double rematrix_volume, double *matrix_param, ptrdiff_t stride, enum AVMatrixEncoding matrix_encoding)
Definition rematrix.c:196
#define BOTTOM_FRONT_RIGHT
Definition rematrix.c:68
#define TOP_BACK_LEFT
Definition rematrix.c:60
#define BACK_LEFT
Definition rematrix.c:49
#define NUM_NAMED_CHANNELS
Definition rematrix.c:69
static int clean_layout(AVChannelLayout *out, const AVChannelLayout *in, void *s)
Definition rematrix.c:99
#define SIDE_RIGHT
Definition rematrix.c:55
static void clean_downmix(AVChannelLayout *ch_layout, const AVChannelLayout *other)
Stereo downmix channels are mixed like stereo, unless the other layout has such channels as well.
Definition rematrix.c:139
static av_cold int auto_matrix(SwrContext *s)
Definition rematrix.c:693
#define LOW_FREQUENCY_2
Definition rematrix.c:63
#define FRONT_LEFT
Definition rematrix.c:45
#define TOP_FRONT_CENTER
Definition rematrix.c:58
#define FRONT_RIGHT_OF_CENTER
Definition rematrix.c:52
#define TOP_SIDE_RIGHT
Definition rematrix.c:65
#define TOP_FRONT_LEFT
Definition rematrix.c:57
#define BACK_RIGHT
Definition rematrix.c:50
#define FRONT_RIGHT
Definition rematrix.c:46
#define LOW_FREQUENCY
Definition rematrix.c:48
#define TOP_FRONT_RIGHT
Definition rematrix.c:59
av_cold int swri_rematrix_build(SwrContext *s)
Definition rematrix.c:713
#define TOP_BACK_CENTER
Definition rematrix.c:61
#define FRONT_CENTER
Definition rematrix.c:47
#define BOTTOM_FRONT_CENTER
Definition rematrix.c:66
#define SIDE_LEFT
Definition rematrix.c:54
av_cold void swri_rematrix_free(SwrContext *s)
Definition rematrix.c:862
#define BACK_CENTER
Definition rematrix.c:53
#define TOP_SIDE_LEFT
Definition rematrix.c:64
#define FF_ARRAY_ELEMS(a)
enum AVChannel id
An AVChannelLayout holds information about the channel layout of audio data.
enum AVChannelOrder order
Channel order used in this layout.
uint64_t mask
This member must be used for AV_CHANNEL_ORDER_NATIVE, and may be used for AV_CHANNEL_ORDER_AMBISONIC ...
union AVChannelLayout::@162063043056170047076125117143030261346263330336 u
Details about which channels are present in this layout.
int nb_channels
Number of channels in this layout.
AVChannelCustom * map
This member must be used when the channel order is AV_CHANNEL_ORDER_CUSTOM.
int ch_count
number of channels
uint8_t * ch[SWR_CH_MAX]
samples buffer per channel
The libswresample context.
#define stride
int swri_check_chlayout(struct SwrContext *s, const AVChannelLayout *chl, const char *name)
Definition swresample.c:33
#define SQRT2_3
int swri_rematrix_init_x86(struct SwrContext *s)
#define SQRT1_3
#define SQRT3_2
#define av_freep(p)
#define av_log(a,...)
static const double coeff[2][5]
int len