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