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