]> git.sesse.net Git - vlc/blob - modules/codec/dts.c
vlc_plugin: fix non-LGPL plugins meta infos
[vlc] / modules / codec / dts.c
1 /*****************************************************************************
2  * dts.c: parse DTS audio sync info and packetize the stream
3  *****************************************************************************
4  * Copyright (C) 2003-2009 VLC authors and VideoLAN
5  * $Id$
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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25 /*****************************************************************************
26  * Preamble
27  *****************************************************************************/
28
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
32 #include <assert.h>
33
34 #define VLC_MODULE_LICENSE VLC_LICENSE_GPL_2_PLUS
35 #include <vlc_common.h>
36 #include <vlc_plugin.h>
37 #include <vlc_codec.h>
38 #include <vlc_block_helper.h>
39 #include <vlc_bits.h>
40 #include <vlc_modules.h>
41 #include <vlc_cpu.h>
42
43 #include "../packetizer/packetizer_helper.h"
44 #include "dts_header.h"
45
46 /*****************************************************************************
47  * Module descriptor
48  *****************************************************************************/
49 static int  OpenDecoder   ( vlc_object_t * );
50 static int  OpenPacketizer( vlc_object_t * );
51 static void CloseCommon   ( vlc_object_t * );
52
53 vlc_module_begin ()
54     set_description( N_("DTS parser") )
55     set_capability( "decoder", 100 )
56     set_callbacks( OpenDecoder, CloseCommon )
57
58     add_submodule ()
59     set_description( N_("DTS audio packetizer") )
60     set_capability( "packetizer", 10 )
61     set_callbacks( OpenPacketizer, CloseCommon )
62 vlc_module_end ()
63
64 /*****************************************************************************
65  * decoder_sys_t : decoder descriptor
66  *****************************************************************************/
67 struct decoder_sys_t
68 {
69     /* Module mode */
70     bool b_packetizer;
71
72     /*
73      * Input properties
74      */
75     int i_state;
76
77     block_bytestream_t bytestream;
78
79     /*
80      * Common properties
81      */
82     date_t  end_date;
83
84     mtime_t i_pts;
85
86     bool         b_dts_hd;  /* Is the current frame a DTS HD one */
87     unsigned int i_bit_rate;
88     unsigned int i_frame_size;
89     unsigned int i_frame_length;
90     unsigned int i_rate;
91     unsigned int i_channels;
92     unsigned int i_channels_conf;
93 };
94
95 /****************************************************************************
96  * Local prototypes
97  ****************************************************************************/
98 static int OpenCommon( vlc_object_t *, bool b_packetizer );
99 static block_t *DecodeBlock( decoder_t *, block_t ** );
100
101 static int  SyncInfo( const uint8_t *, bool *, unsigned int *, unsigned int *,
102                       unsigned int *, unsigned int *, unsigned int * );
103
104 static uint8_t *GetOutBuffer ( decoder_t *, block_t ** );
105 static block_t *GetAoutBuffer( decoder_t * );
106 static block_t *GetSoutBuffer( decoder_t * );
107
108 /*****************************************************************************
109  * OpenDecoder: probe the decoder
110  *****************************************************************************/
111 static int OpenDecoder( vlc_object_t *p_this )
112 {
113     /* HACK: Don't use this codec if we don't have an dts audio filter */
114     if( !module_exists( "dtstofloat32" ) )
115         return VLC_EGENERIC;
116
117     return OpenCommon( p_this, false );
118 }
119
120 /*****************************************************************************
121  * OpenPacketizer: probe the packetizer
122  *****************************************************************************/
123 static int OpenPacketizer( vlc_object_t *p_this )
124 {
125     return OpenCommon( p_this, true );
126 }
127
128 /*****************************************************************************
129  * OpenCommon:
130  *****************************************************************************/
131 static int OpenCommon( vlc_object_t *p_this, bool b_packetizer )
132 {
133     decoder_t *p_dec = (decoder_t*)p_this;
134     decoder_sys_t *p_sys;
135
136     if( p_dec->fmt_in.i_codec != VLC_CODEC_DTS )
137         return VLC_EGENERIC;
138
139     /* Allocate the memory needed to store the decoder's structure */
140     if( ( p_dec->p_sys = p_sys = malloc(sizeof(*p_sys)) ) == NULL )
141         return VLC_ENOMEM;
142
143     /* Misc init */
144     p_sys->b_packetizer = b_packetizer;
145     p_sys->i_state = STATE_NOSYNC;
146     date_Set( &p_sys->end_date, 0 );
147     p_sys->b_dts_hd = false;
148     p_sys->i_pts = VLC_TS_INVALID;
149
150     block_BytestreamInit( &p_sys->bytestream );
151
152     /* Set output properties */
153     p_dec->fmt_out.i_cat = AUDIO_ES;
154     p_dec->fmt_out.i_codec = VLC_CODEC_DTS;
155     p_dec->fmt_out.audio.i_rate = 0; /* So end_date gets initialized */
156
157     /* Set callback */
158     p_dec->pf_decode_audio = DecodeBlock;
159     p_dec->pf_packetize    = DecodeBlock;
160
161     return VLC_SUCCESS;
162 }
163
164 /****************************************************************************
165  * DecodeBlock: the whole thing
166  ****************************************************************************/
167 static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
168 {
169     decoder_sys_t *p_sys = p_dec->p_sys;
170     uint8_t p_header[DTS_HEADER_SIZE];
171     uint8_t *p_buf;
172     block_t *p_out_buffer;
173
174     if( !pp_block || !*pp_block )
175         return NULL;
176
177     if( (*pp_block)->i_flags&(BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
178     {
179         if( (*pp_block)->i_flags&BLOCK_FLAG_CORRUPTED )
180         {
181             p_sys->i_state = STATE_NOSYNC;
182             block_BytestreamEmpty( &p_sys->bytestream );
183         }
184         date_Set( &p_sys->end_date, 0 );
185         block_Release( *pp_block );
186         return NULL;
187     }
188
189     if( !date_Get( &p_sys->end_date ) && (*pp_block)->i_pts <= VLC_TS_INVALID )
190     {
191         /* We've just started the stream, wait for the first PTS. */
192         block_Release( *pp_block );
193         return NULL;
194     }
195
196     block_BytestreamPush( &p_sys->bytestream, *pp_block );
197
198     while( 1 )
199     {
200         switch( p_sys->i_state )
201         {
202         case STATE_NOSYNC:
203             /* Look for sync code - should be 0x7ffe8001 */
204             while( block_PeekBytes( &p_sys->bytestream, p_header, 6 )
205                    == VLC_SUCCESS )
206             {
207                 if( SyncCode( p_header ) == VLC_SUCCESS )
208                 {
209                     p_sys->i_state = STATE_SYNC;
210                     break;
211                 }
212                 block_SkipByte( &p_sys->bytestream );
213             }
214             if( p_sys->i_state != STATE_SYNC )
215             {
216                 block_BytestreamFlush( &p_sys->bytestream );
217
218                 /* Need more data */
219                 return NULL;
220             }
221
222         case STATE_SYNC:
223             /* New frame, set the Presentation Time Stamp */
224             p_sys->i_pts = p_sys->bytestream.p_block->i_pts;
225             if( p_sys->i_pts > VLC_TS_INVALID &&
226                 p_sys->i_pts != date_Get( &p_sys->end_date ) )
227             {
228                 date_Set( &p_sys->end_date, p_sys->i_pts );
229             }
230             p_sys->i_state = STATE_HEADER;
231
232         case STATE_HEADER:
233             /* Get DTS frame header (DTS_HEADER_SIZE bytes) */
234             if( block_PeekBytes( &p_sys->bytestream, p_header,
235                                  DTS_HEADER_SIZE ) != VLC_SUCCESS )
236             {
237                 /* Need more data */
238                 return NULL;
239             }
240
241             /* Check if frame is valid and get frame info */
242             p_sys->i_frame_size = SyncInfo( p_header,
243                                             &p_sys->b_dts_hd,
244                                             &p_sys->i_channels,
245                                             &p_sys->i_channels_conf,
246                                             &p_sys->i_rate,
247                                             &p_sys->i_bit_rate,
248                                             &p_sys->i_frame_length );
249             if( !p_sys->i_frame_size )
250             {
251                 msg_Dbg( p_dec, "emulated sync word" );
252                 block_SkipByte( &p_sys->bytestream );
253                 p_sys->i_state = STATE_NOSYNC;
254                 break;
255             }
256             p_sys->i_state = STATE_NEXT_SYNC;
257
258         case STATE_NEXT_SYNC:
259             /* TODO: If pp_block == NULL, flush the buffer without checking the
260              * next sync word */
261
262             /* Check if next expected frame contains the sync word */
263             if( block_PeekOffsetBytes( &p_sys->bytestream,
264                                        p_sys->i_frame_size, p_header, 6 )
265                 != VLC_SUCCESS )
266             {
267                 /* Need more data */
268                 return NULL;
269             }
270
271             if( p_sys->b_packetizer &&
272                 p_header[0] == 0 && p_header[1] == 0 )
273             {
274                 /* DTS wav files and audio CD's use stuffing */
275                 p_sys->i_state = STATE_SEND_DATA;
276                 break;
277             }
278
279             if( SyncCode( p_header ) != VLC_SUCCESS )
280             {
281                 msg_Dbg( p_dec, "emulated sync word "
282                          "(no sync on following frame): %2.2x%2.2x%2.2x%2.2x",
283                          (int)p_header[0], (int)p_header[1],
284                          (int)p_header[2], (int)p_header[3] );
285                 p_sys->i_state = STATE_NOSYNC;
286                 block_SkipByte( &p_sys->bytestream );
287                 break;
288             }
289             p_sys->i_state = STATE_SEND_DATA;
290             break;
291
292         case STATE_GET_DATA:
293             /* Make sure we have enough data.
294              * (Not useful if we went through NEXT_SYNC) */
295             if( block_WaitBytes( &p_sys->bytestream,
296                                  p_sys->i_frame_size ) != VLC_SUCCESS )
297             {
298                 /* Need more data */
299                 return NULL;
300             }
301             p_sys->i_state = STATE_SEND_DATA;
302
303         case STATE_SEND_DATA:
304             if( p_sys->b_dts_hd  )
305             {
306                 /* Ignore DTS-HD */
307                 block_SkipBytes( &p_sys->bytestream, p_sys->i_frame_size );
308                 p_sys->i_state = STATE_NOSYNC;
309                 break;
310             }
311
312             if( !(p_buf = GetOutBuffer( p_dec, &p_out_buffer )) )
313             {
314                 //p_dec->b_error = true;
315                 return NULL;
316             }
317
318             /* Copy the whole frame into the buffer. When we reach this point
319              * we already know we have enough data available. */
320             block_GetBytes( &p_sys->bytestream,
321                             p_buf, __MIN( p_sys->i_frame_size, p_out_buffer->i_buffer ) );
322
323             /* Make sure we don't reuse the same pts twice */
324             if( p_sys->i_pts == p_sys->bytestream.p_block->i_pts )
325                 p_sys->i_pts = p_sys->bytestream.p_block->i_pts = VLC_TS_INVALID;
326
327             p_sys->i_state = STATE_NOSYNC;
328
329             /* So p_block doesn't get re-added several times */
330             *pp_block = block_BytestreamPop( &p_sys->bytestream );
331
332             return p_out_buffer;
333         }
334     }
335
336     return NULL;
337 }
338
339 /*****************************************************************************
340  * CloseCommon: clean up the decoder
341  *****************************************************************************/
342 static void CloseCommon( vlc_object_t *p_this )
343 {
344     decoder_t *p_dec = (decoder_t*)p_this;
345     decoder_sys_t *p_sys = p_dec->p_sys;
346
347     block_BytestreamRelease( &p_sys->bytestream );
348
349     free( p_sys );
350 }
351
352 /*****************************************************************************
353  * GetOutBuffer:
354  *****************************************************************************/
355 static uint8_t *GetOutBuffer( decoder_t *p_dec, block_t **pp_out_buffer )
356 {
357     decoder_sys_t *p_sys = p_dec->p_sys;
358     uint8_t *p_buf;
359
360     if( p_dec->fmt_out.audio.i_rate != p_sys->i_rate )
361     {
362         msg_Info( p_dec, "DTS channels:%d samplerate:%d bitrate:%d",
363                   p_sys->i_channels, p_sys->i_rate, p_sys->i_bit_rate );
364
365         date_Init( &p_sys->end_date, p_sys->i_rate, 1 );
366         date_Set( &p_sys->end_date, p_sys->i_pts );
367     }
368
369     p_dec->fmt_out.audio.i_rate     = p_sys->i_rate;
370     p_dec->fmt_out.audio.i_channels = p_sys->i_channels;
371     /* Hack for DTS S/PDIF filter which needs to pad the DTS frames */
372     p_dec->fmt_out.audio.i_bytes_per_frame =
373         __MAX( p_sys->i_frame_size, p_sys->i_frame_length * 4 );
374     p_dec->fmt_out.audio.i_frame_length = p_sys->i_frame_length;
375
376     p_dec->fmt_out.audio.i_original_channels = p_sys->i_channels_conf;
377     p_dec->fmt_out.audio.i_physical_channels =
378         p_sys->i_channels_conf & AOUT_CHAN_PHYSMASK;
379
380     p_dec->fmt_out.i_bitrate = p_sys->i_bit_rate;
381
382     if( p_sys->b_packetizer )
383     {
384         block_t *p_sout_buffer = GetSoutBuffer( p_dec );
385         p_buf = p_sout_buffer ? p_sout_buffer->p_buffer : NULL;
386         *pp_out_buffer = p_sout_buffer;
387     }
388     else
389     {
390         block_t *p_aout_buffer = GetAoutBuffer( p_dec );
391         p_buf = p_aout_buffer ? p_aout_buffer->p_buffer : NULL;
392         *pp_out_buffer = p_aout_buffer;
393     }
394
395     return p_buf;
396 }
397
398 /*****************************************************************************
399  * GetAoutBuffer:
400  *****************************************************************************/
401 static block_t *GetAoutBuffer( decoder_t *p_dec )
402 {
403     decoder_sys_t *p_sys = p_dec->p_sys;
404     block_t *p_buf;
405
406     /* Hack for DTS S/PDIF filter which needs to send 3 frames at a time
407      * (plus a few header bytes) */
408     p_buf = decoder_NewAudioBuffer( p_dec, p_sys->i_frame_length * 4 );
409     if( p_buf == NULL ) return NULL;
410
411     p_buf->i_nb_samples = p_sys->i_frame_length;
412     p_buf->i_buffer = p_sys->i_frame_size;
413
414     p_buf->i_pts = date_Get( &p_sys->end_date );
415     p_buf->i_length = date_Increment( &p_sys->end_date, p_sys->i_frame_length )
416                       - p_buf->i_pts;
417
418     return p_buf;
419 }
420
421 /*****************************************************************************
422  * GetSoutBuffer:
423  *****************************************************************************/
424 static block_t *GetSoutBuffer( decoder_t *p_dec )
425 {
426     decoder_sys_t *p_sys = p_dec->p_sys;
427     block_t *p_block;
428
429     p_block = block_Alloc( p_sys->i_frame_size );
430     if( p_block == NULL ) return NULL;
431
432     p_block->i_pts = p_block->i_dts = date_Get( &p_sys->end_date );
433
434     p_block->i_length = date_Increment( &p_sys->end_date,
435         p_sys->i_frame_length ) - p_block->i_pts;
436
437     return p_block;
438 }
439
440 /*****************************************************************************
441  * SyncInfo: parse DTS sync info
442  *****************************************************************************/
443 static const unsigned int ppi_dts_samplerate[] =
444 {
445     0, 8000, 16000, 32000, 0, 0, 11025, 22050, 44100, 0, 0,
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, 1/*open*/, 2/*variable*/, 3/*lossless*/
457 };
458
459 static int SyncInfo( const uint8_t *p_buf,
460                      bool *pb_dts_hd,
461                      unsigned int *pi_channels,
462                      unsigned int *pi_channels_conf,
463                      unsigned int *pi_sample_rate,
464                      unsigned int *pi_bit_rate,
465                      unsigned int *pi_frame_length )
466 {
467     unsigned int i_audio_mode;
468
469     unsigned int i_frame_size = GetSyncInfo( p_buf, pb_dts_hd,
470             pi_sample_rate, pi_bit_rate, pi_frame_length, &i_audio_mode);
471
472     if( *pb_dts_hd == true )
473         return i_frame_size;
474
475     switch( i_audio_mode & 0xFFFF )
476     {
477         case 0x0:
478             /* Mono */
479             *pi_channels = 1;
480             *pi_channels_conf = AOUT_CHAN_CENTER;
481             break;
482         case 0x1:
483             /* Dual-mono = stereo + dual-mono */
484             *pi_channels = 2;
485             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
486                            AOUT_CHAN_DUALMONO;
487             break;
488         case 0x2:
489         case 0x3:
490         case 0x4:
491             /* Stereo */
492             *pi_channels = 2;
493             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
494             break;
495         case 0x5:
496             /* 3F */
497             *pi_channels = 3;
498             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
499                                 AOUT_CHAN_CENTER;
500             break;
501         case 0x6:
502             /* 2F/1R */
503             *pi_channels = 3;
504             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
505                                 AOUT_CHAN_REARCENTER;
506             break;
507         case 0x7:
508             /* 3F/1R */
509             *pi_channels = 4;
510             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
511                                 AOUT_CHAN_CENTER | AOUT_CHAN_REARCENTER;
512             break;
513         case 0x8:
514             /* 2F2R */
515             *pi_channels = 4;
516             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
517                                 AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
518             break;
519         case 0x9:
520             /* 3F2R */
521             *pi_channels = 5;
522             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
523                                 AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT |
524                                 AOUT_CHAN_REARRIGHT;
525             break;
526         case 0xA:
527         case 0xB:
528             /* 2F2M2R */
529             *pi_channels = 6;
530             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
531                                 AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT |
532                                 AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
533             break;
534         case 0xC:
535             /* 3F2M2R */
536             *pi_channels = 7;
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;
541             break;
542         case 0xD:
543         case 0xE:
544             /* 3F2M2R/LFE */
545             *pi_channels = 8;
546             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
547                                 AOUT_CHAN_CENTER | AOUT_CHAN_MIDDLELEFT |
548                                 AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_REARLEFT |
549                                 AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE;
550             break;
551
552         case 0xF:
553         default:
554             if( (i_audio_mode & 0xFFFF) >= 0x10 )
555             {
556                 /* User defined */
557                 *pi_channels = 0;
558                 *pi_channels_conf = 0;
559             }
560             else return 0;
561
562             break;
563     }
564
565     if( *pi_channels && (i_audio_mode & 0x10000) )
566     {
567         (*pi_channels)++;
568         *pi_channels_conf |= AOUT_CHAN_LFE;
569     }
570
571     if( *pi_sample_rate >= sizeof( ppi_dts_samplerate ) /
572                            sizeof( ppi_dts_samplerate[0] ) )
573     {
574         return 0;
575     }
576     *pi_sample_rate = ppi_dts_samplerate[ *pi_sample_rate ];
577     if( !*pi_sample_rate ) return 0;
578
579     if( *pi_bit_rate >= sizeof( ppi_dts_bitrate ) /
580                         sizeof( ppi_dts_bitrate[0] ) )
581     {
582         return 0;
583     }
584     *pi_bit_rate = ppi_dts_bitrate[ *pi_bit_rate ];
585     if( !*pi_bit_rate ) return 0;
586
587     *pi_frame_length = (*pi_frame_length + 1) * 32;
588
589     return i_frame_size;
590 }