Update to MPlayer SVN rev 29473 and FFmpeg SVN rev 19572.
[vaapi:athaifas-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; 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     }
89     case 4:
90     {
91         int32_t *dest_32 = dest;
92         const int32_t *src_32 = src;
93         REORDER_COPY_5(dest_32,src_32,samples,s0,s1,s2,s3,s4);
94         break;
95     }
96     case 8:
97     {
98         int64_t *dest_64 = dest;
99         const int64_t *src_64 = src;
100         REORDER_COPY_5(dest_64,src_64,samples,s0,s1,s2,s3,s4);
101         break;
102     }
103     default:
104         mp_msg(MSGT_GLOBAL, MSGL_WARN,
105                "[reorder_ch] Unsupported sample size: %d, please "
106                "report this error on the MPlayer mailing list.\n",samplesize);
107         return 0;
108     }
109     return 1;
110 }
111
112 #define REORDER_COPY_6(DEST,SRC,SAMPLES,S0,S1,S2,S3,S4,S5) \
113 for (i = 0; i < SAMPLES; i += 6) {\
114     DEST[i]   = SRC[i+S0];\
115     DEST[i+1] = SRC[i+S1];\
116     DEST[i+2] = SRC[i+S2];\
117     DEST[i+3] = SRC[i+S3];\
118     DEST[i+4] = SRC[i+S4];\
119     DEST[i+5] = SRC[i+S5];\
120 }
121
122 static int reorder_copy_6ch(void *dest, const void *src,
123                             unsigned int samples, uint8_t samplesize,
124                             int s0, int s1, int s2, int s3, int s4, int s5)
125 {
126     int i;
127     switch (samplesize) {
128     case 1:
129     {
130         int8_t *dest_8 = dest;
131         const int8_t *src_8 = src;
132         REORDER_COPY_6(dest_8,src_8,samples,s0,s1,s2,s3,s4,s5);
133         break;
134     }
135     case 2:
136     {
137         int16_t *dest_16 = dest;
138         const int16_t *src_16 = src;
139         REORDER_COPY_6(dest_16,src_16,samples,s0,s1,s2,s3,s4,s5);
140         break;
141     }
142     case 3:
143     {
144         int8_t *dest_8 = dest;
145         const int8_t *src_8 = src;
146         for (i = 0; i < samples; i += 18) {
147             dest_8[i]    = src_8[i+s0*3];
148             dest_8[i+1]  = src_8[i+s0*3+1];
149             dest_8[i+2]  = src_8[i+s0*3+2];
150             dest_8[i+3]  = src_8[i+s1*3];
151             dest_8[i+4]  = src_8[i+s1*3+1];
152             dest_8[i+5]  = src_8[i+s1*3+2];
153             dest_8[i+6]  = src_8[i+s2*3];
154             dest_8[i+7]  = src_8[i+s2*3+1];
155             dest_8[i+8]  = src_8[i+s2*3+2];
156             dest_8[i+9]  = src_8[i+s3*3];
157             dest_8[i+10] = src_8[i+s3*3+1];
158             dest_8[i+11] = src_8[i+s3*3+2];
159             dest_8[i+12] = src_8[i+s4*3];
160             dest_8[i+13] = src_8[i+s4*3+1];
161             dest_8[i+14] = src_8[i+s4*3+2];
162             dest_8[i+15] = src_8[i+s5*3];
163             dest_8[i+16] = src_8[i+s5*3+1];
164             dest_8[i+17] = src_8[i+s5*3+2];
165         }
166     }
167     case 4:
168     {
169         int32_t *dest_32 = dest;
170         const int32_t *src_32 = src;
171         REORDER_COPY_6(dest_32,src_32,samples,s0,s1,s2,s3,s4,s5);
172         break;
173     }
174     case 8:
175     {
176         int64_t *dest_64 = dest;
177         const int64_t *src_64 = src;
178         REORDER_COPY_6(dest_64,src_64,samples,s0,s1,s2,s3,s4,s5);
179         break;
180     }
181     default:
182         mp_msg(MSGT_GLOBAL, MSGL_WARN,
183                "[reorder_ch] Unsupported sample size: %d, please "
184                "report this error on the MPlayer mailing list.\n",samplesize);
185         return 0;
186     }
187     return 1;
188 }
189
190 void reorder_channel_copy(void *src,
191                           int src_layout,
192                           void *dest,
193                           int dest_layout,
194                           int samples,
195                           int samplesize)
196 {
197     if (dest_layout==src_layout) {
198         fast_memcpy(dest, src, samples*samplesize);
199         return;
200     }
201     if (!AF_IS_SAME_CH_NUM(dest_layout,src_layout)) {
202         mp_msg(MSGT_GLOBAL, MSGL_WARN, "[reorder_ch] different channel count "
203                "between src and dest: %x, %x\n",
204                AF_GET_CH_NUM_WITH_LFE(src_layout),
205                AF_GET_CH_NUM_WITH_LFE(dest_layout));
206         return;
207     }
208     switch ((src_layout<<16)|dest_layout) {
209     // AF_CHANNEL_LAYOUT_5_0_A   L R C Ls Rs
210     // AF_CHANNEL_LAYOUT_5_0_B   L R Ls Rs C
211     // AF_CHANNEL_LAYOUT_5_0_C   L C R Ls Rs
212     // AF_CHANNEL_LAYOUT_5_0_D   C L R Ls Rs
213     case AF_CHANNEL_LAYOUT_5_0_A << 16 | AF_CHANNEL_LAYOUT_5_0_B:
214         reorder_copy_5ch(dest, src, samples, samplesize, 0, 1, 3, 4, 2);
215         break;
216     case AF_CHANNEL_LAYOUT_5_0_A << 16 | AF_CHANNEL_LAYOUT_5_0_C:
217         reorder_copy_5ch(dest, src, samples, samplesize, 0, 2, 1, 3, 4);
218         break;
219     case AF_CHANNEL_LAYOUT_5_0_A << 16 | AF_CHANNEL_LAYOUT_5_0_D:
220         reorder_copy_5ch(dest, src, samples, samplesize, 2, 0, 1, 3, 4);
221         break;
222     case AF_CHANNEL_LAYOUT_5_0_B << 16 | AF_CHANNEL_LAYOUT_5_0_A:
223         reorder_copy_5ch(dest, src, samples, samplesize, 0, 1, 4, 2, 3);
224         break;
225     case AF_CHANNEL_LAYOUT_5_0_B << 16 | AF_CHANNEL_LAYOUT_5_0_C:
226         reorder_copy_5ch(dest, src, samples, samplesize, 0, 4, 1, 2, 3);
227         break;
228     case AF_CHANNEL_LAYOUT_5_0_B << 16 | AF_CHANNEL_LAYOUT_5_0_D:
229         reorder_copy_5ch(dest, src, samples, samplesize, 4, 0, 1, 2, 3);
230         break;
231     case AF_CHANNEL_LAYOUT_5_0_C << 16 | AF_CHANNEL_LAYOUT_5_0_A:
232         reorder_copy_5ch(dest, src, samples, samplesize, 0, 2, 1, 3, 4);
233         break;
234     case AF_CHANNEL_LAYOUT_5_0_C << 16 | AF_CHANNEL_LAYOUT_5_0_B:
235         reorder_copy_5ch(dest, src, samples, samplesize, 0, 2, 3, 4, 1);
236         break;
237     case AF_CHANNEL_LAYOUT_5_0_C << 16 | AF_CHANNEL_LAYOUT_5_0_D:
238         reorder_copy_5ch(dest, src, samples, samplesize, 1, 0, 2, 3, 4);
239         break;
240     case AF_CHANNEL_LAYOUT_5_0_D << 16 | AF_CHANNEL_LAYOUT_5_0_A:
241         reorder_copy_5ch(dest, src, samples, samplesize, 1, 2, 0, 3, 4);
242         break;
243     case AF_CHANNEL_LAYOUT_5_0_D << 16 | AF_CHANNEL_LAYOUT_5_0_B:
244         reorder_copy_5ch(dest, src, samples, samplesize, 1, 2, 3, 4, 0);
245         break;
246     case AF_CHANNEL_LAYOUT_5_0_D << 16 | AF_CHANNEL_LAYOUT_5_0_C:
247         reorder_copy_5ch(dest, src, samples, samplesize, 1, 0, 2, 3, 4);
248         break;
249     // AF_CHANNEL_LAYOUT_5_1_A   L R C LFE Ls Rs
250     // AF_CHANNEL_LAYOUT_5_1_B   L R Ls Rs C LFE
251     // AF_CHANNEL_LAYOUT_5_1_C   L C R Ls Rs LFE
252     // AF_CHANNEL_LAYOUT_5_1_D   C L R Ls Rs LFE
253     // AF_CHANNEL_LAYOUT_5_1_E   LFE L C R Ls Rs
254     case AF_CHANNEL_LAYOUT_5_1_A << 16 | AF_CHANNEL_LAYOUT_5_1_B:
255         reorder_copy_6ch(dest, src, samples, samplesize, 0, 1, 4, 5, 2, 3);
256         break;
257     case AF_CHANNEL_LAYOUT_5_1_A << 16 | AF_CHANNEL_LAYOUT_5_1_C:
258         reorder_copy_6ch(dest, src, samples, samplesize, 0, 2, 1, 4, 5, 3);
259         break;
260     case AF_CHANNEL_LAYOUT_5_1_A << 16 | AF_CHANNEL_LAYOUT_5_1_D:
261         reorder_copy_6ch(dest, src, samples, samplesize, 2, 0, 1, 4, 5, 3);
262         break;
263     case AF_CHANNEL_LAYOUT_5_1_B << 16 | AF_CHANNEL_LAYOUT_5_1_A:
264         reorder_copy_6ch(dest, src, samples, samplesize, 0, 1, 4, 5, 2, 3);
265         break;
266     case AF_CHANNEL_LAYOUT_5_1_B << 16 | AF_CHANNEL_LAYOUT_5_1_C:
267         reorder_copy_6ch(dest, src, samples, samplesize, 0, 4, 1, 2, 3, 5);
268         break;
269     case AF_CHANNEL_LAYOUT_5_1_B << 16 | AF_CHANNEL_LAYOUT_5_1_D:
270         reorder_copy_6ch(dest, src, samples, samplesize, 4, 0, 1, 2, 3, 5);
271         break;
272     case AF_CHANNEL_LAYOUT_5_1_B << 16 | AF_CHANNEL_LAYOUT_5_1_E:
273         reorder_copy_6ch(dest, src, samples, samplesize, 5, 0, 4, 1, 2, 3);
274         break;
275     case AF_CHANNEL_LAYOUT_5_1_C << 16 | AF_CHANNEL_LAYOUT_5_1_A:
276         reorder_copy_6ch(dest, src, samples, samplesize, 0, 2, 1, 5, 3, 4);
277         break;
278     case AF_CHANNEL_LAYOUT_5_1_C << 16 | AF_CHANNEL_LAYOUT_5_1_B:
279         reorder_copy_6ch(dest, src, samples, samplesize, 0, 2, 3, 4, 1, 5);
280         break;
281     case AF_CHANNEL_LAYOUT_5_1_C << 16 | AF_CHANNEL_LAYOUT_5_1_D:
282         reorder_copy_6ch(dest, src, samples, samplesize, 1, 0, 2, 3, 4, 5);
283         break;
284     case AF_CHANNEL_LAYOUT_5_1_D << 16 | AF_CHANNEL_LAYOUT_5_1_A:
285         reorder_copy_6ch(dest, src, samples, samplesize, 1, 2, 0, 5, 3, 4);
286         break;
287     case AF_CHANNEL_LAYOUT_5_1_D << 16 | AF_CHANNEL_LAYOUT_5_1_B:
288         reorder_copy_6ch(dest, src, samples, samplesize, 1, 2, 3, 4, 0, 5);
289         break;
290     case AF_CHANNEL_LAYOUT_5_1_D << 16 | AF_CHANNEL_LAYOUT_5_1_C:
291         reorder_copy_6ch(dest, src, samples, samplesize, 1, 0, 2, 3, 4, 5);
292         break;
293     case AF_CHANNEL_LAYOUT_5_1_E << 16 | AF_CHANNEL_LAYOUT_5_1_B:
294         reorder_copy_6ch(dest, src, samples, samplesize, 1, 3, 4, 5, 2, 0);
295         break;
296     default:
297         mp_msg(MSGT_GLOBAL, MSGL_WARN, "[reorder_channel_copy] unsupport "
298                "from %x to %x, %d * %d\n", src_layout, dest_layout,
299                samples, samplesize);
300         fast_memcpy(dest, src, samples*samplesize);
301     }
302 }
303
304
305 #define REORDER_SELF_SWAP_2(SRC,TMP,SAMPLES,CHNUM,S0,S1) \
306 for (i = 0; i < SAMPLES; i += CHNUM) {\
307     TMP = SRC[i+S0];\
308     SRC[i+S0] = SRC[i+S1];\
309     SRC[i+S1] = TMP;\
310 }
311
312 static int reorder_self_2(void *src, unsigned int samples,
313                           unsigned int samplesize, unsigned int chnum,
314                           int s0, int s1)
315 {
316     int i;
317     switch (samplesize) {
318     case 1:
319     {
320         int8_t *src_8 = src;
321         int8_t tmp;
322         if (chnum==6) {
323             REORDER_SELF_SWAP_2(src_8,tmp,samples,6,s0,s1);
324         }
325         else {
326             REORDER_SELF_SWAP_2(src_8,tmp,samples,5,s0,s1);
327         }
328         break;
329     }
330     case 2:
331     {
332         int16_t *src_16 = src;
333         int16_t tmp;
334         if (chnum==6) {
335             REORDER_SELF_SWAP_2(src_16,tmp,samples,6,s0,s1);
336         }
337         else if (chnum==3) {
338             REORDER_SELF_SWAP_2(src_16,tmp,samples,3,s0,s1);
339         }
340         else {
341             REORDER_SELF_SWAP_2(src_16,tmp,samples,5,s0,s1);
342         }
343         break;
344     }
345     case 3:
346     {
347         int8_t *src_8 = src;
348         int8_t tmp0, tmp1, tmp2;
349         for (i = 0; i < samples; i += chnum*3) {
350             tmp0 = src_8[i+s0*3];
351             tmp1 = src_8[i+s0*3+1];
352             tmp2 = src_8[i+s0*3+2];
353             src_8[i+s0*3]   = src_8[i+s1*3];
354             src_8[i+s0*3+1] = src_8[i+s1*3+1];
355             src_8[i+s0*3+2] = src_8[i+s1*3+2];
356             src_8[i+s1*3]   = tmp0;
357             src_8[i+s1*3+1] = tmp1;
358             src_8[i+s1*3+2] = tmp2;
359         }
360     }
361     case 4:
362     {
363         int32_t *src_32 = src;
364         int32_t tmp;
365         if (chnum==6) {
366             REORDER_SELF_SWAP_2(src_32,tmp,samples,6,s0,s1);
367         }
368         else if (chnum==3) {
369             REORDER_SELF_SWAP_2(src_32,tmp,samples,3,s0,s1);
370         }
371         else {
372             REORDER_SELF_SWAP_2(src_32,tmp,samples,5,s0,s1);
373         }
374         break;
375     }
376     case 8:
377     {
378         int64_t *src_64 = src;
379         int64_t tmp;
380         if (chnum==6) {
381             REORDER_SELF_SWAP_2(src_64,tmp,samples,6,s0,s1);
382         }
383         else if (chnum==3) {
384             REORDER_SELF_SWAP_2(src_64,tmp,samples,3,s0,s1);
385         }
386         else {
387             REORDER_SELF_SWAP_2(src_64,tmp,samples,5,s0,s1);
388         }
389         break;
390     }
391     default:
392         mp_msg(MSGT_GLOBAL, MSGL_WARN,
393                "[reorder_ch] Unsupported sample size: %d, please "
394                "report this error on the MPlayer mailing list.\n",samplesize);
395         return 0;
396     }
397     return 1;
398 }
399
400 #define REORDER_SELF_SWAP_3(SRC,TMP,SAMPLES,CHNUM,S0,S1,S2) \
401 for (i = 0; i < SAMPLES; i += CHNUM) {\
402     TMP = SRC[i+S0];\
403     SRC[i+S0] = SRC[i+S1];\
404     SRC[i+S1] = SRC[i+S2];\
405     SRC[i+S2] = TMP;\
406 }
407
408 static int reorder_self_3(void *src, unsigned int samples,
409                           unsigned int samplesize, unsigned int chnum,
410                           int s0, int s1, int s2)
411 {
412     int i;
413     switch (samplesize) {
414     case 1:
415     {
416         int8_t *src_8 = src;
417         int8_t tmp;
418         if (chnum==6) {
419             REORDER_SELF_SWAP_3(src_8,tmp,samples,6,s0,s1,s2);
420         }
421         else {
422             REORDER_SELF_SWAP_3(src_8,tmp,samples,5,s0,s1,s2);
423         }
424         break;
425     }
426     case 2:
427     {
428         int16_t *src_16 = src;
429         int16_t tmp;
430         if (chnum==6) {
431             REORDER_SELF_SWAP_3(src_16,tmp,samples,6,s0,s1,s2);
432         }
433         else {
434             REORDER_SELF_SWAP_3(src_16,tmp,samples,5,s0,s1,s2);
435         }
436         break;
437     }
438     case 3:
439     {
440         int8_t *src_8 = src;
441         int8_t tmp0, tmp1, tmp2;
442         for (i = 0; i < samples; i += chnum*3) {
443             tmp0 = src_8[i+s0*3];
444             tmp1 = src_8[i+s0*3+1];
445             tmp2 = src_8[i+s0*3+2];
446             src_8[i+s0*3]   = src_8[i+s1*3];
447             src_8[i+s0*3+1] = src_8[i+s1*3+1];
448             src_8[i+s0*3+2] = src_8[i+s1*3+2];
449             src_8[i+s1*3]   = src_8[i+s2*3];
450             src_8[i+s1*3+1] = src_8[i+s2*3+1];
451             src_8[i+s1*3+2] = src_8[i+s2*3+2];
452             src_8[i+s2*3]   = tmp0;
453             src_8[i+s2*3+1] = tmp1;
454             src_8[i+s2*3+2] = tmp2;
455         }
456         break;
457     }
458     case 4:
459     {
460         int32_t *src_32 = src;
461         int32_t tmp;
462         if (chnum==6) {
463             REORDER_SELF_SWAP_3(src_32,tmp,samples,6,s0,s1,s2);
464         }
465         else {
466             REORDER_SELF_SWAP_3(src_32,tmp,samples,5,s0,s1,s2);
467         }
468         break;
469     }
470     case 8:
471     {
472         int64_t *src_64 = src;
473         int64_t tmp;
474         if (chnum==6) {
475             REORDER_SELF_SWAP_3(src_64,tmp,samples,6,s0,s1,s2);
476         }
477         else {
478             REORDER_SELF_SWAP_3(src_64,tmp,samples,5,s0,s1,s2);
479         }
480         break;
481     }
482     default:
483         mp_msg(MSGT_GLOBAL, MSGL_WARN,
484                "[reorder_ch] Unsupported sample size: %d, please "
485                "report this error on the MPlayer mailing list.\n",samplesize);
486         return 0;
487     }
488     return 1;
489 }
490
491 #define REORDER_SELF_SWAP_4_STEP_1(SRC,TMP,SAMPLES,CHNUM,S0,S1,S2,S3) \
492 for (i = 0; i < SAMPLES; i += CHNUM) {\
493     TMP = SRC[i+S0];\
494     SRC[i+S0] = SRC[i+S1];\
495     SRC[i+S1] = SRC[i+S2];\
496     SRC[i+S2] = SRC[i+S3];\
497     SRC[i+S3] = TMP;\
498 }
499
500 static int reorder_self_4_step_1(void *src, unsigned int samples,
501                                  unsigned int samplesize, unsigned int chnum,
502                                  int s0, int s1, int s2, int s3)
503 {
504     int i;
505     switch (samplesize) {
506     case 1:
507     {
508         int8_t *src_8 = src;
509         int8_t tmp;
510         if (chnum==6) {
511             REORDER_SELF_SWAP_4_STEP_1(src_8,tmp,samples,6,s0,s1,s2,s3);
512         }
513         else {
514             REORDER_SELF_SWAP_4_STEP_1(src_8,tmp,samples,5,s0,s1,s2,s3);
515         }
516         break;
517     }
518     case 2:
519     {
520         int16_t *src_16 = src;
521         int16_t tmp;
522         if (chnum==6) {
523             REORDER_SELF_SWAP_4_STEP_1(src_16,tmp,samples,6,s0,s1,s2,s3);
524         }
525         else {
526             REORDER_SELF_SWAP_4_STEP_1(src_16,tmp,samples,5,s0,s1,s2,s3);
527         }
528         break;
529     }
530     case 3:
531     {
532         int8_t *src_8 = src;
533         int8_t tmp0, tmp1, tmp2;
534         for (i = 0; i < samples; i += chnum*3) {
535             tmp0 = src_8[i+s0*3];
536             tmp1 = src_8[i+s0*3+1];
537             tmp2 = src_8[i+s0*3+2];
538             src_8[i+s0*3]   = src_8[i+s1*3];
539             src_8[i+s0*3+1] = src_8[i+s1*3+1];
540             src_8[i+s0*3+2] = src_8[i+s1*3+2];
541             src_8[i+s1*3]   = src_8[i+s2*3];
542             src_8[i+s1*3+1] = src_8[i+s2*3+1];
543             src_8[i+s1*3+2] = src_8[i+s2*3+2];
544             src_8[i+s2*3]   = src_8[i+s3*3];
545             src_8[i+s2*3+1] = src_8[i+s3*3+1];
546             src_8[i+s2*3+2] = src_8[i+s3*3+2];
547             src_8[i+s3*3]   = tmp0;
548             src_8[i+s3*3+1] = tmp1;
549             src_8[i+s3*3+2] = tmp2;
550         }
551         break;
552     }
553     case 4:
554     {
555         int32_t *src_32 = src;
556         int32_t tmp;
557         if (chnum==6) {
558             REORDER_SELF_SWAP_4_STEP_1(src_32,tmp,samples,6,s0,s1,s2,s3);
559         }
560         else {
561             REORDER_SELF_SWAP_4_STEP_1(src_32,tmp,samples,5,s0,s1,s2,s3);
562         }
563         break;
564     }
565     case 8:
566     {
567         int64_t *src_64 = src;
568         int64_t tmp;
569         if (chnum==6) {
570             REORDER_SELF_SWAP_4_STEP_1(src_64,tmp,samples,6,s0,s1,s2,s3);
571         }
572         else {
573             REORDER_SELF_SWAP_4_STEP_1(src_64,tmp,samples,5,s0,s1,s2,s3);
574         }
575         break;
576     }
577     default:
578         mp_msg(MSGT_GLOBAL, MSGL_WARN,
579                "[reorder_ch] Unsupported sample size: %d, please "
580                "report this error on the MPlayer mailing list.\n",samplesize);
581         return 0;
582     }
583     return 1;
584 }
585
586 #define REORDER_SELF_SWAP_4_STEP_2(SRC,TMP,SAMPLES,CHNUM,S0,S1,S2,S3) \
587 for (i = 0; i < SAMPLES; i += CHNUM) {\
588     TMP = SRC[i+S0];\
589     SRC[i+S0] = SRC[i+S2];\
590     SRC[i+S2] = TMP;\
591     TMP = SRC[i+S1];\
592     SRC[i+S1] = SRC[i+S3];\
593     SRC[i+S3] = TMP;\
594 }
595
596 static int reorder_self_4_step_2(void *src, unsigned int samples,
597                                  unsigned int samplesize, unsigned int chnum,
598                                  int s0, int s1, int s2, int s3)
599 {
600     int i;
601     switch (samplesize) {
602     case 3:
603     {
604         int8_t *src_8 = src;
605         int8_t tmp0, tmp1, tmp2;
606         for (i = 0; i < samples; i += chnum*3) {
607             tmp0 = src_8[i+s0*3];
608             tmp1 = src_8[i+s0*3+1];
609             tmp2 = src_8[i+s0*3+2];
610             src_8[i+s0*3]   = src_8[i+s2*3];
611             src_8[i+s0*3+1] = src_8[i+s2*3+1];
612             src_8[i+s0*3+2] = src_8[i+s2*3+2];
613             src_8[i+s2*3]   = tmp0;
614             src_8[i+s2*3+1] = tmp1;
615             src_8[i+s2*3+2] = tmp2;
616             tmp0 = src_8[i+s1*3];
617             tmp1 = src_8[i+s1*3+1];
618             tmp2 = src_8[i+s1*3+2];
619             src_8[i+s1*3]   = src_8[i+s3*3];
620             src_8[i+s1*3+1] = src_8[i+s3*3+1];
621             src_8[i+s1*3+2] = src_8[i+s3*3+2];
622             src_8[i+s3*3]   = tmp0;
623             src_8[i+s3*3+1] = tmp1;
624             src_8[i+s3*3+2] = tmp2;
625         }
626     }
627     default:
628         mp_msg(MSGT_GLOBAL, MSGL_WARN,
629                "[reorder_ch] Unsupported sample size: %d, please "
630                "report this error on the MPlayer mailing list.\n",samplesize);
631         return 0;
632     }
633     return 1;
634 }
635
636 #define REORDER_SELF_SWAP_5_STEP_1(SRC,TMP,SAMPLES,CHNUM,S0,S1,S2,S3,S4) \
637 for (i = 0; i < SAMPLES; i += CHNUM) {\
638     TMP = SRC[i+S0];\
639     SRC[i+S0] = SRC[i+S1];\
640     SRC[i+S1] = SRC[i+S2];\
641     SRC[i+S2] = SRC[i+S3];\
642     SRC[i+S3] = SRC[i+S4];\
643     SRC[i+S4] = TMP;\
644 }
645
646 static int reorder_self_5_step_1(void *src, unsigned int samples,
647                                  unsigned int samplesize, unsigned int chnum,
648                                  int s0, int s1, int s2, int s3, int s4)
649 {
650     int i;
651     switch (samplesize) {
652     case 1:
653     {
654         int8_t *src_8 = src;
655         int8_t tmp;
656         if (chnum==6) {
657             REORDER_SELF_SWAP_5_STEP_1(src_8,tmp,samples,6,s0,s1,s2,s3,s4);
658         }
659         else {
660             REORDER_SELF_SWAP_5_STEP_1(src_8,tmp,samples,5,s0,s1,s2,s3,s4);
661         }
662         break;
663     }
664     case 2:
665     {
666         int16_t *src_16 = src;
667         int16_t tmp;
668         if (chnum==6) {
669             REORDER_SELF_SWAP_5_STEP_1(src_16,tmp,samples,6,s0,s1,s2,s3,s4);
670         }
671         else {
672             REORDER_SELF_SWAP_5_STEP_1(src_16,tmp,samples,5,s0,s1,s2,s3,s4);
673         }
674         break;
675     }
676     case 3:
677     {
678         int8_t *src_8 = src;
679         int8_t tmp0, tmp1, tmp2;
680         for (i = 0; i < samples; i += chnum*3) {
681             tmp0 = src_8[i+s0*3];
682             tmp1 = src_8[i+s0*3+1];
683             tmp2 = src_8[i+s0*3+2];
684             src_8[i+s0*3]   = src_8[i+s1*3];
685             src_8[i+s0*3+1] = src_8[i+s1*3+1];
686             src_8[i+s0*3+2] = src_8[i+s1*3+2];
687             src_8[i+s1*3]   = src_8[i+s2*3];
688             src_8[i+s1*3+1] = src_8[i+s2*3+1];
689             src_8[i+s1*3+2] = src_8[i+s2*3+2];
690             src_8[i+s2*3]   = src_8[i+s3*3];
691             src_8[i+s2*3+1] = src_8[i+s3*3+1];
692             src_8[i+s2*3+2] = src_8[i+s3*3+2];
693             src_8[i+s3*3]   = src_8[i+s4*3];
694             src_8[i+s3*3+1] = src_8[i+s4*3+1];
695             src_8[i+s3*3+2] = src_8[i+s4*3+2];
696             src_8[i+s4*3]   = tmp0;
697             src_8[i+s4*3+1] = tmp1;
698             src_8[i+s4*3+2] = tmp2;
699         }
700         break;
701     }
702     case 4:
703     {
704         int32_t *src_32 = src;
705         int32_t tmp;
706         if (chnum==6) {
707             REORDER_SELF_SWAP_5_STEP_1(src_32,tmp,samples,6,s0,s1,s2,s3,s4);
708         }
709         else {
710             REORDER_SELF_SWAP_5_STEP_1(src_32,tmp,samples,5,s0,s1,s2,s3,s4);
711         }
712         break;
713     }
714     case 8:
715     {
716         int64_t *src_64 = src;
717         int64_t tmp;
718         if (chnum==6) {
719             REORDER_SELF_SWAP_5_STEP_1(src_64,tmp,samples,6,s0,s1,s2,s3,s4);
720         }
721         else {
722             REORDER_SELF_SWAP_5_STEP_1(src_64,tmp,samples,5,s0,s1,s2,s3,s4);
723         }
724         break;
725     }
726     default:
727         mp_msg(MSGT_GLOBAL, MSGL_WARN,
728                "[reorder_ch] Unsupported sample size: %d, please "
729                "report this error on the MPlayer mailing list.\n",samplesize);
730         return 0;
731     }
732     return 1;
733 }
734
735 #define REORDER_SELF_SWAP_2_3(SRC,TMP,SAMPLES,CHNUM,S0,S1,S2,S3,S4) \
736 for (i = 0; i < SAMPLES; i += CHNUM) {\
737     TMP = SRC[i+S0];\
738     SRC[i+S0] = SRC[i+S1];\
739     SRC[i+S1] = TMP;\
740     TMP = SRC[i+S2];\
741     SRC[i+S2] = SRC[i+S3];\
742     SRC[i+S3] = SRC[i+S4];\
743     SRC[i+S4] = TMP;\
744 }
745
746 static int reorder_self_2_3(void *src, unsigned int samples,
747                             unsigned int samplesize,
748                             int s0, int s1, int s2, int s3, int s4)
749 {
750     int i;
751     switch (samplesize) {
752     case 1:
753     {
754         int8_t *src_8 = src;
755         int8_t tmp;
756         REORDER_SELF_SWAP_2_3(src_8,tmp,samples,6,s0,s1,s2,s3,s4);
757         break;
758     }
759     case 2:
760     {
761         int16_t *src_16 = src;
762         int16_t tmp;
763         REORDER_SELF_SWAP_2_3(src_16,tmp,samples,6,s0,s1,s2,s3,s4);
764         break;
765     }
766     case 3:
767     {
768         int8_t *src_8 = src;
769         int8_t tmp0, tmp1, tmp2;
770         for (i = 0; i < samples; i += 18) {
771             tmp0 = src_8[i+s0*3];
772             tmp1 = src_8[i+s0*3+1];
773             tmp2 = src_8[i+s0*3+2];
774             src_8[i+s0*3]   = src_8[i+s1*3];
775             src_8[i+s0*3+1] = src_8[i+s1*3+1];
776             src_8[i+s0*3+2] = src_8[i+s1*3+2];
777             src_8[i+s1*3]   = tmp0;
778             src_8[i+s1*3+1] = tmp1;
779             src_8[i+s1*3+2] = tmp2;
780             tmp0 = src_8[i+s2*3];
781             tmp1 = src_8[i+s2*3+1];
782             tmp2 = src_8[i+s2*3+2];
783             src_8[i+s2*3]   = src_8[i+s3*3];
784             src_8[i+s2*3+1] = src_8[i+s3*3+1];
785             src_8[i+s2*3+2] = src_8[i+s3*3+2];
786             src_8[i+s3*3]   = src_8[i+s4*3];
787             src_8[i+s3*3+1] = src_8[i+s4*3+1];
788             src_8[i+s3*3+2] = src_8[i+s4*3+2];
789             src_8[i+s4*3]   = tmp0;
790             src_8[i+s4*3+1] = tmp1;
791             src_8[i+s4*3+2] = tmp2;
792         }
793         break;
794     }
795     case 4:
796     {
797         int32_t *src_32 = src;
798         int32_t tmp;
799         REORDER_SELF_SWAP_2_3(src_32,tmp,samples,6,s0,s1,s2,s3,s4);
800         break;
801     }
802     case 8:
803     {
804         int64_t *src_64 = src;
805         int64_t tmp;
806         REORDER_SELF_SWAP_2_3(src_64,tmp,samples,6,s0,s1,s2,s3,s4);
807         break;
808     }
809     default:
810         mp_msg(MSGT_GLOBAL, MSGL_WARN,
811                "[reorder_ch] Unsupported sample size: %d, please "
812                "report this error on the MPlayer mailing list.\n",samplesize);
813         return 0;
814     }
815     return 1;
816 }
817
818 #define REORDER_SELF_SWAP_3_3(SRC,TMP,SAMPLES,CHNUM,S0,S1,S2,S3,S4,S5) \
819 for (i = 0; i < SAMPLES; i += CHNUM) {\
820     TMP = SRC[i+S0];\
821     SRC[i+S0] = SRC[i+S1];\
822     SRC[i+S1] = SRC[i+S2];\
823     SRC[i+S2] = TMP;\
824     TMP = SRC[i+S3];\
825     SRC[i+S3] = SRC[i+S4];\
826     SRC[i+S4] = SRC[i+S5];\
827     SRC[i+S5] = TMP;\
828 }
829
830 static int reorder_self_3_3(void *src, unsigned int samples,
831                             unsigned int samplesize,
832                             int s0, int s1, int s2, int s3, int s4, int s5)
833 {
834     int i;
835     switch (samplesize) {
836     case 1:
837     {
838         int8_t *src_8 = src;
839         int8_t tmp;
840         REORDER_SELF_SWAP_3_3(src_8,tmp,samples,6,s0,s1,s2,s3,s4,s5);
841         break;
842     }
843     case 2:
844     {
845         int16_t *src_16 = src;
846         int16_t tmp;
847         REORDER_SELF_SWAP_3_3(src_16,tmp,samples,6,s0,s1,s2,s3,s4,s5);
848         break;
849     }
850     case 3:
851     {
852         int8_t *src_8 = src;
853         int8_t tmp0, tmp1, tmp2;
854         for (i = 0; i < samples; i += 18) {
855             tmp0 = src_8[i+s0*3];
856             tmp1 = src_8[i+s0*3+1];
857             tmp2 = src_8[i+s0*3+2];
858             src_8[i+s0*3]   = src_8[i+s1*3];
859             src_8[i+s0*3+1] = src_8[i+s1*3+1];
860             src_8[i+s0*3+2] = src_8[i+s1*3+2];
861             src_8[i+s1*3]   = src_8[i+s2*3];
862             src_8[i+s1*3+1] = src_8[i+s2*3+1];
863             src_8[i+s1*3+2] = src_8[i+s2*3+2];
864             src_8[i+s2*3]   = tmp0;
865             src_8[i+s2*3+1] = tmp1;
866             src_8[i+s2*3+2] = tmp2;
867             tmp0 = src_8[i+s3*3];
868             tmp1 = src_8[i+s3*3+1];
869             tmp2 = src_8[i+s3*3+2];
870             src_8[i+s3*3]   = src_8[i+s4*3];
871             src_8[i+s3*3+1] = src_8[i+s4*3+1];
872             src_8[i+s3*3+2] = src_8[i+s4*3+2];
873             src_8[i+s4*3]   = src_8[i+s5*3];
874             src_8[i+s4*3+1] = src_8[i+s5*3+1];
875             src_8[i+s4*3+2] = src_8[i+s5*3+2];
876             src_8[i+s5*3]   = tmp0;
877             src_8[i+s5*3+1] = tmp1;
878             src_8[i+s5*3+2] = tmp2;
879         }
880         break;
881     }
882     case 4:
883     {
884         int32_t *src_32 = src;
885         int32_t tmp;
886         REORDER_SELF_SWAP_3_3(src_32,tmp,samples,6,s0,s1,s2,s3,s4,s5);
887         break;
888     }
889     case 8:
890     {
891         int64_t *src_64 = src;
892         int64_t tmp;
893         REORDER_SELF_SWAP_3_3(src_64,tmp,samples,6,s0,s1,s2,s3,s4,s5);
894         break;
895     }
896     default:
897         mp_msg(MSGT_GLOBAL, MSGL_WARN,
898                "[reorder_ch] Unsupported sample size: %d, please "
899                "report this error on the MPlayer mailing list.\n",samplesize);
900         return 0;
901     }
902     return 1;
903 }
904
905 #define REORDER_SELF_SWAP_2_4(SRC,TMP,SAMPLES,CHNUM,S0,S1,S2,S3,S4,S5) \
906 for (i = 0; i < SAMPLES; i += CHNUM) {\
907     TMP = SRC[i+S0];\
908     SRC[i+S0] = SRC[i+S1];\
909     SRC[i+S1] = TMP;\
910     TMP = SRC[i+S2];\
911     SRC[i+S2] = SRC[i+S3];\
912     SRC[i+S3] = SRC[i+S4];\
913     SRC[i+S4] = SRC[i+S5];\
914     SRC[i+S5] = TMP;\
915 }
916
917 static int reorder_self_2_4(void *src, unsigned int samples,
918                             unsigned int samplesize,
919                             int s0, int s1, int s2, int s3, int s4, int s5)
920 {
921     int i;
922     switch (samplesize) {
923     case 1:
924     {
925         int8_t *src_8 = src;
926         int8_t tmp;
927         REORDER_SELF_SWAP_2_4(src_8,tmp,samples,6,s0,s1,s2,s3,s4,s5);
928         break;
929     }
930     case 2:
931     {
932         int16_t *src_16 = src;
933         int16_t tmp;
934         REORDER_SELF_SWAP_2_4(src_16,tmp,samples,6,s0,s1,s2,s3,s4,s5);
935         break;
936     }
937     case 3:
938     {
939         int8_t *src_8 = src;
940         int8_t tmp0, tmp1, tmp2;
941         for (i = 0; i < samples; i += 18) {
942             tmp0 = src_8[i+s0*3];
943             tmp1 = src_8[i+s0*3+1];
944             tmp2 = src_8[i+s0*3+2];
945             src_8[i+s0*3]   = src_8[i+s1*3];
946             src_8[i+s0*3+1] = src_8[i+s1*3+1];
947             src_8[i+s0*3+2] = src_8[i+s1*3+2];
948             src_8[i+s1*3]   = tmp0;
949             src_8[i+s1*3+1] = tmp1;
950             src_8[i+s1*3+2] = tmp2;
951             tmp0 = src_8[i+s2*3];
952             tmp1 = src_8[i+s2*3+1];
953             tmp2 = src_8[i+s2*3+2];
954             src_8[i+s2*3]   = src_8[i+s3*3];
955             src_8[i+s2*3+1] = src_8[i+s3*3+1];
956             src_8[i+s2*3+2] = src_8[i+s3*3+2];
957             src_8[i+s3*3]   = src_8[i+s4*3];
958             src_8[i+s3*3+1] = src_8[i+s4*3+1];
959             src_8[i+s3*3+2] = src_8[i+s4*3+2];
960             src_8[i+s4*3]   = src_8[i+s5*3];
961             src_8[i+s4*3+1] = src_8[i+s5*3+1];
962             src_8[i+s4*3+2] = src_8[i+s5*3+2];
963             src_8[i+s5*3]   = tmp0;
964             src_8[i+s5*3+1] = tmp1;
965             src_8[i+s5*3+2] = tmp2;
966         }
967         break;
968     }
969     case 4:
970     {
971         int32_t *src_32 = src;
972         int32_t tmp;
973         REORDER_SELF_SWAP_2_4(src_32,tmp,samples,6,s0,s1,s2,s3,s4,s5);
974         break;
975     }
976     case 8:
977     {
978         int64_t *src_64 = src;
979         int64_t tmp;
980         REORDER_SELF_SWAP_2_4(src_64,tmp,samples,6,s0,s1,s2,s3,s4,s5);
981         break;
982     }
983     default:
984         mp_msg(MSGT_GLOBAL, MSGL_WARN,
985                "[reorder_ch] Unsupported sample size: %d, please "
986                "report this error on the MPlayer mailing list.\n",samplesize);
987         return 0;
988     }
989     return 1;
990 }
991
992 void reorder_channel(void *src,
993                      int src_layout,
994                      int dest_layout,
995                      int samples,
996                      int samplesize)
997 {
998     if (dest_layout==src_layout)
999         return;
1000     if (!AF_IS_SAME_CH_NUM(dest_layout,src_layout)) {
1001         mp_msg(MSGT_GLOBAL, MSGL_WARN,
1002                "[reorder_channel] different channel count "
1003                "between current and target: %x, %x\n",
1004                AF_GET_CH_NUM_WITH_LFE(src_layout),
1005                AF_GET_CH_NUM_WITH_LFE(dest_layout));
1006         return;
1007     }
1008     switch ((src_layout<<16)|dest_layout) {
1009     // AF_CHANNEL_LAYOUT_5_0_A   L R C Ls Rs
1010     // AF_CHANNEL_LAYOUT_5_0_B   L R Ls Rs C
1011     // AF_CHANNEL_LAYOUT_5_0_C   L C R Ls Rs
1012     // AF_CHANNEL_LAYOUT_5_0_D   C L R Ls Rs
1013     case AF_CHANNEL_LAYOUT_5_0_A << 16 | AF_CHANNEL_LAYOUT_5_0_B:
1014         reorder_self_3(src, samples, samplesize, 5, 2, 3, 4);
1015         break;
1016     case AF_CHANNEL_LAYOUT_5_0_A << 16 | AF_CHANNEL_LAYOUT_5_0_C:
1017         reorder_self_2(src, samples, samplesize, 5, 1, 2);
1018         break;
1019     case AF_CHANNEL_LAYOUT_5_0_A << 16 | AF_CHANNEL_LAYOUT_5_0_D:
1020         reorder_self_3(src, samples, samplesize, 5, 2, 1, 0);
1021         break;
1022     case AF_CHANNEL_LAYOUT_5_0_B << 16 | AF_CHANNEL_LAYOUT_5_0_A:
1023         reorder_self_3(src, samples, samplesize, 5, 4, 3, 2);
1024         break;
1025     case AF_CHANNEL_LAYOUT_5_0_B << 16 | AF_CHANNEL_LAYOUT_5_0_C:
1026         reorder_self_4_step_1(src, samples, samplesize, 5, 4, 3, 2, 1);
1027         break;
1028     case AF_CHANNEL_LAYOUT_5_0_B << 16 | AF_CHANNEL_LAYOUT_5_0_D:
1029         reorder_self_5_step_1(src, samples, samplesize, 5, 4, 3, 2, 1, 0);
1030         break;
1031     case AF_CHANNEL_LAYOUT_5_0_C << 16 | AF_CHANNEL_LAYOUT_5_0_A:
1032         reorder_self_2(src, samples, samplesize, 5, 1, 2);
1033         break;
1034     case AF_CHANNEL_LAYOUT_5_0_C << 16 | AF_CHANNEL_LAYOUT_5_0_B:
1035         reorder_self_4_step_1(src, samples, samplesize, 5, 1, 2, 3, 4);
1036         break;
1037     case AF_CHANNEL_LAYOUT_5_0_C << 16 | AF_CHANNEL_LAYOUT_5_0_D:
1038         reorder_self_2(src, samples, samplesize, 5, 0, 1);
1039         break;
1040     case AF_CHANNEL_LAYOUT_5_0_D << 16 | AF_CHANNEL_LAYOUT_5_0_A:
1041         reorder_self_3(src, samples, samplesize, 5, 0, 1, 2);
1042         break;
1043     case AF_CHANNEL_LAYOUT_5_0_D << 16 | AF_CHANNEL_LAYOUT_5_0_B:
1044         reorder_self_5_step_1(src, samples, samplesize, 5, 0, 1, 2, 3, 4);
1045         break;
1046     case AF_CHANNEL_LAYOUT_5_0_D << 16 | AF_CHANNEL_LAYOUT_5_0_C:
1047         reorder_self_2(src, samples, samplesize, 5, 0, 1);
1048         break;
1049     // AF_CHANNEL_LAYOUT_5_1_A   L R C LFE Ls Rs
1050     // AF_CHANNEL_LAYOUT_5_1_B   L R Ls Rs C LFE
1051     // AF_CHANNEL_LAYOUT_5_1_C   L C R Ls Rs LFE
1052     // AF_CHANNEL_LAYOUT_5_1_D   C L R Ls Rs LFE
1053     // AF_CHANNEL_LAYOUT_5_1_E   LFE L C R Ls Rs
1054     case AF_CHANNEL_LAYOUT_5_1_A << 16 | AF_CHANNEL_LAYOUT_5_1_B:
1055         if (samplesize != 3)
1056             reorder_self_2(src, samples/2, samplesize*2, 3, 1, 2);
1057         else
1058             reorder_self_4_step_2(src, samples, samplesize, 6, 2, 3, 4, 5);
1059         break;
1060     case AF_CHANNEL_LAYOUT_5_1_A << 16 | AF_CHANNEL_LAYOUT_5_1_C:
1061         reorder_self_2_3(src, samples, samplesize, 1, 2, 3, 4, 5);
1062         break;
1063     case AF_CHANNEL_LAYOUT_5_1_A << 16 | AF_CHANNEL_LAYOUT_5_1_D:
1064         reorder_self_3_3(src, samples, samplesize, 2, 1, 0, 3, 4, 5);
1065         break;
1066     case AF_CHANNEL_LAYOUT_5_1_B << 16 | AF_CHANNEL_LAYOUT_5_1_A:
1067         if (samplesize != 3)
1068             reorder_self_2(src, samples/2, samplesize*2, 3, 1, 2);
1069         else
1070             reorder_self_4_step_2(src, samples, samplesize, 6, 2, 3, 4, 5);
1071         break;
1072     case AF_CHANNEL_LAYOUT_5_1_B << 16 | AF_CHANNEL_LAYOUT_5_1_C:
1073         reorder_self_4_step_1(src, samples, samplesize, 6, 4, 3, 2, 1);
1074         break;
1075     case AF_CHANNEL_LAYOUT_5_1_B << 16 | AF_CHANNEL_LAYOUT_5_1_D:
1076         reorder_self_5_step_1(src, samples, samplesize, 6, 4, 3, 2, 1, 0);
1077         break;
1078     case AF_CHANNEL_LAYOUT_5_1_B << 16 | AF_CHANNEL_LAYOUT_5_1_E:
1079         reorder_self_2_4(src, samples, samplesize, 2, 4, 5, 3, 1, 0);
1080         break;
1081     case AF_CHANNEL_LAYOUT_5_1_C << 16 | AF_CHANNEL_LAYOUT_5_1_A:
1082         reorder_self_2_3(src, samples, samplesize, 1, 2, 5, 4, 3);
1083         break;
1084     case AF_CHANNEL_LAYOUT_5_1_C << 16 | AF_CHANNEL_LAYOUT_5_1_B:
1085         reorder_self_4_step_1(src, samples, samplesize, 6, 1, 2, 3, 4);
1086         break;
1087     case AF_CHANNEL_LAYOUT_5_1_C << 16 | AF_CHANNEL_LAYOUT_5_1_D:
1088         reorder_self_2(src, samples, samplesize, 6, 0, 1);
1089         break;
1090     case AF_CHANNEL_LAYOUT_5_1_D << 16 | AF_CHANNEL_LAYOUT_5_1_A:
1091         reorder_self_3_3(src, samples, samplesize, 0, 1, 2, 5, 4, 3);
1092         break;
1093     case AF_CHANNEL_LAYOUT_5_1_D << 16 | AF_CHANNEL_LAYOUT_5_1_B:
1094         reorder_self_5_step_1(src, samples, samplesize, 6, 0, 1, 2, 3, 4);
1095         break;
1096     case AF_CHANNEL_LAYOUT_5_1_D << 16 | AF_CHANNEL_LAYOUT_5_1_C:
1097         reorder_self_2(src, samples, samplesize, 6, 0, 1);
1098         break;
1099     case AF_CHANNEL_LAYOUT_5_1_E << 16 | AF_CHANNEL_LAYOUT_5_1_B:
1100         reorder_self_2_4(src, samples, samplesize, 2, 4, 0, 1, 3, 5);
1101         break;
1102     default:
1103         mp_msg(MSGT_GLOBAL, MSGL_WARN,
1104                "[reorder_channel] unsupported from %x to %x, %d * %d\n",
1105                src_layout, dest_layout, samples, samplesize);
1106     }
1107 }
1108
1109
1110 static int channel_layout_mapping_5ch[AF_CHANNEL_LAYOUT_SOURCE_NUM] = {
1111     AF_CHANNEL_LAYOUT_ALSA_5CH_DEFAULT,
1112     AF_CHANNEL_LAYOUT_AAC_5CH_DEFAULT,
1113     AF_CHANNEL_LAYOUT_WAVEEX_5CH_DEFAULT,
1114     AF_CHANNEL_LAYOUT_LAVC_AC3_5CH_DEFAULT,
1115     AF_CHANNEL_LAYOUT_LAVC_LIBA52_5CH_DEFAULT,
1116     AF_CHANNEL_LAYOUT_LAVC_DCA_5CH_DEFAULT,
1117     AF_CHANNEL_LAYOUT_VORBIS_5CH_DEFAULT,
1118     AF_CHANNEL_LAYOUT_FLAC_5CH_DEFAULT,
1119 };
1120
1121 static int channel_layout_mapping_6ch[AF_CHANNEL_LAYOUT_SOURCE_NUM] = {
1122     AF_CHANNEL_LAYOUT_ALSA_6CH_DEFAULT,
1123     AF_CHANNEL_LAYOUT_AAC_6CH_DEFAULT,
1124     AF_CHANNEL_LAYOUT_WAVEEX_6CH_DEFAULT,
1125     AF_CHANNEL_LAYOUT_LAVC_AC3_6CH_DEFAULT,
1126     AF_CHANNEL_LAYOUT_LAVC_LIBA52_6CH_DEFAULT,
1127     AF_CHANNEL_LAYOUT_LAVC_DCA_6CH_DEFAULT,
1128     AF_CHANNEL_LAYOUT_VORBIS_6CH_DEFAULT,
1129     AF_CHANNEL_LAYOUT_FLAC_6CH_DEFAULT,
1130 };
1131
1132 void reorder_channel_copy_nch(void *src,
1133                               int src_layout,
1134                               void *dest,
1135                               int dest_layout,
1136                               int chnum,
1137                               int samples,
1138                               int samplesize)
1139 {
1140     if (chnum < 5 || chnum > 6 || src_layout < 0 || dest_layout < 0 ||
1141             src_layout >= AF_CHANNEL_LAYOUT_SOURCE_NUM ||
1142             dest_layout >= AF_CHANNEL_LAYOUT_SOURCE_NUM)
1143         fast_memcpy(dest, src, samples*samplesize);
1144     else if (chnum == 6)
1145         reorder_channel_copy(src, channel_layout_mapping_6ch[src_layout],
1146                              dest, channel_layout_mapping_6ch[dest_layout],
1147                              samples, samplesize);
1148     else
1149         reorder_channel_copy(src, channel_layout_mapping_5ch[src_layout],
1150                              dest, channel_layout_mapping_5ch[dest_layout],
1151                              samples, samplesize);
1152 }
1153
1154 void reorder_channel_nch(void *buf,
1155                          int src_layout,
1156                          int dest_layout,
1157                          int chnum,
1158                          int samples,
1159                          int samplesize)
1160 {
1161     if (src_layout == dest_layout || chnum < 5 || chnum > 6 ||
1162             src_layout < 0 || dest_layout < 0 ||
1163             src_layout >= AF_CHANNEL_LAYOUT_SOURCE_NUM ||
1164             dest_layout >= AF_CHANNEL_LAYOUT_SOURCE_NUM ||
1165             src_layout == dest_layout)
1166         return;
1167     if (chnum == 6)
1168         reorder_channel(buf, channel_layout_mapping_6ch[src_layout],
1169                         channel_layout_mapping_6ch[dest_layout],
1170                         samples, samplesize);
1171     else
1172         reorder_channel(buf, channel_layout_mapping_5ch[src_layout],
1173                         channel_layout_mapping_5ch[dest_layout],
1174                         samples, samplesize);
1175 }
1176
1177
1178 #ifdef TEST
1179
1180 static void test_copy(int channels) {
1181     int samples = 12*1024*1024;
1182     int samplesize = 2;
1183     int i;
1184     unsigned char *bufin = malloc((samples+100)*samplesize);
1185     unsigned char *bufout = malloc((samples+100)*samplesize);
1186     memset(bufin, 0xFF, samples*samplesize);
1187     for (i = 0;i < 100; ++i)
1188         reorder_channel_copy(bufin, AF_CHANNEL_LAYOUT_5_1_A,
1189                              bufout, AF_CHANNEL_LAYOUT_5_1_B,
1190                              samples, samplesize);
1191 //    reorder_channel(bufin, AF_CHANNEL_LAYOUT_5_1_B,
1192 //                         AF_CHANNEL_LAYOUT_5_1_D,
1193 //                         samples, samplesize);
1194     free(bufin);
1195     free(bufout);
1196 }
1197
1198 int main(int argc, char *argv[]) {
1199     int channels = 6;
1200     if (argc > 1)
1201         channels = atoi(argv[1]);
1202     test_copy(channels);
1203     return 0;
1204 }
1205
1206 #endif
1207