]> git.sesse.net Git - vlc/blob - modules/codec/dts.c
* ./modules/codec/dts.c: Steve Jobs did not pay me for this bug. Really.
[vlc] / modules / codec / dts.c
1 /*****************************************************************************
2  * dts.c: DTS basic parser
3  *****************************************************************************
4  * Copyright (C) 2003 VideoLAN
5  * $Id: dts.c,v 1.3 2003/03/18 00:25:27 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( (p_buf[0] != 0x7f) || (p_buf[1] != 0xfe) ||
326         (p_buf[2] != 0x80) || (p_buf[3] != 0x01) )
327     {
328         return( 0 );
329     }
330
331     i_frame_length = (p_buf[4] & 0x01) << 6 | (p_buf[5] >> 2);
332     i_frame_size = (p_buf[5] & 0x03) << 12 | (p_buf[6] << 4) |
333                    (p_buf[7] >> 4);
334
335     i_audio_mode = (p_buf[7] & 0x0f) << 2 | (p_buf[8] >> 6);
336     i_sample_rate = (p_buf[8] >> 2) & 0x0f;
337     i_bit_rate = (p_buf[8] & 0x03) << 3 | ((p_buf[9] >> 5) & 0x07);
338
339     switch( i_audio_mode )
340     {
341         case 0x0:
342             /* Mono */
343             *pi_channels = AOUT_CHAN_CENTER;
344             break;
345         case 0x1:
346             /* Dual-mono = stereo + dual-mono */
347             *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
348                            AOUT_CHAN_DUALMONO;
349             break;
350         case 0x2:
351         case 0x3:
352         case 0x4:
353             /* Stereo */
354             *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
355             break;
356         case 0x5:
357             /* 3F */
358             *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER;
359             break;
360         case 0x6:
361             /* 2F/LFE */
362             *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_LFE;
363             break;
364         case 0x7:
365             /* 3F/LFE */
366             *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
367                            AOUT_CHAN_CENTER | AOUT_CHAN_LFE;
368             break;
369         case 0x8:
370             /* 2F2R */
371             *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
372                            AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
373             break;
374         case 0x9:
375             /* 3F2R */
376             *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
377                            AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT |
378                            AOUT_CHAN_REARRIGHT;
379             break;
380         case 0xA:
381         case 0xB:
382             /* 2F2M2R */
383             *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
384                            AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT |
385                            AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
386             break;
387         case 0xC:
388             /* 3F2M2R */
389             *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
390                            AOUT_CHAN_CENTER | AOUT_CHAN_MIDDLELEFT |
391                            AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_REARLEFT |
392                            AOUT_CHAN_REARRIGHT;
393             break;
394         case 0xD:
395         case 0xE:
396             /* 3F2M2R/LFE */
397             *pi_channels = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
398                            AOUT_CHAN_CENTER | AOUT_CHAN_MIDDLELEFT |
399                            AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_REARLEFT |
400                            AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE;
401             break;
402
403         default:
404             if( i_audio_mode <= 63 )
405             {
406                 /* User defined */
407                 *pi_channels = 0; 
408             }
409             else
410             {
411                 return( 0 );
412             }
413             break;
414     }
415
416     if( i_sample_rate >= sizeof( ppi_dts_samplerate ) /
417                          sizeof( ppi_dts_samplerate[0] ) )
418     {
419         return( 0 );
420     }
421
422     *pi_sample_rate = ppi_dts_samplerate[ i_sample_rate ];
423
424     if( i_bit_rate >= sizeof( ppi_dts_bitrate ) /
425                       sizeof( ppi_dts_bitrate[0] ) )
426     {
427         return( 0 );
428     }
429
430     *pi_bit_rate = ppi_dts_bitrate[ i_bit_rate ];
431
432     *pi_frame_length = (i_frame_length + 1) * 32;
433
434     return( i_frame_size + 1 );
435 }