Update to MPlayer SVN rev 29978 and FFmpeg SVN rev 20757.
[vaapi:challenzhous-mplayer.git] / libaf / .svn / text-base / reorder_ch.c.svn-base
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
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
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
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
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
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
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
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
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
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 {
789             REORDER_SELF_SWAP_5_STEP_1(src_8,tmp,samples,5,s0,s1,s2,s3,s4);
790         }
791         break;
792     }
793     case 2:
794     {
795         int16_t *src_16 = src;
796         int16_t tmp;
797         if (chnum==6) {
798             REORDER_SELF_SWAP_5_STEP_1(src_16,tmp,samples,6,s0,s1,s2,s3,s4);
799         }
800         else {
801             REORDER_SELF_SWAP_5_STEP_1(src_16,tmp,samples,5,s0,s1,s2,s3,s4);
802         }
803         break;
804     }
805     case 3:
806     {
807         int8_t *src_8 = src;
808         int8_t tmp0, tmp1, tmp2;
809         for (i = 0; i < samples * 3; i += chnum * 3) {
810             tmp0 = src_8[i+s0*3];
811             tmp1 = src_8[i+s0*3+1];
812             tmp2 = src_8[i+s0*3+2];
813             src_8[i+s0*3]   = src_8[i+s1*3];
814             src_8[i+s0*3+1] = src_8[i+s1*3+1];
815             src_8[i+s0*3+2] = src_8[i+s1*3+2];
816             src_8[i+s1*3]   = src_8[i+s2*3];
817             src_8[i+s1*3+1] = src_8[i+s2*3+1];
818             src_8[i+s1*3+2] = src_8[i+s2*3+2];
819             src_8[i+s2*3]   = src_8[i+s3*3];
820             src_8[i+s2*3+1] = src_8[i+s3*3+1];
821             src_8[i+s2*3+2] = src_8[i+s3*3+2];
822             src_8[i+s3*3]   = src_8[i+s4*3];
823             src_8[i+s3*3+1] = src_8[i+s4*3+1];
824             src_8[i+s3*3+2] = src_8[i+s4*3+2];
825             src_8[i+s4*3]   = tmp0;
826             src_8[i+s4*3+1] = tmp1;
827             src_8[i+s4*3+2] = tmp2;
828         }
829         break;
830     }
831     case 4:
832     {
833         int32_t *src_32 = src;
834         int32_t tmp;
835         if (chnum==6) {
836             REORDER_SELF_SWAP_5_STEP_1(src_32,tmp,samples,6,s0,s1,s2,s3,s4);
837         }
838         else {
839             REORDER_SELF_SWAP_5_STEP_1(src_32,tmp,samples,5,s0,s1,s2,s3,s4);
840         }
841         break;
842     }
843     case 8:
844     {
845         int64_t *src_64 = src;
846         int64_t tmp;
847         if (chnum==6) {
848             REORDER_SELF_SWAP_5_STEP_1(src_64,tmp,samples,6,s0,s1,s2,s3,s4);
849         }
850         else {
851             REORDER_SELF_SWAP_5_STEP_1(src_64,tmp,samples,5,s0,s1,s2,s3,s4);
852         }
853         break;
854     }
855     default:
856         mp_msg(MSGT_GLOBAL, MSGL_WARN,
857                "[reorder_ch] Unsupported sample size: %d, please "
858                "report this error on the MPlayer mailing list.\n",samplesize);
859         return 0;
860     }
861     return 1;
862 }
863
864 #define REORDER_SELF_SWAP_2_3(SRC,TMP,SAMPLES,CHNUM,S0,S1,S2,S3,S4) \
865 for (i = 0; i < SAMPLES; i += CHNUM) {\
866     TMP = SRC[i+S0];\
867     SRC[i+S0] = SRC[i+S1];\
868     SRC[i+S1] = TMP;\
869     TMP = SRC[i+S2];\
870     SRC[i+S2] = SRC[i+S3];\
871     SRC[i+S3] = SRC[i+S4];\
872     SRC[i+S4] = TMP;\
873 }
874
875 static int reorder_self_2_3(void *src, unsigned int samples,
876                             unsigned int samplesize,
877                             int s0, int s1, int s2, int s3, int s4)
878 {
879     int i;
880     switch (samplesize) {
881     case 1:
882     {
883         int8_t *src_8 = src;
884         int8_t tmp;
885         REORDER_SELF_SWAP_2_3(src_8,tmp,samples,6,s0,s1,s2,s3,s4);
886         break;
887     }
888     case 2:
889     {
890         int16_t *src_16 = src;
891         int16_t tmp;
892         REORDER_SELF_SWAP_2_3(src_16,tmp,samples,6,s0,s1,s2,s3,s4);
893         break;
894     }
895     case 3:
896     {
897         int8_t *src_8 = src;
898         int8_t tmp0, tmp1, tmp2;
899         for (i = 0; i < samples * 3; i += 18) {
900             tmp0 = src_8[i+s0*3];
901             tmp1 = src_8[i+s0*3+1];
902             tmp2 = src_8[i+s0*3+2];
903             src_8[i+s0*3]   = src_8[i+s1*3];
904             src_8[i+s0*3+1] = src_8[i+s1*3+1];
905             src_8[i+s0*3+2] = src_8[i+s1*3+2];
906             src_8[i+s1*3]   = tmp0;
907             src_8[i+s1*3+1] = tmp1;
908             src_8[i+s1*3+2] = tmp2;
909             tmp0 = src_8[i+s2*3];
910             tmp1 = src_8[i+s2*3+1];
911             tmp2 = src_8[i+s2*3+2];
912             src_8[i+s2*3]   = src_8[i+s3*3];
913             src_8[i+s2*3+1] = src_8[i+s3*3+1];
914             src_8[i+s2*3+2] = src_8[i+s3*3+2];
915             src_8[i+s3*3]   = src_8[i+s4*3];
916             src_8[i+s3*3+1] = src_8[i+s4*3+1];
917             src_8[i+s3*3+2] = src_8[i+s4*3+2];
918             src_8[i+s4*3]   = tmp0;
919             src_8[i+s4*3+1] = tmp1;
920             src_8[i+s4*3+2] = tmp2;
921         }
922         break;
923     }
924     case 4:
925     {
926         int32_t *src_32 = src;
927         int32_t tmp;
928         REORDER_SELF_SWAP_2_3(src_32,tmp,samples,6,s0,s1,s2,s3,s4);
929         break;
930     }
931     case 8:
932     {
933         int64_t *src_64 = src;
934         int64_t tmp;
935         REORDER_SELF_SWAP_2_3(src_64,tmp,samples,6,s0,s1,s2,s3,s4);
936         break;
937     }
938     default:
939         mp_msg(MSGT_GLOBAL, MSGL_WARN,
940                "[reorder_ch] Unsupported sample size: %d, please "
941                "report this error on the MPlayer mailing list.\n",samplesize);
942         return 0;
943     }
944     return 1;
945 }
946
947 #define REORDER_SELF_SWAP_3_3(SRC,TMP,SAMPLES,CHNUM,S0,S1,S2,S3,S4,S5) \
948 for (i = 0; i < SAMPLES; i += CHNUM) {\
949     TMP = SRC[i+S0];\
950     SRC[i+S0] = SRC[i+S1];\
951     SRC[i+S1] = SRC[i+S2];\
952     SRC[i+S2] = TMP;\
953     TMP = SRC[i+S3];\
954     SRC[i+S3] = SRC[i+S4];\
955     SRC[i+S4] = SRC[i+S5];\
956     SRC[i+S5] = TMP;\
957 }
958
959 static int reorder_self_3_3(void *src, unsigned int samples,
960                             unsigned int samplesize,
961                             int s0, int s1, int s2, int s3, int s4, int s5)
962 {
963     int i;
964     switch (samplesize) {
965     case 1:
966     {
967         int8_t *src_8 = src;
968         int8_t tmp;
969         REORDER_SELF_SWAP_3_3(src_8,tmp,samples,6,s0,s1,s2,s3,s4,s5);
970         break;
971     }
972     case 2:
973     {
974         int16_t *src_16 = src;
975         int16_t tmp;
976         REORDER_SELF_SWAP_3_3(src_16,tmp,samples,6,s0,s1,s2,s3,s4,s5);
977         break;
978     }
979     case 3:
980     {
981         int8_t *src_8 = src;
982         int8_t tmp0, tmp1, tmp2;
983         for (i = 0; i < samples * 3; i += 18) {
984             tmp0 = src_8[i+s0*3];
985             tmp1 = src_8[i+s0*3+1];
986             tmp2 = src_8[i+s0*3+2];
987             src_8[i+s0*3]   = src_8[i+s1*3];
988             src_8[i+s0*3+1] = src_8[i+s1*3+1];
989             src_8[i+s0*3+2] = src_8[i+s1*3+2];
990             src_8[i+s1*3]   = src_8[i+s2*3];
991             src_8[i+s1*3+1] = src_8[i+s2*3+1];
992             src_8[i+s1*3+2] = src_8[i+s2*3+2];
993             src_8[i+s2*3]   = tmp0;
994             src_8[i+s2*3+1] = tmp1;
995             src_8[i+s2*3+2] = tmp2;
996             tmp0 = src_8[i+s3*3];
997             tmp1 = src_8[i+s3*3+1];
998             tmp2 = src_8[i+s3*3+2];
999             src_8[i+s3*3]   = src_8[i+s4*3];
1000             src_8[i+s3*3+1] = src_8[i+s4*3+1];
1001             src_8[i+s3*3+2] = src_8[i+s4*3+2];
1002             src_8[i+s4*3]   = src_8[i+s5*3];
1003             src_8[i+s4*3+1] = src_8[i+s5*3+1];
1004             src_8[i+s4*3+2] = src_8[i+s5*3+2];
1005             src_8[i+s5*3]   = tmp0;
1006             src_8[i+s5*3+1] = tmp1;
1007             src_8[i+s5*3+2] = tmp2;
1008         }
1009         break;
1010     }
1011     case 4:
1012     {
1013         int32_t *src_32 = src;
1014         int32_t tmp;
1015         REORDER_SELF_SWAP_3_3(src_32,tmp,samples,6,s0,s1,s2,s3,s4,s5);
1016         break;
1017     }
1018     case 8:
1019     {
1020         int64_t *src_64 = src;
1021         int64_t tmp;
1022         REORDER_SELF_SWAP_3_3(src_64,tmp,samples,6,s0,s1,s2,s3,s4,s5);
1023         break;
1024     }
1025     default:
1026         mp_msg(MSGT_GLOBAL, MSGL_WARN,
1027                "[reorder_ch] Unsupported sample size: %d, please "
1028                "report this error on the MPlayer mailing list.\n",samplesize);
1029         return 0;
1030     }
1031     return 1;
1032 }
1033
1034 #define REORDER_SELF_SWAP_2_4(SRC,TMP,SAMPLES,CHNUM,S0,S1,S2,S3,S4,S5) \
1035 for (i = 0; i < SAMPLES; i += CHNUM) {\
1036     TMP = SRC[i+S0];\
1037     SRC[i+S0] = SRC[i+S1];\
1038     SRC[i+S1] = TMP;\
1039     TMP = SRC[i+S2];\
1040     SRC[i+S2] = SRC[i+S3];\
1041     SRC[i+S3] = SRC[i+S4];\
1042     SRC[i+S4] = SRC[i+S5];\
1043     SRC[i+S5] = TMP;\
1044 }
1045
1046 static int reorder_self_2_4(void *src, unsigned int samples,
1047                             unsigned int samplesize, int chnum,
1048                             int s0, int s1, int s2, int s3, int s4, int s5)
1049 {
1050     int i;
1051     switch (samplesize) {
1052     case 1:
1053     {
1054         int8_t *src_8 = src;
1055         int8_t tmp;
1056         if (chnum==6) {
1057             REORDER_SELF_SWAP_2_4(src_8,tmp,samples,6,s0,s1,s2,s3,s4,s5);
1058         } else {
1059             REORDER_SELF_SWAP_2_4(src_8,tmp,samples,8,s0,s1,s2,s3,s4,s5);
1060         }
1061         break;
1062     }
1063     case 2:
1064     {
1065         int16_t *src_16 = src;
1066         int16_t tmp;
1067         if (chnum==6) {
1068             REORDER_SELF_SWAP_2_4(src_16,tmp,samples,6,s0,s1,s2,s3,s4,s5);
1069         } else {
1070             REORDER_SELF_SWAP_2_4(src_16,tmp,samples,8,s0,s1,s2,s3,s4,s5);
1071         }
1072         break;
1073     }
1074     case 3:
1075     {
1076         int8_t *src_8 = src;
1077         int8_t tmp0, tmp1, tmp2;
1078         for (i = 0; i < samples * 3; i += chnum * 3) {
1079             tmp0 = src_8[i+s0*3];
1080             tmp1 = src_8[i+s0*3+1];
1081             tmp2 = src_8[i+s0*3+2];
1082             src_8[i+s0*3]   = src_8[i+s1*3];
1083             src_8[i+s0*3+1] = src_8[i+s1*3+1];
1084             src_8[i+s0*3+2] = src_8[i+s1*3+2];
1085             src_8[i+s1*3]   = tmp0;
1086             src_8[i+s1*3+1] = tmp1;
1087             src_8[i+s1*3+2] = tmp2;
1088             tmp0 = src_8[i+s2*3];
1089             tmp1 = src_8[i+s2*3+1];
1090             tmp2 = src_8[i+s2*3+2];
1091             src_8[i+s2*3]   = src_8[i+s3*3];
1092             src_8[i+s2*3+1] = src_8[i+s3*3+1];
1093             src_8[i+s2*3+2] = src_8[i+s3*3+2];
1094             src_8[i+s3*3]   = src_8[i+s4*3];
1095             src_8[i+s3*3+1] = src_8[i+s4*3+1];
1096             src_8[i+s3*3+2] = src_8[i+s4*3+2];
1097             src_8[i+s4*3]   = src_8[i+s5*3];
1098             src_8[i+s4*3+1] = src_8[i+s5*3+1];
1099             src_8[i+s4*3+2] = src_8[i+s5*3+2];
1100             src_8[i+s5*3]   = tmp0;
1101             src_8[i+s5*3+1] = tmp1;
1102             src_8[i+s5*3+2] = tmp2;
1103         }
1104         break;
1105     }
1106     case 4:
1107     {
1108         int32_t *src_32 = src;
1109         int32_t tmp;
1110         if (chnum==6) {
1111             REORDER_SELF_SWAP_2_4(src_32,tmp,samples,6,s0,s1,s2,s3,s4,s5);
1112         } else {
1113             REORDER_SELF_SWAP_2_4(src_32,tmp,samples,8,s0,s1,s2,s3,s4,s5);
1114         }
1115         break;
1116     }
1117     case 8:
1118     {
1119         int64_t *src_64 = src;
1120         int64_t tmp;
1121         if (chnum==6) {
1122             REORDER_SELF_SWAP_2_4(src_64,tmp,samples,6,s0,s1,s2,s3,s4,s5);
1123         } else {
1124             REORDER_SELF_SWAP_2_4(src_64,tmp,samples,8,s0,s1,s2,s3,s4,s5);
1125         }
1126         break;
1127     }
1128     default:
1129         mp_msg(MSGT_GLOBAL, MSGL_WARN,
1130                "[reorder_ch] Unsupported sample size: %d, please "
1131                "report this error on the MPlayer mailing list.\n",samplesize);
1132         return 0;
1133     }
1134     return 1;
1135 }
1136
1137 void reorder_channel(void *src,
1138                      int src_layout,
1139                      int dest_layout,
1140                      int samples,
1141                      int samplesize)
1142 {
1143     if (dest_layout==src_layout)
1144         return;
1145     if (!AF_IS_SAME_CH_NUM(dest_layout,src_layout)) {
1146         mp_msg(MSGT_GLOBAL, MSGL_WARN,
1147                "[reorder_channel] different channel count "
1148                "between current and target: %x, %x\n",
1149                AF_GET_CH_NUM_WITH_LFE(src_layout),
1150                AF_GET_CH_NUM_WITH_LFE(dest_layout));
1151         return;
1152     }
1153     switch ((src_layout<<16)|dest_layout) {
1154     // AF_CHANNEL_LAYOUT_5_0_A   L R C Ls Rs
1155     // AF_CHANNEL_LAYOUT_5_0_B   L R Ls Rs C
1156     // AF_CHANNEL_LAYOUT_5_0_C   L C R Ls Rs
1157     // AF_CHANNEL_LAYOUT_5_0_D   C L R Ls Rs
1158     case AF_CHANNEL_LAYOUT_5_0_A << 16 | AF_CHANNEL_LAYOUT_5_0_B:
1159         reorder_self_3(src, samples, samplesize, 5, 2, 3, 4);
1160         break;
1161     case AF_CHANNEL_LAYOUT_5_0_A << 16 | AF_CHANNEL_LAYOUT_5_0_C:
1162         reorder_self_2(src, samples, samplesize, 5, 1, 2);
1163         break;
1164     case AF_CHANNEL_LAYOUT_5_0_A << 16 | AF_CHANNEL_LAYOUT_5_0_D:
1165         reorder_self_3(src, samples, samplesize, 5, 2, 1, 0);
1166         break;
1167     case AF_CHANNEL_LAYOUT_5_0_B << 16 | AF_CHANNEL_LAYOUT_5_0_A:
1168         reorder_self_3(src, samples, samplesize, 5, 4, 3, 2);
1169         break;
1170     case AF_CHANNEL_LAYOUT_5_0_B << 16 | AF_CHANNEL_LAYOUT_5_0_C:
1171         reorder_self_4_step_1(src, samples, samplesize, 5, 4, 3, 2, 1);
1172         break;
1173     case AF_CHANNEL_LAYOUT_5_0_B << 16 | AF_CHANNEL_LAYOUT_5_0_D:
1174         reorder_self_5_step_1(src, samples, samplesize, 5, 4, 3, 2, 1, 0);
1175         break;
1176     case AF_CHANNEL_LAYOUT_5_0_C << 16 | AF_CHANNEL_LAYOUT_5_0_A:
1177         reorder_self_2(src, samples, samplesize, 5, 1, 2);
1178         break;
1179     case AF_CHANNEL_LAYOUT_5_0_C << 16 | AF_CHANNEL_LAYOUT_5_0_B:
1180         reorder_self_4_step_1(src, samples, samplesize, 5, 1, 2, 3, 4);
1181         break;
1182     case AF_CHANNEL_LAYOUT_5_0_C << 16 | AF_CHANNEL_LAYOUT_5_0_D:
1183         reorder_self_2(src, samples, samplesize, 5, 0, 1);
1184         break;
1185     case AF_CHANNEL_LAYOUT_5_0_D << 16 | AF_CHANNEL_LAYOUT_5_0_A:
1186         reorder_self_3(src, samples, samplesize, 5, 0, 1, 2);
1187         break;
1188     case AF_CHANNEL_LAYOUT_5_0_D << 16 | AF_CHANNEL_LAYOUT_5_0_B:
1189         reorder_self_5_step_1(src, samples, samplesize, 5, 0, 1, 2, 3, 4);
1190         break;
1191     case AF_CHANNEL_LAYOUT_5_0_D << 16 | AF_CHANNEL_LAYOUT_5_0_C:
1192         reorder_self_2(src, samples, samplesize, 5, 0, 1);
1193         break;
1194     // AF_CHANNEL_LAYOUT_5_1_A   L R C LFE Ls Rs
1195     // AF_CHANNEL_LAYOUT_5_1_B   L R Ls Rs C LFE
1196     // AF_CHANNEL_LAYOUT_5_1_C   L C R Ls Rs LFE
1197     // AF_CHANNEL_LAYOUT_5_1_D   C L R Ls Rs LFE
1198     // AF_CHANNEL_LAYOUT_5_1_E   LFE L C R Ls Rs
1199     case AF_CHANNEL_LAYOUT_5_1_A << 16 | AF_CHANNEL_LAYOUT_5_1_B:
1200         if (samplesize != 3)
1201             reorder_self_2(src, samples/2, samplesize*2, 3, 1, 2);
1202         else
1203             reorder_self_4_step_2(src, samples, samplesize, 6, 2, 3, 4, 5);
1204         break;
1205     case AF_CHANNEL_LAYOUT_5_1_A << 16 | AF_CHANNEL_LAYOUT_5_1_C:
1206         reorder_self_2_3(src, samples, samplesize, 1, 2, 3, 4, 5);
1207         break;
1208     case AF_CHANNEL_LAYOUT_5_1_A << 16 | AF_CHANNEL_LAYOUT_5_1_D:
1209         reorder_self_3_3(src, samples, samplesize, 2, 1, 0, 3, 4, 5);
1210         break;
1211     case AF_CHANNEL_LAYOUT_5_1_B << 16 | AF_CHANNEL_LAYOUT_5_1_A:
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_B << 16 | AF_CHANNEL_LAYOUT_5_1_C:
1218         reorder_self_4_step_1(src, samples, samplesize, 6, 4, 3, 2, 1);
1219         break;
1220     case AF_CHANNEL_LAYOUT_5_1_B << 16 | AF_CHANNEL_LAYOUT_5_1_D:
1221         reorder_self_5_step_1(src, samples, samplesize, 6, 4, 3, 2, 1, 0);
1222         break;
1223     case AF_CHANNEL_LAYOUT_5_1_B << 16 | AF_CHANNEL_LAYOUT_5_1_E:
1224         reorder_self_2_4(src, samples, samplesize, 6, 2, 4, 5, 3, 1, 0);
1225         break;
1226     case AF_CHANNEL_LAYOUT_5_1_C << 16 | AF_CHANNEL_LAYOUT_5_1_A:
1227         reorder_self_2_3(src, samples, samplesize, 1, 2, 5, 4, 3);
1228         break;
1229     case AF_CHANNEL_LAYOUT_5_1_C << 16 | AF_CHANNEL_LAYOUT_5_1_B:
1230         reorder_self_4_step_1(src, samples, samplesize, 6, 1, 2, 3, 4);
1231         break;
1232     case AF_CHANNEL_LAYOUT_5_1_C << 16 | AF_CHANNEL_LAYOUT_5_1_D:
1233         reorder_self_2(src, samples, samplesize, 6, 0, 1);
1234         break;
1235     case AF_CHANNEL_LAYOUT_5_1_D << 16 | AF_CHANNEL_LAYOUT_5_1_A:
1236         reorder_self_3_3(src, samples, samplesize, 0, 1, 2, 5, 4, 3);
1237         break;
1238     case AF_CHANNEL_LAYOUT_5_1_D << 16 | AF_CHANNEL_LAYOUT_5_1_B:
1239         reorder_self_5_step_1(src, samples, samplesize, 6, 0, 1, 2, 3, 4);
1240         break;
1241     case AF_CHANNEL_LAYOUT_5_1_D << 16 | AF_CHANNEL_LAYOUT_5_1_C:
1242         reorder_self_2(src, samples, samplesize, 6, 0, 1);
1243         break;
1244     case AF_CHANNEL_LAYOUT_5_1_E << 16 | AF_CHANNEL_LAYOUT_5_1_B:
1245         reorder_self_2_4(src, samples, samplesize, 6, 2, 4, 0, 1, 3, 5);
1246         break;
1247     case AF_CHANNEL_LAYOUT_5_1_F << 16 | AF_CHANNEL_LAYOUT_5_1_B:
1248         reorder_self_2_4(src, samples, samplesize, 6, 3, 5, 0, 1, 2, 4);
1249         break;
1250     // AF_CHANNEL_LAYOUT_7_1_A   L R C LFE Ls Rs Rls Rrs
1251     // AF_CHANNEL_LAYOUT_7_1_B   L R Ls Rs C LFE Rls Rrs
1252     // AF_CHANNEL_LAYOUT_7_1_C   L C R Ls Rs LFE Rls Rrs
1253     // AF_CHANNEL_LAYOUT_7_1_F   C L R LFE Ls Rs Rls Rrs
1254     case AF_CHANNEL_LAYOUT_7_1_A << 16 | AF_CHANNEL_LAYOUT_7_1_B:
1255     case AF_CHANNEL_LAYOUT_7_1_B << 16 | AF_CHANNEL_LAYOUT_7_1_A:
1256         if (samplesize != 3)
1257             reorder_self_2(src, samples/2, samplesize*2, 4, 1, 2);
1258         else
1259             reorder_self_4_step_2(src, samples, samplesize, 8, 2, 3, 4, 5);
1260         break;
1261     case AF_CHANNEL_LAYOUT_7_1_C << 16 | AF_CHANNEL_LAYOUT_7_1_B:
1262         reorder_self_4_step_1(src, samples, samplesize, 8, 1, 2, 3, 4);
1263         break;
1264     case AF_CHANNEL_LAYOUT_7_1_F << 16 | AF_CHANNEL_LAYOUT_7_1_B:
1265         reorder_self_2_4(src, samples, samplesize, 8, 3, 5, 0, 1, 2, 4);
1266         break;
1267     default:
1268         mp_msg(MSGT_GLOBAL, MSGL_WARN,
1269                "[reorder_channel] unsupported from %x to %x, %d * %d\n",
1270                src_layout, dest_layout, samples, samplesize);
1271     }
1272 }
1273
1274
1275 static int channel_layout_mapping_5ch[AF_CHANNEL_LAYOUT_SOURCE_NUM] = {
1276     AF_CHANNEL_LAYOUT_ALSA_5CH_DEFAULT,
1277     AF_CHANNEL_LAYOUT_AAC_5CH_DEFAULT,
1278     AF_CHANNEL_LAYOUT_WAVEEX_5CH_DEFAULT,
1279     AF_CHANNEL_LAYOUT_LAVC_5CH_DEFAULT,
1280     AF_CHANNEL_LAYOUT_VORBIS_5CH_DEFAULT,
1281 };
1282
1283 static int channel_layout_mapping_6ch[AF_CHANNEL_LAYOUT_SOURCE_NUM] = {
1284     AF_CHANNEL_LAYOUT_ALSA_6CH_DEFAULT,
1285     AF_CHANNEL_LAYOUT_AAC_6CH_DEFAULT,
1286     AF_CHANNEL_LAYOUT_WAVEEX_6CH_DEFAULT,
1287     AF_CHANNEL_LAYOUT_LAVC_6CH_DEFAULT,
1288     AF_CHANNEL_LAYOUT_VORBIS_6CH_DEFAULT,
1289 };
1290
1291 static int channel_layout_mapping_8ch[AF_CHANNEL_LAYOUT_SOURCE_NUM] = {
1292     AF_CHANNEL_LAYOUT_ALSA_8CH_DEFAULT,
1293     AF_CHANNEL_LAYOUT_AAC_8CH_DEFAULT,
1294     AF_CHANNEL_LAYOUT_WAVEEX_8CH_DEFAULT,
1295     AF_CHANNEL_LAYOUT_LAVC_8CH_DEFAULT,
1296     AF_CHANNEL_LAYOUT_VORBIS_8CH_DEFAULT,
1297 };
1298
1299 void reorder_channel_copy_nch(void *src,
1300                               int src_layout,
1301                               void *dest,
1302                               int dest_layout,
1303                               int chnum,
1304                               int samples,
1305                               int samplesize)
1306 {
1307     if (chnum < 5 || chnum == 7 || chnum > 8 ||
1308             src_layout < 0 || dest_layout < 0 ||
1309             src_layout >= AF_CHANNEL_LAYOUT_SOURCE_NUM ||
1310             dest_layout >= AF_CHANNEL_LAYOUT_SOURCE_NUM)
1311         fast_memcpy(dest, src, samples*samplesize);
1312     else if (chnum == 6)
1313         reorder_channel_copy(src, channel_layout_mapping_6ch[src_layout],
1314                              dest, channel_layout_mapping_6ch[dest_layout],
1315                              samples, samplesize);
1316     else if (chnum == 8)
1317         reorder_channel_copy(src, channel_layout_mapping_8ch[src_layout],
1318                              dest, channel_layout_mapping_8ch[dest_layout],
1319                              samples, samplesize);
1320     else
1321         reorder_channel_copy(src, channel_layout_mapping_5ch[src_layout],
1322                              dest, channel_layout_mapping_5ch[dest_layout],
1323                              samples, samplesize);
1324 }
1325
1326 void reorder_channel_nch(void *buf,
1327                          int src_layout,
1328                          int dest_layout,
1329                          int chnum,
1330                          int samples,
1331                          int samplesize)
1332 {
1333     if (src_layout == dest_layout || chnum < 5 || chnum == 7 || chnum > 8 ||
1334             src_layout < 0 || dest_layout < 0 ||
1335             src_layout >= AF_CHANNEL_LAYOUT_SOURCE_NUM ||
1336             dest_layout >= AF_CHANNEL_LAYOUT_SOURCE_NUM ||
1337             src_layout == dest_layout)
1338         return;
1339     if (chnum == 6)
1340         reorder_channel(buf, channel_layout_mapping_6ch[src_layout],
1341                         channel_layout_mapping_6ch[dest_layout],
1342                         samples, samplesize);
1343     else if (chnum == 8)
1344         reorder_channel(buf, channel_layout_mapping_8ch[src_layout],
1345                         channel_layout_mapping_8ch[dest_layout],
1346                         samples, samplesize);
1347     else
1348         reorder_channel(buf, channel_layout_mapping_5ch[src_layout],
1349                         channel_layout_mapping_5ch[dest_layout],
1350                         samples, samplesize);
1351 }
1352
1353
1354 #ifdef TEST
1355
1356 static void test_copy(int channels) {
1357     int samples = 12*1024*1024;
1358     int samplesize = 2;
1359     int i;
1360     unsigned char *bufin = malloc((samples+100)*samplesize);
1361     unsigned char *bufout = malloc((samples+100)*samplesize);
1362     memset(bufin, 0xFF, samples*samplesize);
1363     for (i = 0;i < 100; ++i)
1364         reorder_channel_copy(bufin, AF_CHANNEL_LAYOUT_5_1_A,
1365                              bufout, AF_CHANNEL_LAYOUT_5_1_B,
1366                              samples, samplesize);
1367 //    reorder_channel(bufin, AF_CHANNEL_LAYOUT_5_1_B,
1368 //                         AF_CHANNEL_LAYOUT_5_1_D,
1369 //                         samples, samplesize);
1370     free(bufin);
1371     free(bufout);
1372 }
1373
1374 int main(int argc, char *argv[]) {
1375     int channels = 6;
1376     if (argc > 1)
1377         channels = atoi(argv[1]);
1378     test_copy(channels);
1379     return 0;
1380 }
1381
1382 #endif