1 /*
2 * common functions for reordering audio channels
3 *
4 * Copyright (C) 2007 Ulion <ulion A gmail P com>
5 *
6 * This file is part of MPlayer.
7 *
8 * MPlayer is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * MPlayer is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <inttypes.h>
26 #include <string.h>
27 #include "libvo/fastmemcpy.h"
28
29 #include "reorder_ch.h"
30
31 #ifdef TEST
32 #define mp_msg(mod,lev, fmt, args... ) printf( fmt, ## args )
33 #else
34 #include "mp_msg.h"
35 #endif
36
37
38 #define REORDER_COPY_5(DEST,SRC,SAMPLES,S0,S1,S2,S3,S4) \
39 for (i = 0; i < SAMPLES; i += 5) {\
40 DEST[i] = SRC[i+S0];\
41 DEST[i+1] = SRC[i+S1];\
42 DEST[i+2] = SRC[i+S2];\
43 DEST[i+3] = SRC[i+S3];\
44 DEST[i+4] = SRC[i+S4];\
45 }
46
reorder_copy_5ch(void * dest,const void * src,unsigned int samples,unsigned int samplesize,int s0,int s1,int s2,int s3,int s4)47 static int reorder_copy_5ch(void *dest, const void *src,
48 unsigned int samples, unsigned int samplesize,
49 int s0, int s1, int s2, int s3, int s4)
50 {
51 int i;
52 switch (samplesize) {
53 case 1:
54 {
55 int8_t *dest_8 = dest;
56 const int8_t *src_8 = src;
57 REORDER_COPY_5(dest_8,src_8,samples,s0,s1,s2,s3,s4);
58 break;
59 }
60 case 2:
61 {
62 int16_t *dest_16 = dest;
63 const int16_t *src_16 = src;
64 REORDER_COPY_5(dest_16,src_16,samples,s0,s1,s2,s3,s4);
65 break;
66 }
67 case 3:
68 {
69 int8_t *dest_8 = dest;
70 const int8_t *src_8 = src;
71 for (i = 0; i < samples * 3; i += 15) {
72 dest_8[i] = src_8[i+s0*3];
73 dest_8[i+1] = src_8[i+s0*3+1];
74 dest_8[i+2] = src_8[i+s0*3+2];
75 dest_8[i+3] = src_8[i+s1*3];
76 dest_8[i+4] = src_8[i+s1*3+1];
77 dest_8[i+5] = src_8[i+s1*3+2];
78 dest_8[i+6] = src_8[i+s2*3];
79 dest_8[i+7] = src_8[i+s2*3+1];
80 dest_8[i+8] = src_8[i+s2*3+2];
81 dest_8[i+9] = src_8[i+s3*3];
82 dest_8[i+10] = src_8[i+s3*3+1];
83 dest_8[i+11] = src_8[i+s3*3+2];
84 dest_8[i+12] = src_8[i+s4*3];
85 dest_8[i+13] = src_8[i+s4*3+1];
86 dest_8[i+14] = src_8[i+s4*3+2];
87 }
88 break;
89 }
90 case 4:
91 {
92 int32_t *dest_32 = dest;
93 const int32_t *src_32 = src;
94 REORDER_COPY_5(dest_32,src_32,samples,s0,s1,s2,s3,s4);
95 break;
96 }
97 case 8:
98 {
99 int64_t *dest_64 = dest;
100 const int64_t *src_64 = src;
101 REORDER_COPY_5(dest_64,src_64,samples,s0,s1,s2,s3,s4);
102 break;
103 }
104 default:
105 mp_msg(MSGT_GLOBAL, MSGL_WARN,
106 "[reorder_ch] Unsupported sample size: %d, please "
107 "report this error on the MPlayer mailing list.\n",samplesize);
108 return 0;
109 }
110 return 1;
111 }
112
113 #define REORDER_COPY_6(DEST,SRC,SAMPLES,S0,S1,S2,S3,S4,S5) \
114 for (i = 0; i < SAMPLES; i += 6) {\
115 DEST[i] = SRC[i+S0];\
116 DEST[i+1] = SRC[i+S1];\
117 DEST[i+2] = SRC[i+S2];\
118 DEST[i+3] = SRC[i+S3];\
119 DEST[i+4] = SRC[i+S4];\
120 DEST[i+5] = SRC[i+S5];\
121 }
122
reorder_copy_6ch(void * dest,const void * src,unsigned int samples,uint8_t samplesize,int s0,int s1,int s2,int s3,int s4,int s5)123 static int reorder_copy_6ch(void *dest, const void *src,
124 unsigned int samples, uint8_t samplesize,
125 int s0, int s1, int s2, int s3, int s4, int s5)
126 {
127 int i;
128 switch (samplesize) {
129 case 1:
130 {
131 int8_t *dest_8 = dest;
132 const int8_t *src_8 = src;
133 REORDER_COPY_6(dest_8,src_8,samples,s0,s1,s2,s3,s4,s5);
134 break;
135 }
136 case 2:
137 {
138 int16_t *dest_16 = dest;
139 const int16_t *src_16 = src;
140 REORDER_COPY_6(dest_16,src_16,samples,s0,s1,s2,s3,s4,s5);
141 break;
142 }
143 case 3:
144 {
145 int8_t *dest_8 = dest;
146 const int8_t *src_8 = src;
147 for (i = 0; i < samples * 3; i += 18) {
148 dest_8[i] = src_8[i+s0*3];
149 dest_8[i+1] = src_8[i+s0*3+1];
150 dest_8[i+2] = src_8[i+s0*3+2];
151 dest_8[i+3] = src_8[i+s1*3];
152 dest_8[i+4] = src_8[i+s1*3+1];
153 dest_8[i+5] = src_8[i+s1*3+2];
154 dest_8[i+6] = src_8[i+s2*3];
155 dest_8[i+7] = src_8[i+s2*3+1];
156 dest_8[i+8] = src_8[i+s2*3+2];
157 dest_8[i+9] = src_8[i+s3*3];
158 dest_8[i+10] = src_8[i+s3*3+1];
159 dest_8[i+11] = src_8[i+s3*3+2];
160 dest_8[i+12] = src_8[i+s4*3];
161 dest_8[i+13] = src_8[i+s4*3+1];
162 dest_8[i+14] = src_8[i+s4*3+2];
163 dest_8[i+15] = src_8[i+s5*3];
164 dest_8[i+16] = src_8[i+s5*3+1];
165 dest_8[i+17] = src_8[i+s5*3+2];
166 }
167 break;
168 }
169 case 4:
170 {
171 int32_t *dest_32 = dest;
172 const int32_t *src_32 = src;
173 REORDER_COPY_6(dest_32,src_32,samples,s0,s1,s2,s3,s4,s5);
174 break;
175 }
176 case 8:
177 {
178 int64_t *dest_64 = dest;
179 const int64_t *src_64 = src;
180 REORDER_COPY_6(dest_64,src_64,samples,s0,s1,s2,s3,s4,s5);
181 break;
182 }
183 default:
184 mp_msg(MSGT_GLOBAL, MSGL_WARN,
185 "[reorder_ch] Unsupported sample size: %d, please "
186 "report this error on the MPlayer mailing list.\n",samplesize);
187 return 0;
188 }
189 return 1;
190 }
191
192 #define REORDER_COPY_8(DEST,SRC,SAMPLES,S0,S1,S2,S3,S4,S5,S6,S7) \
193 for (i = 0; i < SAMPLES; i += 8) {\
194 DEST[i] = SRC[i+S0];\
195 DEST[i+1] = SRC[i+S1];\
196 DEST[i+2] = SRC[i+S2];\
197 DEST[i+3] = SRC[i+S3];\
198 DEST[i+4] = SRC[i+S4];\
199 DEST[i+5] = SRC[i+S5];\
200 DEST[i+6] = SRC[i+S6];\
201 DEST[i+7] = SRC[i+S7];\
202 }
203
reorder_copy_8ch(void * dest,const void * src,unsigned int samples,uint8_t samplesize,int s0,int s1,int s2,int s3,int s4,int s5,int s6,int s7)204 static int reorder_copy_8ch(void *dest, const void *src,
205 unsigned int samples, uint8_t samplesize,
206 int s0, int s1, int s2, int s3,
207 int s4, int s5, int s6, int s7)
208 {
209 int i;
210 switch (samplesize) {
211 case 1:
212 {
213 int8_t *dest_8 = dest;
214 const int8_t *src_8 = src;
215 REORDER_COPY_8(dest_8,src_8,samples,s0,s1,s2,s3,s4,s5,s6,s7);
216 break;
217 }
218 case 2:
219 {
220 int16_t *dest_16 = dest;
221 const int16_t *src_16 = src;
222 REORDER_COPY_8(dest_16,src_16,samples,s0,s1,s2,s3,s4,s5,s6,s7);
223 break;
224 }
225 case 3:
226 {
227 int8_t *dest_8 = dest;
228 const int8_t *src_8 = src;
229 for (i = 0; i < samples * 3; i += 24) {
230 dest_8[i] = src_8[i+s0*3];
231 dest_8[i+1] = src_8[i+s0*3+1];
232 dest_8[i+2] = src_8[i+s0*3+2];
233 dest_8[i+3] = src_8[i+s1*3];
234 dest_8[i+4] = src_8[i+s1*3+1];
235 dest_8[i+5] = src_8[i+s1*3+2];
236 dest_8[i+6] = src_8[i+s2*3];
237 dest_8[i+7] = src_8[i+s2*3+1];
238 dest_8[i+8] = src_8[i+s2*3+2];
239 dest_8[i+9] = src_8[i+s3*3];
240 dest_8[i+10] = src_8[i+s3*3+1];
241 dest_8[i+11] = src_8[i+s3*3+2];
242 dest_8[i+12] = src_8[i+s4*3];
243 dest_8[i+13] = src_8[i+s4*3+1];
244 dest_8[i+14] = src_8[i+s4*3+2];
245 dest_8[i+15] = src_8[i+s5*3];
246 dest_8[i+16] = src_8[i+s5*3+1];
247 dest_8[i+17] = src_8[i+s5*3+2];
248 dest_8[i+18] = src_8[i+s6*3];
249 dest_8[i+19] = src_8[i+s6*3+1];
250 dest_8[i+20] = src_8[i+s6*3+2];
251 dest_8[i+21] = src_8[i+s7*3];
252 dest_8[i+22] = src_8[i+s7*3+1];
253 dest_8[i+23] = src_8[i+s7*3+2];
254 }
255 break;
256 }
257 case 4:
258 {
259 int32_t *dest_32 = dest;
260 const int32_t *src_32 = src;
261 REORDER_COPY_8(dest_32,src_32,samples,s0,s1,s2,s3,s4,s5,s6,s7);
262 break;
263 }
264 case 8:
265 {
266 int64_t *dest_64 = dest;
267 const int64_t *src_64 = src;
268 REORDER_COPY_8(dest_64,src_64,samples,s0,s1,s2,s3,s4,s5,s6,s7);
269 break;
270 }
271 default:
272 mp_msg(MSGT_GLOBAL, MSGL_WARN,
273 "[reorder_ch] Unsupported sample size: %d, please "
274 "report this error on the MPlayer mailing list.\n",samplesize);
275 return 0;
276 }
277 return 1;
278 }
279
reorder_channel_copy(void * src,int src_layout,void * dest,int dest_layout,int samples,int samplesize)280 void reorder_channel_copy(void *src,
281 int src_layout,
282 void *dest,
283 int dest_layout,
284 int samples,
285 int samplesize)
286 {
287 if (dest_layout==src_layout) {
288 fast_memcpy(dest, src, samples*samplesize);
289 return;
290 }
291 if (!AF_IS_SAME_CH_NUM(dest_layout,src_layout)) {
292 mp_msg(MSGT_GLOBAL, MSGL_WARN, "[reorder_ch] different channel count "
293 "between src and dest: %x, %x\n",
294 AF_GET_CH_NUM_WITH_LFE(src_layout),
295 AF_GET_CH_NUM_WITH_LFE(dest_layout));
296 return;
297 }
298 switch ((src_layout<<16)|dest_layout) {
299 // AF_CHANNEL_LAYOUT_5_0_A L R C Ls Rs
300 // AF_CHANNEL_LAYOUT_5_0_B L R Ls Rs C
301 // AF_CHANNEL_LAYOUT_5_0_C L C R Ls Rs
302 // AF_CHANNEL_LAYOUT_5_0_D C L R Ls Rs
303 case AF_CHANNEL_LAYOUT_5_0_A << 16 | AF_CHANNEL_LAYOUT_5_0_B:
304 reorder_copy_5ch(dest, src, samples, samplesize, 0, 1, 3, 4, 2);
305 break;
306 case AF_CHANNEL_LAYOUT_5_0_A << 16 | AF_CHANNEL_LAYOUT_5_0_C:
307 reorder_copy_5ch(dest, src, samples, samplesize, 0, 2, 1, 3, 4);
308 break;
309 case AF_CHANNEL_LAYOUT_5_0_A << 16 | AF_CHANNEL_LAYOUT_5_0_D:
310 reorder_copy_5ch(dest, src, samples, samplesize, 2, 0, 1, 3, 4);
311 break;
312 case AF_CHANNEL_LAYOUT_5_0_B << 16 | AF_CHANNEL_LAYOUT_5_0_A:
313 reorder_copy_5ch(dest, src, samples, samplesize, 0, 1, 4, 2, 3);
314 break;
315 case AF_CHANNEL_LAYOUT_5_0_B << 16 | AF_CHANNEL_LAYOUT_5_0_C:
316 reorder_copy_5ch(dest, src, samples, samplesize, 0, 4, 1, 2, 3);
317 break;
318 case AF_CHANNEL_LAYOUT_5_0_B << 16 | AF_CHANNEL_LAYOUT_5_0_D:
319 reorder_copy_5ch(dest, src, samples, samplesize, 4, 0, 1, 2, 3);
320 break;
321 case AF_CHANNEL_LAYOUT_5_0_C << 16 | AF_CHANNEL_LAYOUT_5_0_A:
322 reorder_copy_5ch(dest, src, samples, samplesize, 0, 2, 1, 3, 4);
323 break;
324 case AF_CHANNEL_LAYOUT_5_0_C << 16 | AF_CHANNEL_LAYOUT_5_0_B:
325 reorder_copy_5ch(dest, src, samples, samplesize, 0, 2, 3, 4, 1);
326 break;
327 case AF_CHANNEL_LAYOUT_5_0_C << 16 | AF_CHANNEL_LAYOUT_5_0_D:
328 reorder_copy_5ch(dest, src, samples, samplesize, 1, 0, 2, 3, 4);
329 break;
330 case AF_CHANNEL_LAYOUT_5_0_D << 16 | AF_CHANNEL_LAYOUT_5_0_A:
331 reorder_copy_5ch(dest, src, samples, samplesize, 1, 2, 0, 3, 4);
332 break;
333 case AF_CHANNEL_LAYOUT_5_0_D << 16 | AF_CHANNEL_LAYOUT_5_0_B:
334 reorder_copy_5ch(dest, src, samples, samplesize, 1, 2, 3, 4, 0);
335 break;
336 case AF_CHANNEL_LAYOUT_5_0_D << 16 | AF_CHANNEL_LAYOUT_5_0_C:
337 reorder_copy_5ch(dest, src, samples, samplesize, 1, 0, 2, 3, 4);
338 break;
339 // AF_CHANNEL_LAYOUT_5_1_A L R C LFE Ls Rs
340 // AF_CHANNEL_LAYOUT_5_1_B L R Ls Rs C LFE
341 // AF_CHANNEL_LAYOUT_5_1_C L C R Ls Rs LFE
342 // AF_CHANNEL_LAYOUT_5_1_D C L R Ls Rs LFE
343 // AF_CHANNEL_LAYOUT_5_1_E LFE L C R Ls Rs
344 case AF_CHANNEL_LAYOUT_5_1_A << 16 | AF_CHANNEL_LAYOUT_5_1_B:
345 reorder_copy_6ch(dest, src, samples, samplesize, 0, 1, 4, 5, 2, 3);
346 break;
347 case AF_CHANNEL_LAYOUT_5_1_A << 16 | AF_CHANNEL_LAYOUT_5_1_C:
348 reorder_copy_6ch(dest, src, samples, samplesize, 0, 2, 1, 4, 5, 3);
349 break;
350 case AF_CHANNEL_LAYOUT_5_1_A << 16 | AF_CHANNEL_LAYOUT_5_1_D:
351 reorder_copy_6ch(dest, src, samples, samplesize, 2, 0, 1, 4, 5, 3);
352 break;
353 case AF_CHANNEL_LAYOUT_5_1_B << 16 | AF_CHANNEL_LAYOUT_5_1_A:
354 reorder_copy_6ch(dest, src, samples, samplesize, 0, 1, 4, 5, 2, 3);
355 break;
356 case AF_CHANNEL_LAYOUT_5_1_B << 16 | AF_CHANNEL_LAYOUT_5_1_C:
357 reorder_copy_6ch(dest, src, samples, samplesize, 0, 4, 1, 2, 3, 5);
358 break;
359 case AF_CHANNEL_LAYOUT_5_1_B << 16 | AF_CHANNEL_LAYOUT_5_1_D:
360 reorder_copy_6ch(dest, src, samples, samplesize, 4, 0, 1, 2, 3, 5);
361 break;
362 case AF_CHANNEL_LAYOUT_5_1_B << 16 | AF_CHANNEL_LAYOUT_5_1_E:
363 reorder_copy_6ch(dest, src, samples, samplesize, 5, 0, 4, 1, 2, 3);
364 break;
365 case AF_CHANNEL_LAYOUT_5_1_C << 16 | AF_CHANNEL_LAYOUT_5_1_A:
366 reorder_copy_6ch(dest, src, samples, samplesize, 0, 2, 1, 5, 3, 4);
367 break;
368 case AF_CHANNEL_LAYOUT_5_1_C << 16 | AF_CHANNEL_LAYOUT_5_1_B:
369 reorder_copy_6ch(dest, src, samples, samplesize, 0, 2, 3, 4, 1, 5);
370 break;
371 case AF_CHANNEL_LAYOUT_5_1_C << 16 | AF_CHANNEL_LAYOUT_5_1_D:
372 reorder_copy_6ch(dest, src, samples, samplesize, 1, 0, 2, 3, 4, 5);
373 break;
374 case AF_CHANNEL_LAYOUT_5_1_D << 16 | AF_CHANNEL_LAYOUT_5_1_A:
375 reorder_copy_6ch(dest, src, samples, samplesize, 1, 2, 0, 5, 3, 4);
376 break;
377 case AF_CHANNEL_LAYOUT_5_1_D << 16 | AF_CHANNEL_LAYOUT_5_1_B:
378 reorder_copy_6ch(dest, src, samples, samplesize, 1, 2, 3, 4, 0, 5);
379 break;
380 case AF_CHANNEL_LAYOUT_5_1_D << 16 | AF_CHANNEL_LAYOUT_5_1_C:
381 reorder_copy_6ch(dest, src, samples, samplesize, 1, 0, 2, 3, 4, 5);
382 break;
383 case AF_CHANNEL_LAYOUT_5_1_E << 16 | AF_CHANNEL_LAYOUT_5_1_B:
384 reorder_copy_6ch(dest, src, samples, samplesize, 1, 3, 4, 5, 2, 0);
385 break;
386 case AF_CHANNEL_LAYOUT_5_1_F << 16 | AF_CHANNEL_LAYOUT_5_1_B:
387 reorder_copy_6ch(dest, src, samples, samplesize, 1, 2, 4, 5, 0, 3);
388 break;
389 // AF_CHANNEL_LAYOUT_7_1_A L R C LFE Ls Rs Rls Rrs
390 // AF_CHANNEL_LAYOUT_7_1_B L R Ls Rs C LFE Rls Rrs
391 // AF_CHANNEL_LAYOUT_7_1_D C L R Ls Rs Rls Rrs LFE
392 case AF_CHANNEL_LAYOUT_7_1_A << 16 | AF_CHANNEL_LAYOUT_7_1_B:
393 case AF_CHANNEL_LAYOUT_7_1_B << 16 | AF_CHANNEL_LAYOUT_7_1_A:
394 reorder_copy_8ch(dest, src, samples, samplesize, 0, 1, 4, 5, 2, 3, 6, 7);
395 break;
396 case AF_CHANNEL_LAYOUT_7_1_D << 16 | AF_CHANNEL_LAYOUT_7_1_B:
397 reorder_copy_8ch(dest, src, samples, samplesize, 1, 2, 3, 4, 0, 7, 5, 6);
398 break;
399 default:
400 mp_msg(MSGT_GLOBAL, MSGL_WARN, "[reorder_channel_copy] unsupport "
401 "from %x to %x, %d * %d\n", src_layout, dest_layout,
402 samples, samplesize);
403 fast_memcpy(dest, src, samples*samplesize);
404 }
405 }
406
407
408 #define REORDER_SELF_SWAP_2(SRC,TMP,SAMPLES,CHNUM,S0,S1) \
409 for (i = 0; i < SAMPLES; i += CHNUM) {\
410 TMP = SRC[i+S0];\
411 SRC[i+S0] = SRC[i+S1];\
412 SRC[i+S1] = TMP;\
413 }
414
reorder_self_2(void * src,unsigned int samples,unsigned int samplesize,unsigned int chnum,int s0,int s1)415 static int reorder_self_2(void *src, unsigned int samples,
416 unsigned int samplesize, unsigned int chnum,
417 int s0, int s1)
418 {
419 int i;
420 switch (samplesize) {
421 case 1:
422 {
423 int8_t *src_8 = src;
424 int8_t tmp;
425 if (chnum==6) {
426 REORDER_SELF_SWAP_2(src_8,tmp,samples,6,s0,s1);
427 }
428 else if (chnum==8) {
429 REORDER_SELF_SWAP_2(src_8,tmp,samples,8,s0,s1);
430 }
431 else {
432 REORDER_SELF_SWAP_2(src_8,tmp,samples,5,s0,s1);
433 }
434 break;
435 }
436 case 2:
437 {
438 int16_t *src_16 = src;
439 int16_t tmp;
440 if (chnum==6) {
441 REORDER_SELF_SWAP_2(src_16,tmp,samples,6,s0,s1);
442 }
443 else if (chnum==3) {
444 REORDER_SELF_SWAP_2(src_16,tmp,samples,3,s0,s1);
445 }
446 else if (chnum==4) {
447 REORDER_SELF_SWAP_2(src_16,tmp,samples,3,s0,s1);
448 }
449 else {
450 REORDER_SELF_SWAP_2(src_16,tmp,samples,5,s0,s1);
451 }
452 break;
453 }
454 case 3:
455 {
456 int8_t *src_8 = src;
457 int8_t tmp0, tmp1, tmp2;
458 for (i = 0; i < samples * 3; i += chnum * 3) {
459 tmp0 = src_8[i+s0*3];
460 tmp1 = src_8[i+s0*3+1];
461 tmp2 = src_8[i+s0*3+2];
462 src_8[i+s0*3] = src_8[i+s1*3];
463 src_8[i+s0*3+1] = src_8[i+s1*3+1];
464 src_8[i+s0*3+2] = src_8[i+s1*3+2];
465 src_8[i+s1*3] = tmp0;
466 src_8[i+s1*3+1] = tmp1;
467 src_8[i+s1*3+2] = tmp2;
468 }
469 break;
470 }
471 case 4:
472 {
473 int32_t *src_32 = src;
474 int32_t tmp;
475 if (chnum==6) {
476 REORDER_SELF_SWAP_2(src_32,tmp,samples,6,s0,s1);
477 }
478 else if (chnum==3) {
479 REORDER_SELF_SWAP_2(src_32,tmp,samples,3,s0,s1);
480 }
481 else if (chnum==4) {
482 REORDER_SELF_SWAP_2(src_32,tmp,samples,4,s0,s1);
483 }
484 else {
485 REORDER_SELF_SWAP_2(src_32,tmp,samples,5,s0,s1);
486 }
487 break;
488 }
489 case 8:
490 {
491 int64_t *src_64 = src;
492 int64_t tmp;
493 if (chnum==6) {
494 REORDER_SELF_SWAP_2(src_64,tmp,samples,6,s0,s1);
495 }
496 else if (chnum==3) {
497 REORDER_SELF_SWAP_2(src_64,tmp,samples,3,s0,s1);
498 }
499 else if (chnum==4) {
500 REORDER_SELF_SWAP_2(src_64,tmp,samples,4,s0,s1);
501 }
502 else {
503 REORDER_SELF_SWAP_2(src_64,tmp,samples,5,s0,s1);
504 }
505 break;
506 }
507 default:
508 mp_msg(MSGT_GLOBAL, MSGL_WARN,
509 "[reorder_ch] Unsupported sample size: %d, please "
510 "report this error on the MPlayer mailing list.\n",samplesize);
511 return 0;
512 }
513 return 1;
514 }
515
516 #define REORDER_SELF_SWAP_3(SRC,TMP,SAMPLES,CHNUM,S0,S1,S2) \
517 for (i = 0; i < SAMPLES; i += CHNUM) {\
518 TMP = SRC[i+S0];\
519 SRC[i+S0] = SRC[i+S1];\
520 SRC[i+S1] = SRC[i+S2];\
521 SRC[i+S2] = TMP;\
522 }
523
reorder_self_3(void * src,unsigned int samples,unsigned int samplesize,unsigned int chnum,int s0,int s1,int s2)524 static int reorder_self_3(void *src, unsigned int samples,
525 unsigned int samplesize, unsigned int chnum,
526 int s0, int s1, int s2)
527 {
528 int i;
529 switch (samplesize) {
530 case 1:
531 {
532 int8_t *src_8 = src;
533 int8_t tmp;
534 if (chnum==6) {
535 REORDER_SELF_SWAP_3(src_8,tmp,samples,6,s0,s1,s2);
536 }
537 else {
538 REORDER_SELF_SWAP_3(src_8,tmp,samples,5,s0,s1,s2);
539 }
540 break;
541 }
542 case 2:
543 {
544 int16_t *src_16 = src;
545 int16_t tmp;
546 if (chnum==6) {
547 REORDER_SELF_SWAP_3(src_16,tmp,samples,6,s0,s1,s2);
548 }
549 else {
550 REORDER_SELF_SWAP_3(src_16,tmp,samples,5,s0,s1,s2);
551 }
552 break;
553 }
554 case 3:
555 {
556 int8_t *src_8 = src;
557 int8_t tmp0, tmp1, tmp2;
558 for (i = 0; i < samples * 3; i += chnum * 3) {
559 tmp0 = src_8[i+s0*3];
560 tmp1 = src_8[i+s0*3+1];
561 tmp2 = src_8[i+s0*3+2];
562 src_8[i+s0*3] = src_8[i+s1*3];
563 src_8[i+s0*3+1] = src_8[i+s1*3+1];
564 src_8[i+s0*3+2] = src_8[i+s1*3+2];
565 src_8[i+s1*3] = src_8[i+s2*3];
566 src_8[i+s1*3+1] = src_8[i+s2*3+1];
567 src_8[i+s1*3+2] = src_8[i+s2*3+2];
568 src_8[i+s2*3] = tmp0;
569 src_8[i+s2*3+1] = tmp1;
570 src_8[i+s2*3+2] = tmp2;
571 }
572 break;
573 }
574 case 4:
575 {
576 int32_t *src_32 = src;
577 int32_t tmp;
578 if (chnum==6) {
579 REORDER_SELF_SWAP_3(src_32,tmp,samples,6,s0,s1,s2);
580 }
581 else {
582 REORDER_SELF_SWAP_3(src_32,tmp,samples,5,s0,s1,s2);
583 }
584 break;
585 }
586 case 8:
587 {
588 int64_t *src_64 = src;
589 int64_t tmp;
590 if (chnum==6) {
591 REORDER_SELF_SWAP_3(src_64,tmp,samples,6,s0,s1,s2);
592 }
593 else {
594 REORDER_SELF_SWAP_3(src_64,tmp,samples,5,s0,s1,s2);
595 }
596 break;
597 }
598 default:
599 mp_msg(MSGT_GLOBAL, MSGL_WARN,
600 "[reorder_ch] Unsupported sample size: %d, please "
601 "report this error on the MPlayer mailing list.\n",samplesize);
602 return 0;
603 }
604 return 1;
605 }
606
607 #define REORDER_SELF_SWAP_4_STEP_1(SRC,TMP,SAMPLES,CHNUM,S0,S1,S2,S3) \
608 for (i = 0; i < SAMPLES; i += CHNUM) {\
609 TMP = SRC[i+S0];\
610 SRC[i+S0] = SRC[i+S1];\
611 SRC[i+S1] = SRC[i+S2];\
612 SRC[i+S2] = SRC[i+S3];\
613 SRC[i+S3] = TMP;\
614 }
615
reorder_self_4_step_1(void * src,unsigned int samples,unsigned int samplesize,unsigned int chnum,int s0,int s1,int s2,int s3)616 static int reorder_self_4_step_1(void *src, unsigned int samples,
617 unsigned int samplesize, unsigned int chnum,
618 int s0, int s1, int s2, int s3)
619 {
620 int i;
621 switch (samplesize) {
622 case 1:
623 {
624 int8_t *src_8 = src;
625 int8_t tmp;
626 if (chnum==6) {
627 REORDER_SELF_SWAP_4_STEP_1(src_8,tmp,samples,6,s0,s1,s2,s3);
628 }
629 else if (chnum==8) {
630 REORDER_SELF_SWAP_4_STEP_1(src_8,tmp,samples,8,s0,s1,s2,s3);
631 }
632 else {
633 REORDER_SELF_SWAP_4_STEP_1(src_8,tmp,samples,5,s0,s1,s2,s3);
634 }
635 break;
636 }
637 case 2:
638 {
639 int16_t *src_16 = src;
640 int16_t tmp;
641 if (chnum==6) {
642 REORDER_SELF_SWAP_4_STEP_1(src_16,tmp,samples,6,s0,s1,s2,s3);
643 }
644 else if (chnum==8) {
645 REORDER_SELF_SWAP_4_STEP_1(src_16,tmp,samples,8,s0,s1,s2,s3);
646 }
647 else {
648 REORDER_SELF_SWAP_4_STEP_1(src_16,tmp,samples,5,s0,s1,s2,s3);
649 }
650 break;
651 }
652 case 3:
653 {
654 int8_t *src_8 = src;
655 int8_t tmp0, tmp1, tmp2;
656 for (i = 0; i < samples * 3; i += chnum * 3) {
657 tmp0 = src_8[i+s0*3];
658 tmp1 = src_8[i+s0*3+1];
659 tmp2 = src_8[i+s0*3+2];
660 src_8[i+s0*3] = src_8[i+s1*3];
661 src_8[i+s0*3+1] = src_8[i+s1*3+1];
662 src_8[i+s0*3+2] = src_8[i+s1*3+2];
663 src_8[i+s1*3] = src_8[i+s2*3];
664 src_8[i+s1*3+1] = src_8[i+s2*3+1];
665 src_8[i+s1*3+2] = src_8[i+s2*3+2];
666 src_8[i+s2*3] = src_8[i+s3*3];
667 src_8[i+s2*3+1] = src_8[i+s3*3+1];
668 src_8[i+s2*3+2] = src_8[i+s3*3+2];
669 src_8[i+s3*3] = tmp0;
670 src_8[i+s3*3+1] = tmp1;
671 src_8[i+s3*3+2] = tmp2;
672 }
673 break;
674 }
675 case 4:
676 {
677 int32_t *src_32 = src;
678 int32_t tmp;
679 if (chnum==6) {
680 REORDER_SELF_SWAP_4_STEP_1(src_32,tmp,samples,6,s0,s1,s2,s3);
681 }
682 else if (chnum==8) {
683 REORDER_SELF_SWAP_4_STEP_1(src_32,tmp,samples,8,s0,s1,s2,s3);
684 }
685 else {
686 REORDER_SELF_SWAP_4_STEP_1(src_32,tmp,samples,5,s0,s1,s2,s3);
687 }
688 break;
689 }
690 case 8:
691 {
692 int64_t *src_64 = src;
693 int64_t tmp;
694 if (chnum==6) {
695 REORDER_SELF_SWAP_4_STEP_1(src_64,tmp,samples,6,s0,s1,s2,s3);
696 }
697 else if (chnum==8) {
698 REORDER_SELF_SWAP_4_STEP_1(src_64,tmp,samples,8,s0,s1,s2,s3);
699 }
700 else {
701 REORDER_SELF_SWAP_4_STEP_1(src_64,tmp,samples,5,s0,s1,s2,s3);
702 }
703 break;
704 }
705 default:
706 mp_msg(MSGT_GLOBAL, MSGL_WARN,
707 "[reorder_ch] Unsupported sample size: %d, please "
708 "report this error on the MPlayer mailing list.\n",samplesize);
709 return 0;
710 }
711 return 1;
712 }
713
714 #define REORDER_SELF_SWAP_4_STEP_2(SRC,TMP,SAMPLES,CHNUM,S0,S1,S2,S3) \
715 for (i = 0; i < SAMPLES; i += CHNUM) {\
716 TMP = SRC[i+S0];\
717 SRC[i+S0] = SRC[i+S2];\
718 SRC[i+S2] = TMP;\
719 TMP = SRC[i+S1];\
720 SRC[i+S1] = SRC[i+S3];\
721 SRC[i+S3] = TMP;\
722 }
723
reorder_self_4_step_2(void * src,unsigned int samples,unsigned int samplesize,unsigned int chnum,int s0,int s1,int s2,int s3)724 static int reorder_self_4_step_2(void *src, unsigned int samples,
725 unsigned int samplesize, unsigned int chnum,
726 int s0, int s1, int s2, int s3)
727 {
728 int i;
729 switch (samplesize) {
730 case 3:
731 {
732 int8_t *src_8 = src;
733 int8_t tmp0, tmp1, tmp2;
734 for (i = 0; i < samples * 3; i += chnum * 3) {
735 tmp0 = src_8[i+s0*3];
736 tmp1 = src_8[i+s0*3+1];
737 tmp2 = src_8[i+s0*3+2];
738 src_8[i+s0*3] = src_8[i+s2*3];
739 src_8[i+s0*3+1] = src_8[i+s2*3+1];
740 src_8[i+s0*3+2] = src_8[i+s2*3+2];
741 src_8[i+s2*3] = tmp0;
742 src_8[i+s2*3+1] = tmp1;
743 src_8[i+s2*3+2] = tmp2;
744 tmp0 = src_8[i+s1*3];
745 tmp1 = src_8[i+s1*3+1];
746 tmp2 = src_8[i+s1*3+2];
747 src_8[i+s1*3] = src_8[i+s3*3];
748 src_8[i+s1*3+1] = src_8[i+s3*3+1];
749 src_8[i+s1*3+2] = src_8[i+s3*3+2];
750 src_8[i+s3*3] = tmp0;
751 src_8[i+s3*3+1] = tmp1;
752 src_8[i+s3*3+2] = tmp2;
753 }
754 break;
755 }
756 default:
757 mp_msg(MSGT_GLOBAL, MSGL_WARN,
758 "[reorder_ch] Unsupported sample size: %d, please "
759 "report this error on the MPlayer mailing list.\n",samplesize);
760 return 0;
761 }
762 return 1;
763 }
764
765 #define REORDER_SELF_SWAP_5_STEP_1(SRC,TMP,SAMPLES,CHNUM,S0,S1,S2,S3,S4) \
766 for (i = 0; i < SAMPLES; i += CHNUM) {\
767 TMP = SRC[i+S0];\
768 SRC[i+S0] = SRC[i+S1];\
769 SRC[i+S1] = SRC[i+S2];\
770 SRC[i+S2] = SRC[i+S3];\
771 SRC[i+S3] = SRC[i+S4];\
772 SRC[i+S4] = TMP;\
773 }
774
reorder_self_5_step_1(void * src,unsigned int samples,unsigned int samplesize,unsigned int chnum,int s0,int s1,int s2,int s3,int s4)775 static int reorder_self_5_step_1(void *src, unsigned int samples,
776 unsigned int samplesize, unsigned int chnum,
777 int s0, int s1, int s2, int s3, int s4)
778 {
779 int i;
780 switch (samplesize) {
781 case 1:
782 {
783 int8_t *src_8 = src;
784 int8_t tmp;
785 if (chnum==6) {
786 REORDER_SELF_SWAP_5_STEP_1(src_8,tmp,samples,6,s0,s1,s2,s3,s4);
787 }
788 else if (chnum==8) {
789 REORDER_SELF_SWAP_5_STEP_1(src_8,tmp,samples,8,s0,s1,s2,s3,s4);
790 }
791 else {
792 REORDER_SELF_SWAP_5_STEP_1(src_8,tmp,samples,5,s0,s1,s2,s3,s4);
793 }
794 break;
795 }
796 case 2:
797 {
798 int16_t *src_16 = src;
799 int16_t tmp;
800 if (chnum==6) {
801 REORDER_SELF_SWAP_5_STEP_1(src_16,tmp,samples,6,s0,s1,s2,s3,s4);
802 }
803 else if (chnum==8) {
804 REORDER_SELF_SWAP_5_STEP_1(src_16,tmp,samples,8,s0,s1,s2,s3,s4);
805 }
806 else {
807 REORDER_SELF_SWAP_5_STEP_1(src_16,tmp,samples,5,s0,s1,s2,s3,s4);
808 }
809 break;
810 }
811 case 3:
812 {
813 int8_t *src_8 = src;
814 int8_t tmp0, tmp1, tmp2;
815 for (i = 0; i < samples * 3; i += chnum * 3) {
816 tmp0 = src_8[i+s0*3];
817 tmp1 = src_8[i+s0*3+1];
818 tmp2 = src_8[i+s0*3+2];
819 src_8[i+s0*3] = src_8[i+s1*3];
820 src_8[i+s0*3+1] = src_8[i+s1*3+1];
821 src_8[i+s0*3+2] = src_8[i+s1*3+2];
822 src_8[i+s1*3] = src_8[i+s2*3];
823 src_8[i+s1*3+1] = src_8[i+s2*3+1];
824 src_8[i+s1*3+2] = src_8[i+s2*3+2];
825 src_8[i+s2*3] = src_8[i+s3*3];
826 src_8[i+s2*3+1] = src_8[i+s3*3+1];
827 src_8[i+s2*3+2] = src_8[i+s3*3+2];
828 src_8[i+s3*3] = src_8[i+s4*3];
829 src_8[i+s3*3+1] = src_8[i+s4*3+1];
830 src_8[i+s3*3+2] = src_8[i+s4*3+2];
831 src_8[i+s4*3] = tmp0;
832 src_8[i+s4*3+1] = tmp1;
833 src_8[i+s4*3+2] = tmp2;
834 }
835 break;
836 }
837 case 4:
838 {
839 int32_t *src_32 = src;
840 int32_t tmp;
841 if (chnum==6) {
842 REORDER_SELF_SWAP_5_STEP_1(src_32,tmp,samples,6,s0,s1,s2,s3,s4);
843 }
844 else if (chnum==8) {
845 REORDER_SELF_SWAP_5_STEP_1(src_32,tmp,samples,8,s0,s1,s2,s3,s4);
846 }
847 else {
848 REORDER_SELF_SWAP_5_STEP_1(src_32,tmp,samples,5,s0,s1,s2,s3,s4);
849 }
850 break;
851 }
852 case 8:
853 {
854 int64_t *src_64 = src;
855 int64_t tmp;
856 if (chnum==6) {
857 REORDER_SELF_SWAP_5_STEP_1(src_64,tmp,samples,6,s0,s1,s2,s3,s4);
858 }
859 else if (chnum==8) {
860 REORDER_SELF_SWAP_5_STEP_1(src_64,tmp,samples,8,s0,s1,s2,s3,s4);
861 }
862 else {
863 REORDER_SELF_SWAP_5_STEP_1(src_64,tmp,samples,5,s0,s1,s2,s3,s4);
864 }
865 break;
866 }
867 default:
868 mp_msg(MSGT_GLOBAL, MSGL_WARN,
869 "[reorder_ch] Unsupported sample size: %d, please "
870 "report this error on the MPlayer mailing list.\n",samplesize);
871 return 0;
872 }
873 return 1;
874 }
875
876 #define REORDER_SELF_SWAP_2_3(SRC,TMP,SAMPLES,CHNUM,S0,S1,S2,S3,S4) \
877 for (i = 0; i < SAMPLES; i += CHNUM) {\
878 TMP = SRC[i+S0];\
879 SRC[i+S0] = SRC[i+S1];\
880 SRC[i+S1] = TMP;\
881 TMP = SRC[i+S2];\
882 SRC[i+S2] = SRC[i+S3];\
883 SRC[i+S3] = SRC[i+S4];\
884 SRC[i+S4] = TMP;\
885 }
886
reorder_self_2_3(void * src,unsigned int samples,unsigned int samplesize,int s0,int s1,int s2,int s3,int s4)887 static int reorder_self_2_3(void *src, unsigned int samples,
888 unsigned int samplesize,
889 int s0, int s1, int s2, int s3, int s4)
890 {
891 int i;
892 switch (samplesize) {
893 case 1:
894 {
895 int8_t *src_8 = src;
896 int8_t tmp;
897 REORDER_SELF_SWAP_2_3(src_8,tmp,samples,6,s0,s1,s2,s3,s4);
898 break;
899 }
900 case 2:
901 {
902 int16_t *src_16 = src;
903 int16_t tmp;
904 REORDER_SELF_SWAP_2_3(src_16,tmp,samples,6,s0,s1,s2,s3,s4);
905 break;
906 }
907 case 3:
908 {
909 int8_t *src_8 = src;
910 int8_t tmp0, tmp1, tmp2;
911 for (i = 0; i < samples * 3; i += 18) {
912 tmp0 = src_8[i+s0*3];
913 tmp1 = src_8[i+s0*3+1];
914 tmp2 = src_8[i+s0*3+2];
915 src_8[i+s0*3] = src_8[i+s1*3];
916 src_8[i+s0*3+1] = src_8[i+s1*3+1];
917 src_8[i+s0*3+2] = src_8[i+s1*3+2];
918 src_8[i+s1*3] = tmp0;
919 src_8[i+s1*3+1] = tmp1;
920 src_8[i+s1*3+2] = tmp2;
921 tmp0 = src_8[i+s2*3];
922 tmp1 = src_8[i+s2*3+1];
923 tmp2 = src_8[i+s2*3+2];
924 src_8[i+s2*3] = src_8[i+s3*3];
925 src_8[i+s2*3+1] = src_8[i+s3*3+1];
926 src_8[i+s2*3+2] = src_8[i+s3*3+2];
927 src_8[i+s3*3] = src_8[i+s4*3];
928 src_8[i+s3*3+1] = src_8[i+s4*3+1];
929 src_8[i+s3*3+2] = src_8[i+s4*3+2];
930 src_8[i+s4*3] = tmp0;
931 src_8[i+s4*3+1] = tmp1;
932 src_8[i+s4*3+2] = tmp2;
933 }
934 break;
935 }
936 case 4:
937 {
938 int32_t *src_32 = src;
939 int32_t tmp;
940 REORDER_SELF_SWAP_2_3(src_32,tmp,samples,6,s0,s1,s2,s3,s4);
941 break;
942 }
943 case 8:
944 {
945 int64_t *src_64 = src;
946 int64_t tmp;
947 REORDER_SELF_SWAP_2_3(src_64,tmp,samples,6,s0,s1,s2,s3,s4);
948 break;
949 }
950 default:
951 mp_msg(MSGT_GLOBAL, MSGL_WARN,
952 "[reorder_ch] Unsupported sample size: %d, please "
953 "report this error on the MPlayer mailing list.\n",samplesize);
954 return 0;
955 }
956 return 1;
957 }
958
959 #define REORDER_SELF_SWAP_3_3(SRC,TMP,SAMPLES,CHNUM,S0,S1,S2,S3,S4,S5) \
960 for (i = 0; i < SAMPLES; i += CHNUM) {\
961 TMP = SRC[i+S0];\
962 SRC[i+S0] = SRC[i+S1];\
963 SRC[i+S1] = SRC[i+S2];\
964 SRC[i+S2] = TMP;\
965 TMP = SRC[i+S3];\
966 SRC[i+S3] = SRC[i+S4];\
967 SRC[i+S4] = SRC[i+S5];\
968 SRC[i+S5] = TMP;\
969 }
970
reorder_self_3_3(void * src,unsigned int samples,unsigned int samplesize,int s0,int s1,int s2,int s3,int s4,int s5)971 static int reorder_self_3_3(void *src, unsigned int samples,
972 unsigned int samplesize,
973 int s0, int s1, int s2, int s3, int s4, int s5)
974 {
975 int i;
976 switch (samplesize) {
977 case 1:
978 {
979 int8_t *src_8 = src;
980 int8_t tmp;
981 REORDER_SELF_SWAP_3_3(src_8,tmp,samples,6,s0,s1,s2,s3,s4,s5);
982 break;
983 }
984 case 2:
985 {
986 int16_t *src_16 = src;
987 int16_t tmp;
988 REORDER_SELF_SWAP_3_3(src_16,tmp,samples,6,s0,s1,s2,s3,s4,s5);
989 break;
990 }
991 case 3:
992 {
993 int8_t *src_8 = src;
994 int8_t tmp0, tmp1, tmp2;
995 for (i = 0; i < samples * 3; i += 18) {
996 tmp0 = src_8[i+s0*3];
997 tmp1 = src_8[i+s0*3+1];
998 tmp2 = src_8[i+s0*3+2];
999 src_8[i+s0*3] = src_8[i+s1*3];
1000 src_8[i+s0*3+1] = src_8[i+s1*3+1];
1001 src_8[i+s0*3+2] = src_8[i+s1*3+2];
1002 src_8[i+s1*3] = src_8[i+s2*3];
1003 src_8[i+s1*3+1] = src_8[i+s2*3+1];
1004 src_8[i+s1*3+2] = src_8[i+s2*3+2];
1005 src_8[i+s2*3] = tmp0;
1006 src_8[i+s2*3+1] = tmp1;
1007 src_8[i+s2*3+2] = tmp2;
1008 tmp0 = src_8[i+s3*3];
1009 tmp1 = src_8[i+s3*3+1];
1010 tmp2 = src_8[i+s3*3+2];
1011 src_8[i+s3*3] = src_8[i+s4*3];
1012 src_8[i+s3*3+1] = src_8[i+s4*3+1];
1013 src_8[i+s3*3+2] = src_8[i+s4*3+2];
1014 src_8[i+s4*3] = src_8[i+s5*3];
1015 src_8[i+s4*3+1] = src_8[i+s5*3+1];
1016 src_8[i+s4*3+2] = src_8[i+s5*3+2];
1017 src_8[i+s5*3] = tmp0;
1018 src_8[i+s5*3+1] = tmp1;
1019 src_8[i+s5*3+2] = tmp2;
1020 }
1021 break;
1022 }
1023 case 4:
1024 {
1025 int32_t *src_32 = src;
1026 int32_t tmp;
1027 REORDER_SELF_SWAP_3_3(src_32,tmp,samples,6,s0,s1,s2,s3,s4,s5);
1028 break;
1029 }
1030 case 8:
1031 {
1032 int64_t *src_64 = src;
1033 int64_t tmp;
1034 REORDER_SELF_SWAP_3_3(src_64,tmp,samples,6,s0,s1,s2,s3,s4,s5);
1035 break;
1036 }
1037 default:
1038 mp_msg(MSGT_GLOBAL, MSGL_WARN,
1039 "[reorder_ch] Unsupported sample size: %d, please "
1040 "report this error on the MPlayer mailing list.\n",samplesize);
1041 return 0;
1042 }
1043 return 1;
1044 }
1045
1046 #define REORDER_SELF_SWAP_2_4(SRC,TMP,SAMPLES,CHNUM,S0,S1,S2,S3,S4,S5) \
1047 for (i = 0; i < SAMPLES; i += CHNUM) {\
1048 TMP = SRC[i+S0];\
1049 SRC[i+S0] = SRC[i+S1];\
1050 SRC[i+S1] = TMP;\
1051 TMP = SRC[i+S2];\
1052 SRC[i+S2] = SRC[i+S3];\
1053 SRC[i+S3] = SRC[i+S4];\
1054 SRC[i+S4] = SRC[i+S5];\
1055 SRC[i+S5] = TMP;\
1056 }
1057
reorder_self_2_4(void * src,unsigned int samples,unsigned int samplesize,int chnum,int s0,int s1,int s2,int s3,int s4,int s5)1058 static int reorder_self_2_4(void *src, unsigned int samples,
1059 unsigned int samplesize, int chnum,
1060 int s0, int s1, int s2, int s3, int s4, int s5)
1061 {
1062 int i;
1063 switch (samplesize) {
1064 case 1:
1065 {
1066 int8_t *src_8 = src;
1067 int8_t tmp;
1068 if (chnum==6) {
1069 REORDER_SELF_SWAP_2_4(src_8,tmp,samples,6,s0,s1,s2,s3,s4,s5);
1070 } else {
1071 REORDER_SELF_SWAP_2_4(src_8,tmp,samples,8,s0,s1,s2,s3,s4,s5);
1072 }
1073 break;
1074 }
1075 case 2:
1076 {
1077 int16_t *src_16 = src;
1078 int16_t tmp;
1079 if (chnum==6) {
1080 REORDER_SELF_SWAP_2_4(src_16,tmp,samples,6,s0,s1,s2,s3,s4,s5);
1081 } else {
1082 REORDER_SELF_SWAP_2_4(src_16,tmp,samples,8,s0,s1,s2,s3,s4,s5);
1083 }
1084 break;
1085 }
1086 case 3:
1087 {
1088 int8_t *src_8 = src;
1089 int8_t tmp0, tmp1, tmp2;
1090 for (i = 0; i < samples * 3; i += chnum * 3) {
1091 tmp0 = src_8[i+s0*3];
1092 tmp1 = src_8[i+s0*3+1];
1093 tmp2 = src_8[i+s0*3+2];
1094 src_8[i+s0*3] = src_8[i+s1*3];
1095 src_8[i+s0*3+1] = src_8[i+s1*3+1];
1096 src_8[i+s0*3+2] = src_8[i+s1*3+2];
1097 src_8[i+s1*3] = tmp0;
1098 src_8[i+s1*3+1] = tmp1;
1099 src_8[i+s1*3+2] = tmp2;
1100 tmp0 = src_8[i+s2*3];
1101 tmp1 = src_8[i+s2*3+1];
1102 tmp2 = src_8[i+s2*3+2];
1103 src_8[i+s2*3] = src_8[i+s3*3];
1104 src_8[i+s2*3+1] = src_8[i+s3*3+1];
1105 src_8[i+s2*3+2] = src_8[i+s3*3+2];
1106 src_8[i+s3*3] = src_8[i+s4*3];
1107 src_8[i+s3*3+1] = src_8[i+s4*3+1];
1108 src_8[i+s3*3+2] = src_8[i+s4*3+2];
1109 src_8[i+s4*3] = src_8[i+s5*3];
1110 src_8[i+s4*3+1] = src_8[i+s5*3+1];
1111 src_8[i+s4*3+2] = src_8[i+s5*3+2];
1112 src_8[i+s5*3] = tmp0;
1113 src_8[i+s5*3+1] = tmp1;
1114 src_8[i+s5*3+2] = tmp2;
1115 }
1116 break;
1117 }
1118 case 4:
1119 {
1120 int32_t *src_32 = src;
1121 int32_t tmp;
1122 if (chnum==6) {
1123 REORDER_SELF_SWAP_2_4(src_32,tmp,samples,6,s0,s1,s2,s3,s4,s5);
1124 } else {
1125 REORDER_SELF_SWAP_2_4(src_32,tmp,samples,8,s0,s1,s2,s3,s4,s5);
1126 }
1127 break;
1128 }
1129 case 8:
1130 {
1131 int64_t *src_64 = src;
1132 int64_t tmp;
1133 if (chnum==6) {
1134 REORDER_SELF_SWAP_2_4(src_64,tmp,samples,6,s0,s1,s2,s3,s4,s5);
1135 } else {
1136 REORDER_SELF_SWAP_2_4(src_64,tmp,samples,8,s0,s1,s2,s3,s4,s5);
1137 }
1138 break;
1139 }
1140 default:
1141 mp_msg(MSGT_GLOBAL, MSGL_WARN,
1142 "[reorder_ch] Unsupported sample size: %d, please "
1143 "report this error on the MPlayer mailing list.\n",samplesize);
1144 return 0;
1145 }
1146 return 1;
1147 }
1148
reorder_channel(void * src,int src_layout,int dest_layout,int samples,int samplesize)1149 void reorder_channel(void *src,
1150 int src_layout,
1151 int dest_layout,
1152 int samples,
1153 int samplesize)
1154 {
1155 if (dest_layout==src_layout)
1156 return;
1157 if (!AF_IS_SAME_CH_NUM(dest_layout,src_layout)) {
1158 mp_msg(MSGT_GLOBAL, MSGL_WARN,
1159 "[reorder_channel] different channel count "
1160 "between current and target: %x, %x\n",
1161 AF_GET_CH_NUM_WITH_LFE(src_layout),
1162 AF_GET_CH_NUM_WITH_LFE(dest_layout));
1163 return;
1164 }
1165 switch ((src_layout<<16)|dest_layout) {
1166 // AF_CHANNEL_LAYOUT_5_0_A L R C Ls Rs
1167 // AF_CHANNEL_LAYOUT_5_0_B L R Ls Rs C
1168 // AF_CHANNEL_LAYOUT_5_0_C L C R Ls Rs
1169 // AF_CHANNEL_LAYOUT_5_0_D C L R Ls Rs
1170 case AF_CHANNEL_LAYOUT_5_0_A << 16 | AF_CHANNEL_LAYOUT_5_0_B:
1171 reorder_self_3(src, samples, samplesize, 5, 2, 3, 4);
1172 break;
1173 case AF_CHANNEL_LAYOUT_5_0_A << 16 | AF_CHANNEL_LAYOUT_5_0_C:
1174 reorder_self_2(src, samples, samplesize, 5, 1, 2);
1175 break;
1176 case AF_CHANNEL_LAYOUT_5_0_A << 16 | AF_CHANNEL_LAYOUT_5_0_D:
1177 reorder_self_3(src, samples, samplesize, 5, 2, 1, 0);
1178 break;
1179 case AF_CHANNEL_LAYOUT_5_0_B << 16 | AF_CHANNEL_LAYOUT_5_0_A:
1180 reorder_self_3(src, samples, samplesize, 5, 4, 3, 2);
1181 break;
1182 case AF_CHANNEL_LAYOUT_5_0_B << 16 | AF_CHANNEL_LAYOUT_5_0_C:
1183 reorder_self_4_step_1(src, samples, samplesize, 5, 4, 3, 2, 1);
1184 break;
1185 case AF_CHANNEL_LAYOUT_5_0_B << 16 | AF_CHANNEL_LAYOUT_5_0_D:
1186 reorder_self_5_step_1(src, samples, samplesize, 5, 4, 3, 2, 1, 0);
1187 break;
1188 case AF_CHANNEL_LAYOUT_5_0_C << 16 | AF_CHANNEL_LAYOUT_5_0_A:
1189 reorder_self_2(src, samples, samplesize, 5, 1, 2);
1190 break;
1191 case AF_CHANNEL_LAYOUT_5_0_C << 16 | AF_CHANNEL_LAYOUT_5_0_B:
1192 reorder_self_4_step_1(src, samples, samplesize, 5, 1, 2, 3, 4);
1193 break;
1194 case AF_CHANNEL_LAYOUT_5_0_C << 16 | AF_CHANNEL_LAYOUT_5_0_D:
1195 reorder_self_2(src, samples, samplesize, 5, 0, 1);
1196 break;
1197 case AF_CHANNEL_LAYOUT_5_0_D << 16 | AF_CHANNEL_LAYOUT_5_0_A:
1198 reorder_self_3(src, samples, samplesize, 5, 0, 1, 2);
1199 break;
1200 case AF_CHANNEL_LAYOUT_5_0_D << 16 | AF_CHANNEL_LAYOUT_5_0_B:
1201 reorder_self_5_step_1(src, samples, samplesize, 5, 0, 1, 2, 3, 4);
1202 break;
1203 case AF_CHANNEL_LAYOUT_5_0_D << 16 | AF_CHANNEL_LAYOUT_5_0_C:
1204 reorder_self_2(src, samples, samplesize, 5, 0, 1);
1205 break;
1206 // AF_CHANNEL_LAYOUT_5_1_A L R C LFE Ls Rs
1207 // AF_CHANNEL_LAYOUT_5_1_B L R Ls Rs C LFE
1208 // AF_CHANNEL_LAYOUT_5_1_C L C R Ls Rs LFE
1209 // AF_CHANNEL_LAYOUT_5_1_D C L R Ls Rs LFE
1210 // AF_CHANNEL_LAYOUT_5_1_E LFE L C R Ls Rs
1211 case AF_CHANNEL_LAYOUT_5_1_A << 16 | AF_CHANNEL_LAYOUT_5_1_B:
1212 if (samplesize != 3)
1213 reorder_self_2(src, samples/2, samplesize*2, 3, 1, 2);
1214 else
1215 reorder_self_4_step_2(src, samples, samplesize, 6, 2, 3, 4, 5);
1216 break;
1217 case AF_CHANNEL_LAYOUT_5_1_A << 16 | AF_CHANNEL_LAYOUT_5_1_C:
1218 reorder_self_2_3(src, samples, samplesize, 1, 2, 3, 4, 5);
1219 break;
1220 case AF_CHANNEL_LAYOUT_5_1_A << 16 | AF_CHANNEL_LAYOUT_5_1_D:
1221 reorder_self_3_3(src, samples, samplesize, 2, 1, 0, 3, 4, 5);
1222 break;
1223 case AF_CHANNEL_LAYOUT_5_1_B << 16 | AF_CHANNEL_LAYOUT_5_1_A:
1224 if (samplesize != 3)
1225 reorder_self_2(src, samples/2, samplesize*2, 3, 1, 2);
1226 else
1227 reorder_self_4_step_2(src, samples, samplesize, 6, 2, 3, 4, 5);
1228 break;
1229 case AF_CHANNEL_LAYOUT_5_1_B << 16 | AF_CHANNEL_LAYOUT_5_1_C:
1230 reorder_self_4_step_1(src, samples, samplesize, 6, 4, 3, 2, 1);
1231 break;
1232 case AF_CHANNEL_LAYOUT_5_1_B << 16 | AF_CHANNEL_LAYOUT_5_1_D:
1233 reorder_self_5_step_1(src, samples, samplesize, 6, 4, 3, 2, 1, 0);
1234 break;
1235 case AF_CHANNEL_LAYOUT_5_1_B << 16 | AF_CHANNEL_LAYOUT_5_1_E:
1236 reorder_self_2_4(src, samples, samplesize, 6, 2, 4, 5, 3, 1, 0);
1237 break;
1238 case AF_CHANNEL_LAYOUT_5_1_C << 16 | AF_CHANNEL_LAYOUT_5_1_A:
1239 reorder_self_2_3(src, samples, samplesize, 1, 2, 5, 4, 3);
1240 break;
1241 case AF_CHANNEL_LAYOUT_5_1_C << 16 | AF_CHANNEL_LAYOUT_5_1_B:
1242 reorder_self_4_step_1(src, samples, samplesize, 6, 1, 2, 3, 4);
1243 break;
1244 case AF_CHANNEL_LAYOUT_5_1_C << 16 | AF_CHANNEL_LAYOUT_5_1_D:
1245 reorder_self_2(src, samples, samplesize, 6, 0, 1);
1246 break;
1247 case AF_CHANNEL_LAYOUT_5_1_D << 16 | AF_CHANNEL_LAYOUT_5_1_A:
1248 reorder_self_3_3(src, samples, samplesize, 0, 1, 2, 5, 4, 3);
1249 break;
1250 case AF_CHANNEL_LAYOUT_5_1_D << 16 | AF_CHANNEL_LAYOUT_5_1_B:
1251 reorder_self_5_step_1(src, samples, samplesize, 6, 0, 1, 2, 3, 4);
1252 break;
1253 case AF_CHANNEL_LAYOUT_5_1_D << 16 | AF_CHANNEL_LAYOUT_5_1_C:
1254 reorder_self_2(src, samples, samplesize, 6, 0, 1);
1255 break;
1256 case AF_CHANNEL_LAYOUT_5_1_E << 16 | AF_CHANNEL_LAYOUT_5_1_B:
1257 reorder_self_2_4(src, samples, samplesize, 6, 2, 4, 0, 1, 3, 5);
1258 break;
1259 case AF_CHANNEL_LAYOUT_5_1_F << 16 | AF_CHANNEL_LAYOUT_5_1_B:
1260 reorder_self_2_4(src, samples, samplesize, 6, 3, 5, 0, 1, 2, 4);
1261 break;
1262 // AF_CHANNEL_LAYOUT_7_1_A L R C LFE Ls Rs Rls Rrs
1263 // AF_CHANNEL_LAYOUT_7_1_B L R Ls Rs C LFE Rls Rrs
1264 // AF_CHANNEL_LAYOUT_7_1_C L C R Ls Rs LFE Rls Rrs
1265 // AF_CHANNEL_LAYOUT_7_1_D C L R Ls Rs Rls Rrs LFE
1266 // AF_CHANNEL_LAYOUT_7_1_F C L R LFE Ls Rs Rls Rrs
1267 case AF_CHANNEL_LAYOUT_7_1_A << 16 | AF_CHANNEL_LAYOUT_7_1_B:
1268 case AF_CHANNEL_LAYOUT_7_1_B << 16 | AF_CHANNEL_LAYOUT_7_1_A:
1269 if (samplesize != 3)
1270 reorder_self_2(src, samples/2, samplesize*2, 4, 1, 2);
1271 else
1272 reorder_self_4_step_2(src, samples, samplesize, 8, 2, 3, 4, 5);
1273 break;
1274 case AF_CHANNEL_LAYOUT_7_1_B << 16 | AF_CHANNEL_LAYOUT_7_1_D:
1275 // First convert to AF_CHANNEL_LAYOUT_7_1_F
1276 reorder_self_2_4(src, samples, samplesize, 8, 3, 5, 4, 2, 1, 0);
1277 // then convert to AF_CHANNEL_LAYOUT_7_1_D
1278 reorder_self_5_step_1(src, samples, samplesize, 8, 3, 4, 5, 6, 7);
1279 break;
1280 case AF_CHANNEL_LAYOUT_7_1_C << 16 | AF_CHANNEL_LAYOUT_7_1_B:
1281 reorder_self_4_step_1(src, samples, samplesize, 8, 1, 2, 3, 4);
1282 break;
1283 case AF_CHANNEL_LAYOUT_7_1_F << 16 | AF_CHANNEL_LAYOUT_7_1_B:
1284 reorder_self_2_4(src, samples, samplesize, 8, 3, 5, 0, 1, 2, 4);
1285 break;
1286 default:
1287 mp_msg(MSGT_GLOBAL, MSGL_WARN,
1288 "[reorder_channel] unsupported from %x to %x, %d * %d\n",
1289 src_layout, dest_layout, samples, samplesize);
1290 }
1291 }
1292
1293
1294 static int channel_layout_mapping_5ch[AF_CHANNEL_LAYOUT_SOURCE_NUM] = {
1295 AF_CHANNEL_LAYOUT_ALSA_5CH_DEFAULT,
1296 AF_CHANNEL_LAYOUT_AAC_5CH_DEFAULT,
1297 AF_CHANNEL_LAYOUT_WAVEEX_5CH_DEFAULT,
1298 AF_CHANNEL_LAYOUT_LAVC_5CH_DEFAULT,
1299 AF_CHANNEL_LAYOUT_VORBIS_5CH_DEFAULT,
1300 };
1301
1302 static int channel_layout_mapping_6ch[AF_CHANNEL_LAYOUT_SOURCE_NUM] = {
1303 AF_CHANNEL_LAYOUT_ALSA_6CH_DEFAULT,
1304 AF_CHANNEL_LAYOUT_AAC_6CH_DEFAULT,
1305 AF_CHANNEL_LAYOUT_WAVEEX_6CH_DEFAULT,
1306 AF_CHANNEL_LAYOUT_LAVC_6CH_DEFAULT,
1307 AF_CHANNEL_LAYOUT_VORBIS_6CH_DEFAULT,
1308 };
1309
1310 static int channel_layout_mapping_8ch[AF_CHANNEL_LAYOUT_SOURCE_NUM] = {
1311 AF_CHANNEL_LAYOUT_ALSA_8CH_DEFAULT,
1312 AF_CHANNEL_LAYOUT_AAC_8CH_DEFAULT,
1313 AF_CHANNEL_LAYOUT_WAVEEX_8CH_DEFAULT,
1314 AF_CHANNEL_LAYOUT_LAVC_8CH_DEFAULT,
1315 AF_CHANNEL_LAYOUT_VORBIS_8CH_DEFAULT,
1316 };
1317
reorder_channel_copy_nch(void * src,int src_layout,void * dest,int dest_layout,int chnum,int samples,int samplesize)1318 void reorder_channel_copy_nch(void *src,
1319 int src_layout,
1320 void *dest,
1321 int dest_layout,
1322 int chnum,
1323 int samples,
1324 int samplesize)
1325 {
1326 if (chnum < 5 || chnum == 7 || chnum > 8 ||
1327 src_layout < 0 || dest_layout < 0 ||
1328 src_layout >= AF_CHANNEL_LAYOUT_SOURCE_NUM ||
1329 dest_layout >= AF_CHANNEL_LAYOUT_SOURCE_NUM)
1330 fast_memcpy(dest, src, samples*samplesize);
1331 else if (chnum == 6)
1332 reorder_channel_copy(src, channel_layout_mapping_6ch[src_layout],
1333 dest, channel_layout_mapping_6ch[dest_layout],
1334 samples, samplesize);
1335 else if (chnum == 8)
1336 reorder_channel_copy(src, channel_layout_mapping_8ch[src_layout],
1337 dest, channel_layout_mapping_8ch[dest_layout],
1338 samples, samplesize);
1339 else
1340 reorder_channel_copy(src, channel_layout_mapping_5ch[src_layout],
1341 dest, channel_layout_mapping_5ch[dest_layout],
1342 samples, samplesize);
1343 }
1344
reorder_channel_nch(void * buf,int src_layout,int dest_layout,int chnum,int samples,int samplesize)1345 void reorder_channel_nch(void *buf,
1346 int src_layout,
1347 int dest_layout,
1348 int chnum,
1349 int samples,
1350 int samplesize)
1351 {
1352 if (src_layout == dest_layout || chnum < 5 || chnum == 7 || chnum > 8 ||
1353 src_layout < 0 || dest_layout < 0 ||
1354 src_layout >= AF_CHANNEL_LAYOUT_SOURCE_NUM ||
1355 dest_layout >= AF_CHANNEL_LAYOUT_SOURCE_NUM ||
1356 src_layout == dest_layout)
1357 return;
1358 if (chnum == 6)
1359 reorder_channel(buf, channel_layout_mapping_6ch[src_layout],
1360 channel_layout_mapping_6ch[dest_layout],
1361 samples, samplesize);
1362 else if (chnum == 8)
1363 reorder_channel(buf, channel_layout_mapping_8ch[src_layout],
1364 channel_layout_mapping_8ch[dest_layout],
1365 samples, samplesize);
1366 else
1367 reorder_channel(buf, channel_layout_mapping_5ch[src_layout],
1368 channel_layout_mapping_5ch[dest_layout],
1369 samples, samplesize);
1370 }
1371
1372
1373 #ifdef TEST
1374
test_copy(int channels)1375 static void test_copy(int channels) {
1376 int samples = 12*1024*1024;
1377 int samplesize = 2;
1378 int i;
1379 unsigned char *bufin = malloc((samples+100)*samplesize);
1380 unsigned char *bufout = malloc((samples+100)*samplesize);
1381 memset(bufin, 0xFF, samples*samplesize);
1382 for (i = 0;i < 100; ++i)
1383 reorder_channel_copy(bufin, AF_CHANNEL_LAYOUT_5_1_A,
1384 bufout, AF_CHANNEL_LAYOUT_5_1_B,
1385 samples, samplesize);
1386 // reorder_channel(bufin, AF_CHANNEL_LAYOUT_5_1_B,
1387 // AF_CHANNEL_LAYOUT_5_1_D,
1388 // samples, samplesize);
1389 free(bufin);
1390 free(bufout);
1391 }
1392
main(int argc,char * argv[])1393 int main(int argc, char *argv[]) {
1394 int channels = 6;
1395 if (argc > 1)
1396 channels = atoi(argv[1]);
1397 test_copy(channels);
1398 return 0;
1399 }
1400
1401 #endif
1402