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