]> git.sesse.net Git - vlc/blob - modules/codec/dts.c
* DTS S/PDIF support.
[vlc] / modules / codec / dts.c
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 $
6  *
7  * Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
8  *
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.
13  *
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.
18  *
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  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>                                              /* memcpy() */
30 #include <fcntl.h>
31
32 #include <vlc/vlc.h>
33 #include <vlc/decoder.h>
34 #include <vlc/aout.h>
35
36 #ifdef HAVE_UNISTD_H
37 #   include <unistd.h>
38 #endif
39
40 /*****************************************************************************
41  * dec_thread_t : decoder thread descriptor
42  *****************************************************************************/
43 typedef struct dec_thread_t
44 {
45     /*
46      * Thread properties
47      */
48     vlc_thread_t        thread_id;                /* id for thread functions */
49
50     /*
51      * Input properties
52      */
53     decoder_fifo_t *    p_fifo;                /* stores the PES stream data */
54     bit_stream_t        bit_stream;
55
56     /*
57      * Output properties
58      */
59     aout_instance_t *   p_aout; /* opaque */
60     aout_input_t *      p_aout_input; /* opaque */
61     audio_sample_format_t output_format;
62 } dec_thread_t;
63
64 /****************************************************************************
65  * Local prototypes
66  ****************************************************************************/
67 static int  OpenDecoder    ( vlc_object_t * );
68 static int  RunDecoder     ( decoder_fifo_t * );
69
70 static void EndThread      ( dec_thread_t * );
71
72 static int  SyncInfo       ( const byte_t *, unsigned int *,
73                              unsigned int *, unsigned int *,
74                              unsigned int * );
75
76 /*****************************************************************************
77  * Module descriptor
78  *****************************************************************************/
79 vlc_module_begin();
80     set_description( _("DTS parser") );
81     set_capability( "decoder", 100 );
82     set_callbacks( OpenDecoder, NULL );
83 vlc_module_end();
84
85 /*****************************************************************************
86  * OpenDecoder: probe the decoder and return score
87  *****************************************************************************/
88 static int OpenDecoder( vlc_object_t *p_this )
89 {
90     decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
91
92     if( p_fifo->i_fourcc != VLC_FOURCC('d','t','s',' ')
93          && p_fifo->i_fourcc != VLC_FOURCC('d','t','s','b') )
94     {
95         return VLC_EGENERIC;
96     }
97
98     p_fifo->pf_run = RunDecoder;
99     return VLC_SUCCESS;
100 }
101
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 )
108 {
109     dec_thread_t * p_dec;
110     audio_date_t end_date;
111
112     /* Allocate the memory needed to store the thread's structure */
113     p_dec = malloc( sizeof(dec_thread_t) );
114     if( p_dec == NULL )
115     {
116         msg_Err( p_fifo, "out of memory" );
117         DecoderError( p_fifo );
118         return -1;
119     }
120
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',' ');
126
127     aout_DateSet( &end_date, 0 );
128
129     /* Init the bitstream */
130     if( InitBitstream( &p_dec->bit_stream, p_dec->p_fifo,
131                        NULL, NULL ) != VLC_SUCCESS )
132     {
133         msg_Err( p_fifo, "cannot initialize bitstream" );
134         DecoderError( p_fifo );
135         free( p_dec );
136         return -1;
137     }
138
139     /* Decoder thread's main loop */
140     while( !p_dec->p_fifo->b_die && !p_dec->p_fifo->b_error )
141     {
142         int i;
143         mtime_t pts;
144         byte_t p_header[10];
145
146         unsigned int i_rate;
147         unsigned int i_bit_rate;
148         unsigned int i_frame_size;
149         unsigned int i_frame_length;
150         unsigned int i_original_channels;
151
152         aout_buffer_t * p_buffer = NULL;
153
154         for( i = 0; i < 3; i++ )
155         {
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) )
159             {
160                 RemoveBits( &p_dec->bit_stream, 8 );
161             }
162             if( p_dec->p_fifo->b_die || p_dec->p_fifo->b_error ) break;
163
164             if( i == 0 )
165             {
166                 /* Set the Presentation Time Stamp */
167                 NextPTS( &p_dec->bit_stream, &pts, NULL );
168                 if( pts != 0 && pts != aout_DateGet( &end_date ) )
169                 {
170                     aout_DateSet( &end_date, pts );
171                 }
172             }
173
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;
177
178             i_frame_size = SyncInfo( p_header, &i_original_channels, &i_rate,
179                                                &i_bit_rate, &i_frame_length );
180             if( !i_frame_size )
181             {
182                 msg_Warn( p_dec->p_fifo, "dts_syncinfo failed" );
183                 i--; continue;
184             }
185
186             if( i == 0 )
187             {
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) ) )
194                 {
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;
198                 }
199
200                 /* Creating the audio input if not created yet. */
201                 if( p_dec->p_aout_input == NULL )
202                 {
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,
212                                                        &p_dec->p_aout,
213                                                        &p_dec->output_format );
214
215                     if( p_dec->p_aout_input == NULL )
216                     {
217                         p_dec->p_fifo->b_error = 1;
218                         break;
219                     }
220                 }
221             }
222
223             if( !aout_DateGet( &end_date ) )
224             {
225                 byte_t p_junk[ i_frame_size ];
226
227                 /* We've just started the stream, wait for the first PTS. */
228                 GetChunk( &p_dec->bit_stream, p_junk, i_frame_size - 10 );
229                 i--; continue;
230             }
231
232             if( i == 0 )
233             {
234                 p_buffer = aout_DecNewBuffer( p_dec->p_aout, 
235                                               p_dec->p_aout_input,
236                                               i_frame_length * 3 );
237                 if( p_buffer == NULL )
238                 {
239                     p_dec->p_fifo->b_error = 1;
240                     break;
241                 }
242                 p_buffer->start_date = aout_DateGet( &end_date );
243                 p_buffer->end_date = aout_DateIncrement( &end_date,
244                                                          i_frame_length * 3 );
245             }
246
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,
251                       i_frame_size - 10 );
252             if( p_dec->p_fifo->b_die ) break;
253         }
254
255         if( p_dec->p_fifo->b_die || p_dec->p_fifo->b_error )
256         {
257             if( p_buffer != NULL )
258             {
259                 aout_DecDeleteBuffer( p_dec->p_aout, p_dec->p_aout_input,
260                                       p_buffer );
261             }
262
263             break;
264         }
265
266         /* Send the buffer to the aout core. */
267         aout_DecPlay( p_dec->p_aout, p_dec->p_aout_input, p_buffer );
268     }
269
270     if( p_dec->p_fifo->b_error )
271     {
272         DecoderError( p_dec->p_fifo );
273     }
274
275     EndThread( p_dec );
276
277     return 0;
278 }
279
280 /*****************************************************************************
281  * EndThread : thread destruction
282  *****************************************************************************/
283 static void EndThread( dec_thread_t * p_dec )
284 {
285     if ( p_dec->p_aout_input != NULL )
286     {
287         aout_DecDelete( p_dec->p_aout, p_dec->p_aout_input );
288     }
289
290     CloseBitstream( &p_dec->bit_stream );
291     free( p_dec );
292 }
293
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 )
301 {
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;
307
308     static const unsigned int ppi_dts_samplerate[] =
309     {
310         0, 8000, 16000, 32000, 64000, 128000,
311         11025, 22050, 44010, 88020, 176400,
312         12000, 24000, 48000, 96000, 192000
313     };
314
315     static const unsigned int ppi_dts_bitrate[] =
316     {
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
323     };
324
325     if( ((uint32_t*)p_buf)[0] != 0x7ffe8001 )
326     {
327         return( 0 );
328     }
329
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) |
332                    (p_buf[7] >> 4);
333
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);
337
338     switch( i_audio_mode )
339     {
340         case 0x0:
341             /* Mono */
342             *pi_channels = AOUT_CHAN_CENTER;
343             break;
344         case 0x1:
345             /* Dual-mono = stereo + dual-mono */
346             *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
347                            AOUT_CHAN_DUALMONO;
348             break;
349         case 0x2:
350         case 0x3:
351         case 0x4:
352             /* Stereo */
353             *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
354             break;
355         case 0x5:
356             /* 3F */
357             *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER;
358             break;
359         case 0x6:
360             /* 2F/LFE */
361             *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_LFE;
362             break;
363         case 0x7:
364             /* 3F/LFE */
365             *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
366                            AOUT_CHAN_CENTER | AOUT_CHAN_LFE;
367             break;
368         case 0x8:
369             /* 2F2R */
370             *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
371                            AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
372             break;
373         case 0x9:
374             /* 3F2R */
375             *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
376                            AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT |
377                            AOUT_CHAN_REARRIGHT;
378             break;
379         case 0xA:
380         case 0xB:
381             /* 2F2M2R */
382             *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
383                            AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT |
384                            AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
385             break;
386         case 0xC:
387             /* 3F2M2R */
388             *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
389                            AOUT_CHAN_CENTER | AOUT_CHAN_MIDDLELEFT |
390                            AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_REARLEFT |
391                            AOUT_CHAN_REARRIGHT;
392             break;
393         case 0xD:
394         case 0xE:
395             /* 3F2M2R/LFE */
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;
400             break;
401
402         default:
403             return( 0 );
404     }
405
406     if( i_sample_rate >= sizeof( ppi_dts_samplerate ) /
407                          sizeof( ppi_dts_samplerate[0] ) )
408     {
409         return( 0 );
410     }
411
412     *pi_sample_rate = ppi_dts_samplerate[ i_sample_rate ];
413
414     if( i_bit_rate >= sizeof( ppi_dts_bitrate ) /
415                       sizeof( ppi_dts_bitrate[0] ) )
416     {
417         return( 0 );
418     }
419
420     *pi_bit_rate = ppi_dts_bitrate[ i_bit_rate ];
421
422     *pi_frame_length = (i_frame_length + 1) * 32;
423
424     return( i_frame_size + 1 );
425 }