1 /*****************************************************************************
2 * dts.c: DTS basic parser
3 *****************************************************************************
4 * Copyright (C) 2003 VideoLAN
5 * $Id: dts.c,v 1.1 2003/03/09 20:07:47 jlj Exp $
7 * Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
29 #include <string.h> /* memcpy() */
33 #include <vlc/decoder.h>
40 /*****************************************************************************
41 * dec_thread_t : decoder thread descriptor
42 *****************************************************************************/
43 typedef struct dec_thread_t
48 vlc_thread_t thread_id; /* id for thread functions */
53 decoder_fifo_t * p_fifo; /* stores the PES stream data */
54 bit_stream_t bit_stream;
59 aout_instance_t * p_aout; /* opaque */
60 aout_input_t * p_aout_input; /* opaque */
61 audio_sample_format_t output_format;
64 /****************************************************************************
66 ****************************************************************************/
67 static int OpenDecoder ( vlc_object_t * );
68 static int RunDecoder ( decoder_fifo_t * );
70 static void EndThread ( dec_thread_t * );
72 static int SyncInfo ( const byte_t *, unsigned int *,
73 unsigned int *, unsigned int *,
76 /*****************************************************************************
78 *****************************************************************************/
80 set_description( _("DTS parser") );
81 set_capability( "decoder", 100 );
82 set_callbacks( OpenDecoder, NULL );
85 /*****************************************************************************
86 * OpenDecoder: probe the decoder and return score
87 *****************************************************************************/
88 static int OpenDecoder( vlc_object_t *p_this )
90 decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
92 if( p_fifo->i_fourcc != VLC_FOURCC('d','t','s',' ')
93 && p_fifo->i_fourcc != VLC_FOURCC('d','t','s','b') )
98 p_fifo->pf_run = RunDecoder;
102 /****************************************************************************
103 * RunDecoder: the whole thing
104 ****************************************************************************
105 * This function is called just after the thread is launched.
106 ****************************************************************************/
107 static int RunDecoder( decoder_fifo_t *p_fifo )
109 dec_thread_t * p_dec;
110 audio_date_t end_date;
112 /* Allocate the memory needed to store the thread's structure */
113 p_dec = malloc( sizeof(dec_thread_t) );
116 msg_Err( p_fifo, "out of memory" );
117 DecoderError( p_fifo );
121 /* Initialize the thread properties */
122 p_dec->p_aout = NULL;
123 p_dec->p_aout_input = NULL;
124 p_dec->p_fifo = p_fifo;
125 p_dec->output_format.i_format = VLC_FOURCC('d','t','s',' ');
127 aout_DateSet( &end_date, 0 );
129 /* Init the bitstream */
130 if( InitBitstream( &p_dec->bit_stream, p_dec->p_fifo,
131 NULL, NULL ) != VLC_SUCCESS )
133 msg_Err( p_fifo, "cannot initialize bitstream" );
134 DecoderError( p_fifo );
139 /* Decoder thread's main loop */
140 while( !p_dec->p_fifo->b_die && !p_dec->p_fifo->b_error )
147 unsigned int i_bit_rate;
148 unsigned int i_frame_size;
149 unsigned int i_frame_length;
150 unsigned int i_original_channels;
152 aout_buffer_t * p_buffer = NULL;
154 for( i = 0; i < 3; i++ )
156 RealignBits( &p_dec->bit_stream );
157 while( (ShowBits( &p_dec->bit_stream, 32 ) ) != 0x7ffe8001 &&
158 (!p_dec->p_fifo->b_die) && (!p_dec->p_fifo->b_error) )
160 RemoveBits( &p_dec->bit_stream, 8 );
162 if( p_dec->p_fifo->b_die || p_dec->p_fifo->b_error ) break;
166 /* Set the Presentation Time Stamp */
167 NextPTS( &p_dec->bit_stream, &pts, NULL );
168 if( pts != 0 && pts != aout_DateGet( &end_date ) )
170 aout_DateSet( &end_date, pts );
174 /* Get DTS frame header */
175 GetChunk( &p_dec->bit_stream, p_header, 10 );
176 if( p_dec->p_fifo->b_die || p_dec->p_fifo->b_error ) break;
178 i_frame_size = SyncInfo( p_header, &i_original_channels, &i_rate,
179 &i_bit_rate, &i_frame_length );
182 msg_Warn( p_dec->p_fifo, "dts_syncinfo failed" );
188 if( (p_dec->p_aout_input != NULL) &&
189 ( (p_dec->output_format.i_rate != i_rate)
190 || (p_dec->output_format.i_original_channels
191 != i_original_channels)
192 || (p_dec->output_format.i_bytes_per_frame
193 != i_frame_size * 3) ) )
195 /* Parameters changed - this should not happen. */
196 aout_DecDelete( p_dec->p_aout, p_dec->p_aout_input );
197 p_dec->p_aout_input = NULL;
200 /* Creating the audio input if not created yet. */
201 if( p_dec->p_aout_input == NULL )
203 p_dec->output_format.i_rate = i_rate;
204 p_dec->output_format.i_original_channels
205 = i_original_channels;
206 p_dec->output_format.i_physical_channels
207 = i_original_channels & AOUT_CHAN_PHYSMASK;
208 p_dec->output_format.i_bytes_per_frame = i_frame_size * 3;
209 p_dec->output_format.i_frame_length = i_frame_length * 3;
210 aout_DateInit( &end_date, i_rate );
211 p_dec->p_aout_input = aout_DecNew( p_dec->p_fifo,
213 &p_dec->output_format );
215 if( p_dec->p_aout_input == NULL )
217 p_dec->p_fifo->b_error = 1;
223 if( !aout_DateGet( &end_date ) )
225 byte_t p_junk[ i_frame_size ];
227 /* We've just started the stream, wait for the first PTS. */
228 GetChunk( &p_dec->bit_stream, p_junk, i_frame_size - 10 );
234 p_buffer = aout_DecNewBuffer( p_dec->p_aout,
236 i_frame_length * 3 );
237 if( p_buffer == NULL )
239 p_dec->p_fifo->b_error = 1;
242 p_buffer->start_date = aout_DateGet( &end_date );
243 p_buffer->end_date = aout_DateIncrement( &end_date,
244 i_frame_length * 3 );
247 /* Get the whole frame. */
248 memcpy( p_buffer->p_buffer + (i * i_frame_size), p_header, 10 );
249 GetChunk( &p_dec->bit_stream,
250 p_buffer->p_buffer + (i * i_frame_size) + 10,
252 if( p_dec->p_fifo->b_die ) break;
255 if( p_dec->p_fifo->b_die || p_dec->p_fifo->b_error )
257 if( p_buffer != NULL )
259 aout_DecDeleteBuffer( p_dec->p_aout, p_dec->p_aout_input,
266 /* Send the buffer to the aout core. */
267 aout_DecPlay( p_dec->p_aout, p_dec->p_aout_input, p_buffer );
270 if( p_dec->p_fifo->b_error )
272 DecoderError( p_dec->p_fifo );
280 /*****************************************************************************
281 * EndThread : thread destruction
282 *****************************************************************************/
283 static void EndThread( dec_thread_t * p_dec )
285 if ( p_dec->p_aout_input != NULL )
287 aout_DecDelete( p_dec->p_aout, p_dec->p_aout_input );
290 CloseBitstream( &p_dec->bit_stream );
294 /*****************************************************************************
295 * SyncInfo: parse DTS sync info
296 *****************************************************************************/
297 static int SyncInfo( const byte_t * p_buf, unsigned int * pi_channels,
298 unsigned int * pi_sample_rate,
299 unsigned int * pi_bit_rate,
300 unsigned int * pi_frame_length )
302 unsigned int i_bit_rate;
303 unsigned int i_audio_mode;
304 unsigned int i_sample_rate;
305 unsigned int i_frame_size;
306 unsigned int i_frame_length;
308 static const unsigned int ppi_dts_samplerate[] =
310 0, 8000, 16000, 32000, 64000, 128000,
311 11025, 22050, 44010, 88020, 176400,
312 12000, 24000, 48000, 96000, 192000
315 static const unsigned int ppi_dts_bitrate[] =
317 32000, 56000, 64000, 96000, 112000, 128000,
318 192000, 224000, 256000, 320000, 384000,
319 448000, 512000, 576000, 640000, 768000,
320 896000, 1024000, 1152000, 1280000, 1344000,
321 1408000, 1411200, 1472000, 1536000, 1920000,
322 2048000, 3072000, 3840000, 4096000, 0, 0
325 if( ((uint32_t*)p_buf)[0] != 0x7ffe8001 )
330 i_frame_length = (p_buf[4] & 0x01) << 6 | (p_buf[5] >> 2);
331 i_frame_size = (p_buf[5] & 0x03) << 12 | (p_buf[6] << 4) |
334 i_audio_mode = (p_buf[7] & 0x0f) << 2 | (p_buf[8] >> 6);
335 i_sample_rate = (p_buf[8] >> 2) & 0x0f;
336 i_bit_rate = (p_buf[8] & 0x03) << 3 | ((p_buf[9] >> 5) & 0x07);
338 switch( i_audio_mode )
342 *pi_channels = AOUT_CHAN_CENTER;
345 /* Dual-mono = stereo + dual-mono */
346 *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
353 *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
357 *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER;
361 *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_LFE;
365 *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
366 AOUT_CHAN_CENTER | AOUT_CHAN_LFE;
370 *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
371 AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
375 *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
376 AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT |
382 *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
383 AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT |
384 AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
388 *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
389 AOUT_CHAN_CENTER | AOUT_CHAN_MIDDLELEFT |
390 AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_REARLEFT |
396 *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
397 AOUT_CHAN_CENTER | AOUT_CHAN_MIDDLELEFT |
398 AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_REARLEFT |
399 AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE;
406 if( i_sample_rate >= sizeof( ppi_dts_samplerate ) /
407 sizeof( ppi_dts_samplerate[0] ) )
412 *pi_sample_rate = ppi_dts_samplerate[ i_sample_rate ];
414 if( i_bit_rate >= sizeof( ppi_dts_bitrate ) /
415 sizeof( ppi_dts_bitrate[0] ) )
420 *pi_bit_rate = ppi_dts_bitrate[ i_bit_rate ];
422 *pi_frame_length = (i_frame_length + 1) * 32;
424 return( i_frame_size + 1 );