]> git.sesse.net Git - vlc/blob - modules/codec/dts.c
982f013fb75d194b36684dce48112c67b09411a2
[vlc] / modules / codec / dts.c
1 /*****************************************************************************
2  * dts.c: parse DTS audio sync info and packetize the stream
3  *****************************************************************************
4  * Copyright (C) 2003 VideoLAN
5  * $Id: dts.c,v 1.6 2003/11/16 22:54:12 gbazin Exp $
6  *
7  * Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
8  *          Gildas Bazin <gbazin@netcourrier.com>
9  *
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.
14  *
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.
19  *
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., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
23  *****************************************************************************/
24
25 /*****************************************************************************
26  * Preamble
27  *****************************************************************************/
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>                                              /* memcpy() */
31
32 #include <vlc/vlc.h>
33 #include <vlc/decoder.h>
34 #include <vlc/input.h>
35
36 #include "vlc_block_helper.h"
37
38 #define DTS_HEADER_SIZE 10
39
40 /*****************************************************************************
41  * decoder_sys_t : decoder descriptor
42  *****************************************************************************/
43 struct decoder_sys_t
44 {
45     /* Module mode */
46     vlc_bool_t b_packetizer;
47
48     /*
49      * Input properties
50      */
51     int i_state;
52
53     block_bytestream_t bytestream;
54
55     /*
56      * Common properties
57      */
58     audio_date_t   end_date;
59
60     mtime_t i_pts;
61
62     int i_frame_size, i_bit_rate;
63     unsigned int i_frame_length, i_rate, i_channels, i_channels_conf;
64
65     /* This is very hacky. For DTS over S/PDIF we apparently need to send
66      * 3 frames at a time. This should likely be moved to the output stage. */
67     int i_frames_in_buf;
68     aout_buffer_t *p_aout_buffer;        /* current aout buffer being filled */
69
70 };
71
72 enum {
73
74     STATE_NOSYNC,
75     STATE_SYNC,
76     STATE_HEADER,
77     STATE_NEXT_SYNC,
78     STATE_GET_DATA,
79     STATE_SEND_DATA
80 };
81
82 /****************************************************************************
83  * Local prototypes
84  ****************************************************************************/
85 static int  OpenDecoder   ( vlc_object_t * );
86 static int  OpenPacketizer( vlc_object_t * );
87 static void CloseDecoder  ( vlc_object_t * );
88 static void *DecodeBlock  ( decoder_t *, block_t ** );
89
90 static int  SyncInfo      ( const byte_t *, unsigned int *, unsigned int *,
91                             unsigned int *, unsigned int *, unsigned int * );
92
93 static uint8_t       *GetOutBuffer ( decoder_t *, void ** );
94 static aout_buffer_t *GetAoutBuffer( decoder_t * );
95 static block_t       *GetSoutBuffer( decoder_t * );
96
97 /*****************************************************************************
98  * Module descriptor
99  *****************************************************************************/
100 vlc_module_begin();
101     set_description( _("DTS parser") );
102     set_capability( "decoder", 100 );
103     set_callbacks( OpenDecoder, CloseDecoder );
104
105     add_submodule();
106     set_description( _("DTS audio packetizer") );
107     set_capability( "packetizer", 10 );
108     set_callbacks( OpenPacketizer, NULL );
109 vlc_module_end();
110
111 /*****************************************************************************
112  * OpenDecoder: probe the decoder and return score
113  *****************************************************************************/
114 static int OpenDecoder( vlc_object_t *p_this )
115 {
116     decoder_t *p_dec = (decoder_t*)p_this;
117     decoder_sys_t *p_sys;
118
119     if( p_dec->fmt_in.i_codec != VLC_FOURCC('d','t','s',' ')
120          && p_dec->fmt_in.i_codec != VLC_FOURCC('d','t','s','b') )
121     {
122         return VLC_EGENERIC;
123     }
124
125     /* Allocate the memory needed to store the decoder's structure */
126     if( ( p_dec->p_sys = p_sys =
127           (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
128     {
129         msg_Err( p_dec, "out of memory" );
130         return VLC_EGENERIC;
131     }
132
133     /* Misc init */
134     p_sys->b_packetizer = VLC_FALSE;
135     p_sys->i_state = STATE_NOSYNC;
136     aout_DateSet( &p_sys->end_date, 0 );
137     p_sys->i_frames_in_buf = 0;
138
139     p_sys->bytestream = block_BytestreamInit( p_dec );
140
141     /* Set output properties */
142     p_dec->fmt_out.i_cat = AUDIO_ES;
143     p_dec->fmt_out.i_codec = VLC_FOURCC('d','t','s',' ');
144
145     /* Set callback */
146     p_dec->pf_decode_audio = (aout_buffer_t *(*)(decoder_t *, block_t **))
147         DecodeBlock;
148     p_dec->pf_packetize    = (block_t *(*)(decoder_t *, block_t **))
149         DecodeBlock;
150
151     return VLC_SUCCESS;
152 }
153
154 static int OpenPacketizer( vlc_object_t *p_this )
155 {
156     decoder_t *p_dec = (decoder_t*)p_this;
157
158     int i_ret = OpenDecoder( p_this );
159
160     if( i_ret == VLC_SUCCESS ) p_dec->p_sys->b_packetizer = VLC_TRUE;
161
162     return i_ret;
163 }
164
165 /****************************************************************************
166  * DecodeBlock: the whole thing
167  ****************************************************************************
168  * This function is called just after the thread is launched.
169  ****************************************************************************/
170 static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
171 {
172     decoder_sys_t *p_sys = p_dec->p_sys;
173     uint8_t p_header[DTS_HEADER_SIZE];
174     uint8_t *p_buf;
175     void *p_out_buffer;
176
177     if( !pp_block || !*pp_block ) return NULL;
178
179     if( !aout_DateGet( &p_sys->end_date ) && !(*pp_block)->i_pts )
180     {
181         /* We've just started the stream, wait for the first PTS. */
182         block_Release( *pp_block );
183         return NULL;
184     }
185
186     if( (*pp_block)->b_discontinuity )
187     {
188         p_sys->i_state = STATE_NOSYNC;
189     }
190
191     block_BytestreamPush( &p_sys->bytestream, *pp_block );
192
193     while( 1 )
194     {
195         switch( p_sys->i_state )
196         {
197         case STATE_NOSYNC:
198             /* Look for sync dword - should be 0x7ffe8001 */
199             while( block_PeekBytes( &p_sys->bytestream, p_header, 4 )
200                    == VLC_SUCCESS )
201             {
202                 if( p_header[0] == 0x7f && p_header[1] == 0xfe &&
203                     p_header[2] == 0x80 && p_header[3] == 0x01 )
204                 {
205                     p_sys->i_state = STATE_SYNC;
206                     break;
207                 }
208                 block_SkipByte( &p_sys->bytestream );
209             }
210             if( p_sys->i_state != STATE_SYNC )
211             {
212                 block_BytestreamFlush( &p_sys->bytestream );
213
214                 /* Need more data */
215                 return NULL;
216             }
217
218         case STATE_SYNC:
219             /* New frame, set the Presentation Time Stamp */
220             p_sys->i_pts = p_sys->bytestream.p_block->i_pts;
221             if( p_sys->i_pts != 0 &&
222                 p_sys->i_pts != aout_DateGet( &p_sys->end_date ) )
223             {
224                 aout_DateSet( &p_sys->end_date, p_sys->i_pts );
225             }
226             p_sys->i_state = STATE_HEADER;
227
228         case STATE_HEADER:
229             /* Get DTS frame header (DTS_HEADER_SIZE bytes) */
230             if( block_PeekBytes( &p_sys->bytestream, p_header,
231                                  DTS_HEADER_SIZE ) != VLC_SUCCESS )
232             {
233                 /* Need more data */
234                 return NULL;
235             }
236
237             /* Check if frame is valid and get frame info */
238             p_sys->i_frame_size = SyncInfo( p_header,
239                                             &p_sys->i_channels,
240                                             &p_sys->i_channels_conf,
241                                             &p_sys->i_rate,
242                                             &p_sys->i_bit_rate,
243                                             &p_sys->i_frame_length );
244             if( !p_sys->i_frame_size )
245             {
246                 msg_Dbg( p_dec, "emulated sync word" );
247                 block_SkipByte( &p_sys->bytestream );
248                 p_sys->i_state = STATE_NOSYNC;
249                 break;
250             }
251             p_sys->i_state = STATE_NEXT_SYNC;
252
253         case STATE_NEXT_SYNC:
254             /* TODO: If pp_block == NULL, flush the buffer without checking the
255              * next sync word */
256
257             /* Check if next expected frame contains the sync word */
258             if( block_PeekOffsetBytes( &p_sys->bytestream,
259                                        p_sys->i_frame_size, p_header, 4 )
260                 != VLC_SUCCESS )
261             {
262                 /* Need more data */
263                 return NULL;
264             }
265
266             if( p_header[0] == 0x7f && p_header[1] == 0xfe &&
267                 p_header[2] == 0x80 && p_header[3] == 0x01 )
268             {
269                 msg_Dbg( p_dec, "emulated sync word "
270                          "(no sync on following frame)" );
271                 p_sys->i_state = STATE_NOSYNC;
272                 block_SkipByte( &p_sys->bytestream );
273                 break;
274             }
275             p_sys->i_state = STATE_SEND_DATA;
276             break;
277
278         case STATE_GET_DATA:
279             /* Make sure we have enough data.
280              * (Not useful if we went through NEXT_SYNC) */
281             if( block_WaitBytes( &p_sys->bytestream,
282                                  p_sys->i_frame_size ) != VLC_SUCCESS )
283             {
284                 /* Need more data */
285                 return NULL;
286             }
287             p_sys->i_state = STATE_SEND_DATA;
288
289         case STATE_SEND_DATA:
290             if( !(p_buf = GetOutBuffer( p_dec, &p_out_buffer )) )
291             {
292                 //p_dec->b_error = VLC_TRUE;
293                 return NULL;
294             }
295
296             /* Copy the whole frame into the buffer. When we reach this point
297              * we already know we have enough data available. */
298             block_GetBytes( &p_sys->bytestream, p_buf, p_sys->i_frame_size );
299
300             /* Make sure we don't reuse the same pts twice */
301             if( p_sys->i_pts == p_sys->bytestream.p_block->i_pts )
302                 p_sys->i_pts = p_sys->bytestream.p_block->i_pts = 0;
303
304             /* So p_block doesn't get re-added several times */
305             *pp_block = block_BytestreamPop( &p_sys->bytestream );
306
307             p_sys->i_state = STATE_NOSYNC;
308
309             if( !p_sys->b_packetizer )
310             {
311                 if( p_sys->i_frames_in_buf != 3 ) return NULL;
312                 else
313                 {
314                     p_sys->i_frames_in_buf = 0;
315                     p_sys->p_aout_buffer = 0;
316                 }
317             }
318
319             return p_out_buffer;
320         }
321     }
322
323     return NULL;
324 }
325
326 /*****************************************************************************
327  * CloseDecoder: clean up the decoder
328  *****************************************************************************/
329 static void CloseDecoder( vlc_object_t *p_this )
330 {
331     decoder_t *p_dec = (decoder_t*)p_this;
332     decoder_sys_t *p_sys = p_dec->p_sys;
333
334     block_BytestreamRelease( &p_sys->bytestream );
335
336     free( p_sys );
337 }
338
339 /*****************************************************************************
340  * GetOutBuffer:
341  *****************************************************************************/
342 static uint8_t *GetOutBuffer( decoder_t *p_dec, void **pp_out_buffer )
343 {
344     decoder_sys_t *p_sys = p_dec->p_sys;
345     uint8_t *p_buf;
346
347     if( p_dec->fmt_out.audio.i_rate != p_sys->i_rate )
348     {
349         msg_Info( p_dec, "DTS channels:%d samplerate:%d bitrate:%d",
350                   p_sys->i_channels, p_sys->i_rate, p_sys->i_bit_rate );
351
352         aout_DateInit( &p_sys->end_date, p_sys->i_rate );
353         aout_DateSet( &p_sys->end_date, p_sys->i_pts );
354     }
355
356     p_dec->fmt_out.audio.i_rate     = p_sys->i_rate;
357     p_dec->fmt_out.audio.i_channels = p_sys->i_channels;
358     p_dec->fmt_out.audio.i_bytes_per_frame = p_sys->i_frame_size;
359     p_dec->fmt_out.audio.i_frame_length = p_sys->i_frame_length;
360
361     p_dec->fmt_out.audio.i_original_channels = p_sys->i_channels_conf;
362     p_dec->fmt_out.audio.i_physical_channels =
363         p_sys->i_channels_conf & AOUT_CHAN_PHYSMASK;
364
365     p_dec->fmt_out.i_bitrate = p_sys->i_bit_rate;
366
367     if( p_sys->b_packetizer )
368     {
369         block_t *p_sout_buffer = GetSoutBuffer( p_dec );
370         p_buf = p_sout_buffer ? p_sout_buffer->p_buffer : NULL;
371         *pp_out_buffer = p_sout_buffer;
372     }
373     else
374     {
375         if( !p_sys->i_frames_in_buf )
376         {
377             p_sys->p_aout_buffer = GetAoutBuffer( p_dec );
378         }
379         p_buf = p_sys->p_aout_buffer ? p_sys->p_aout_buffer->p_buffer +
380             p_sys->i_frames_in_buf * p_sys->i_frame_size : NULL;
381         *pp_out_buffer = p_sys->p_aout_buffer;
382     }
383
384     p_sys->i_frames_in_buf++;
385
386     return p_buf;
387 }
388
389 /*****************************************************************************
390  * GetAoutBuffer:
391  *****************************************************************************/
392 static aout_buffer_t *GetAoutBuffer( decoder_t *p_dec )
393 {
394     decoder_sys_t *p_sys = p_dec->p_sys;
395     aout_buffer_t *p_buf;
396
397     p_buf = p_dec->pf_aout_buffer_new( p_dec, p_sys->i_frame_length * 3 );
398     if( p_buf == NULL ) return NULL;
399
400     p_buf->start_date = aout_DateGet( &p_sys->end_date );
401     p_buf->end_date =
402         aout_DateIncrement( &p_sys->end_date, p_sys->i_frame_length * 3 );
403
404     return p_buf;
405 }
406
407 /*****************************************************************************
408  * GetSoutBuffer:
409  *****************************************************************************/
410 static block_t *GetSoutBuffer( decoder_t *p_dec )
411 {
412     decoder_sys_t *p_sys = p_dec->p_sys;
413     block_t *p_block;
414
415     p_block = block_New( p_dec, p_sys->i_frame_size );
416     if( p_block == NULL ) return NULL;
417
418     p_block->i_pts = p_block->i_dts = aout_DateGet( &p_sys->end_date );
419
420     p_block->i_length = aout_DateIncrement( &p_sys->end_date,
421         p_sys->i_frame_length ) - p_block->i_pts;
422
423     return p_block;
424 }
425
426 /*****************************************************************************
427  * SyncInfo: parse DTS sync info
428  *****************************************************************************/
429 static int SyncInfo( const byte_t * p_buf,
430                      unsigned int * pi_channels,
431                      unsigned int * pi_channels_conf,
432                      unsigned int * pi_sample_rate,
433                      unsigned int * pi_bit_rate,
434                      unsigned int * pi_frame_length )
435 {
436     unsigned int i_bit_rate;
437     unsigned int i_audio_mode;
438     unsigned int i_sample_rate;
439     unsigned int i_frame_size;
440     unsigned int i_frame_length;
441
442     static const unsigned int ppi_dts_samplerate[] =
443     {
444         0, 8000, 16000, 32000, 64000, 128000,
445         11025, 22050, 44010, 88020, 176400,
446         12000, 24000, 48000, 96000, 192000
447     };
448
449     static const unsigned int ppi_dts_bitrate[] =
450     {
451         32000, 56000, 64000, 96000, 112000, 128000,
452         192000, 224000, 256000, 320000, 384000,
453         448000, 512000, 576000, 640000, 768000,
454         896000, 1024000, 1152000, 1280000, 1344000,
455         1408000, 1411200, 1472000, 1536000, 1920000,
456         2048000, 3072000, 3840000, 4096000, 0, 0
457     };
458
459     if( (p_buf[0] != 0x7f) || (p_buf[1] != 0xfe) ||
460         (p_buf[2] != 0x80) || (p_buf[3] != 0x01) )
461     {
462         return( 0 );
463     }
464
465     i_frame_length = (p_buf[4] & 0x01) << 6 | (p_buf[5] >> 2);
466     i_frame_size = (p_buf[5] & 0x03) << 12 | (p_buf[6] << 4) |
467                    (p_buf[7] >> 4);
468
469     i_audio_mode = (p_buf[7] & 0x0f) << 2 | (p_buf[8] >> 6);
470     i_sample_rate = (p_buf[8] >> 2) & 0x0f;
471     i_bit_rate = (p_buf[8] & 0x03) << 3 | ((p_buf[9] >> 5) & 0x07);
472
473     switch( i_audio_mode )
474     {
475         case 0x0:
476             /* Mono */
477             *pi_channels_conf = AOUT_CHAN_CENTER;
478             break;
479         case 0x1:
480             /* Dual-mono = stereo + dual-mono */
481             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
482                            AOUT_CHAN_DUALMONO;
483             break;
484         case 0x2:
485         case 0x3:
486         case 0x4:
487             /* Stereo */
488             *pi_channels = 2;
489             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
490             break;
491         case 0x5:
492             /* 3F */
493             *pi_channels = 3;
494             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
495                                 AOUT_CHAN_CENTER;
496             break;
497         case 0x6:
498             /* 2F/LFE */
499             *pi_channels = 3;
500             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
501                                 AOUT_CHAN_LFE;
502             break;
503         case 0x7:
504             /* 3F/LFE */
505             *pi_channels = 4;
506             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
507                                 AOUT_CHAN_CENTER | AOUT_CHAN_LFE;
508             break;
509         case 0x8:
510             /* 2F2R */
511             *pi_channels = 4;
512             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
513                                 AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
514             break;
515         case 0x9:
516             /* 3F2R */
517             *pi_channels = 5;
518             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
519                                 AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT |
520                                 AOUT_CHAN_REARRIGHT;
521             break;
522         case 0xA:
523         case 0xB:
524             /* 2F2M2R */
525             *pi_channels = 6;
526             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
527                                 AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT |
528                                 AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
529             break;
530         case 0xC:
531             /* 3F2M2R */
532             *pi_channels = 7;
533             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
534                                 AOUT_CHAN_CENTER | AOUT_CHAN_MIDDLELEFT |
535                                 AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_REARLEFT |
536                                 AOUT_CHAN_REARRIGHT;
537             break;
538         case 0xD:
539         case 0xE:
540             /* 3F2M2R/LFE */
541             *pi_channels = 8;
542             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
543                                 AOUT_CHAN_CENTER | AOUT_CHAN_MIDDLELEFT |
544                                 AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_REARLEFT |
545                                 AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE;
546             break;
547
548         default:
549             if( i_audio_mode <= 63 )
550             {
551                 /* User defined */
552                 *pi_channels = 0;
553                 *pi_channels_conf = 0; 
554             }
555             else
556             {
557                 return( 0 );
558             }
559             break;
560     }
561
562     if( i_sample_rate >= sizeof( ppi_dts_samplerate ) /
563                          sizeof( ppi_dts_samplerate[0] ) )
564     {
565         return( 0 );
566     }
567
568     *pi_sample_rate = ppi_dts_samplerate[ i_sample_rate ];
569
570     if( i_bit_rate >= sizeof( ppi_dts_bitrate ) /
571                       sizeof( ppi_dts_bitrate[0] ) )
572     {
573         return( 0 );
574     }
575
576     *pi_bit_rate = ppi_dts_bitrate[ i_bit_rate ];
577
578     *pi_frame_length = (i_frame_length + 1) * 32;
579
580     return( i_frame_size + 1 );
581 }