Add DreX fourCCs
[vlc.git] / modules / codec / dts.c
blobd12c89ae43cb949fa29fc3f06eeade61171c5ba7
1 /*****************************************************************************
2 * dts.c: parse DTS audio sync info and packetize the stream
3 *****************************************************************************
4 * Copyright (C) 2003-2009 the VideoLAN team
5 * $Id$
7 * Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
8 * Gildas Bazin <gbazin@netcourrier.com>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 *****************************************************************************/
25 /*****************************************************************************
26 * Preamble
27 *****************************************************************************/
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
32 #include <assert.h>
34 #include <vlc_common.h>
35 #include <vlc_plugin.h>
36 #include <vlc_codec.h>
37 #include <vlc_aout.h>
38 #include <vlc_block_helper.h>
39 #include <vlc_bits.h>
40 #include <vlc_modules.h>
42 /*****************************************************************************
43 * Module descriptor
44 *****************************************************************************/
45 static int OpenDecoder ( vlc_object_t * );
46 static int OpenPacketizer( vlc_object_t * );
47 static void CloseCommon ( vlc_object_t * );
49 vlc_module_begin ()
50 set_description( N_("DTS parser") )
51 set_capability( "decoder", 100 )
52 set_callbacks( OpenDecoder, CloseCommon )
54 add_submodule ()
55 set_description( N_("DTS audio packetizer") )
56 set_capability( "packetizer", 10 )
57 set_callbacks( OpenPacketizer, CloseCommon )
58 vlc_module_end ()
60 /*****************************************************************************
61 * decoder_sys_t : decoder descriptor
62 *****************************************************************************/
63 struct decoder_sys_t
65 /* Module mode */
66 bool b_packetizer;
69 * Input properties
71 int i_state;
73 block_bytestream_t bytestream;
76 * Common properties
78 date_t end_date;
80 mtime_t i_pts;
82 bool b_dts_hd; /* Is the current frame a DTS HD one */
83 unsigned int i_bit_rate;
84 unsigned int i_frame_size;
85 unsigned int i_frame_length;
86 unsigned int i_rate;
87 unsigned int i_channels;
88 unsigned int i_channels_conf;
91 enum {
93 STATE_NOSYNC,
94 STATE_SYNC,
95 STATE_HEADER,
96 STATE_NEXT_SYNC,
97 STATE_GET_DATA,
98 STATE_SEND_DATA
101 #define DTS_HEADER_SIZE 14
103 /****************************************************************************
104 * Local prototypes
105 ****************************************************************************/
106 static int OpenCommon( vlc_object_t *, bool b_packetizer );
107 static void *DecodeBlock( decoder_t *, block_t ** );
109 static inline int SyncCode( const uint8_t * );
110 static int SyncInfo( const uint8_t *, bool *, unsigned int *, unsigned int *,
111 unsigned int *, unsigned int *, unsigned int * );
113 static uint8_t *GetOutBuffer ( decoder_t *, block_t ** );
114 static aout_buffer_t *GetAoutBuffer( decoder_t * );
115 static block_t *GetSoutBuffer( decoder_t * );
117 /*****************************************************************************
118 * OpenDecoder: probe the decoder
119 *****************************************************************************/
120 static int OpenDecoder( vlc_object_t *p_this )
122 /* HACK: Don't use this codec if we don't have an dts audio filter */
123 if( !module_exists( "dtstofloat32" ) )
124 return VLC_EGENERIC;
126 return OpenCommon( p_this, false );
129 /*****************************************************************************
130 * OpenPacketizer: probe the packetizer
131 *****************************************************************************/
132 static int OpenPacketizer( vlc_object_t *p_this )
134 return OpenCommon( p_this, true );
137 /*****************************************************************************
138 * OpenCommon:
139 *****************************************************************************/
140 static int OpenCommon( vlc_object_t *p_this, bool b_packetizer )
142 decoder_t *p_dec = (decoder_t*)p_this;
143 decoder_sys_t *p_sys;
145 if( p_dec->fmt_in.i_codec != VLC_CODEC_DTS )
146 return VLC_EGENERIC;
148 /* Allocate the memory needed to store the decoder's structure */
149 if( ( p_dec->p_sys = p_sys = malloc(sizeof(*p_sys)) ) == NULL )
150 return VLC_ENOMEM;
152 /* Misc init */
153 p_sys->b_packetizer = b_packetizer;
154 p_sys->i_state = STATE_NOSYNC;
155 date_Set( &p_sys->end_date, 0 );
156 p_sys->b_dts_hd = false;
157 p_sys->i_pts = VLC_TS_INVALID;
159 p_sys->bytestream = block_BytestreamInit();
161 /* Set output properties */
162 p_dec->fmt_out.i_cat = AUDIO_ES;
163 p_dec->fmt_out.i_codec = VLC_CODEC_DTS;
164 p_dec->fmt_out.audio.i_rate = 0; /* So end_date gets initialized */
166 /* Set callback */
167 p_dec->pf_decode_audio = (aout_buffer_t *(*)(decoder_t *, block_t **))
168 DecodeBlock;
169 p_dec->pf_packetize = (block_t *(*)(decoder_t *, block_t **))
170 DecodeBlock;
172 return VLC_SUCCESS;
175 /****************************************************************************
176 * DecodeBlock: the whole thing
177 ****************************************************************************/
178 static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
180 decoder_sys_t *p_sys = p_dec->p_sys;
181 uint8_t p_header[DTS_HEADER_SIZE];
182 uint8_t *p_buf;
183 block_t *p_out_buffer;
185 if( !pp_block || !*pp_block )
186 return NULL;
188 if( (*pp_block)->i_flags&(BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
190 if( (*pp_block)->i_flags&BLOCK_FLAG_CORRUPTED )
192 p_sys->i_state = STATE_NOSYNC;
193 block_BytestreamEmpty( &p_sys->bytestream );
195 date_Set( &p_sys->end_date, 0 );
196 block_Release( *pp_block );
197 return NULL;
200 if( !date_Get( &p_sys->end_date ) && (*pp_block)->i_pts <= VLC_TS_INVALID )
202 /* We've just started the stream, wait for the first PTS. */
203 block_Release( *pp_block );
204 return NULL;
207 block_BytestreamPush( &p_sys->bytestream, *pp_block );
209 while( 1 )
211 switch( p_sys->i_state )
213 case STATE_NOSYNC:
214 /* Look for sync code - should be 0x7ffe8001 */
215 while( block_PeekBytes( &p_sys->bytestream, p_header, 6 )
216 == VLC_SUCCESS )
218 if( SyncCode( p_header ) == VLC_SUCCESS )
220 p_sys->i_state = STATE_SYNC;
221 break;
223 block_SkipByte( &p_sys->bytestream );
225 if( p_sys->i_state != STATE_SYNC )
227 block_BytestreamFlush( &p_sys->bytestream );
229 /* Need more data */
230 return NULL;
233 case STATE_SYNC:
234 /* New frame, set the Presentation Time Stamp */
235 p_sys->i_pts = p_sys->bytestream.p_block->i_pts;
236 if( p_sys->i_pts > VLC_TS_INVALID &&
237 p_sys->i_pts != date_Get( &p_sys->end_date ) )
239 date_Set( &p_sys->end_date, p_sys->i_pts );
241 p_sys->i_state = STATE_HEADER;
243 case STATE_HEADER:
244 /* Get DTS frame header (DTS_HEADER_SIZE bytes) */
245 if( block_PeekBytes( &p_sys->bytestream, p_header,
246 DTS_HEADER_SIZE ) != VLC_SUCCESS )
248 /* Need more data */
249 return NULL;
252 /* Check if frame is valid and get frame info */
253 p_sys->i_frame_size = SyncInfo( p_header,
254 &p_sys->b_dts_hd,
255 &p_sys->i_channels,
256 &p_sys->i_channels_conf,
257 &p_sys->i_rate,
258 &p_sys->i_bit_rate,
259 &p_sys->i_frame_length );
260 if( !p_sys->i_frame_size )
262 msg_Dbg( p_dec, "emulated sync word" );
263 block_SkipByte( &p_sys->bytestream );
264 p_sys->i_state = STATE_NOSYNC;
265 break;
267 p_sys->i_state = STATE_NEXT_SYNC;
269 case STATE_NEXT_SYNC:
270 /* TODO: If pp_block == NULL, flush the buffer without checking the
271 * next sync word */
273 /* Check if next expected frame contains the sync word */
274 if( block_PeekOffsetBytes( &p_sys->bytestream,
275 p_sys->i_frame_size, p_header, 6 )
276 != VLC_SUCCESS )
278 /* Need more data */
279 return NULL;
282 if( p_sys->b_packetizer &&
283 p_header[0] == 0 && p_header[1] == 0 )
285 /* DTS wav files and audio CD's use stuffing */
286 p_sys->i_state = STATE_SEND_DATA;
287 break;
290 if( SyncCode( p_header ) != VLC_SUCCESS )
292 msg_Dbg( p_dec, "emulated sync word "
293 "(no sync on following frame): %2.2x%2.2x%2.2x%2.2x",
294 (int)p_header[0], (int)p_header[1],
295 (int)p_header[2], (int)p_header[3] );
296 p_sys->i_state = STATE_NOSYNC;
297 block_SkipByte( &p_sys->bytestream );
298 break;
300 p_sys->i_state = STATE_SEND_DATA;
301 break;
303 case STATE_GET_DATA:
304 /* Make sure we have enough data.
305 * (Not useful if we went through NEXT_SYNC) */
306 if( block_WaitBytes( &p_sys->bytestream,
307 p_sys->i_frame_size ) != VLC_SUCCESS )
309 /* Need more data */
310 return NULL;
312 p_sys->i_state = STATE_SEND_DATA;
314 case STATE_SEND_DATA:
315 if( p_sys->b_dts_hd )
317 /* Ignore DTS-HD */
318 block_SkipBytes( &p_sys->bytestream, p_sys->i_frame_size );
319 p_sys->i_state = STATE_NOSYNC;
320 break;
323 if( !(p_buf = GetOutBuffer( p_dec, &p_out_buffer )) )
325 //p_dec->b_error = true;
326 return NULL;
329 /* Copy the whole frame into the buffer. When we reach this point
330 * we already know we have enough data available. */
331 block_GetBytes( &p_sys->bytestream,
332 p_buf, __MIN( p_sys->i_frame_size, p_out_buffer->i_buffer ) );
334 /* Make sure we don't reuse the same pts twice */
335 if( p_sys->i_pts == p_sys->bytestream.p_block->i_pts )
336 p_sys->i_pts = p_sys->bytestream.p_block->i_pts = VLC_TS_INVALID;
338 p_sys->i_state = STATE_NOSYNC;
340 /* So p_block doesn't get re-added several times */
341 *pp_block = block_BytestreamPop( &p_sys->bytestream );
343 return p_out_buffer;
347 return NULL;
350 /*****************************************************************************
351 * CloseCommon: clean up the decoder
352 *****************************************************************************/
353 static void CloseCommon( vlc_object_t *p_this )
355 decoder_t *p_dec = (decoder_t*)p_this;
356 decoder_sys_t *p_sys = p_dec->p_sys;
358 block_BytestreamRelease( &p_sys->bytestream );
360 free( p_sys );
363 /*****************************************************************************
364 * GetOutBuffer:
365 *****************************************************************************/
366 static uint8_t *GetOutBuffer( decoder_t *p_dec, block_t **pp_out_buffer )
368 decoder_sys_t *p_sys = p_dec->p_sys;
369 uint8_t *p_buf;
371 if( p_dec->fmt_out.audio.i_rate != p_sys->i_rate )
373 msg_Info( p_dec, "DTS channels:%d samplerate:%d bitrate:%d",
374 p_sys->i_channels, p_sys->i_rate, p_sys->i_bit_rate );
376 date_Init( &p_sys->end_date, p_sys->i_rate, 1 );
377 date_Set( &p_sys->end_date, p_sys->i_pts );
380 p_dec->fmt_out.audio.i_rate = p_sys->i_rate;
381 p_dec->fmt_out.audio.i_channels = p_sys->i_channels;
382 /* Hack for DTS S/PDIF filter which needs to pad the DTS frames */
383 p_dec->fmt_out.audio.i_bytes_per_frame =
384 __MAX( p_sys->i_frame_size, p_sys->i_frame_length * 4 );
385 p_dec->fmt_out.audio.i_frame_length = p_sys->i_frame_length;
387 p_dec->fmt_out.audio.i_original_channels = p_sys->i_channels_conf;
388 p_dec->fmt_out.audio.i_physical_channels =
389 p_sys->i_channels_conf & AOUT_CHAN_PHYSMASK;
391 p_dec->fmt_out.i_bitrate = p_sys->i_bit_rate;
393 if( p_sys->b_packetizer )
395 block_t *p_sout_buffer = GetSoutBuffer( p_dec );
396 p_buf = p_sout_buffer ? p_sout_buffer->p_buffer : NULL;
397 *pp_out_buffer = p_sout_buffer;
399 else
401 aout_buffer_t *p_aout_buffer = GetAoutBuffer( p_dec );
402 p_buf = p_aout_buffer ? p_aout_buffer->p_buffer : NULL;
403 *pp_out_buffer = p_aout_buffer;
406 return p_buf;
409 /*****************************************************************************
410 * GetAoutBuffer:
411 *****************************************************************************/
412 static aout_buffer_t *GetAoutBuffer( decoder_t *p_dec )
414 decoder_sys_t *p_sys = p_dec->p_sys;
415 aout_buffer_t *p_buf;
417 /* Hack for DTS S/PDIF filter which needs to send 3 frames at a time
418 * (plus a few header bytes) */
419 p_buf = decoder_NewAudioBuffer( p_dec, p_sys->i_frame_length * 4 );
420 if( p_buf == NULL ) return NULL;
421 p_buf->i_nb_samples = p_sys->i_frame_length;
422 p_buf->i_buffer = p_sys->i_frame_size;
424 p_buf->i_pts = date_Get( &p_sys->end_date );
425 p_buf->i_length = date_Increment( &p_sys->end_date, p_sys->i_frame_length )
426 - p_buf->i_pts;
428 return p_buf;
431 /*****************************************************************************
432 * GetSoutBuffer:
433 *****************************************************************************/
434 static block_t *GetSoutBuffer( decoder_t *p_dec )
436 decoder_sys_t *p_sys = p_dec->p_sys;
437 block_t *p_block;
439 p_block = block_New( p_dec, p_sys->i_frame_size );
440 if( p_block == NULL ) return NULL;
442 p_block->i_pts = p_block->i_dts = date_Get( &p_sys->end_date );
444 p_block->i_length = date_Increment( &p_sys->end_date,
445 p_sys->i_frame_length ) - p_block->i_pts;
447 return p_block;
450 /*****************************************************************************
451 * SyncInfo: parse DTS sync info
452 *****************************************************************************/
453 static const unsigned int ppi_dts_samplerate[] =
455 0, 8000, 16000, 32000, 0, 0, 11025, 22050, 44100, 0, 0,
456 12000, 24000, 48000, 96000, 192000
459 static const unsigned int ppi_dts_bitrate[] =
461 32000, 56000, 64000, 96000, 112000, 128000,
462 192000, 224000, 256000, 320000, 384000,
463 448000, 512000, 576000, 640000, 768000,
464 896000, 1024000, 1152000, 1280000, 1344000,
465 1408000, 1411200, 1472000, 1536000, 1920000,
466 2048000, 3072000, 3840000, 1/*open*/, 2/*variable*/, 3/*lossless*/
469 static int SyncInfo16be( const uint8_t *p_buf,
470 unsigned int *pi_audio_mode,
471 unsigned int *pi_sample_rate,
472 unsigned int *pi_bit_rate,
473 unsigned int *pi_frame_length )
475 unsigned int i_frame_size;
476 unsigned int i_lfe;
478 *pi_frame_length = (p_buf[4] & 0x01) << 6 | (p_buf[5] >> 2);
479 i_frame_size = (p_buf[5] & 0x03) << 12 | (p_buf[6] << 4) |
480 (p_buf[7] >> 4);
482 *pi_audio_mode = (p_buf[7] & 0x0f) << 2 | (p_buf[8] >> 6);
483 *pi_sample_rate = (p_buf[8] >> 2) & 0x0f;
484 *pi_bit_rate = (p_buf[8] & 0x03) << 3 | ((p_buf[9] >> 5) & 0x07);
486 i_lfe = (p_buf[10] >> 1) & 0x03;
487 if( i_lfe ) *pi_audio_mode |= 0x10000;
489 return i_frame_size + 1;
492 static void BufLeToBe( uint8_t *p_out, const uint8_t *p_in, int i_in )
494 int i;
496 for( i = 0; i < i_in/2; i++ )
498 p_out[i*2] = p_in[i*2+1];
499 p_out[i*2+1] = p_in[i*2];
503 static int Buf14To16( uint8_t *p_out, const uint8_t *p_in, int i_in, int i_le )
505 unsigned char tmp, cur = 0;
506 int bits_in, bits_out = 0;
507 int i, i_out = 0;
509 for( i = 0; i < i_in; i++ )
511 if( i%2 )
513 tmp = p_in[i-i_le];
514 bits_in = 8;
516 else
518 tmp = p_in[i+i_le] & 0x3F;
519 bits_in = 8 - 2;
522 if( bits_out < 8 )
524 int need = __MIN( 8 - bits_out, bits_in );
525 cur <<= need;
526 cur |= ( tmp >> (bits_in - need) );
527 tmp <<= (8 - bits_in + need);
528 tmp >>= (8 - bits_in + need);
529 bits_in -= need;
530 bits_out += need;
533 if( bits_out == 8 )
535 p_out[i_out] = cur;
536 cur = 0;
537 bits_out = 0;
538 i_out++;
541 bits_out += bits_in;
542 cur <<= bits_in;
543 cur |= tmp;
546 return i_out;
549 static inline int SyncCode( const uint8_t *p_buf )
551 /* 14 bits, little endian version of the bitstream */
552 if( p_buf[0] == 0xff && p_buf[1] == 0x1f &&
553 p_buf[2] == 0x00 && p_buf[3] == 0xe8 &&
554 (p_buf[4] & 0xf0) == 0xf0 && p_buf[5] == 0x07 )
556 return VLC_SUCCESS;
558 /* 14 bits, big endian version of the bitstream */
559 else if( p_buf[0] == 0x1f && p_buf[1] == 0xff &&
560 p_buf[2] == 0xe8 && p_buf[3] == 0x00 &&
561 p_buf[4] == 0x07 && (p_buf[5] & 0xf0) == 0xf0 )
563 return VLC_SUCCESS;
565 /* 16 bits, big endian version of the bitstream */
566 else if( p_buf[0] == 0x7f && p_buf[1] == 0xfe &&
567 p_buf[2] == 0x80 && p_buf[3] == 0x01 )
569 return VLC_SUCCESS;
571 /* 16 bits, little endian version of the bitstream */
572 else if( p_buf[0] == 0xfe && p_buf[1] == 0x7f &&
573 p_buf[2] == 0x01 && p_buf[3] == 0x80 )
575 return VLC_SUCCESS;
577 /* DTS-HD */
578 else if( p_buf[0] == 0x64 && p_buf[1] == 0x58 &&
579 p_buf[2] == 0x20 && p_buf[3] == 0x25 )
581 return VLC_SUCCESS;
584 return VLC_EGENERIC;
587 static int SyncInfo( const uint8_t *p_buf,
588 bool *pb_dts_hd,
589 unsigned int *pi_channels,
590 unsigned int *pi_channels_conf,
591 unsigned int *pi_sample_rate,
592 unsigned int *pi_bit_rate,
593 unsigned int *pi_frame_length )
595 unsigned int i_audio_mode;
596 unsigned int i_frame_size;
598 /* 14 bits, little endian version of the bitstream */
599 if( p_buf[0] == 0xff && p_buf[1] == 0x1f &&
600 p_buf[2] == 0x00 && p_buf[3] == 0xe8 &&
601 (p_buf[4] & 0xf0) == 0xf0 && p_buf[5] == 0x07 )
603 uint8_t conv_buf[DTS_HEADER_SIZE];
604 Buf14To16( conv_buf, p_buf, DTS_HEADER_SIZE, 1 );
605 i_frame_size = SyncInfo16be( conv_buf, &i_audio_mode, pi_sample_rate,
606 pi_bit_rate, pi_frame_length );
607 i_frame_size = i_frame_size * 8 / 14 * 2;
609 /* 14 bits, big endian version of the bitstream */
610 else if( p_buf[0] == 0x1f && p_buf[1] == 0xff &&
611 p_buf[2] == 0xe8 && p_buf[3] == 0x00 &&
612 p_buf[4] == 0x07 && (p_buf[5] & 0xf0) == 0xf0 )
614 uint8_t conv_buf[DTS_HEADER_SIZE];
615 Buf14To16( conv_buf, p_buf, DTS_HEADER_SIZE, 0 );
616 i_frame_size = SyncInfo16be( conv_buf, &i_audio_mode, pi_sample_rate,
617 pi_bit_rate, pi_frame_length );
618 i_frame_size = i_frame_size * 8 / 14 * 2;
620 /* 16 bits, big endian version of the bitstream */
621 else if( p_buf[0] == 0x7f && p_buf[1] == 0xfe &&
622 p_buf[2] == 0x80 && p_buf[3] == 0x01 )
624 i_frame_size = SyncInfo16be( p_buf, &i_audio_mode, pi_sample_rate,
625 pi_bit_rate, pi_frame_length );
627 /* 16 bits, little endian version of the bitstream */
628 else if( p_buf[0] == 0xfe && p_buf[1] == 0x7f &&
629 p_buf[2] == 0x01 && p_buf[3] == 0x80 )
631 uint8_t conv_buf[DTS_HEADER_SIZE];
632 BufLeToBe( conv_buf, p_buf, DTS_HEADER_SIZE );
633 i_frame_size = SyncInfo16be( p_buf, &i_audio_mode, pi_sample_rate,
634 pi_bit_rate, pi_frame_length );
636 /* DTS-HD */
637 else
639 assert( p_buf[0] == 0x64 && p_buf[1] == 0x58 &&
640 p_buf[2] == 0x20 && p_buf[3] == 0x25 );
642 int i_dts_hd_size;
643 bs_t s;
644 bs_init( &s, &p_buf[4], DTS_HEADER_SIZE - 4 );
646 bs_skip( &s, 8 + 2 );
648 if( bs_read1( &s ) )
650 bs_skip( &s, 12 );
651 i_dts_hd_size = bs_read( &s, 20 ) + 1;
653 else
655 bs_skip( &s, 8 );
656 i_dts_hd_size = bs_read( &s, 16 ) + 1;
658 //uint16_t s0 = bs_read( &s, 16 );
659 //uint16_t s1 = bs_read( &s, 16 );
660 //fprintf( stderr, "DTS HD=%d : %x %x\n", i_dts_hd_size, s0, s1 );
662 *pb_dts_hd = true;
663 /* As we ignore the stream, do not modify those variables:
664 *pi_channels = ;
665 *pi_channels_conf = ;
666 *pi_sample_rate = ;
667 *pi_bit_rate = ;
668 *pi_frame_length = ;
670 return i_dts_hd_size;
673 *pb_dts_hd = false;
675 switch( i_audio_mode & 0xFFFF )
677 case 0x0:
678 /* Mono */
679 *pi_channels = 1;
680 *pi_channels_conf = AOUT_CHAN_CENTER;
681 break;
682 case 0x1:
683 /* Dual-mono = stereo + dual-mono */
684 *pi_channels = 2;
685 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
686 AOUT_CHAN_DUALMONO;
687 break;
688 case 0x2:
689 case 0x3:
690 case 0x4:
691 /* Stereo */
692 *pi_channels = 2;
693 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
694 break;
695 case 0x5:
696 /* 3F */
697 *pi_channels = 3;
698 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
699 AOUT_CHAN_CENTER;
700 break;
701 case 0x6:
702 /* 2F/1R */
703 *pi_channels = 3;
704 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
705 AOUT_CHAN_REARCENTER;
706 break;
707 case 0x7:
708 /* 3F/1R */
709 *pi_channels = 4;
710 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
711 AOUT_CHAN_CENTER | AOUT_CHAN_REARCENTER;
712 break;
713 case 0x8:
714 /* 2F2R */
715 *pi_channels = 4;
716 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
717 AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
718 break;
719 case 0x9:
720 /* 3F2R */
721 *pi_channels = 5;
722 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
723 AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT |
724 AOUT_CHAN_REARRIGHT;
725 break;
726 case 0xA:
727 case 0xB:
728 /* 2F2M2R */
729 *pi_channels = 6;
730 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
731 AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT |
732 AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
733 break;
734 case 0xC:
735 /* 3F2M2R */
736 *pi_channels = 7;
737 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
738 AOUT_CHAN_CENTER | AOUT_CHAN_MIDDLELEFT |
739 AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_REARLEFT |
740 AOUT_CHAN_REARRIGHT;
741 break;
742 case 0xD:
743 case 0xE:
744 /* 3F2M2R/LFE */
745 *pi_channels = 8;
746 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
747 AOUT_CHAN_CENTER | AOUT_CHAN_MIDDLELEFT |
748 AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_REARLEFT |
749 AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE;
750 break;
752 default:
753 if( i_audio_mode <= 63 )
755 /* User defined */
756 *pi_channels = 0;
757 *pi_channels_conf = 0;
759 else return 0;
760 break;
763 if( i_audio_mode & 0x10000 )
765 (*pi_channels)++;
766 *pi_channels_conf |= AOUT_CHAN_LFE;
769 if( *pi_sample_rate >= sizeof( ppi_dts_samplerate ) /
770 sizeof( ppi_dts_samplerate[0] ) )
772 return 0;
774 *pi_sample_rate = ppi_dts_samplerate[ *pi_sample_rate ];
775 if( !*pi_sample_rate ) return 0;
777 if( *pi_bit_rate >= sizeof( ppi_dts_bitrate ) /
778 sizeof( ppi_dts_bitrate[0] ) )
780 return 0;
782 *pi_bit_rate = ppi_dts_bitrate[ *pi_bit_rate ];
783 if( !*pi_bit_rate ) return 0;
785 *pi_frame_length = (*pi_frame_length + 1) * 32;
787 return i_frame_size;