input: add input_SetProgramId
[vlc.git] / modules / codec / lpcm.c
blobf698c5195e8182a165a3794d79804d0928e53f38
1 /*****************************************************************************
2 * lpcm.c: lpcm decoder/packetizer module
3 *****************************************************************************
4 * Copyright (C) 1999-2008 VLC authors and VideoLAN
6 * Authors: Samuel Hocevar <sam@zoy.org>
7 * Henri Fallon <henri@videolan.org>
8 * Christophe Massiot <massiot@via.ecp.fr>
9 * Gildas Bazin <gbazin@videolan.org>
10 * Lauren Aimar <fenrir _AT_ videolan _DOT_ org >
11 * Steinar H. Gunderson <steinar+vlc@gunderson.no>
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU Lesser General Public License as published by
15 * the Free Software Foundation; either version 2.1 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License for more details.
23 * You should have received a copy of the GNU Lesser General Public License
24 * along with this program; if not, write to the Free Software Foundation,
25 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
26 *****************************************************************************/
28 /*****************************************************************************
29 * Preamble
30 *****************************************************************************/
31 #ifdef HAVE_CONFIG_H
32 # include "config.h"
33 #endif
35 #include <vlc_common.h>
36 #include <vlc_plugin.h>
37 #include <vlc_codec.h>
38 #include <vlc_aout.h>
39 #include <unistd.h>
40 #include <assert.h>
42 /*****************************************************************************
43 * Module descriptor
44 *****************************************************************************/
45 static int OpenDecoder ( vlc_object_t * );
46 static int OpenPacketizer( vlc_object_t * );
48 #ifdef ENABLE_SOUT
49 static int OpenEncoder ( vlc_object_t * );
50 static void CloseEncoder ( vlc_object_t * );
51 static block_t *EncodeFrames( encoder_t *, block_t * );
52 #endif
54 vlc_module_begin ()
56 set_category( CAT_INPUT )
57 set_subcategory( SUBCAT_INPUT_ACODEC )
58 set_description( N_("Linear PCM audio decoder") )
59 set_capability( "audio decoder", 100 )
60 set_callback( OpenDecoder )
62 add_submodule ()
63 set_description( N_("Linear PCM audio packetizer") )
64 set_capability( "packetizer", 100 )
65 set_callback( OpenPacketizer )
67 #ifdef ENABLE_SOUT
68 add_submodule ()
69 set_description( N_("Linear PCM audio encoder") )
70 set_capability( "encoder", 100 )
71 set_callbacks( OpenEncoder, CloseEncoder )
72 add_shortcut( "lpcm" )
73 #endif
75 vlc_module_end ()
78 /*****************************************************************************
79 * decoder_sys_t : lpcm decoder descriptor
80 *****************************************************************************/
81 typedef struct
83 /* Module mode */
84 bool b_packetizer;
87 * Output properties
89 date_t end_date;
91 /* */
92 unsigned i_header_size;
93 int i_type;
94 uint8_t i_chans_to_reorder;
95 uint8_t pi_chan_table[AOUT_CHAN_MAX];
96 } decoder_sys_t;
98 #ifdef ENABLE_SOUT
99 typedef struct
101 int i_channels;
102 int i_rate;
104 int i_frame_samples;
105 uint8_t *p_buffer;
106 int i_buffer_used;
107 int i_frame_num;
108 } encoder_sys_t;
109 #endif
112 * LPCM DVD header :
113 * - number of frames in this packet (8 bits)
114 * - first access unit (16 bits) == 0x0003 ?
115 * - emphasis (1 bit)
116 * - mute (1 bit)
117 * - reserved (1 bit)
118 * - current frame (5 bits)
119 * - quantisation (2 bits) 0 == 16bps, 1 == 20bps, 2 == 24bps, 3 == illegal
120 * - frequency (2 bits) 0 == 48 kHz, 1 == 96 kHz, 2 == 44.1 kHz, 3 == 32 kHz
121 * - reserved (1 bit)
122 * - number of channels - 1 (3 bits) 1 == 2 channels
123 * - dynamic range (8 bits) 0x80 == neutral
125 * LPCM DVD-A header (http://dvd-audio.sourceforge.net/spec/aob.shtml)
126 * - continuity counter (8 bits, clipped to 0x00-0x1f)
127 * - header size (16 bits)
128 * - byte pointer to start of first audio frame.
129 * - unknown (8bits, 0x10 for stereo, 0x00 for surround)
130 * - sample size (4+4 bits)
131 * - samplerate (4+4 bits)
132 * - unknown (8 bits)
133 * - group assignment (8 bits)
134 * - unknown (8 bits)
135 * - padding(variable)
137 * LPCM BD header :
138 * - unknown (16 bits)
139 * - number of channels (4 bits)
140 * - frequency (4 bits)
141 * - bits per sample (2 bits)
142 * - unknown (6 bits)
144 * LPCM WIDI header
145 * refers http://www.dvdforum.org/images/Guideline1394V10R0_20020911.pdf
146 * - sub stream id (8 bits) = 0xa0
147 * - frame header count (8 bits) = 0x06
148 * [ 0b0000000 (7 bits)
149 * - audio emphasis (1 bit) ] (8 bits)
150 * [ qz word length (2 bits) 0x00 == 16bits
151 * - sampling freq (3 bits) 0b001 == 44.1K, 0b010 == 48K Hz
152 * - channels count(3 bits) ] (8 bits) 0b000 == dual mono, 0b001 == stereo
153 * follows: LPCM data (15360 bits/1920 bytes)
156 #define LPCM_VOB_HEADER_LEN (6)
157 #define LPCM_AOB_HEADER_LEN (11)
158 #define LPCM_BD_HEADER_LEN (4)
159 #define LPCM_WIDI_HEADER_LEN (4)
161 enum
163 LPCM_VOB,
164 LPCM_AOB,
165 LPCM_BD,
166 LPCM_WIDI,
169 typedef struct
171 unsigned i_channels;
172 unsigned i_bits;
173 unsigned pi_position[6];
174 } aob_group_t;
176 /*****************************************************************************
177 * Local prototypes
178 *****************************************************************************/
179 static int DecodeFrame ( decoder_t *, block_t * );
180 static block_t *Packetize ( decoder_t *, block_t ** );
181 static void Flush( decoder_t * );
183 /* */
184 static int VobHeader( unsigned *pi_rate,
185 unsigned *pi_channels, unsigned *pi_original_channels,
186 unsigned *pi_bits,
187 const uint8_t *p_header );
188 static void VobExtract( block_t *, block_t *, unsigned i_bits );
189 /* */
190 static int AobHeader( unsigned *pi_rate,
191 unsigned *pi_channels, unsigned *pi_layout,
192 unsigned *pi_bits,
193 unsigned *pi_padding,
194 aob_group_t g[2],
195 const uint8_t *p_header );
196 static void AobExtract( block_t *, block_t *, unsigned i_bits, aob_group_t p_group[2] );
197 /* */
198 static int BdHeader( decoder_sys_t *p_sys,
199 unsigned *pi_rate,
200 unsigned *pi_channels,
201 unsigned *pi_channels_padding,
202 unsigned *pi_original_channels,
203 unsigned *pi_bits,
204 const uint8_t *p_header );
205 static void BdExtract( block_t *, block_t *, unsigned, unsigned, unsigned, unsigned );
206 /* */
207 static int WidiHeader( unsigned *pi_rate,
208 unsigned *pi_channels, unsigned *pi_original_channels,
209 unsigned *pi_bits,
210 const uint8_t *p_header );
212 /*****************************************************************************
213 * OpenCommon:
214 *****************************************************************************/
215 static int OpenCommon( decoder_t *p_dec, bool b_packetizer )
217 decoder_sys_t *p_sys;
218 int i_type;
219 int i_header_size;
221 switch( p_dec->fmt_in.i_codec )
223 /* DVD LPCM */
224 case VLC_CODEC_DVD_LPCM:
225 i_type = LPCM_VOB;
226 i_header_size = LPCM_VOB_HEADER_LEN;
227 break;
228 /* DVD-Audio LPCM */
229 case VLC_CODEC_DVDA_LPCM:
230 i_type = LPCM_AOB;
231 i_header_size = LPCM_AOB_HEADER_LEN;
232 break;
233 /* BD LPCM */
234 case VLC_CODEC_BD_LPCM:
235 i_type = LPCM_BD;
236 i_header_size = LPCM_BD_HEADER_LEN;
237 break;
238 /* WIDI LPCM */
239 case VLC_CODEC_WIDI_LPCM:
240 i_type = LPCM_WIDI;
241 i_header_size = LPCM_WIDI_HEADER_LEN;
242 break;
243 default:
244 return VLC_EGENERIC;
247 /* Allocate the memory needed to store the decoder's structure */
248 p_sys = vlc_obj_malloc(VLC_OBJECT(p_dec), sizeof (*p_sys));
249 if (unlikely(p_sys == NULL))
250 return VLC_ENOMEM;
252 /* Misc init */
253 p_sys->b_packetizer = b_packetizer;
254 date_Set( &p_sys->end_date, VLC_TICK_INVALID );
255 p_sys->i_type = i_type;
256 p_sys->i_header_size = i_header_size;
257 p_sys->i_chans_to_reorder = 0;
259 /* Set output properties */
260 if( b_packetizer )
262 switch( i_type )
264 case LPCM_VOB:
265 p_dec->fmt_out.i_codec = VLC_CODEC_DVD_LPCM;
266 break;
267 case LPCM_AOB:
268 p_dec->fmt_out.i_codec = VLC_CODEC_DVDA_LPCM;
269 break;
270 case LPCM_WIDI:
271 p_dec->fmt_out.i_codec = VLC_CODEC_WIDI_LPCM;
272 break;
273 default:
274 vlc_assert_unreachable();
275 case LPCM_BD:
276 p_dec->fmt_out.i_codec = VLC_CODEC_BD_LPCM;
277 break;
280 else
282 switch( p_dec->fmt_out.audio.i_bitspersample )
284 case 24:
285 case 20:
286 p_dec->fmt_out.i_codec = VLC_CODEC_S32N;
287 p_dec->fmt_out.audio.i_bitspersample = 32;
288 break;
289 default:
290 p_dec->fmt_out.i_codec = VLC_CODEC_S16N;
291 p_dec->fmt_out.audio.i_bitspersample = 16;
292 break;
296 /* Set callback */
297 if( !b_packetizer )
298 p_dec->pf_decode = DecodeFrame;
299 else
300 p_dec->pf_packetize = Packetize;
301 p_dec->pf_flush = Flush;
302 p_dec->p_sys = p_sys;
303 return VLC_SUCCESS;
305 static int OpenDecoder( vlc_object_t *p_this )
307 return OpenCommon( (decoder_t*) p_this, false );
309 static int OpenPacketizer( vlc_object_t *p_this )
311 return OpenCommon( (decoder_t*) p_this, true );
314 /*****************************************************************************
315 * Flush:
316 *****************************************************************************/
317 static void Flush( decoder_t *p_dec )
319 decoder_sys_t *p_sys = p_dec->p_sys;
321 date_Set( &p_sys->end_date, VLC_TICK_INVALID );
324 /*****************************************************************************
325 * DecodeFrame: decodes an lpcm frame.
326 ****************************************************************************
327 * Beware, this function must be fed with complete frames (PES packet).
328 *****************************************************************************/
329 static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
331 decoder_sys_t *p_sys = p_dec->p_sys;
332 block_t *p_block;
333 unsigned int i_rate = 0, i_original_channels = 0, i_channels = 0, i_bits = 0;
334 int i_frame_length;
336 if( !pp_block || !*pp_block ) return NULL;
338 p_block = *pp_block;
339 *pp_block = NULL; /* So the packet doesn't get re-sent */
341 if( p_block->i_flags & (BLOCK_FLAG_CORRUPTED|BLOCK_FLAG_DISCONTINUITY) )
343 Flush( p_dec );
344 if( p_block->i_flags & BLOCK_FLAG_CORRUPTED )
346 block_Release( p_block );
347 *pp_block = NULL;
348 return NULL;
352 /* Date management */
353 if( p_block->i_pts != VLC_TICK_INVALID &&
354 p_block->i_pts != date_Get( &p_sys->end_date ) )
356 date_Set( &p_sys->end_date, p_block->i_pts );
359 if( date_Get( &p_sys->end_date ) == VLC_TICK_INVALID )
361 /* We've just started the stream, wait for the first PTS. */
362 block_Release( p_block );
363 return NULL;
366 if( p_block->i_buffer <= p_sys->i_header_size )
368 msg_Err(p_dec, "frame is too short");
369 block_Release( p_block );
370 return NULL;
373 int i_ret;
374 unsigned i_channels_padding = 0;
375 unsigned i_padding = 0; /* only for AOB */
376 aob_group_t p_aob_group[2];
378 switch( p_sys->i_type )
380 case LPCM_VOB:
381 i_ret = VobHeader( &i_rate, &i_channels, &i_original_channels, &i_bits,
382 p_block->p_buffer );
383 break;
384 case LPCM_AOB:
385 i_ret = AobHeader( &i_rate, &i_channels, &i_original_channels, &i_bits, &i_padding,
386 p_aob_group,
387 p_block->p_buffer );
388 break;
389 case LPCM_BD:
390 i_ret = BdHeader( p_sys, &i_rate, &i_channels, &i_channels_padding, &i_original_channels, &i_bits,
391 p_block->p_buffer );
392 break;
393 case LPCM_WIDI:
394 i_ret = WidiHeader( &i_rate, &i_channels, &i_original_channels, &i_bits,
395 p_block->p_buffer );
396 break;
397 default:
398 abort();
401 if( i_ret || p_block->i_buffer <= p_sys->i_header_size + i_padding )
403 msg_Warn( p_dec, "no frame sync or too small frame" );
404 block_Release( p_block );
405 return NULL;
408 /* Set output properties */
409 if( p_dec->fmt_out.audio.i_rate != i_rate )
411 date_Init( &p_sys->end_date, i_rate, 1 );
412 date_Set( &p_sys->end_date, p_block->i_pts );
414 p_dec->fmt_out.audio.i_rate = i_rate;
415 p_dec->fmt_out.audio.i_channels = i_channels;
416 p_dec->fmt_out.audio.i_physical_channels = i_original_channels;
418 if ( p_sys->i_type == LPCM_AOB )
420 i_frame_length = (p_block->i_buffer - p_sys->i_header_size - i_padding) /
422 ( (p_aob_group[0].i_bits / 8) * p_aob_group[0].i_channels ) +
423 ( (p_aob_group[1].i_bits / 8) * p_aob_group[1].i_channels )
426 else
428 i_frame_length = (p_block->i_buffer - p_sys->i_header_size - i_padding) /
429 (i_channels + i_channels_padding) * 8 / i_bits;
432 if( p_sys->b_packetizer )
434 p_block->i_pts = p_block->i_dts = date_Get( &p_sys->end_date );
435 p_block->i_length =
436 date_Increment( &p_sys->end_date, i_frame_length ) -
437 p_block->i_pts;
439 /* Just pass on the incoming frame */
440 return p_block;
442 else
444 /* */
445 if( i_bits == 16 )
447 p_dec->fmt_out.audio.i_format =
448 p_dec->fmt_out.i_codec = VLC_CODEC_S16N;
449 p_dec->fmt_out.audio.i_bitspersample = 16;
451 else
453 p_dec->fmt_out.audio.i_format =
454 p_dec->fmt_out.i_codec = VLC_CODEC_S32N;
455 p_dec->fmt_out.audio.i_bitspersample = 32;
457 aout_FormatPrepare(&p_dec->fmt_out.audio);
459 /* */
460 block_t *p_aout_buffer;
461 if( decoder_UpdateAudioFormat( p_dec ) != VLC_SUCCESS ||
462 !(p_aout_buffer = decoder_NewAudioBuffer( p_dec, i_frame_length )) )
464 block_Release( p_block );
465 return NULL;
468 p_aout_buffer->i_pts = date_Get( &p_sys->end_date );
469 p_aout_buffer->i_length =
470 date_Increment( &p_sys->end_date, i_frame_length )
471 - p_aout_buffer->i_pts;
473 p_block->p_buffer += p_sys->i_header_size + i_padding;
474 p_block->i_buffer -= p_sys->i_header_size + i_padding;
476 switch( p_sys->i_type )
478 case LPCM_WIDI:
479 case LPCM_VOB:
480 VobExtract( p_aout_buffer, p_block, i_bits );
481 break;
482 case LPCM_AOB:
483 AobExtract( p_aout_buffer, p_block, i_bits, p_aob_group );
484 break;
485 default:
486 vlc_assert_unreachable();
487 case LPCM_BD:
488 BdExtract( p_aout_buffer, p_block, i_frame_length, i_channels, i_channels_padding, i_bits );
489 break;
492 if( p_sys->i_chans_to_reorder )
494 aout_ChannelReorder( p_aout_buffer->p_buffer, p_aout_buffer->i_buffer,
495 p_sys->i_chans_to_reorder, p_sys->pi_chan_table,
496 p_dec->fmt_out.i_codec );
499 block_Release( p_block );
500 return p_aout_buffer;
504 static int DecodeFrame( decoder_t *p_dec, block_t *p_block )
506 block_t *p_out = Packetize( p_dec, &p_block );
507 if( p_out != NULL )
508 decoder_QueueAudio( p_dec, p_out );
509 return VLCDEC_SUCCESS;
512 #ifdef ENABLE_SOUT
513 /*****************************************************************************
514 * OpenEncoder: lpcm encoder construction
515 *****************************************************************************/
516 static int OpenEncoder( vlc_object_t *p_this )
518 encoder_t *p_enc = (encoder_t *)p_this;
519 encoder_sys_t *p_sys;
521 /* We only support DVD LPCM yet. */
522 if( p_enc->fmt_out.i_codec != VLC_CODEC_DVD_LPCM )
523 return VLC_EGENERIC;
525 if( p_enc->fmt_in.audio.i_rate != 48000 &&
526 p_enc->fmt_in.audio.i_rate != 96000 &&
527 p_enc->fmt_in.audio.i_rate != 44100 &&
528 p_enc->fmt_in.audio.i_rate != 32000 )
530 msg_Err( p_enc, "DVD LPCM supports only sample rates of 48, 96, 44.1 or 32 kHz" );
531 return VLC_EGENERIC;
534 if( p_enc->fmt_in.audio.i_channels > 8 )
536 msg_Err( p_enc, "DVD LPCM supports a maximum of eight channels" );
537 return VLC_EGENERIC;
540 /* Allocate the memory needed to store the encoder's structure */
541 if( ( p_enc->p_sys = p_sys =
542 (encoder_sys_t *)malloc(sizeof(encoder_sys_t)) ) == NULL )
543 return VLC_ENOMEM;
545 /* In DVD LCPM, a frame is always 150 PTS ticks. */
546 p_sys->i_frame_samples = p_enc->fmt_in.audio.i_rate * 150 / 90000;
547 p_sys->p_buffer = xmalloc(p_sys->i_frame_samples
548 * p_enc->fmt_in.audio.i_channels * 16);
549 p_sys->i_buffer_used = 0;
550 p_sys->i_frame_num = 0;
552 p_sys->i_channels = p_enc->fmt_in.audio.i_channels;
553 p_sys->i_rate = p_enc->fmt_in.audio.i_rate;
555 p_enc->pf_encode_audio = EncodeFrames;
556 p_enc->fmt_in.i_codec = p_enc->fmt_out.i_codec;
558 p_enc->fmt_in.audio.i_bitspersample = 16;
559 p_enc->fmt_in.i_codec = VLC_CODEC_S16N;
561 p_enc->fmt_out.i_bitrate =
562 p_enc->fmt_in.audio.i_channels *
563 p_enc->fmt_in.audio.i_rate *
564 p_enc->fmt_in.audio.i_bitspersample *
565 (p_sys->i_frame_samples + LPCM_VOB_HEADER_LEN) /
566 p_sys->i_frame_samples;
568 return VLC_SUCCESS;
571 /*****************************************************************************
572 * CloseEncoder: lpcm encoder destruction
573 *****************************************************************************/
574 static void CloseEncoder ( vlc_object_t *p_this )
576 encoder_t *p_enc = (encoder_t *)p_this;
577 encoder_sys_t *p_sys = p_enc->p_sys;
579 free( p_sys->p_buffer );
580 free( p_sys );
583 /*****************************************************************************
584 * EncodeFrames: encode zero or more LCPM audio packets
585 *****************************************************************************/
586 static block_t *EncodeFrames( encoder_t *p_enc, block_t *p_aout_buf )
588 encoder_sys_t *p_sys = p_enc->p_sys;
589 block_t *p_first_block = NULL, *p_last_block = NULL;
591 if( !p_aout_buf || !p_aout_buf->i_buffer ) return NULL;
593 const int i_num_frames = ( p_sys->i_buffer_used + p_aout_buf->i_nb_samples ) /
594 p_sys->i_frame_samples;
595 const int i_leftover_samples = ( p_sys->i_buffer_used + p_aout_buf->i_nb_samples ) %
596 p_sys->i_frame_samples;
597 const int i_frame_size = p_sys->i_frame_samples * p_sys->i_channels * 2 + LPCM_VOB_HEADER_LEN;
598 const int i_start_offset = -p_sys->i_buffer_used;
600 uint8_t i_freq_code = 0;
602 switch( p_sys->i_rate ) {
603 case 48000:
604 i_freq_code = 0;
605 break;
606 case 96000:
607 i_freq_code = 1;
608 break;
609 case 44100:
610 i_freq_code = 2;
611 break;
612 case 32000:
613 i_freq_code = 3;
614 break;
615 default:
616 vlc_assert_unreachable();
619 int i_bytes_consumed = 0;
621 for ( int i = 0; i < i_num_frames; ++i )
623 block_t *p_block = block_Alloc( i_frame_size );
624 if( !p_block )
625 return NULL;
627 uint8_t *frame = (uint8_t *)p_block->p_buffer;
628 frame[0] = 1; /* one frame in packet */
629 frame[1] = 0;
630 frame[2] = 0; /* no first access unit */
631 frame[3] = (p_sys->i_frame_num + i) & 0x1f; /* no emphasis, no mute */
632 frame[4] = (i_freq_code << 4) | (p_sys->i_channels - 1);
633 frame[5] = 0x80; /* neutral dynamic range */
635 const int i_consume_samples = p_sys->i_frame_samples - p_sys->i_buffer_used;
636 const int i_kept_bytes = p_sys->i_buffer_used * p_sys->i_channels * 2;
637 const int i_consume_bytes = i_consume_samples * p_sys->i_channels * 2;
639 #ifdef WORDS_BIGENDIAN
640 memcpy( frame + 6, p_sys->p_buffer, i_kept_bytes );
641 memcpy( frame + 6 + i_kept_bytes, p_aout_buf->p_buffer + i_bytes_consumed,
642 i_consume_bytes );
643 #else
644 swab( p_sys->p_buffer, frame + 6, i_kept_bytes );
645 swab( p_aout_buf->p_buffer + i_bytes_consumed, frame + 6 + i_kept_bytes,
646 i_consume_bytes );
647 #endif
649 p_sys->i_frame_num++;
650 p_sys->i_buffer_used = 0;
651 i_bytes_consumed += i_consume_bytes;
653 /* We need to find i_length by means of next_pts due to possible roundoff errors. */
654 vlc_tick_t this_pts = p_aout_buf->i_pts +
655 vlc_tick_from_samples(i * p_sys->i_frame_samples + i_start_offset, p_sys->i_rate);
656 vlc_tick_t next_pts = p_aout_buf->i_pts +
657 vlc_tick_from_samples((i + 1) * p_sys->i_frame_samples + i_start_offset, p_sys->i_rate);
659 p_block->i_pts = p_block->i_dts = this_pts;
660 p_block->i_length = next_pts - this_pts;
662 if( !p_first_block )
663 p_first_block = p_last_block = p_block;
664 else
665 p_last_block = p_last_block->p_next = p_block;
668 memcpy( p_sys->p_buffer,
669 p_aout_buf->p_buffer + i_bytes_consumed,
670 i_leftover_samples * p_sys->i_channels * 2 );
671 p_sys->i_buffer_used = i_leftover_samples;
673 return p_first_block;
675 #endif
677 /*****************************************************************************
679 *****************************************************************************/
680 static int VobHeader( unsigned *pi_rate,
681 unsigned *pi_channels, unsigned *pi_original_channels,
682 unsigned *pi_bits,
683 const uint8_t *p_header )
685 const uint8_t i_header = p_header[4];
687 switch( (i_header >> 4) & 0x3 )
689 case 0:
690 *pi_rate = 48000;
691 break;
692 case 1:
693 *pi_rate = 96000;
694 break;
695 case 2:
696 *pi_rate = 44100;
697 break;
698 case 3:
699 *pi_rate = 32000;
700 break;
703 *pi_channels = (i_header & 0x7) + 1;
704 switch( *pi_channels - 1 )
706 case 0:
707 *pi_original_channels = AOUT_CHAN_CENTER;
708 break;
709 case 1:
710 *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
711 break;
712 case 2:
713 /* This is unsure. */
714 *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_LFE;
715 break;
716 case 3:
717 *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
718 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
719 break;
720 case 4:
721 /* This is unsure. */
722 *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
723 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
724 | AOUT_CHAN_LFE;
725 break;
726 case 5:
727 *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
728 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
729 | AOUT_CHAN_CENTER | AOUT_CHAN_LFE;
730 break;
731 case 6:
732 *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
733 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
734 | AOUT_CHAN_CENTER | AOUT_CHAN_MIDDLELEFT
735 | AOUT_CHAN_MIDDLERIGHT;
736 break;
737 case 7:
738 *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
739 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
740 | AOUT_CHAN_CENTER | AOUT_CHAN_MIDDLELEFT
741 | AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_LFE;
742 break;
745 switch( (i_header >> 6) & 0x3 )
747 case 2:
748 *pi_bits = 24;
749 break;
750 case 1:
751 *pi_bits = 20;
752 break;
753 case 0:
754 default:
755 *pi_bits = 16;
756 break;
759 /* Check frame sync and drop it. */
760 if( p_header[5] != 0x80 )
761 return -1;
762 return 0;
765 static const unsigned p_aob_group1[21][6] = {
766 { AOUT_CHAN_CENTER, 0 },
767 { AOUT_CHAN_LEFT, AOUT_CHAN_RIGHT, 0 },
768 { AOUT_CHAN_LEFT, AOUT_CHAN_RIGHT, 0 },
769 { AOUT_CHAN_LEFT, AOUT_CHAN_RIGHT, 0 },
770 { AOUT_CHAN_LEFT, AOUT_CHAN_RIGHT, 0 },
771 { AOUT_CHAN_LEFT, AOUT_CHAN_RIGHT, 0 },
772 { AOUT_CHAN_LEFT, AOUT_CHAN_RIGHT, 0 },
773 { AOUT_CHAN_LEFT, AOUT_CHAN_RIGHT, 0 },
774 { AOUT_CHAN_LEFT, AOUT_CHAN_RIGHT, 0 },
775 { AOUT_CHAN_LEFT, AOUT_CHAN_RIGHT, 0 },
776 { AOUT_CHAN_LEFT, AOUT_CHAN_RIGHT, 0 },
777 { AOUT_CHAN_LEFT, AOUT_CHAN_RIGHT, 0 },
778 { AOUT_CHAN_LEFT, AOUT_CHAN_RIGHT, 0 },
779 { AOUT_CHAN_LEFT, AOUT_CHAN_RIGHT, AOUT_CHAN_CENTER, 0 },
780 { AOUT_CHAN_LEFT, AOUT_CHAN_RIGHT, AOUT_CHAN_CENTER, 0 },
781 { AOUT_CHAN_LEFT, AOUT_CHAN_RIGHT, AOUT_CHAN_CENTER, 0 },
782 { AOUT_CHAN_LEFT, AOUT_CHAN_RIGHT, AOUT_CHAN_CENTER, 0 },
783 { AOUT_CHAN_LEFT, AOUT_CHAN_RIGHT, AOUT_CHAN_CENTER, 0 },
784 { AOUT_CHAN_LEFT, AOUT_CHAN_RIGHT, AOUT_CHAN_REARLEFT, AOUT_CHAN_REARRIGHT, 0 },
785 { AOUT_CHAN_LEFT, AOUT_CHAN_RIGHT, AOUT_CHAN_REARLEFT, AOUT_CHAN_REARRIGHT, 0 },
786 { AOUT_CHAN_LEFT, AOUT_CHAN_RIGHT, AOUT_CHAN_REARLEFT, AOUT_CHAN_REARRIGHT, 0 },
788 static const unsigned p_aob_group2[21][6] = {
789 { 0 },
790 { 0 },
791 { AOUT_CHAN_REARCENTER, 0 },
792 { AOUT_CHAN_REARLEFT, AOUT_CHAN_REARRIGHT, 0 },
793 { AOUT_CHAN_LFE, 0 },
794 { AOUT_CHAN_LFE, AOUT_CHAN_REARCENTER, 0 },
795 { AOUT_CHAN_LFE, AOUT_CHAN_REARLEFT, AOUT_CHAN_REARRIGHT, 0 },
796 { AOUT_CHAN_CENTER, 0 },
797 { AOUT_CHAN_CENTER, AOUT_CHAN_REARCENTER, 0 },
798 { AOUT_CHAN_CENTER, AOUT_CHAN_REARLEFT, AOUT_CHAN_REARRIGHT, 0 },
799 { AOUT_CHAN_CENTER, AOUT_CHAN_LFE, 0 },
800 { AOUT_CHAN_CENTER, AOUT_CHAN_LFE, AOUT_CHAN_REARCENTER, 0 },
801 { AOUT_CHAN_CENTER, AOUT_CHAN_LFE, AOUT_CHAN_REARLEFT, AOUT_CHAN_REARRIGHT, 0 },
802 { AOUT_CHAN_REARCENTER, 0 },
803 { AOUT_CHAN_REARLEFT, AOUT_CHAN_REARRIGHT, 0 },
804 { AOUT_CHAN_LFE, 0 },
805 { AOUT_CHAN_LFE, AOUT_CHAN_REARCENTER, 0 },
806 { AOUT_CHAN_LFE, AOUT_CHAN_REARLEFT, AOUT_CHAN_REARRIGHT, 0 },
807 { AOUT_CHAN_LFE, 0 },
808 { AOUT_CHAN_CENTER, 0 },
809 { AOUT_CHAN_CENTER, AOUT_CHAN_LFE, 0 },
812 static int AobHeader( unsigned *pi_rate,
813 unsigned *pi_channels, unsigned *pi_layout,
814 unsigned *pi_bits,
815 unsigned *pi_padding,
816 aob_group_t g[2],
817 const uint8_t *p_header )
819 const unsigned i_header_size = GetWBE( &p_header[1] );
820 if( i_header_size + 3 < LPCM_AOB_HEADER_LEN )
821 return VLC_EGENERIC;
823 /* Padding = Total header size - Normal AOB header
824 * + 3 bytes (1 for continuity counter + 2 for header_size ) */
825 *pi_padding = 3 + i_header_size - LPCM_AOB_HEADER_LEN;
827 const int i_index_size_g1 = (p_header[6] >> 4);
828 const int i_index_size_g2 = (p_header[6] ) & 0x0f;
829 const int i_index_rate_g1 = (p_header[7] >> 4);
830 const int i_index_rate_g2 = (p_header[7] ) & 0x0f;
831 const int i_assignment = p_header[9];
833 /* Validate */
834 if( i_index_size_g1 > 0x02 ||
835 ( i_index_size_g2 != 0x0f && i_index_size_g2 > 0x02 ) )
836 return VLC_EGENERIC;
837 if( (i_index_rate_g1 & 0x07) > 0x02 ||
838 ( i_index_rate_g2 != 0x0f && (i_index_rate_g1 & 0x07) > 0x02 ) )
839 return VLC_EGENERIC;
840 if( i_assignment > 20 )
841 return VLC_EGENERIC;
843 /* */
844 /* max is 0x2, 0xf == unused */
845 g[0].i_bits = 16 + 4 * i_index_size_g1;
846 g[1].i_bits = ( i_index_size_g2 != 0x0f ) ? 16 + 4 * i_index_size_g2 : 0;
848 /* No info about interlacing of different sampling rate */
849 if ( g[1].i_bits && ( i_index_rate_g1 != i_index_rate_g2 ) )
850 return VLC_EGENERIC;
852 /* only set 16bits if both are <= */
853 if( g[0].i_bits )
855 if( g[0].i_bits > 16 || g[1].i_bits > 16 )
856 *pi_bits = 32;
857 else
858 *pi_bits = 16;
860 else
861 return VLC_EGENERIC;
863 if( i_index_rate_g1 & 0x08 )
864 *pi_rate = 44100 << (i_index_rate_g1 & 0x07);
865 else
866 *pi_rate = 48000 << (i_index_rate_g1 & 0x07);
869 /* Group1 */
870 unsigned i_channels1 = 0;
871 unsigned i_layout1 = 0;
872 for( int i = 0; p_aob_group1[i_assignment][i] != 0; i++ )
874 i_channels1++;
875 i_layout1 |= p_aob_group1[i_assignment][i];
877 /* Group2 */
878 unsigned i_channels2 = 0;
879 unsigned i_layout2 = 0;
880 if( i_index_size_g2 != 0x0f && i_index_rate_g2 != 0x0f )
882 for( int i = 0; p_aob_group2[i_assignment][i] != 0; i++ )
884 i_channels2++;
885 i_layout2 |= p_aob_group2[i_assignment][i];
887 assert( (i_layout1 & i_layout2) == 0 );
890 /* */
891 *pi_channels = i_channels1 + ( g[1].i_bits ? i_channels2 : 0 );
892 *pi_layout = i_layout1 | ( g[1].i_bits ? i_layout2 : 0 );
894 /* */
895 for( unsigned i = 0; i < 2; i++ )
897 const unsigned *p_aob = i == 0 ? p_aob_group1[i_assignment] :
898 p_aob_group2[i_assignment];
899 g[i].i_channels = i == 0 ? i_channels1 :
900 i_channels2;
902 if( !g[i].i_bits )
903 continue;
904 for( unsigned j = 0; j < g[i].i_channels; j++ )
906 g[i].pi_position[j] = 0;
907 for( int k = 0; pi_vlc_chan_order_wg4[k] != 0; k++ )
909 const unsigned i_channel = pi_vlc_chan_order_wg4[k];
910 if( i_channel == p_aob[j] )
911 break;
912 if( (*pi_layout) & i_channel )
913 g[i].pi_position[j]++;
917 return VLC_SUCCESS;
920 static const uint32_t pi_8channels_in[] =
921 { AOUT_CHAN_LEFT, AOUT_CHAN_RIGHT, AOUT_CHAN_CENTER,
922 AOUT_CHAN_MIDDLELEFT, AOUT_CHAN_REARLEFT, AOUT_CHAN_REARRIGHT,
923 AOUT_CHAN_MIDDLERIGHT, AOUT_CHAN_LFE, 0 };
925 static const uint32_t pi_7channels_in[] =
926 { AOUT_CHAN_LEFT, AOUT_CHAN_RIGHT, AOUT_CHAN_CENTER,
927 AOUT_CHAN_MIDDLELEFT, AOUT_CHAN_REARLEFT, AOUT_CHAN_REARRIGHT,
928 AOUT_CHAN_MIDDLERIGHT, 0 };
930 static const uint32_t pi_6channels_in[] =
931 { AOUT_CHAN_LEFT, AOUT_CHAN_RIGHT, AOUT_CHAN_CENTER,
932 AOUT_CHAN_REARLEFT, AOUT_CHAN_REARRIGHT, AOUT_CHAN_LFE, 0 };
934 static const uint32_t pi_5channels_in[] =
935 { AOUT_CHAN_LEFT, AOUT_CHAN_RIGHT, AOUT_CHAN_CENTER,
936 AOUT_CHAN_MIDDLELEFT, AOUT_CHAN_MIDDLERIGHT, 0 };
938 static const uint32_t pi_4channels_in[] =
939 { AOUT_CHAN_LEFT, AOUT_CHAN_RIGHT,
940 AOUT_CHAN_REARLEFT, AOUT_CHAN_REARRIGHT, 0 };
942 static const uint32_t pi_3channels_in[] =
943 { AOUT_CHAN_LEFT, AOUT_CHAN_RIGHT,
944 AOUT_CHAN_CENTER, 0 };
947 static int BdHeader( decoder_sys_t *p_sys,
948 unsigned *pi_rate,
949 unsigned *pi_channels,
950 unsigned *pi_channels_padding,
951 unsigned *pi_original_channels,
952 unsigned *pi_bits,
953 const uint8_t *p_header )
955 const uint32_t h = GetDWBE( p_header );
956 const uint32_t *pi_channels_in = NULL;
957 switch( ( h & 0xf000) >> 12 )
959 case 1:
960 *pi_channels = 1;
961 *pi_original_channels = AOUT_CHAN_CENTER;
962 break;
963 case 3:
964 *pi_channels = 2;
965 *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
966 break;
967 case 4:
968 *pi_channels = 3;
969 *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER;
970 pi_channels_in = pi_3channels_in;
971 break;
972 case 5:
973 *pi_channels = 3;
974 *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARCENTER;
975 break;
976 case 6:
977 *pi_channels = 4;
978 *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER |
979 AOUT_CHAN_REARCENTER;
980 break;
981 case 7:
982 *pi_channels = 4;
983 *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
984 AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
985 pi_channels_in = pi_4channels_in;
986 break;
987 case 8:
988 *pi_channels = 5;
989 *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER |
990 AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
991 pi_channels_in = pi_5channels_in;
992 break;
993 case 9:
994 *pi_channels = 6;
995 *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER |
996 AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT |
997 AOUT_CHAN_LFE;
998 pi_channels_in = pi_6channels_in;
999 break;
1000 case 10:
1001 *pi_channels = 7;
1002 *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER |
1003 AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT |
1004 AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT;
1005 pi_channels_in = pi_7channels_in;
1006 break;
1007 case 11:
1008 *pi_channels = 8;
1009 *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER |
1010 AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT |
1011 AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT |
1012 AOUT_CHAN_LFE;
1013 pi_channels_in = pi_8channels_in;
1014 break;
1016 default:
1017 return -1;
1019 *pi_channels_padding = *pi_channels & 1;
1021 switch( (h >> 6) & 0x03 )
1023 case 1:
1024 *pi_bits = 16;
1025 break;
1026 case 2: /* 20 bits but samples are stored on 24 bits */
1027 case 3: /* 24 bits */
1028 *pi_bits = 24;
1029 break;
1030 default:
1031 return -1;
1033 switch( (h >> 8) & 0x0f )
1035 case 1:
1036 *pi_rate = 48000;
1037 break;
1038 case 4:
1039 *pi_rate = 96000;
1040 break;
1041 case 5:
1042 *pi_rate = 192000;
1043 break;
1044 default:
1045 return -1;
1048 if( pi_channels_in )
1050 p_sys->i_chans_to_reorder =
1051 aout_CheckChannelReorder( pi_channels_in, NULL,
1052 *pi_original_channels,
1053 p_sys->pi_chan_table );
1056 return 0;
1059 static int WidiHeader( unsigned *pi_rate,
1060 unsigned *pi_channels, unsigned *pi_original_channels,
1061 unsigned *pi_bits,
1062 const uint8_t *p_header )
1064 if ( p_header[0] != 0xa0 || p_header[1] != 0x06 )
1065 return -1;
1067 switch( ( p_header[3] & 0x38 ) >> 3 )
1069 case 0x01: //0b001
1070 *pi_rate = 44100;
1071 break;
1072 case 0x02: //0b010
1073 *pi_rate = 48000;
1074 break;
1075 default:
1076 return -1;
1079 if( p_header[3] >> 6 != 0 )
1080 return -1;
1081 else
1082 *pi_bits = 16;
1084 *pi_channels = (p_header[3] & 0x7) + 1;
1086 *pi_original_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
1088 return 0;
1091 static void VobExtract( block_t *p_aout_buffer, block_t *p_block,
1092 unsigned i_bits )
1094 /* 20/24 bits LPCM use special packing */
1095 if( i_bits == 24 )
1097 uint32_t *p_out = (uint32_t *)p_aout_buffer->p_buffer;
1099 while( p_block->i_buffer / 12 )
1101 /* Sample 1 */
1102 *(p_out++) = (p_block->p_buffer[ 0] << 24)
1103 | (p_block->p_buffer[ 1] << 16)
1104 | (p_block->p_buffer[ 8] << 8);
1105 /* Sample 2 */
1106 *(p_out++) = (p_block->p_buffer[ 2] << 24)
1107 | (p_block->p_buffer[ 3] << 16)
1108 | (p_block->p_buffer[ 9] << 8);
1109 /* Sample 3 */
1110 *(p_out++) = (p_block->p_buffer[ 4] << 24)
1111 | (p_block->p_buffer[ 5] << 16)
1112 | (p_block->p_buffer[10] << 8);
1113 /* Sample 4 */
1114 *(p_out++) = (p_block->p_buffer[ 6] << 24)
1115 | (p_block->p_buffer[ 7] << 16)
1116 | (p_block->p_buffer[11] << 8);
1118 p_block->i_buffer -= 12;
1119 p_block->p_buffer += 12;
1122 else if( i_bits == 20 )
1124 uint32_t *p_out = (uint32_t *)p_aout_buffer->p_buffer;
1126 while( p_block->i_buffer / 10 )
1128 /* Sample 1 */
1129 *(p_out++) = ( p_block->p_buffer[0] << 24)
1130 | ( p_block->p_buffer[1] << 16)
1131 | ((p_block->p_buffer[8] & 0xF0) << 8);
1132 /* Sample 2 */
1133 *(p_out++) = ( p_block->p_buffer[2] << 24)
1134 | ( p_block->p_buffer[3] << 16)
1135 | ((p_block->p_buffer[8] & 0x0F) << 12);
1136 /* Sample 3 */
1137 *(p_out++) = ( p_block->p_buffer[4] << 24)
1138 | ( p_block->p_buffer[5] << 16)
1139 | ((p_block->p_buffer[9] & 0xF0) << 8);
1140 /* Sample 4 */
1141 *(p_out++) = ( p_block->p_buffer[6] << 24)
1142 | ( p_block->p_buffer[7] << 16)
1143 | ((p_block->p_buffer[9] & 0x0F) << 12);
1145 p_block->i_buffer -= 10;
1146 p_block->p_buffer += 10;
1149 else
1151 assert( i_bits == 16 );
1152 #ifdef WORDS_BIGENDIAN
1153 memcpy( p_aout_buffer->p_buffer, p_block->p_buffer, p_block->i_buffer );
1154 #else
1155 swab( p_block->p_buffer, p_aout_buffer->p_buffer, p_block->i_buffer );
1156 #endif
1160 static void AobExtract( block_t *p_aout_buffer,
1161 block_t *p_block, unsigned i_aoutbits, aob_group_t p_group[2] )
1163 uint8_t *p_out = p_aout_buffer->p_buffer;
1164 const unsigned i_total_channels = p_group[0].i_channels +
1165 ( p_group[1].i_bits ? p_group[1].i_channels : 0 );
1167 while( p_block->i_buffer > 0 )
1169 unsigned int i_aout_written = 0;
1171 for( int i = 0; i < 2; i++ )
1173 const aob_group_t *g = &p_group[1-i];
1174 const unsigned int i_group_size = 2 * g->i_channels * g->i_bits / 8;
1176 if( p_block->i_buffer < i_group_size )
1178 p_block->i_buffer = 0;
1179 break;
1182 if( !g->i_bits )
1183 continue;
1185 for( unsigned n = 0; n < 2; n++ )
1187 for( unsigned j = 0; j < g->i_channels; j++ )
1189 const int i_src = n * g->i_channels + j;
1190 const int i_dst = n * i_total_channels + g->pi_position[j];
1191 uint32_t *p_out32 = (uint32_t *) &p_out[4*i_dst];
1193 if( g->i_bits == 24 )
1195 assert( i_aoutbits == 32 );
1196 *p_out32 = (p_block->p_buffer[2*i_src+0] << 24)
1197 | (p_block->p_buffer[2*i_src+1] << 16)
1198 | (p_block->p_buffer[4*g->i_channels+i_src] << 8);
1199 #ifdef WORDS_BIGENDIAN
1200 *p_out32 = vlc_bswap32(*p_out32);
1201 #endif
1202 i_aout_written += 4;
1204 else if( g->i_bits == 20 )
1206 assert( i_aoutbits == 32 );
1207 *p_out32 = (p_block->p_buffer[2*i_src+0] << 24)
1208 | (p_block->p_buffer[2*i_src+1] << 16)
1209 | (((p_block->p_buffer[4*g->i_channels+i_src] << ((!n)?0:4) ) & 0xf0) << 8);
1210 #ifdef WORDS_BIGENDIAN
1211 *p_out32 = vlc_bswap32(*p_out32);
1212 #endif
1213 i_aout_written += 4;
1215 else
1217 assert( g->i_bits == 16 );
1218 assert( i_aoutbits == 16 || i_aoutbits == 32 );
1219 if( i_aoutbits == 16 )
1221 #ifdef WORDS_BIGENDIAN
1222 memcpy( &p_out[2*i_dst], &p_block->p_buffer[2*i_src], 2 );
1223 #else
1224 p_out[2*i_dst+1] = p_block->p_buffer[2*i_src+0];
1225 p_out[2*i_dst+0] = p_block->p_buffer[2*i_src+1];
1226 #endif
1227 i_aout_written += 2;
1229 else
1231 *p_out32 = (p_block->p_buffer[2*i_src+0] << 24)
1232 | (p_block->p_buffer[2*i_src+1] << 16);
1233 #ifdef WORDS_BIGENDIAN
1234 *p_out32 = vlc_bswap32(*p_out32);
1235 #endif
1236 i_aout_written += 4;
1242 /* */
1243 p_block->i_buffer -= i_group_size;
1244 p_block->p_buffer += i_group_size;
1246 p_out += i_aout_written;
1249 static void BdExtract( block_t *p_aout_buffer, block_t *p_block,
1250 unsigned i_frame_length,
1251 unsigned i_channels, unsigned i_channels_padding,
1252 unsigned i_bits )
1254 if( i_bits != 16 || i_channels_padding > 0 )
1256 uint8_t *p_src = p_block->p_buffer;
1257 uint8_t *p_dst = p_aout_buffer->p_buffer;
1258 int dst_inc = ((i_bits == 16) ? 2 : 4) * i_channels;
1260 while( i_frame_length > 0 )
1262 #ifdef WORDS_BIGENDIAN
1263 memcpy( p_dst, p_src, i_channels * i_bits / 8 );
1264 #else
1265 if (i_bits == 16) {
1266 swab( p_src, p_dst, (i_channels + i_channels_padding) * i_bits / 8 );
1267 } else {
1268 for (unsigned i = 0; i < i_channels; ++i) {
1269 p_dst[i * 4] = 0;
1270 p_dst[1 + (i * 4)] = p_src[2 + (i * 3)];
1271 p_dst[2 + (i * 4)] = p_src[1 + (i * 3)];
1272 p_dst[3 + (i * 4)] = p_src[i * 3];
1275 #endif
1276 p_src += (i_channels + i_channels_padding) * i_bits / 8;
1277 p_dst += dst_inc;
1278 i_frame_length--;
1281 else
1283 #ifdef WORDS_BIGENDIAN
1284 memcpy( p_aout_buffer->p_buffer, p_block->p_buffer, p_block->i_buffer );
1285 #else
1286 swab( p_block->p_buffer, p_aout_buffer->p_buffer, p_block->i_buffer );
1287 #endif