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 /*****************************************************************************
30 *****************************************************************************/
35 #include <vlc_common.h>
36 #include <vlc_plugin.h>
37 #include <vlc_codec.h>
42 /*****************************************************************************
44 *****************************************************************************/
45 static int OpenDecoder ( vlc_object_t
* );
46 static int OpenPacketizer( vlc_object_t
* );
49 static int OpenEncoder ( vlc_object_t
* );
50 static void CloseEncoder ( vlc_object_t
* );
51 static block_t
*EncodeFrames( encoder_t
*, block_t
* );
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
)
63 set_description( N_("Linear PCM audio packetizer") )
64 set_capability( "packetizer", 100 )
65 set_callback( OpenPacketizer
)
69 set_description( N_("Linear PCM audio encoder") )
70 set_capability( "encoder", 100 )
71 set_callbacks( OpenEncoder
, CloseEncoder
)
72 add_shortcut( "lpcm" )
78 /*****************************************************************************
79 * decoder_sys_t : lpcm decoder descriptor
80 *****************************************************************************/
92 unsigned i_header_size
;
94 uint8_t i_chans_to_reorder
;
95 uint8_t pi_chan_table
[AOUT_CHAN_MAX
];
113 * - number of frames in this packet (8 bits)
114 * - first access unit (16 bits) == 0x0003 ?
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
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)
133 * - group assignment (8 bits)
135 * - padding(variable)
138 * - unknown (16 bits)
139 * - number of channels (4 bits)
140 * - frequency (4 bits)
141 * - bits per sample (2 bits)
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)
173 unsigned pi_position
[6];
176 /*****************************************************************************
178 *****************************************************************************/
179 static int DecodeFrame ( decoder_t
*, block_t
* );
180 static block_t
*Packetize ( decoder_t
*, block_t
** );
181 static void Flush( decoder_t
* );
184 static int VobHeader( unsigned *pi_rate
,
185 unsigned *pi_channels
, unsigned *pi_original_channels
,
187 const uint8_t *p_header
);
188 static void VobExtract( block_t
*, block_t
*, unsigned i_bits
);
190 static int AobHeader( unsigned *pi_rate
,
191 unsigned *pi_channels
, unsigned *pi_layout
,
193 unsigned *pi_padding
,
195 const uint8_t *p_header
);
196 static void AobExtract( block_t
*, block_t
*, unsigned i_bits
, aob_group_t p_group
[2] );
198 static int BdHeader( decoder_sys_t
*p_sys
,
200 unsigned *pi_channels
,
201 unsigned *pi_channels_padding
,
202 unsigned *pi_original_channels
,
204 const uint8_t *p_header
);
205 static void BdExtract( block_t
*, block_t
*, unsigned, unsigned, unsigned, unsigned );
207 static int WidiHeader( unsigned *pi_rate
,
208 unsigned *pi_channels
, unsigned *pi_original_channels
,
210 const uint8_t *p_header
);
212 /*****************************************************************************
214 *****************************************************************************/
215 static int OpenCommon( decoder_t
*p_dec
, bool b_packetizer
)
217 decoder_sys_t
*p_sys
;
221 switch( p_dec
->fmt_in
.i_codec
)
224 case VLC_CODEC_DVD_LPCM
:
226 i_header_size
= LPCM_VOB_HEADER_LEN
;
229 case VLC_CODEC_DVDA_LPCM
:
231 i_header_size
= LPCM_AOB_HEADER_LEN
;
234 case VLC_CODEC_BD_LPCM
:
236 i_header_size
= LPCM_BD_HEADER_LEN
;
239 case VLC_CODEC_WIDI_LPCM
:
241 i_header_size
= LPCM_WIDI_HEADER_LEN
;
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
))
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 */
265 p_dec
->fmt_out
.i_codec
= VLC_CODEC_DVD_LPCM
;
268 p_dec
->fmt_out
.i_codec
= VLC_CODEC_DVDA_LPCM
;
271 p_dec
->fmt_out
.i_codec
= VLC_CODEC_WIDI_LPCM
;
274 vlc_assert_unreachable();
276 p_dec
->fmt_out
.i_codec
= VLC_CODEC_BD_LPCM
;
282 switch( p_dec
->fmt_out
.audio
.i_bitspersample
)
286 p_dec
->fmt_out
.i_codec
= VLC_CODEC_S32N
;
287 p_dec
->fmt_out
.audio
.i_bitspersample
= 32;
290 p_dec
->fmt_out
.i_codec
= VLC_CODEC_S16N
;
291 p_dec
->fmt_out
.audio
.i_bitspersample
= 16;
298 p_dec
->pf_decode
= DecodeFrame
;
300 p_dec
->pf_packetize
= Packetize
;
301 p_dec
->pf_flush
= Flush
;
302 p_dec
->p_sys
= p_sys
;
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 /*****************************************************************************
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
;
333 unsigned int i_rate
= 0, i_original_channels
= 0, i_channels
= 0, i_bits
= 0;
336 if( !pp_block
|| !*pp_block
) return NULL
;
339 *pp_block
= NULL
; /* So the packet doesn't get re-sent */
341 if( p_block
->i_flags
& (BLOCK_FLAG_CORRUPTED
|BLOCK_FLAG_DISCONTINUITY
) )
344 if( p_block
->i_flags
& BLOCK_FLAG_CORRUPTED
)
346 block_Release( p_block
);
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
);
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
);
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
)
381 i_ret
= VobHeader( &i_rate
, &i_channels
, &i_original_channels
, &i_bits
,
385 i_ret
= AobHeader( &i_rate
, &i_channels
, &i_original_channels
, &i_bits
, &i_padding
,
390 i_ret
= BdHeader( p_sys
, &i_rate
, &i_channels
, &i_channels_padding
, &i_original_channels
, &i_bits
,
394 i_ret
= WidiHeader( &i_rate
, &i_channels
, &i_original_channels
, &i_bits
,
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
);
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
)
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
);
436 date_Increment( &p_sys
->end_date
, i_frame_length
) -
439 /* Just pass on the incoming frame */
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;
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
);
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
);
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
)
480 VobExtract( p_aout_buffer
, p_block
, i_bits
);
483 AobExtract( p_aout_buffer
, p_block
, i_bits
, p_aob_group
);
486 vlc_assert_unreachable();
488 BdExtract( p_aout_buffer
, p_block
, i_frame_length
, i_channels
, i_channels_padding
, i_bits
);
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
);
508 decoder_QueueAudio( p_dec
, p_out
);
509 return VLCDEC_SUCCESS
;
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
)
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" );
534 if( p_enc
->fmt_in
.audio
.i_channels
> 8 )
536 msg_Err( p_enc
, "DVD LPCM supports a maximum of eight channels" );
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
)
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
;
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
);
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
) {
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
);
627 uint8_t *frame
= (uint8_t *)p_block
->p_buffer
;
628 frame
[0] = 1; /* one frame in packet */
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
,
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
,
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
;
663 p_first_block
= p_last_block
= p_block
;
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
;
677 /*****************************************************************************
679 *****************************************************************************/
680 static int VobHeader( unsigned *pi_rate
,
681 unsigned *pi_channels
, unsigned *pi_original_channels
,
683 const uint8_t *p_header
)
685 const uint8_t i_header
= p_header
[4];
687 switch( (i_header
>> 4) & 0x3 )
703 *pi_channels
= (i_header
& 0x7) + 1;
704 switch( *pi_channels
- 1 )
707 *pi_original_channels
= AOUT_CHAN_CENTER
;
710 *pi_original_channels
= AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
;
713 /* This is unsure. */
714 *pi_original_channels
= AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
| AOUT_CHAN_LFE
;
717 *pi_original_channels
= AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
718 | AOUT_CHAN_REARLEFT
| AOUT_CHAN_REARRIGHT
;
721 /* This is unsure. */
722 *pi_original_channels
= AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
723 | AOUT_CHAN_REARLEFT
| AOUT_CHAN_REARRIGHT
727 *pi_original_channels
= AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
728 | AOUT_CHAN_REARLEFT
| AOUT_CHAN_REARRIGHT
729 | AOUT_CHAN_CENTER
| AOUT_CHAN_LFE
;
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
;
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
;
745 switch( (i_header
>> 6) & 0x3 )
759 /* Check frame sync and drop it. */
760 if( p_header
[5] != 0x80 )
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] = {
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
,
815 unsigned *pi_padding
,
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
)
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];
834 if( i_index_size_g1
> 0x02 ||
835 ( i_index_size_g2
!= 0x0f && i_index_size_g2
> 0x02 ) )
837 if( (i_index_rate_g1
& 0x07) > 0x02 ||
838 ( i_index_rate_g2
!= 0x0f && (i_index_rate_g1
& 0x07) > 0x02 ) )
840 if( i_assignment
> 20 )
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
) )
852 /* only set 16bits if both are <= */
855 if( g
[0].i_bits
> 16 || g
[1].i_bits
> 16 )
863 if( i_index_rate_g1
& 0x08 )
864 *pi_rate
= 44100 << (i_index_rate_g1
& 0x07);
866 *pi_rate
= 48000 << (i_index_rate_g1
& 0x07);
870 unsigned i_channels1
= 0;
871 unsigned i_layout1
= 0;
872 for( int i
= 0; p_aob_group1
[i_assignment
][i
] != 0; i
++ )
875 i_layout1
|= p_aob_group1
[i_assignment
][i
];
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
++ )
885 i_layout2
|= p_aob_group2
[i_assignment
][i
];
887 assert( (i_layout1
& i_layout2
) == 0 );
891 *pi_channels
= i_channels1
+ ( g
[1].i_bits
? i_channels2
: 0 );
892 *pi_layout
= i_layout1
| ( g
[1].i_bits
? i_layout2
: 0 );
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
:
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
] )
912 if( (*pi_layout
) & i_channel
)
913 g
[i
].pi_position
[j
]++;
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
,
949 unsigned *pi_channels
,
950 unsigned *pi_channels_padding
,
951 unsigned *pi_original_channels
,
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 )
961 *pi_original_channels
= AOUT_CHAN_CENTER
;
965 *pi_original_channels
= AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
;
969 *pi_original_channels
= AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
| AOUT_CHAN_CENTER
;
970 pi_channels_in
= pi_3channels_in
;
974 *pi_original_channels
= AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
| AOUT_CHAN_REARCENTER
;
978 *pi_original_channels
= AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
| AOUT_CHAN_CENTER
|
979 AOUT_CHAN_REARCENTER
;
983 *pi_original_channels
= AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
|
984 AOUT_CHAN_REARLEFT
| AOUT_CHAN_REARRIGHT
;
985 pi_channels_in
= pi_4channels_in
;
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
;
995 *pi_original_channels
= AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
| AOUT_CHAN_CENTER
|
996 AOUT_CHAN_REARLEFT
| AOUT_CHAN_REARRIGHT
|
998 pi_channels_in
= pi_6channels_in
;
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
;
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
|
1013 pi_channels_in
= pi_8channels_in
;
1019 *pi_channels_padding
= *pi_channels
& 1;
1021 switch( (h
>> 6) & 0x03 )
1026 case 2: /* 20 bits but samples are stored on 24 bits */
1027 case 3: /* 24 bits */
1033 switch( (h
>> 8) & 0x0f )
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
);
1059 static int WidiHeader( unsigned *pi_rate
,
1060 unsigned *pi_channels
, unsigned *pi_original_channels
,
1062 const uint8_t *p_header
)
1064 if ( p_header
[0] != 0xa0 || p_header
[1] != 0x06 )
1067 switch( ( p_header
[3] & 0x38 ) >> 3 )
1079 if( p_header
[3] >> 6 != 0 )
1084 *pi_channels
= (p_header
[3] & 0x7) + 1;
1086 *pi_original_channels
= AOUT_CHAN_LEFT
| AOUT_CHAN_RIGHT
;
1091 static void VobExtract( block_t
*p_aout_buffer
, block_t
*p_block
,
1094 /* 20/24 bits LPCM use special packing */
1097 uint32_t *p_out
= (uint32_t *)p_aout_buffer
->p_buffer
;
1099 while( p_block
->i_buffer
/ 12 )
1102 *(p_out
++) = (p_block
->p_buffer
[ 0] << 24)
1103 | (p_block
->p_buffer
[ 1] << 16)
1104 | (p_block
->p_buffer
[ 8] << 8);
1106 *(p_out
++) = (p_block
->p_buffer
[ 2] << 24)
1107 | (p_block
->p_buffer
[ 3] << 16)
1108 | (p_block
->p_buffer
[ 9] << 8);
1110 *(p_out
++) = (p_block
->p_buffer
[ 4] << 24)
1111 | (p_block
->p_buffer
[ 5] << 16)
1112 | (p_block
->p_buffer
[10] << 8);
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 )
1129 *(p_out
++) = ( p_block
->p_buffer
[0] << 24)
1130 | ( p_block
->p_buffer
[1] << 16)
1131 | ((p_block
->p_buffer
[8] & 0xF0) << 8);
1133 *(p_out
++) = ( p_block
->p_buffer
[2] << 24)
1134 | ( p_block
->p_buffer
[3] << 16)
1135 | ((p_block
->p_buffer
[8] & 0x0F) << 12);
1137 *(p_out
++) = ( p_block
->p_buffer
[4] << 24)
1138 | ( p_block
->p_buffer
[5] << 16)
1139 | ((p_block
->p_buffer
[9] & 0xF0) << 8);
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;
1151 assert( i_bits
== 16 );
1152 #ifdef WORDS_BIGENDIAN
1153 memcpy( p_aout_buffer
->p_buffer
, p_block
->p_buffer
, p_block
->i_buffer
);
1155 swab( p_block
->p_buffer
, p_aout_buffer
->p_buffer
, p_block
->i_buffer
);
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;
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
);
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
);
1213 i_aout_written
+= 4;
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 );
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];
1227 i_aout_written
+= 2;
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
);
1236 i_aout_written
+= 4;
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
,
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 );
1266 swab( p_src
, p_dst
, (i_channels
+ i_channels_padding
) * i_bits
/ 8 );
1268 for (unsigned i
= 0; i
< i_channels
; ++i
) {
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];
1276 p_src
+= (i_channels
+ i_channels_padding
) * i_bits
/ 8;
1283 #ifdef WORDS_BIGENDIAN
1284 memcpy( p_aout_buffer
->p_buffer
, p_block
->p_buffer
, p_block
->i_buffer
);
1286 swab( p_block
->p_buffer
, p_aout_buffer
->p_buffer
, p_block
->i_buffer
);