Qt: do not show open options in both normal and advanced UI
[vlc.git] / modules / codec / dts.c
blob50240ea3cb8ed36c3250e8db7e8ab646f39fe8b4
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>
41 #include <vlc_cpu.h>
43 #include "../packetizer/packetizer_helper.h"
45 /*****************************************************************************
46 * Module descriptor
47 *****************************************************************************/
48 static int OpenDecoder ( vlc_object_t * );
49 static int OpenPacketizer( vlc_object_t * );
50 static void CloseCommon ( vlc_object_t * );
52 vlc_module_begin ()
53 set_description( N_("DTS parser") )
54 set_capability( "decoder", 100 )
55 set_callbacks( OpenDecoder, CloseCommon )
57 add_submodule ()
58 set_description( N_("DTS audio packetizer") )
59 set_capability( "packetizer", 10 )
60 set_callbacks( OpenPacketizer, CloseCommon )
61 vlc_module_end ()
63 /*****************************************************************************
64 * decoder_sys_t : decoder descriptor
65 *****************************************************************************/
66 struct decoder_sys_t
68 /* Module mode */
69 bool b_packetizer;
72 * Input properties
74 int i_state;
76 block_bytestream_t bytestream;
79 * Common properties
81 date_t end_date;
83 mtime_t i_pts;
85 bool b_dts_hd; /* Is the current frame a DTS HD one */
86 unsigned int i_bit_rate;
87 unsigned int i_frame_size;
88 unsigned int i_frame_length;
89 unsigned int i_rate;
90 unsigned int i_channels;
91 unsigned int i_channels_conf;
94 #define DTS_HEADER_SIZE 14
96 /****************************************************************************
97 * Local prototypes
98 ****************************************************************************/
99 static int OpenCommon( vlc_object_t *, bool b_packetizer );
100 static block_t *DecodeBlock( decoder_t *, block_t ** );
102 static inline int SyncCode( const uint8_t * );
103 static int SyncInfo( const uint8_t *, bool *, unsigned int *, unsigned int *,
104 unsigned int *, unsigned int *, unsigned int * );
106 static uint8_t *GetOutBuffer ( decoder_t *, block_t ** );
107 static aout_buffer_t *GetAoutBuffer( decoder_t * );
108 static block_t *GetSoutBuffer( decoder_t * );
110 /*****************************************************************************
111 * OpenDecoder: probe the decoder
112 *****************************************************************************/
113 static int OpenDecoder( vlc_object_t *p_this )
115 /* HACK: Don't use this codec if we don't have an dts audio filter */
116 if( !HAVE_FPU || !module_exists( "dtstofloat32" ) )
117 return VLC_EGENERIC;
119 return OpenCommon( p_this, false );
122 /*****************************************************************************
123 * OpenPacketizer: probe the packetizer
124 *****************************************************************************/
125 static int OpenPacketizer( vlc_object_t *p_this )
127 return OpenCommon( p_this, true );
130 /*****************************************************************************
131 * OpenCommon:
132 *****************************************************************************/
133 static int OpenCommon( vlc_object_t *p_this, bool b_packetizer )
135 decoder_t *p_dec = (decoder_t*)p_this;
136 decoder_sys_t *p_sys;
138 if( p_dec->fmt_in.i_codec != VLC_CODEC_DTS )
139 return VLC_EGENERIC;
141 /* Allocate the memory needed to store the decoder's structure */
142 if( ( p_dec->p_sys = p_sys = malloc(sizeof(*p_sys)) ) == NULL )
143 return VLC_ENOMEM;
145 /* Misc init */
146 p_sys->b_packetizer = b_packetizer;
147 p_sys->i_state = STATE_NOSYNC;
148 date_Set( &p_sys->end_date, 0 );
149 p_sys->b_dts_hd = false;
150 p_sys->i_pts = VLC_TS_INVALID;
152 block_BytestreamInit( &p_sys->bytestream );
154 /* Set output properties */
155 p_dec->fmt_out.i_cat = AUDIO_ES;
156 p_dec->fmt_out.i_codec = VLC_CODEC_DTS;
157 p_dec->fmt_out.audio.i_rate = 0; /* So end_date gets initialized */
159 /* Set callback */
160 p_dec->pf_decode_audio = DecodeBlock;
161 p_dec->pf_packetize = DecodeBlock;
163 return VLC_SUCCESS;
166 /****************************************************************************
167 * DecodeBlock: the whole thing
168 ****************************************************************************/
169 static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
171 decoder_sys_t *p_sys = p_dec->p_sys;
172 uint8_t p_header[DTS_HEADER_SIZE];
173 uint8_t *p_buf;
174 block_t *p_out_buffer;
176 if( !pp_block || !*pp_block )
177 return NULL;
179 if( (*pp_block)->i_flags&(BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
181 if( (*pp_block)->i_flags&BLOCK_FLAG_CORRUPTED )
183 p_sys->i_state = STATE_NOSYNC;
184 block_BytestreamEmpty( &p_sys->bytestream );
186 date_Set( &p_sys->end_date, 0 );
187 block_Release( *pp_block );
188 return NULL;
191 if( !date_Get( &p_sys->end_date ) && (*pp_block)->i_pts <= VLC_TS_INVALID )
193 /* We've just started the stream, wait for the first PTS. */
194 block_Release( *pp_block );
195 return NULL;
198 block_BytestreamPush( &p_sys->bytestream, *pp_block );
200 while( 1 )
202 switch( p_sys->i_state )
204 case STATE_NOSYNC:
205 /* Look for sync code - should be 0x7ffe8001 */
206 while( block_PeekBytes( &p_sys->bytestream, p_header, 6 )
207 == VLC_SUCCESS )
209 if( SyncCode( p_header ) == VLC_SUCCESS )
211 p_sys->i_state = STATE_SYNC;
212 break;
214 block_SkipByte( &p_sys->bytestream );
216 if( p_sys->i_state != STATE_SYNC )
218 block_BytestreamFlush( &p_sys->bytestream );
220 /* Need more data */
221 return NULL;
224 case STATE_SYNC:
225 /* New frame, set the Presentation Time Stamp */
226 p_sys->i_pts = p_sys->bytestream.p_block->i_pts;
227 if( p_sys->i_pts > VLC_TS_INVALID &&
228 p_sys->i_pts != date_Get( &p_sys->end_date ) )
230 date_Set( &p_sys->end_date, p_sys->i_pts );
232 p_sys->i_state = STATE_HEADER;
234 case STATE_HEADER:
235 /* Get DTS frame header (DTS_HEADER_SIZE bytes) */
236 if( block_PeekBytes( &p_sys->bytestream, p_header,
237 DTS_HEADER_SIZE ) != VLC_SUCCESS )
239 /* Need more data */
240 return NULL;
243 /* Check if frame is valid and get frame info */
244 p_sys->i_frame_size = SyncInfo( p_header,
245 &p_sys->b_dts_hd,
246 &p_sys->i_channels,
247 &p_sys->i_channels_conf,
248 &p_sys->i_rate,
249 &p_sys->i_bit_rate,
250 &p_sys->i_frame_length );
251 if( !p_sys->i_frame_size )
253 msg_Dbg( p_dec, "emulated sync word" );
254 block_SkipByte( &p_sys->bytestream );
255 p_sys->i_state = STATE_NOSYNC;
256 break;
258 p_sys->i_state = STATE_NEXT_SYNC;
260 case STATE_NEXT_SYNC:
261 /* TODO: If pp_block == NULL, flush the buffer without checking the
262 * next sync word */
264 /* Check if next expected frame contains the sync word */
265 if( block_PeekOffsetBytes( &p_sys->bytestream,
266 p_sys->i_frame_size, p_header, 6 )
267 != VLC_SUCCESS )
269 /* Need more data */
270 return NULL;
273 if( p_sys->b_packetizer &&
274 p_header[0] == 0 && p_header[1] == 0 )
276 /* DTS wav files and audio CD's use stuffing */
277 p_sys->i_state = STATE_SEND_DATA;
278 break;
281 if( SyncCode( p_header ) != VLC_SUCCESS )
283 msg_Dbg( p_dec, "emulated sync word "
284 "(no sync on following frame): %2.2x%2.2x%2.2x%2.2x",
285 (int)p_header[0], (int)p_header[1],
286 (int)p_header[2], (int)p_header[3] );
287 p_sys->i_state = STATE_NOSYNC;
288 block_SkipByte( &p_sys->bytestream );
289 break;
291 p_sys->i_state = STATE_SEND_DATA;
292 break;
294 case STATE_GET_DATA:
295 /* Make sure we have enough data.
296 * (Not useful if we went through NEXT_SYNC) */
297 if( block_WaitBytes( &p_sys->bytestream,
298 p_sys->i_frame_size ) != VLC_SUCCESS )
300 /* Need more data */
301 return NULL;
303 p_sys->i_state = STATE_SEND_DATA;
305 case STATE_SEND_DATA:
306 if( p_sys->b_dts_hd )
308 /* Ignore DTS-HD */
309 block_SkipBytes( &p_sys->bytestream, p_sys->i_frame_size );
310 p_sys->i_state = STATE_NOSYNC;
311 break;
314 if( !(p_buf = GetOutBuffer( p_dec, &p_out_buffer )) )
316 //p_dec->b_error = true;
317 return NULL;
320 /* Copy the whole frame into the buffer. When we reach this point
321 * we already know we have enough data available. */
322 block_GetBytes( &p_sys->bytestream,
323 p_buf, __MIN( p_sys->i_frame_size, p_out_buffer->i_buffer ) );
325 /* Make sure we don't reuse the same pts twice */
326 if( p_sys->i_pts == p_sys->bytestream.p_block->i_pts )
327 p_sys->i_pts = p_sys->bytestream.p_block->i_pts = VLC_TS_INVALID;
329 p_sys->i_state = STATE_NOSYNC;
331 /* So p_block doesn't get re-added several times */
332 *pp_block = block_BytestreamPop( &p_sys->bytestream );
334 return p_out_buffer;
338 return NULL;
341 /*****************************************************************************
342 * CloseCommon: clean up the decoder
343 *****************************************************************************/
344 static void CloseCommon( vlc_object_t *p_this )
346 decoder_t *p_dec = (decoder_t*)p_this;
347 decoder_sys_t *p_sys = p_dec->p_sys;
349 block_BytestreamRelease( &p_sys->bytestream );
351 free( p_sys );
354 /*****************************************************************************
355 * GetOutBuffer:
356 *****************************************************************************/
357 static uint8_t *GetOutBuffer( decoder_t *p_dec, block_t **pp_out_buffer )
359 decoder_sys_t *p_sys = p_dec->p_sys;
360 uint8_t *p_buf;
362 if( p_dec->fmt_out.audio.i_rate != p_sys->i_rate )
364 msg_Info( p_dec, "DTS channels:%d samplerate:%d bitrate:%d",
365 p_sys->i_channels, p_sys->i_rate, p_sys->i_bit_rate );
367 date_Init( &p_sys->end_date, p_sys->i_rate, 1 );
368 date_Set( &p_sys->end_date, p_sys->i_pts );
371 p_dec->fmt_out.audio.i_rate = p_sys->i_rate;
372 p_dec->fmt_out.audio.i_channels = p_sys->i_channels;
373 /* Hack for DTS S/PDIF filter which needs to pad the DTS frames */
374 p_dec->fmt_out.audio.i_bytes_per_frame =
375 __MAX( p_sys->i_frame_size, p_sys->i_frame_length * 4 );
376 p_dec->fmt_out.audio.i_frame_length = p_sys->i_frame_length;
378 p_dec->fmt_out.audio.i_original_channels = p_sys->i_channels_conf;
379 p_dec->fmt_out.audio.i_physical_channels =
380 p_sys->i_channels_conf & AOUT_CHAN_PHYSMASK;
382 p_dec->fmt_out.i_bitrate = p_sys->i_bit_rate;
384 if( p_sys->b_packetizer )
386 block_t *p_sout_buffer = GetSoutBuffer( p_dec );
387 p_buf = p_sout_buffer ? p_sout_buffer->p_buffer : NULL;
388 *pp_out_buffer = p_sout_buffer;
390 else
392 aout_buffer_t *p_aout_buffer = GetAoutBuffer( p_dec );
393 p_buf = p_aout_buffer ? p_aout_buffer->p_buffer : NULL;
394 *pp_out_buffer = p_aout_buffer;
397 return p_buf;
400 /*****************************************************************************
401 * GetAoutBuffer:
402 *****************************************************************************/
403 static aout_buffer_t *GetAoutBuffer( decoder_t *p_dec )
405 decoder_sys_t *p_sys = p_dec->p_sys;
406 aout_buffer_t *p_buf;
408 /* Hack for DTS S/PDIF filter which needs to send 3 frames at a time
409 * (plus a few header bytes) */
410 p_buf = decoder_NewAudioBuffer( p_dec, p_sys->i_frame_length * 4 );
411 if( p_buf == NULL ) return NULL;
412 p_buf->i_nb_samples = p_sys->i_frame_length;
413 p_buf->i_buffer = p_sys->i_frame_size;
415 p_buf->i_pts = date_Get( &p_sys->end_date );
416 p_buf->i_length = date_Increment( &p_sys->end_date, p_sys->i_frame_length )
417 - p_buf->i_pts;
419 return p_buf;
422 /*****************************************************************************
423 * GetSoutBuffer:
424 *****************************************************************************/
425 static block_t *GetSoutBuffer( decoder_t *p_dec )
427 decoder_sys_t *p_sys = p_dec->p_sys;
428 block_t *p_block;
430 p_block = block_New( p_dec, p_sys->i_frame_size );
431 if( p_block == NULL ) return NULL;
433 p_block->i_pts = p_block->i_dts = date_Get( &p_sys->end_date );
435 p_block->i_length = date_Increment( &p_sys->end_date,
436 p_sys->i_frame_length ) - p_block->i_pts;
438 return p_block;
441 /*****************************************************************************
442 * SyncInfo: parse DTS sync info
443 *****************************************************************************/
444 static const unsigned int ppi_dts_samplerate[] =
446 0, 8000, 16000, 32000, 0, 0, 11025, 22050, 44100, 0, 0,
447 12000, 24000, 48000, 96000, 192000
450 static const unsigned int ppi_dts_bitrate[] =
452 32000, 56000, 64000, 96000, 112000, 128000,
453 192000, 224000, 256000, 320000, 384000,
454 448000, 512000, 576000, 640000, 768000,
455 896000, 1024000, 1152000, 1280000, 1344000,
456 1408000, 1411200, 1472000, 1536000, 1920000,
457 2048000, 3072000, 3840000, 1/*open*/, 2/*variable*/, 3/*lossless*/
460 static int SyncInfo16be( const uint8_t *p_buf,
461 unsigned int *pi_audio_mode,
462 unsigned int *pi_sample_rate,
463 unsigned int *pi_bit_rate,
464 unsigned int *pi_frame_length )
466 unsigned int i_frame_size;
467 unsigned int i_lfe;
469 *pi_frame_length = (p_buf[4] & 0x01) << 6 | (p_buf[5] >> 2);
470 i_frame_size = (p_buf[5] & 0x03) << 12 | (p_buf[6] << 4) |
471 (p_buf[7] >> 4);
473 *pi_audio_mode = (p_buf[7] & 0x0f) << 2 | (p_buf[8] >> 6);
474 *pi_sample_rate = (p_buf[8] >> 2) & 0x0f;
475 *pi_bit_rate = (p_buf[8] & 0x03) << 3 | ((p_buf[9] >> 5) & 0x07);
477 i_lfe = (p_buf[10] >> 1) & 0x03;
478 if( i_lfe ) *pi_audio_mode |= 0x10000;
480 return i_frame_size + 1;
483 static void BufLeToBe( uint8_t *p_out, const uint8_t *p_in, int i_in )
485 int i;
487 for( i = 0; i < i_in/2; i++ )
489 p_out[i*2] = p_in[i*2+1];
490 p_out[i*2+1] = p_in[i*2];
494 static int Buf14To16( uint8_t *p_out, const uint8_t *p_in, int i_in, int i_le )
496 unsigned char tmp, cur = 0;
497 int bits_in, bits_out = 0;
498 int i, i_out = 0;
500 for( i = 0; i < i_in; i++ )
502 if( i%2 )
504 tmp = p_in[i-i_le];
505 bits_in = 8;
507 else
509 tmp = p_in[i+i_le] & 0x3F;
510 bits_in = 8 - 2;
513 if( bits_out < 8 )
515 int need = __MIN( 8 - bits_out, bits_in );
516 cur <<= need;
517 cur |= ( tmp >> (bits_in - need) );
518 tmp <<= (8 - bits_in + need);
519 tmp >>= (8 - bits_in + need);
520 bits_in -= need;
521 bits_out += need;
524 if( bits_out == 8 )
526 p_out[i_out] = cur;
527 cur = 0;
528 bits_out = 0;
529 i_out++;
532 bits_out += bits_in;
533 cur <<= bits_in;
534 cur |= tmp;
537 return i_out;
540 static inline int SyncCode( const uint8_t *p_buf )
542 /* 14 bits, little endian version of the bitstream */
543 if( p_buf[0] == 0xff && p_buf[1] == 0x1f &&
544 p_buf[2] == 0x00 && p_buf[3] == 0xe8 &&
545 (p_buf[4] & 0xf0) == 0xf0 && p_buf[5] == 0x07 )
547 return VLC_SUCCESS;
549 /* 14 bits, big endian version of the bitstream */
550 else if( p_buf[0] == 0x1f && p_buf[1] == 0xff &&
551 p_buf[2] == 0xe8 && p_buf[3] == 0x00 &&
552 p_buf[4] == 0x07 && (p_buf[5] & 0xf0) == 0xf0 )
554 return VLC_SUCCESS;
556 /* 16 bits, big endian version of the bitstream */
557 else if( p_buf[0] == 0x7f && p_buf[1] == 0xfe &&
558 p_buf[2] == 0x80 && p_buf[3] == 0x01 )
560 return VLC_SUCCESS;
562 /* 16 bits, little endian version of the bitstream */
563 else if( p_buf[0] == 0xfe && p_buf[1] == 0x7f &&
564 p_buf[2] == 0x01 && p_buf[3] == 0x80 )
566 return VLC_SUCCESS;
568 /* DTS-HD */
569 else if( p_buf[0] == 0x64 && p_buf[1] == 0x58 &&
570 p_buf[2] == 0x20 && p_buf[3] == 0x25 )
572 return VLC_SUCCESS;
575 return VLC_EGENERIC;
578 static int SyncInfo( const uint8_t *p_buf,
579 bool *pb_dts_hd,
580 unsigned int *pi_channels,
581 unsigned int *pi_channels_conf,
582 unsigned int *pi_sample_rate,
583 unsigned int *pi_bit_rate,
584 unsigned int *pi_frame_length )
586 unsigned int i_audio_mode;
587 unsigned int i_frame_size;
589 /* 14 bits, little endian version of the bitstream */
590 if( p_buf[0] == 0xff && p_buf[1] == 0x1f &&
591 p_buf[2] == 0x00 && p_buf[3] == 0xe8 &&
592 (p_buf[4] & 0xf0) == 0xf0 && p_buf[5] == 0x07 )
594 uint8_t conv_buf[DTS_HEADER_SIZE];
595 Buf14To16( conv_buf, p_buf, DTS_HEADER_SIZE, 1 );
596 i_frame_size = SyncInfo16be( conv_buf, &i_audio_mode, pi_sample_rate,
597 pi_bit_rate, pi_frame_length );
598 i_frame_size = i_frame_size * 8 / 14 * 2;
600 /* 14 bits, big endian version of the bitstream */
601 else if( p_buf[0] == 0x1f && p_buf[1] == 0xff &&
602 p_buf[2] == 0xe8 && p_buf[3] == 0x00 &&
603 p_buf[4] == 0x07 && (p_buf[5] & 0xf0) == 0xf0 )
605 uint8_t conv_buf[DTS_HEADER_SIZE];
606 Buf14To16( conv_buf, p_buf, DTS_HEADER_SIZE, 0 );
607 i_frame_size = SyncInfo16be( conv_buf, &i_audio_mode, pi_sample_rate,
608 pi_bit_rate, pi_frame_length );
609 i_frame_size = i_frame_size * 8 / 14 * 2;
611 /* 16 bits, big endian version of the bitstream */
612 else if( p_buf[0] == 0x7f && p_buf[1] == 0xfe &&
613 p_buf[2] == 0x80 && p_buf[3] == 0x01 )
615 i_frame_size = SyncInfo16be( p_buf, &i_audio_mode, pi_sample_rate,
616 pi_bit_rate, pi_frame_length );
618 /* 16 bits, little endian version of the bitstream */
619 else if( p_buf[0] == 0xfe && p_buf[1] == 0x7f &&
620 p_buf[2] == 0x01 && p_buf[3] == 0x80 )
622 uint8_t conv_buf[DTS_HEADER_SIZE];
623 BufLeToBe( conv_buf, p_buf, DTS_HEADER_SIZE );
624 i_frame_size = SyncInfo16be( p_buf, &i_audio_mode, pi_sample_rate,
625 pi_bit_rate, pi_frame_length );
627 /* DTS-HD */
628 else
630 assert( p_buf[0] == 0x64 && p_buf[1] == 0x58 &&
631 p_buf[2] == 0x20 && p_buf[3] == 0x25 );
633 int i_dts_hd_size;
634 bs_t s;
635 bs_init( &s, &p_buf[4], DTS_HEADER_SIZE - 4 );
637 bs_skip( &s, 8 + 2 );
639 if( bs_read1( &s ) )
641 bs_skip( &s, 12 );
642 i_dts_hd_size = bs_read( &s, 20 ) + 1;
644 else
646 bs_skip( &s, 8 );
647 i_dts_hd_size = bs_read( &s, 16 ) + 1;
649 //uint16_t s0 = bs_read( &s, 16 );
650 //uint16_t s1 = bs_read( &s, 16 );
651 //fprintf( stderr, "DTS HD=%d : %x %x\n", i_dts_hd_size, s0, s1 );
653 *pb_dts_hd = true;
654 /* As we ignore the stream, do not modify those variables:
655 *pi_channels = ;
656 *pi_channels_conf = ;
657 *pi_sample_rate = ;
658 *pi_bit_rate = ;
659 *pi_frame_length = ;
661 return i_dts_hd_size;
664 *pb_dts_hd = false;
666 switch( i_audio_mode & 0xFFFF )
668 case 0x0:
669 /* Mono */
670 *pi_channels = 1;
671 *pi_channels_conf = AOUT_CHAN_CENTER;
672 break;
673 case 0x1:
674 /* Dual-mono = stereo + dual-mono */
675 *pi_channels = 2;
676 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
677 AOUT_CHAN_DUALMONO;
678 break;
679 case 0x2:
680 case 0x3:
681 case 0x4:
682 /* Stereo */
683 *pi_channels = 2;
684 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
685 break;
686 case 0x5:
687 /* 3F */
688 *pi_channels = 3;
689 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
690 AOUT_CHAN_CENTER;
691 break;
692 case 0x6:
693 /* 2F/1R */
694 *pi_channels = 3;
695 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
696 AOUT_CHAN_REARCENTER;
697 break;
698 case 0x7:
699 /* 3F/1R */
700 *pi_channels = 4;
701 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
702 AOUT_CHAN_CENTER | AOUT_CHAN_REARCENTER;
703 break;
704 case 0x8:
705 /* 2F2R */
706 *pi_channels = 4;
707 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
708 AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
709 break;
710 case 0x9:
711 /* 3F2R */
712 *pi_channels = 5;
713 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
714 AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT |
715 AOUT_CHAN_REARRIGHT;
716 break;
717 case 0xA:
718 case 0xB:
719 /* 2F2M2R */
720 *pi_channels = 6;
721 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
722 AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT |
723 AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
724 break;
725 case 0xC:
726 /* 3F2M2R */
727 *pi_channels = 7;
728 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
729 AOUT_CHAN_CENTER | AOUT_CHAN_MIDDLELEFT |
730 AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_REARLEFT |
731 AOUT_CHAN_REARRIGHT;
732 break;
733 case 0xD:
734 case 0xE:
735 /* 3F2M2R/LFE */
736 *pi_channels = 8;
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 | AOUT_CHAN_LFE;
741 break;
743 default:
744 if( i_audio_mode <= 63 )
746 /* User defined */
747 *pi_channels = 0;
748 *pi_channels_conf = 0;
750 else return 0;
751 break;
754 if( i_audio_mode & 0x10000 )
756 (*pi_channels)++;
757 *pi_channels_conf |= AOUT_CHAN_LFE;
760 if( *pi_sample_rate >= sizeof( ppi_dts_samplerate ) /
761 sizeof( ppi_dts_samplerate[0] ) )
763 return 0;
765 *pi_sample_rate = ppi_dts_samplerate[ *pi_sample_rate ];
766 if( !*pi_sample_rate ) return 0;
768 if( *pi_bit_rate >= sizeof( ppi_dts_bitrate ) /
769 sizeof( ppi_dts_bitrate[0] ) )
771 return 0;
773 *pi_bit_rate = ppi_dts_bitrate[ *pi_bit_rate ];
774 if( !*pi_bit_rate ) return 0;
776 *pi_frame_length = (*pi_frame_length + 1) * 32;
778 return i_frame_size;