Line | Branch | Exec | Source |
---|---|---|---|
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" | ||
23 | #include "libavutil/channel_layout.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 NUM_NAMED_CHANNELS 18 | ||
64 | |||
65 | 8 | int swr_set_matrix(struct SwrContext *s, const double *matrix, int stride) | |
66 | { | ||
67 | int nb_in, nb_out, in, out; | ||
68 | |||
69 |
2/4✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
|
8 | if (!s || s->in_convert) // s needs to be allocated but not initialized |
70 | ✗ | return AVERROR(EINVAL); | |
71 | 8 | memset(s->matrix, 0, sizeof(s->matrix)); | |
72 | 8 | memset(s->matrix_flt, 0, sizeof(s->matrix_flt)); | |
73 | |||
74 | 8 | nb_in = s->user_in_chlayout.nb_channels; | |
75 | 8 | nb_out = s->user_out_chlayout.nb_channels; | |
76 |
2/2✓ Branch 0 taken 27 times.
✓ Branch 1 taken 8 times.
|
35 | for (out = 0; out < nb_out; out++) { |
77 |
2/2✓ Branch 0 taken 123 times.
✓ Branch 1 taken 27 times.
|
150 | for (in = 0; in < nb_in; in++) |
78 | 123 | s->matrix_flt[out][in] = s->matrix[out][in] = matrix[in]; | |
79 | 27 | matrix += stride; | |
80 | } | ||
81 | 8 | s->rematrix_custom = 1; | |
82 | 8 | return 0; | |
83 | } | ||
84 | |||
85 | 170 | static int even(int64_t layout){ | |
86 |
2/2✓ Branch 0 taken 155 times.
✓ Branch 1 taken 15 times.
|
170 | if(!layout) return 1; |
87 |
1/2✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
|
15 | if(layout&(layout-1)) return 1; |
88 | ✗ | return 0; | |
89 | } | ||
90 | |||
91 | 34 | static int clean_layout(AVChannelLayout *out, const AVChannelLayout *in, void *s) | |
92 | { | ||
93 | 34 | int ret = 0; | |
94 | |||
95 |
4/4✓ Branch 1 taken 17 times.
✓ Branch 2 taken 17 times.
✓ Branch 3 taken 7 times.
✓ Branch 4 taken 10 times.
|
34 | if (av_channel_layout_index_from_channel(in, AV_CHAN_FRONT_CENTER) < 0 && in->nb_channels == 1) { |
96 | char buf[128]; | ||
97 | 7 | av_channel_layout_describe(in, buf, sizeof(buf)); | |
98 | 7 | av_log(s, AV_LOG_VERBOSE, "Treating %s as mono\n", buf); | |
99 | 7 | *out = (AVChannelLayout)AV_CHANNEL_LAYOUT_MONO; | |
100 | } else | ||
101 | 27 | ret = av_channel_layout_copy(out, in); | |
102 | |||
103 | 34 | return ret; | |
104 | } | ||
105 | |||
106 | 34 | static int sane_layout(AVChannelLayout *ch_layout) { | |
107 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 34 times.
|
34 | if (ch_layout->order != AV_CHANNEL_ORDER_NATIVE) |
108 | ✗ | return 0; | |
109 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 34 times.
|
34 | if(!av_channel_layout_subset(ch_layout, AV_CH_LAYOUT_SURROUND)) // at least 1 front speaker |
110 | ✗ | return 0; | |
111 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 34 times.
|
34 | if(!even(av_channel_layout_subset(ch_layout, (AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT)))) // no asymetric front |
112 | ✗ | return 0; | |
113 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 34 times.
|
34 | if(!even(av_channel_layout_subset(ch_layout, (AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT)))) // no asymetric side |
114 | ✗ | return 0; | |
115 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 34 times.
|
34 | if(!even(av_channel_layout_subset(ch_layout, (AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT)))) |
116 | ✗ | return 0; | |
117 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 34 times.
|
34 | if(!even(av_channel_layout_subset(ch_layout, (AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER)))) |
118 | ✗ | return 0; | |
119 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 34 times.
|
34 | if(!even(av_channel_layout_subset(ch_layout, (AV_CH_TOP_FRONT_LEFT | AV_CH_TOP_FRONT_RIGHT)))) |
120 | ✗ | return 0; | |
121 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 34 times.
|
34 | if(ch_layout->nb_channels >= SWR_CH_MAX) |
122 | ✗ | return 0; | |
123 | |||
124 | 34 | return 1; | |
125 | } | ||
126 | |||
127 | 17 | av_cold int swr_build_matrix2(const AVChannelLayout *in_layout, const AVChannelLayout *out_layout, | |
128 | double center_mix_level, double surround_mix_level, | ||
129 | double lfe_mix_level, double maxval, | ||
130 | double rematrix_volume, double *matrix_param, | ||
131 | ptrdiff_t stride, enum AVMatrixEncoding matrix_encoding, void *log_context) | ||
132 | { | ||
133 | int i, j, out_i, ret; | ||
134 | 17 | AVChannelLayout in_ch_layout = { 0 }, out_ch_layout = { 0 }; | |
135 | 17 | double matrix[NUM_NAMED_CHANNELS][NUM_NAMED_CHANNELS]={{0}}; | |
136 | int64_t unaccounted; | ||
137 | 17 | double maxcoef=0; | |
138 | char buf[128]; | ||
139 | |||
140 | 17 | ret = clean_layout(&in_ch_layout, in_layout, log_context); | |
141 | 17 | ret |= clean_layout(&out_ch_layout, out_layout, log_context); | |
142 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
|
17 | if (ret < 0) |
143 | ✗ | goto fail; | |
144 | |||
145 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 17 times.
|
17 | if( !av_channel_layout_compare(&out_ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO_DOWNMIX) |
146 | ✗ | && !av_channel_layout_subset(&in_ch_layout, AV_CH_LAYOUT_STEREO_DOWNMIX) | |
147 | ) { | ||
148 | ✗ | av_channel_layout_uninit(&out_ch_layout); | |
149 | ✗ | out_ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO; | |
150 | } | ||
151 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 17 times.
|
17 | if( !av_channel_layout_compare(&in_ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO_DOWNMIX) |
152 | ✗ | && !av_channel_layout_subset(&out_ch_layout, AV_CH_LAYOUT_STEREO_DOWNMIX) | |
153 | ) { | ||
154 | ✗ | av_channel_layout_uninit(&in_ch_layout); | |
155 | ✗ | in_ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO; | |
156 | } | ||
157 |
1/4✗ Branch 1 not taken.
✓ Branch 2 taken 17 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
17 | if (!av_channel_layout_compare(&in_ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_22POINT2) && |
158 | ✗ | av_channel_layout_compare(&out_ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_22POINT2)) { | |
159 | ✗ | av_channel_layout_from_mask(&in_ch_layout, (AV_CH_LAYOUT_7POINT1_WIDE_BACK|AV_CH_BACK_CENTER)); | |
160 | ✗ | av_channel_layout_describe(&in_ch_layout, buf, sizeof(buf)); | |
161 | ✗ | av_log(log_context, AV_LOG_WARNING, | |
162 | "Full-on remixing from 22.2 has not yet been implemented! " | ||
163 | "Processing the input as '%s'\n", | ||
164 | buf); | ||
165 | } | ||
166 | |||
167 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 17 times.
|
17 | if(!av_channel_layout_check(&in_ch_layout)) { |
168 | ✗ | av_log(log_context, AV_LOG_ERROR, "Input channel layout is invalid\n"); | |
169 | ✗ | ret = AVERROR(EINVAL); | |
170 | ✗ | goto fail; | |
171 | } | ||
172 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 17 times.
|
17 | if(!sane_layout(&in_ch_layout)) { |
173 | ✗ | av_channel_layout_describe(&in_ch_layout, buf, sizeof(buf)); | |
174 | ✗ | av_log(log_context, AV_LOG_ERROR, "Input channel layout '%s' is not supported\n", buf); | |
175 | ✗ | ret = AVERROR(EINVAL); | |
176 | ✗ | goto fail; | |
177 | } | ||
178 | |||
179 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 17 times.
|
17 | if(!av_channel_layout_check(&out_ch_layout)) { |
180 | ✗ | av_log(log_context, AV_LOG_ERROR, "Output channel layout is invalid\n"); | |
181 | ✗ | ret = AVERROR(EINVAL); | |
182 | ✗ | goto fail; | |
183 | } | ||
184 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 17 times.
|
17 | if(!sane_layout(&out_ch_layout)) { |
185 | ✗ | av_channel_layout_describe(&out_ch_layout, buf, sizeof(buf)); | |
186 | ✗ | av_log(log_context, AV_LOG_ERROR, "Output channel layout '%s' is not supported\n", buf); | |
187 | ✗ | ret = AVERROR(EINVAL); | |
188 | ✗ | goto fail; | |
189 | } | ||
190 | |||
191 |
2/2✓ Branch 0 taken 306 times.
✓ Branch 1 taken 17 times.
|
323 | for(i=0; i<FF_ARRAY_ELEMS(matrix); i++){ |
192 |
2/2✓ Branch 1 taken 30 times.
✓ Branch 2 taken 276 times.
|
306 | if( av_channel_layout_index_from_channel(&in_ch_layout, i) >= 0 |
193 |
2/2✓ Branch 1 taken 11 times.
✓ Branch 2 taken 19 times.
|
30 | && av_channel_layout_index_from_channel(&out_ch_layout, i) >= 0) |
194 | 11 | matrix[i][i]= 1.0; | |
195 | } | ||
196 | |||
197 | 17 | unaccounted = in_ch_layout.u.mask & ~out_ch_layout.u.mask; | |
198 | |||
199 | //FIXME implement dolby surround | ||
200 | //FIXME implement full ac3 | ||
201 | |||
202 | |||
203 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 13 times.
|
17 | if(unaccounted & AV_CH_FRONT_CENTER){ |
204 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
4 | if (av_channel_layout_subset(&out_ch_layout, AV_CH_LAYOUT_STEREO) == AV_CH_LAYOUT_STEREO) { |
205 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 3 times.
|
4 | if (av_channel_layout_subset(&in_ch_layout, AV_CH_LAYOUT_STEREO)) { |
206 | 1 | matrix[ FRONT_LEFT][FRONT_CENTER]+= center_mix_level; | |
207 | 1 | matrix[FRONT_RIGHT][FRONT_CENTER]+= center_mix_level; | |
208 | } else { | ||
209 | 3 | matrix[ FRONT_LEFT][FRONT_CENTER]+= M_SQRT1_2; | |
210 | 3 | matrix[FRONT_RIGHT][FRONT_CENTER]+= M_SQRT1_2; | |
211 | } | ||
212 | }else | ||
213 | ✗ | av_assert0(0); | |
214 | } | ||
215 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 12 times.
|
17 | if(unaccounted & AV_CH_LAYOUT_STEREO){ |
216 |
1/2✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
|
5 | if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) { |
217 | 5 | matrix[FRONT_CENTER][ FRONT_LEFT]+= M_SQRT1_2; | |
218 | 5 | matrix[FRONT_CENTER][FRONT_RIGHT]+= M_SQRT1_2; | |
219 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
|
5 | if (av_channel_layout_index_from_channel(&in_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) |
220 | ✗ | matrix[FRONT_CENTER][ FRONT_CENTER] = center_mix_level*sqrt(2); | |
221 | }else | ||
222 | ✗ | av_assert0(0); | |
223 | } | ||
224 | |||
225 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
|
17 | if(unaccounted & AV_CH_BACK_CENTER){ |
226 | ✗ | if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_BACK_LEFT) >= 0) { | |
227 | ✗ | matrix[ BACK_LEFT][BACK_CENTER]+= M_SQRT1_2; | |
228 | ✗ | matrix[BACK_RIGHT][BACK_CENTER]+= M_SQRT1_2; | |
229 | ✗ | } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_SIDE_LEFT) >= 0) { | |
230 | ✗ | matrix[ SIDE_LEFT][BACK_CENTER]+= M_SQRT1_2; | |
231 | ✗ | matrix[SIDE_RIGHT][BACK_CENTER]+= M_SQRT1_2; | |
232 | ✗ | } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) { | |
233 | ✗ | if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY || | |
234 | matrix_encoding == AV_MATRIX_ENCODING_DPLII) { | ||
235 | ✗ | if (unaccounted & (AV_CH_BACK_LEFT | AV_CH_SIDE_LEFT)) { | |
236 | ✗ | matrix[FRONT_LEFT ][BACK_CENTER] -= surround_mix_level * M_SQRT1_2; | |
237 | ✗ | matrix[FRONT_RIGHT][BACK_CENTER] += surround_mix_level * M_SQRT1_2; | |
238 | } else { | ||
239 | ✗ | matrix[FRONT_LEFT ][BACK_CENTER] -= surround_mix_level; | |
240 | ✗ | matrix[FRONT_RIGHT][BACK_CENTER] += surround_mix_level; | |
241 | } | ||
242 | } else { | ||
243 | ✗ | matrix[ FRONT_LEFT][BACK_CENTER]+= surround_mix_level * M_SQRT1_2; | |
244 | ✗ | matrix[FRONT_RIGHT][BACK_CENTER]+= surround_mix_level * M_SQRT1_2; | |
245 | } | ||
246 | ✗ | } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) { | |
247 | ✗ | matrix[ FRONT_CENTER][BACK_CENTER]+= surround_mix_level * M_SQRT1_2; | |
248 | }else | ||
249 | ✗ | av_assert0(0); | |
250 | } | ||
251 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 16 times.
|
17 | if(unaccounted & AV_CH_BACK_LEFT){ |
252 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_BACK_CENTER) >= 0) { |
253 | ✗ | matrix[BACK_CENTER][ BACK_LEFT]+= M_SQRT1_2; | |
254 | ✗ | matrix[BACK_CENTER][BACK_RIGHT]+= M_SQRT1_2; | |
255 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_SIDE_LEFT) >= 0) { |
256 | ✗ | if (av_channel_layout_index_from_channel(&in_ch_layout, AV_CHAN_SIDE_LEFT) >= 0) { | |
257 | ✗ | matrix[ SIDE_LEFT][ BACK_LEFT]+= M_SQRT1_2; | |
258 | ✗ | matrix[SIDE_RIGHT][BACK_RIGHT]+= M_SQRT1_2; | |
259 | }else{ | ||
260 | ✗ | matrix[ SIDE_LEFT][ BACK_LEFT]+= 1.0; | |
261 | ✗ | matrix[SIDE_RIGHT][BACK_RIGHT]+= 1.0; | |
262 | } | ||
263 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) { |
264 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY) { |
265 | ✗ | matrix[FRONT_LEFT ][BACK_LEFT ] -= surround_mix_level * M_SQRT1_2; | |
266 | ✗ | matrix[FRONT_LEFT ][BACK_RIGHT] -= surround_mix_level * M_SQRT1_2; | |
267 | ✗ | matrix[FRONT_RIGHT][BACK_LEFT ] += surround_mix_level * M_SQRT1_2; | |
268 | ✗ | matrix[FRONT_RIGHT][BACK_RIGHT] += surround_mix_level * M_SQRT1_2; | |
269 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | } else if (matrix_encoding == AV_MATRIX_ENCODING_DPLII) { |
270 | ✗ | matrix[FRONT_LEFT ][BACK_LEFT ] -= surround_mix_level * SQRT3_2; | |
271 | ✗ | matrix[FRONT_LEFT ][BACK_RIGHT] -= surround_mix_level * M_SQRT1_2; | |
272 | ✗ | matrix[FRONT_RIGHT][BACK_LEFT ] += surround_mix_level * M_SQRT1_2; | |
273 | ✗ | matrix[FRONT_RIGHT][BACK_RIGHT] += surround_mix_level * SQRT3_2; | |
274 | } else { | ||
275 | 1 | matrix[ FRONT_LEFT][ BACK_LEFT] += surround_mix_level; | |
276 | 1 | matrix[FRONT_RIGHT][BACK_RIGHT] += surround_mix_level; | |
277 | } | ||
278 | ✗ | } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) { | |
279 | ✗ | matrix[ FRONT_CENTER][BACK_LEFT ]+= surround_mix_level*M_SQRT1_2; | |
280 | ✗ | matrix[ FRONT_CENTER][BACK_RIGHT]+= surround_mix_level*M_SQRT1_2; | |
281 | }else | ||
282 | ✗ | av_assert0(0); | |
283 | } | ||
284 | |||
285 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 16 times.
|
17 | if(unaccounted & AV_CH_SIDE_LEFT){ |
286 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_BACK_LEFT) >= 0) { |
287 | /* if back channels do not exist in the input, just copy side | ||
288 | channels to back channels, otherwise mix side into back */ | ||
289 | ✗ | if (av_channel_layout_index_from_channel(&in_ch_layout, AV_CHAN_BACK_LEFT) >= 0) { | |
290 | ✗ | matrix[BACK_LEFT ][SIDE_LEFT ] += M_SQRT1_2; | |
291 | ✗ | matrix[BACK_RIGHT][SIDE_RIGHT] += M_SQRT1_2; | |
292 | } else { | ||
293 | ✗ | matrix[BACK_LEFT ][SIDE_LEFT ] += 1.0; | |
294 | ✗ | matrix[BACK_RIGHT][SIDE_RIGHT] += 1.0; | |
295 | } | ||
296 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_BACK_CENTER) >= 0) { |
297 | ✗ | matrix[BACK_CENTER][ SIDE_LEFT]+= M_SQRT1_2; | |
298 | ✗ | matrix[BACK_CENTER][SIDE_RIGHT]+= M_SQRT1_2; | |
299 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) { |
300 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (matrix_encoding == AV_MATRIX_ENCODING_DOLBY) { |
301 | ✗ | matrix[FRONT_LEFT ][SIDE_LEFT ] -= surround_mix_level * M_SQRT1_2; | |
302 | ✗ | matrix[FRONT_LEFT ][SIDE_RIGHT] -= surround_mix_level * M_SQRT1_2; | |
303 | ✗ | matrix[FRONT_RIGHT][SIDE_LEFT ] += surround_mix_level * M_SQRT1_2; | |
304 | ✗ | matrix[FRONT_RIGHT][SIDE_RIGHT] += surround_mix_level * M_SQRT1_2; | |
305 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | } else if (matrix_encoding == AV_MATRIX_ENCODING_DPLII) { |
306 | ✗ | matrix[FRONT_LEFT ][SIDE_LEFT ] -= surround_mix_level * SQRT3_2; | |
307 | ✗ | matrix[FRONT_LEFT ][SIDE_RIGHT] -= surround_mix_level * M_SQRT1_2; | |
308 | ✗ | matrix[FRONT_RIGHT][SIDE_LEFT ] += surround_mix_level * M_SQRT1_2; | |
309 | ✗ | matrix[FRONT_RIGHT][SIDE_RIGHT] += surround_mix_level * SQRT3_2; | |
310 | } else { | ||
311 | 1 | matrix[ FRONT_LEFT][ SIDE_LEFT] += surround_mix_level; | |
312 | 1 | matrix[FRONT_RIGHT][SIDE_RIGHT] += surround_mix_level; | |
313 | } | ||
314 | ✗ | } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) { | |
315 | ✗ | matrix[ FRONT_CENTER][SIDE_LEFT ]+= surround_mix_level * M_SQRT1_2; | |
316 | ✗ | matrix[ FRONT_CENTER][SIDE_RIGHT]+= surround_mix_level * M_SQRT1_2; | |
317 | }else | ||
318 | ✗ | av_assert0(0); | |
319 | } | ||
320 | |||
321 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
|
17 | if(unaccounted & AV_CH_FRONT_LEFT_OF_CENTER){ |
322 | ✗ | if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) { | |
323 | ✗ | matrix[ FRONT_LEFT][ FRONT_LEFT_OF_CENTER]+= 1.0; | |
324 | ✗ | matrix[FRONT_RIGHT][FRONT_RIGHT_OF_CENTER]+= 1.0; | |
325 | ✗ | } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) { | |
326 | ✗ | matrix[ FRONT_CENTER][ FRONT_LEFT_OF_CENTER]+= M_SQRT1_2; | |
327 | ✗ | matrix[ FRONT_CENTER][FRONT_RIGHT_OF_CENTER]+= M_SQRT1_2; | |
328 | }else | ||
329 | ✗ | av_assert0(0); | |
330 | } | ||
331 | |||
332 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
|
17 | if (unaccounted & AV_CH_TOP_FRONT_LEFT) { |
333 | ✗ | if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_TOP_FRONT_CENTER) >= 0) { | |
334 | ✗ | matrix[TOP_FRONT_CENTER][TOP_FRONT_LEFT ] += M_SQRT1_2; | |
335 | ✗ | matrix[TOP_FRONT_CENTER][TOP_FRONT_RIGHT] += M_SQRT1_2; | |
336 | ✗ | if (av_channel_layout_index_from_channel(&in_ch_layout, AV_CHAN_TOP_FRONT_CENTER) >= 0) | |
337 | ✗ | matrix[TOP_FRONT_CENTER][TOP_FRONT_CENTER] = center_mix_level * sqrt(2); | |
338 | ✗ | } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) { | |
339 | ✗ | if (av_channel_layout_index_from_channel(&in_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) { | |
340 | ✗ | matrix[FRONT_LEFT ][TOP_FRONT_LEFT ] += M_SQRT1_2; | |
341 | ✗ | matrix[FRONT_RIGHT][TOP_FRONT_RIGHT] += M_SQRT1_2; | |
342 | } else { | ||
343 | ✗ | matrix[FRONT_LEFT ][TOP_FRONT_LEFT ] += 1.0; | |
344 | ✗ | matrix[FRONT_RIGHT][TOP_FRONT_RIGHT] += 1.0; | |
345 | } | ||
346 | ✗ | } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) { | |
347 | ✗ | matrix[FRONT_CENTER][TOP_FRONT_LEFT ] += M_SQRT1_2; | |
348 | ✗ | matrix[FRONT_CENTER][TOP_FRONT_RIGHT] += M_SQRT1_2; | |
349 | } else | ||
350 | ✗ | av_assert0(0); | |
351 | } | ||
352 | |||
353 | /* mix LFE into front left/right or center */ | ||
354 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 16 times.
|
17 | if (unaccounted & AV_CH_LOW_FREQUENCY) { |
355 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_CENTER) >= 0) { |
356 | ✗ | matrix[FRONT_CENTER][LOW_FREQUENCY] += lfe_mix_level; | |
357 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | } else if (av_channel_layout_index_from_channel(&out_ch_layout, AV_CHAN_FRONT_LEFT) >= 0) { |
358 | 1 | matrix[FRONT_LEFT ][LOW_FREQUENCY] += lfe_mix_level * M_SQRT1_2; | |
359 | 1 | matrix[FRONT_RIGHT][LOW_FREQUENCY] += lfe_mix_level * M_SQRT1_2; | |
360 | } else | ||
361 | ✗ | av_assert0(0); | |
362 | } | ||
363 | |||
364 |
2/2✓ Branch 0 taken 1088 times.
✓ Branch 1 taken 17 times.
|
1105 | for(out_i=i=0; i<64; i++){ |
365 | 1088 | double sum=0; | |
366 | 1088 | int in_i=0; | |
367 |
2/2✓ Branch 1 taken 1062 times.
✓ Branch 2 taken 26 times.
|
1088 | if (av_channel_layout_index_from_channel(&out_ch_layout, i) < 0) |
368 | 1062 | continue; | |
369 |
2/2✓ Branch 0 taken 1664 times.
✓ Branch 1 taken 26 times.
|
1690 | for(j=0; j<64; j++){ |
370 |
2/2✓ Branch 1 taken 1613 times.
✓ Branch 2 taken 51 times.
|
1664 | if (av_channel_layout_index_from_channel(&in_ch_layout, j) < 0) |
371 | 1613 | continue; | |
372 |
2/4✓ Branch 0 taken 51 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 51 times.
✗ Branch 3 not taken.
|
51 | if (i < FF_ARRAY_ELEMS(matrix) && j < FF_ARRAY_ELEMS(matrix[0])) |
373 | 51 | matrix_param[stride*out_i + in_i] = matrix[i][j]; | |
374 | else | ||
375 | ✗ | matrix_param[stride*out_i + in_i] = i == j && | |
376 | ✗ | ( av_channel_layout_index_from_channel(&in_ch_layout, i) >= 0 | |
377 | ✗ | && av_channel_layout_index_from_channel(&out_ch_layout, i) >= 0); | |
378 | 51 | sum += fabs(matrix_param[stride*out_i + in_i]); | |
379 | 51 | in_i++; | |
380 | } | ||
381 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 22 times.
|
26 | maxcoef= FFMAX(maxcoef, sum); |
382 | 26 | out_i++; | |
383 | } | ||
384 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
|
17 | if(rematrix_volume < 0) |
385 | ✗ | maxcoef = -rematrix_volume; | |
386 | |||
387 |
3/4✓ Branch 0 taken 11 times.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
|
17 | if(maxcoef > maxval || rematrix_volume < 0){ |
388 | 6 | maxcoef /= maxval; | |
389 |
2/2✓ Branch 0 taken 384 times.
✓ Branch 1 taken 6 times.
|
390 | for(i=0; i<SWR_CH_MAX; i++) |
390 |
2/2✓ Branch 0 taken 24576 times.
✓ Branch 1 taken 384 times.
|
24960 | for(j=0; j<SWR_CH_MAX; j++){ |
391 | 24576 | matrix_param[stride*i + j] /= maxcoef; | |
392 | } | ||
393 | } | ||
394 | |||
395 |
1/2✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
|
17 | if(rematrix_volume > 0){ |
396 |
2/2✓ Branch 0 taken 1088 times.
✓ Branch 1 taken 17 times.
|
1105 | for(i=0; i<SWR_CH_MAX; i++) |
397 |
2/2✓ Branch 0 taken 69632 times.
✓ Branch 1 taken 1088 times.
|
70720 | for(j=0; j<SWR_CH_MAX; j++){ |
398 | 69632 | matrix_param[stride*i + j] *= rematrix_volume; | |
399 | } | ||
400 | } | ||
401 | |||
402 | 17 | av_log(log_context, AV_LOG_DEBUG, "Matrix coefficients:\n"); | |
403 |
2/2✓ Branch 0 taken 26 times.
✓ Branch 1 taken 17 times.
|
43 | for (i = 0; i < out_ch_layout.nb_channels; i++){ |
404 | 26 | av_channel_name(buf, sizeof(buf), av_channel_layout_channel_from_index(&out_ch_layout, i)); | |
405 | 26 | av_log(log_context, AV_LOG_DEBUG, "%s: ", buf); | |
406 |
2/2✓ Branch 0 taken 51 times.
✓ Branch 1 taken 26 times.
|
77 | for (j = 0; j < in_ch_layout.nb_channels; j++){ |
407 | 51 | av_channel_name(buf, sizeof(buf), av_channel_layout_channel_from_index(&in_ch_layout, j)); | |
408 | 51 | av_log(log_context, AV_LOG_DEBUG, "%s:%f ", buf, matrix_param[stride*i + j]); | |
409 | } | ||
410 | 26 | av_log(log_context, AV_LOG_DEBUG, "\n"); | |
411 | } | ||
412 | |||
413 | 17 | ret = 0; | |
414 | 17 | fail: | |
415 | 17 | av_channel_layout_uninit(&in_ch_layout); | |
416 | 17 | av_channel_layout_uninit(&out_ch_layout); | |
417 | |||
418 | 17 | return ret; | |
419 | } | ||
420 | |||
421 | 17 | av_cold static int auto_matrix(SwrContext *s) | |
422 | { | ||
423 | double maxval; | ||
424 | int ret; | ||
425 | |||
426 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
|
17 | if (s->rematrix_maxval > 0) { |
427 | ✗ | maxval = s->rematrix_maxval; | |
428 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 16 times.
|
17 | } else if ( av_get_packed_sample_fmt(s->out_sample_fmt) < AV_SAMPLE_FMT_FLT |
429 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
|
1 | || av_get_packed_sample_fmt(s->int_sample_fmt) < AV_SAMPLE_FMT_FLT) { |
430 | 16 | maxval = 1.0; | |
431 | } else | ||
432 | 1 | maxval = INT_MAX; | |
433 | |||
434 | 17 | memset(s->matrix, 0, sizeof(s->matrix)); | |
435 | 17 | ret = swr_build_matrix2(&s->in_ch_layout, &s->out_ch_layout, | |
436 | 17 | s->clev, s->slev, s->lfe_mix_level, | |
437 | 17 | maxval, s->rematrix_volume, (double*)s->matrix, | |
438 | 17 | s->matrix[1] - s->matrix[0], s->matrix_encoding, s); | |
439 | |||
440 |
3/4✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 10 times.
|
17 | if (ret >= 0 && s->int_sample_fmt == AV_SAMPLE_FMT_FLTP) { |
441 | int i, j; | ||
442 |
2/2✓ Branch 0 taken 448 times.
✓ Branch 1 taken 7 times.
|
455 | for (i = 0; i < FF_ARRAY_ELEMS(s->matrix[0]); i++) |
443 |
2/2✓ Branch 0 taken 28672 times.
✓ Branch 1 taken 448 times.
|
29120 | for (j = 0; j < FF_ARRAY_ELEMS(s->matrix[0]); j++) |
444 | 28672 | s->matrix_flt[i][j] = s->matrix[i][j]; | |
445 | } | ||
446 | |||
447 | 17 | return ret; | |
448 | } | ||
449 | |||
450 | 25 | av_cold int swri_rematrix_init(SwrContext *s){ | |
451 | int i, j; | ||
452 | 25 | int nb_in = s->used_ch_layout.nb_channels; | |
453 | 25 | int nb_out = s->out.ch_count; | |
454 | |||
455 | 25 | s->mix_any_f = NULL; | |
456 | |||
457 |
2/2✓ Branch 0 taken 17 times.
✓ Branch 1 taken 8 times.
|
25 | if (!s->rematrix_custom) { |
458 | 17 | int r = auto_matrix(s); | |
459 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
|
17 | if (r) |
460 | ✗ | return r; | |
461 | } | ||
462 |
2/2✓ Branch 0 taken 18 times.
✓ Branch 1 taken 7 times.
|
25 | if (s->midbuf.fmt == AV_SAMPLE_FMT_S16P){ |
463 | 18 | int maxsum = 0; | |
464 | 18 | s->native_matrix = av_calloc(nb_in * nb_out, sizeof(int)); | |
465 | 18 | s->native_one = av_mallocz(sizeof(int)); | |
466 |
2/4✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 18 times.
|
18 | if (!s->native_matrix || !s->native_one) |
467 | ✗ | return AVERROR(ENOMEM); | |
468 |
2/2✓ Branch 0 taken 40 times.
✓ Branch 1 taken 18 times.
|
58 | for (i = 0; i < nb_out; i++) { |
469 | 40 | double rem = 0; | |
470 | 40 | int sum = 0; | |
471 | |||
472 |
2/2✓ Branch 0 taken 150 times.
✓ Branch 1 taken 40 times.
|
190 | for (j = 0; j < nb_in; j++) { |
473 | 150 | double target = s->matrix[i][j] * 32768 + rem; | |
474 | 150 | ((int*)s->native_matrix)[i * nb_in + j] = lrintf(target); | |
475 | 150 | rem += target - ((int*)s->native_matrix)[i * nb_in + j]; | |
476 | 150 | sum += FFABS(((int*)s->native_matrix)[i * nb_in + j]); | |
477 | } | ||
478 | 40 | maxsum = FFMAX(maxsum, sum); | |
479 | } | ||
480 | 18 | *((int*)s->native_one) = 32768; | |
481 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 8 times.
|
18 | if (maxsum <= 32768) { |
482 | 10 | s->mix_1_1_f = (mix_1_1_func_type*)copy_s16; | |
483 | 10 | s->mix_2_1_f = (mix_2_1_func_type*)sum2_s16; | |
484 | 10 | s->mix_any_f = (mix_any_func_type*)get_mix_any_func_s16(s); | |
485 | } else { | ||
486 | 8 | s->mix_1_1_f = (mix_1_1_func_type*)copy_clip_s16; | |
487 | 8 | s->mix_2_1_f = (mix_2_1_func_type*)sum2_clip_s16; | |
488 | 8 | s->mix_any_f = (mix_any_func_type*)get_mix_any_func_clip_s16(s); | |
489 | } | ||
490 |
1/2✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
|
7 | }else if(s->midbuf.fmt == AV_SAMPLE_FMT_FLTP){ |
491 | 7 | s->native_matrix = av_calloc(nb_in * nb_out, sizeof(float)); | |
492 | 7 | s->native_one = av_mallocz(sizeof(float)); | |
493 |
2/4✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 7 times.
|
7 | if (!s->native_matrix || !s->native_one) |
494 | ✗ | return AVERROR(ENOMEM); | |
495 |
2/2✓ Branch 0 taken 13 times.
✓ Branch 1 taken 7 times.
|
20 | for (i = 0; i < nb_out; i++) |
496 |
2/2✓ Branch 0 taken 24 times.
✓ Branch 1 taken 13 times.
|
37 | for (j = 0; j < nb_in; j++) |
497 | 24 | ((float*)s->native_matrix)[i * nb_in + j] = s->matrix[i][j]; | |
498 | 7 | *((float*)s->native_one) = 1.0; | |
499 | 7 | s->mix_1_1_f = (mix_1_1_func_type*)copy_float; | |
500 | 7 | s->mix_2_1_f = (mix_2_1_func_type*)sum2_float; | |
501 | 7 | s->mix_any_f = (mix_any_func_type*)get_mix_any_func_float(s); | |
502 | ✗ | }else if(s->midbuf.fmt == AV_SAMPLE_FMT_DBLP){ | |
503 | ✗ | s->native_matrix = av_calloc(nb_in * nb_out, sizeof(double)); | |
504 | ✗ | s->native_one = av_mallocz(sizeof(double)); | |
505 | ✗ | if (!s->native_matrix || !s->native_one) | |
506 | ✗ | return AVERROR(ENOMEM); | |
507 | ✗ | for (i = 0; i < nb_out; i++) | |
508 | ✗ | for (j = 0; j < nb_in; j++) | |
509 | ✗ | ((double*)s->native_matrix)[i * nb_in + j] = s->matrix[i][j]; | |
510 | ✗ | *((double*)s->native_one) = 1.0; | |
511 | ✗ | s->mix_1_1_f = (mix_1_1_func_type*)copy_double; | |
512 | ✗ | s->mix_2_1_f = (mix_2_1_func_type*)sum2_double; | |
513 | ✗ | s->mix_any_f = (mix_any_func_type*)get_mix_any_func_double(s); | |
514 | ✗ | }else if(s->midbuf.fmt == AV_SAMPLE_FMT_S32P){ | |
515 | ✗ | s->native_one = av_mallocz(sizeof(int)); | |
516 | ✗ | if (!s->native_one) | |
517 | ✗ | return AVERROR(ENOMEM); | |
518 | ✗ | s->native_matrix = av_calloc(nb_in * nb_out, sizeof(int)); | |
519 | ✗ | if (!s->native_matrix) { | |
520 | ✗ | av_freep(&s->native_one); | |
521 | ✗ | return AVERROR(ENOMEM); | |
522 | } | ||
523 | ✗ | for (i = 0; i < nb_out; i++) { | |
524 | ✗ | double rem = 0; | |
525 | |||
526 | ✗ | for (j = 0; j < nb_in; j++) { | |
527 | ✗ | double target = s->matrix[i][j] * 32768 + rem; | |
528 | ✗ | ((int*)s->native_matrix)[i * nb_in + j] = lrintf(target); | |
529 | ✗ | rem += target - ((int*)s->native_matrix)[i * nb_in + j]; | |
530 | } | ||
531 | } | ||
532 | ✗ | *((int*)s->native_one) = 32768; | |
533 | ✗ | s->mix_1_1_f = (mix_1_1_func_type*)copy_s32; | |
534 | ✗ | s->mix_2_1_f = (mix_2_1_func_type*)sum2_s32; | |
535 | ✗ | s->mix_any_f = (mix_any_func_type*)get_mix_any_func_s32(s); | |
536 | }else | ||
537 | ✗ | av_assert0(0); | |
538 | //FIXME quantize for integeres | ||
539 |
2/2✓ Branch 0 taken 1600 times.
✓ Branch 1 taken 25 times.
|
1625 | for (i = 0; i < SWR_CH_MAX; i++) { |
540 | 1600 | int ch_in=0; | |
541 |
2/2✓ Branch 0 taken 102400 times.
✓ Branch 1 taken 1600 times.
|
104000 | for (j = 0; j < SWR_CH_MAX; j++) { |
542 | 102400 | s->matrix32[i][j]= lrintf(s->matrix[i][j] * 32768); | |
543 |
2/2✓ Branch 0 taken 79 times.
✓ Branch 1 taken 102321 times.
|
102400 | if(s->matrix[i][j]) |
544 | 79 | s->matrix_ch[i][++ch_in]= j; | |
545 | } | ||
546 | 1600 | s->matrix_ch[i][0]= ch_in; | |
547 | } | ||
548 | |||
549 | #if ARCH_X86 && HAVE_X86ASM && HAVE_MMX | ||
550 | 25 | return swri_rematrix_init_x86(s); | |
551 | #endif | ||
552 | |||
553 | return 0; | ||
554 | } | ||
555 | |||
556 | 3967 | av_cold void swri_rematrix_free(SwrContext *s){ | |
557 | 3967 | av_freep(&s->native_matrix); | |
558 | 3967 | av_freep(&s->native_one); | |
559 | 3967 | av_freep(&s->native_simd_matrix); | |
560 | 3967 | av_freep(&s->native_simd_one); | |
561 | 3967 | } | |
562 | |||
563 | 1020 | int swri_rematrix(SwrContext *s, AudioData *out, AudioData *in, int len, int mustcopy){ | |
564 | int out_i, in_i, i, j; | ||
565 | 1020 | int len1 = 0; | |
566 | 1020 | int off = 0; | |
567 | |||
568 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1016 times.
|
1020 | if(s->mix_any_f) { |
569 | 4 | s->mix_any_f(out->ch, (const uint8_t **)in->ch, s->native_matrix, len); | |
570 | 4 | return 0; | |
571 | } | ||
572 | |||
573 |
3/4✓ Branch 0 taken 969 times.
✓ Branch 1 taken 47 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 969 times.
|
1016 | if(s->mix_2_1_simd || s->mix_1_1_simd){ |
574 | 47 | len1= len&~15; | |
575 | 47 | off = len1 * out->bps; | |
576 | } | ||
577 | |||
578 |
3/4✓ Branch 0 taken 996 times.
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 996 times.
|
1016 | av_assert0(s->out_ch_layout.order == AV_CHANNEL_ORDER_UNSPEC || out->ch_count == s->out_ch_layout.nb_channels); |
579 |
3/4✓ Branch 0 taken 996 times.
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 996 times.
|
1016 | av_assert0(s-> in_ch_layout.order == AV_CHANNEL_ORDER_UNSPEC || in ->ch_count == s->in_ch_layout.nb_channels); |
580 | |||
581 |
2/2✓ Branch 0 taken 2082 times.
✓ Branch 1 taken 1016 times.
|
3098 | for(out_i=0; out_i<out->ch_count; out_i++){ |
582 |
3/4✓ Branch 0 taken 532 times.
✓ Branch 1 taken 923 times.
✓ Branch 2 taken 627 times.
✗ Branch 3 not taken.
|
2082 | switch(s->matrix_ch[out_i][0]){ |
583 | 532 | case 0: | |
584 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 532 times.
|
532 | if(mustcopy) |
585 | ✗ | memset(out->ch[out_i], 0, len * av_get_bytes_per_sample(s->int_sample_fmt)); | |
586 | 532 | break; | |
587 | 923 | case 1: | |
588 | 923 | in_i= s->matrix_ch[out_i][1]; | |
589 |
2/2✓ Branch 0 taken 142 times.
✓ Branch 1 taken 781 times.
|
923 | if(s->matrix[out_i][in_i]!=1.0){ |
590 |
3/4✓ Branch 0 taken 94 times.
✓ Branch 1 taken 48 times.
✓ Branch 2 taken 94 times.
✗ Branch 3 not taken.
|
142 | if(s->mix_1_1_simd && len1) |
591 | 94 | 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); | |
592 |
2/2✓ Branch 0 taken 48 times.
✓ Branch 1 taken 94 times.
|
142 | if(len != len1) |
593 | 48 | 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); | |
594 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 781 times.
|
781 | }else if(mustcopy){ |
595 | ✗ | memcpy(out->ch[out_i], in->ch[in_i], len*out->bps); | |
596 | }else{ | ||
597 | 781 | out->ch[out_i]= in->ch[in_i]; | |
598 | } | ||
599 | 923 | break; | |
600 | 627 | case 2: { | |
601 | 627 | int in_i1 = s->matrix_ch[out_i][1]; | |
602 | 627 | int in_i2 = s->matrix_ch[out_i][2]; | |
603 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 627 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
627 | if(s->mix_2_1_simd && len1) |
604 | ✗ | 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); | |
605 | else | ||
606 | 627 | 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); | |
607 |
2/2✓ Branch 0 taken 625 times.
✓ Branch 1 taken 2 times.
|
627 | if(len != len1) |
608 | 625 | 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); | |
609 | 627 | break;} | |
610 | ✗ | default: | |
611 | ✗ | if(s->int_sample_fmt == AV_SAMPLE_FMT_FLTP){ | |
612 | ✗ | for(i=0; i<len; i++){ | |
613 | ✗ | float v=0; | |
614 | ✗ | for(j=0; j<s->matrix_ch[out_i][0]; j++){ | |
615 | ✗ | in_i= s->matrix_ch[out_i][1+j]; | |
616 | ✗ | v+= ((float*)in->ch[in_i])[i] * s->matrix_flt[out_i][in_i]; | |
617 | } | ||
618 | ✗ | ((float*)out->ch[out_i])[i]= v; | |
619 | } | ||
620 | ✗ | }else if(s->int_sample_fmt == AV_SAMPLE_FMT_DBLP){ | |
621 | ✗ | for(i=0; i<len; i++){ | |
622 | ✗ | double v=0; | |
623 | ✗ | for(j=0; j<s->matrix_ch[out_i][0]; j++){ | |
624 | ✗ | in_i= s->matrix_ch[out_i][1+j]; | |
625 | ✗ | v+= ((double*)in->ch[in_i])[i] * s->matrix[out_i][in_i]; | |
626 | } | ||
627 | ✗ | ((double*)out->ch[out_i])[i]= v; | |
628 | } | ||
629 | }else{ | ||
630 | ✗ | for(i=0; i<len; i++){ | |
631 | ✗ | int v=0; | |
632 | ✗ | for(j=0; j<s->matrix_ch[out_i][0]; j++){ | |
633 | ✗ | in_i= s->matrix_ch[out_i][1+j]; | |
634 | ✗ | v+= ((int16_t*)in->ch[in_i])[i] * s->matrix32[out_i][in_i]; | |
635 | } | ||
636 | ✗ | ((int16_t*)out->ch[out_i])[i]= (v + 16384)>>15; | |
637 | } | ||
638 | } | ||
639 | } | ||
640 | } | ||
641 | 1016 | return 0; | |
642 | } | ||
643 |