Ignore svn changes up to r30255
[mplayer/glamo.git] / libaf / reorder_ch.c
blob5a6a1d9d93fd0599cd91b31d3a651229991349e6
1 /*
2 * common functions for reordering audio channels
4 * Copyright (C) 2007 Ulion <ulion A gmail P com>
6 * This file is part of MPlayer.
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.
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.
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.
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <inttypes.h>
26 #include <string.h>
27 #include "libvo/fastmemcpy.h"
29 #include "reorder_ch.h"
31 #ifdef TEST
32 #define mp_msg(mod,lev, fmt, args... ) printf( fmt, ## args )
33 #else
34 #include "mp_msg.h"
35 #endif
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];\
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)
51 int i;
52 switch (samplesize) {
53 case 1:
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;
60 case 2:
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;
67 case 3:
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];
88 break;
90 case 4:
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;
97 case 8:
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;
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;
110 return 1;
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];\
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)
127 int i;
128 switch (samplesize) {
129 case 1:
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;
136 case 2:
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;
143 case 3:
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];
167 break;
169 case 4:
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;
176 case 8:
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;
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;
189 return 1;
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];\
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)
209 int i;
210 switch (samplesize) {
211 case 1:
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;
218 case 2:
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;
225 case 3:
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];
255 break;
257 case 4:
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;
264 case 8:
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;
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;
277 return 1;
280 void reorder_channel_copy(void *src,
281 int src_layout,
282 void *dest,
283 int dest_layout,
284 int samples,
285 int samplesize)
287 if (dest_layout==src_layout) {
288 fast_memcpy(dest, src, samples*samplesize);
289 return;
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;
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);
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;\
415 static int reorder_self_2(void *src, unsigned int samples,
416 unsigned int samplesize, unsigned int chnum,
417 int s0, int s1)
419 int i;
420 switch (samplesize) {
421 case 1:
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);
428 else if (chnum==8) {
429 REORDER_SELF_SWAP_2(src_8,tmp,samples,8,s0,s1);
431 else {
432 REORDER_SELF_SWAP_2(src_8,tmp,samples,5,s0,s1);
434 break;
436 case 2:
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);
443 else if (chnum==3) {
444 REORDER_SELF_SWAP_2(src_16,tmp,samples,3,s0,s1);
446 else if (chnum==4) {
447 REORDER_SELF_SWAP_2(src_16,tmp,samples,3,s0,s1);
449 else {
450 REORDER_SELF_SWAP_2(src_16,tmp,samples,5,s0,s1);
452 break;
454 case 3:
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;
469 break;
471 case 4:
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);
478 else if (chnum==3) {
479 REORDER_SELF_SWAP_2(src_32,tmp,samples,3,s0,s1);
481 else if (chnum==4) {
482 REORDER_SELF_SWAP_2(src_32,tmp,samples,4,s0,s1);
484 else {
485 REORDER_SELF_SWAP_2(src_32,tmp,samples,5,s0,s1);
487 break;
489 case 8:
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);
496 else if (chnum==3) {
497 REORDER_SELF_SWAP_2(src_64,tmp,samples,3,s0,s1);
499 else if (chnum==4) {
500 REORDER_SELF_SWAP_2(src_64,tmp,samples,4,s0,s1);
502 else {
503 REORDER_SELF_SWAP_2(src_64,tmp,samples,5,s0,s1);
505 break;
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;
513 return 1;
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;\
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)
528 int i;
529 switch (samplesize) {
530 case 1:
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);
537 else {
538 REORDER_SELF_SWAP_3(src_8,tmp,samples,5,s0,s1,s2);
540 break;
542 case 2:
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);
549 else {
550 REORDER_SELF_SWAP_3(src_16,tmp,samples,5,s0,s1,s2);
552 break;
554 case 3:
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;
572 break;
574 case 4:
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);
581 else {
582 REORDER_SELF_SWAP_3(src_32,tmp,samples,5,s0,s1,s2);
584 break;
586 case 8:
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);
593 else {
594 REORDER_SELF_SWAP_3(src_64,tmp,samples,5,s0,s1,s2);
596 break;
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;
604 return 1;
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;\
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)
620 int i;
621 switch (samplesize) {
622 case 1:
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);
629 else if (chnum==8) {
630 REORDER_SELF_SWAP_4_STEP_1(src_8,tmp,samples,8,s0,s1,s2,s3);
632 else {
633 REORDER_SELF_SWAP_4_STEP_1(src_8,tmp,samples,5,s0,s1,s2,s3);
635 break;
637 case 2:
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);
644 else if (chnum==8) {
645 REORDER_SELF_SWAP_4_STEP_1(src_16,tmp,samples,8,s0,s1,s2,s3);
647 else {
648 REORDER_SELF_SWAP_4_STEP_1(src_16,tmp,samples,5,s0,s1,s2,s3);
650 break;
652 case 3:
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;
673 break;
675 case 4:
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);
682 else if (chnum==8) {
683 REORDER_SELF_SWAP_4_STEP_1(src_32,tmp,samples,8,s0,s1,s2,s3);
685 else {
686 REORDER_SELF_SWAP_4_STEP_1(src_32,tmp,samples,5,s0,s1,s2,s3);
688 break;
690 case 8:
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);
697 else if (chnum==8) {
698 REORDER_SELF_SWAP_4_STEP_1(src_64,tmp,samples,8,s0,s1,s2,s3);
700 else {
701 REORDER_SELF_SWAP_4_STEP_1(src_64,tmp,samples,5,s0,s1,s2,s3);
703 break;
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;
711 return 1;
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;\
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)
728 int i;
729 switch (samplesize) {
730 case 3:
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;
754 break;
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;
762 return 1;
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;\
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)
779 int i;
780 switch (samplesize) {
781 case 1:
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);
788 else {
789 REORDER_SELF_SWAP_5_STEP_1(src_8,tmp,samples,5,s0,s1,s2,s3,s4);
791 break;
793 case 2:
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);
800 else {
801 REORDER_SELF_SWAP_5_STEP_1(src_16,tmp,samples,5,s0,s1,s2,s3,s4);
803 break;
805 case 3:
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;
829 break;
831 case 4:
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);
838 else {
839 REORDER_SELF_SWAP_5_STEP_1(src_32,tmp,samples,5,s0,s1,s2,s3,s4);
841 break;
843 case 8:
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);
850 else {
851 REORDER_SELF_SWAP_5_STEP_1(src_64,tmp,samples,5,s0,s1,s2,s3,s4);
853 break;
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;
861 return 1;
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;\
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)
879 int i;
880 switch (samplesize) {
881 case 1:
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;
888 case 2:
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;
895 case 3:
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;
922 break;
924 case 4:
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;
931 case 8:
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;
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;
944 return 1;
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;\
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)
963 int i;
964 switch (samplesize) {
965 case 1:
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;
972 case 2:
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;
979 case 3:
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;
1009 break;
1011 case 4:
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;
1018 case 8:
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;
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;
1031 return 1;
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;\
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)
1050 int i;
1051 switch (samplesize) {
1052 case 1:
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);
1061 break;
1063 case 2:
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);
1072 break;
1074 case 3:
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;
1104 break;
1106 case 4:
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);
1115 break;
1117 case 8:
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);
1126 break;
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;
1134 return 1;
1137 void reorder_channel(void *src,
1138 int src_layout,
1139 int dest_layout,
1140 int samples,
1141 int samplesize)
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;
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);
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,
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,
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,
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)
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);
1326 void reorder_channel_nch(void *buf,
1327 int src_layout,
1328 int dest_layout,
1329 int chnum,
1330 int samples,
1331 int samplesize)
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);
1354 #ifdef TEST
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);
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;
1382 #endif