]> git.sesse.net Git - vlc/blob - modules/codec/dts.c
* encoder.c: corrected required LIBAVCODEC_BUILD
[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.9 2003/12/22 14:32:55 sam 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) %2.2x%2.2x%2.2x%2.2x",
266                          p_header[0], p_header[1], p_header[2], p_header[3] );
267                 p_sys->i_state = STATE_NOSYNC;
268                 block_SkipByte( &p_sys->bytestream );
269                 break;
270             }
271             p_sys->i_state = STATE_SEND_DATA;
272             break;
273
274         case STATE_GET_DATA:
275             /* Make sure we have enough data.
276              * (Not useful if we went through NEXT_SYNC) */
277             if( block_WaitBytes( &p_sys->bytestream,
278                                  p_sys->i_frame_size ) != VLC_SUCCESS )
279             {
280                 /* Need more data */
281                 return NULL;
282             }
283             p_sys->i_state = STATE_SEND_DATA;
284
285         case STATE_SEND_DATA:
286             if( !(p_buf = GetOutBuffer( p_dec, &p_out_buffer )) )
287             {
288                 //p_dec->b_error = VLC_TRUE;
289                 return NULL;
290             }
291
292             /* Copy the whole frame into the buffer. When we reach this point
293              * we already know we have enough data available. */
294             block_GetBytes( &p_sys->bytestream, p_buf, p_sys->i_frame_size );
295
296             /* Make sure we don't reuse the same pts twice */
297             if( p_sys->i_pts == p_sys->bytestream.p_block->i_pts )
298                 p_sys->i_pts = p_sys->bytestream.p_block->i_pts = 0;
299
300             /* So p_block doesn't get re-added several times */
301             *pp_block = block_BytestreamPop( &p_sys->bytestream );
302
303             p_sys->i_state = STATE_NOSYNC;
304
305             if( !p_sys->b_packetizer )
306             {
307                 if( p_sys->i_frames_in_buf != 3 ) return NULL;
308                 else
309                 {
310                     p_sys->i_frames_in_buf = 0;
311                     p_sys->p_aout_buffer = 0;
312                 }
313             }
314
315             return p_out_buffer;
316         }
317     }
318
319     return NULL;
320 }
321
322 /*****************************************************************************
323  * CloseDecoder: clean up the decoder
324  *****************************************************************************/
325 static void CloseDecoder( vlc_object_t *p_this )
326 {
327     decoder_t *p_dec = (decoder_t*)p_this;
328     decoder_sys_t *p_sys = p_dec->p_sys;
329
330     block_BytestreamRelease( &p_sys->bytestream );
331
332     free( p_sys );
333 }
334
335 /*****************************************************************************
336  * GetOutBuffer:
337  *****************************************************************************/
338 static uint8_t *GetOutBuffer( decoder_t *p_dec, void **pp_out_buffer )
339 {
340     decoder_sys_t *p_sys = p_dec->p_sys;
341     uint8_t *p_buf;
342
343     if( p_dec->fmt_out.audio.i_rate != p_sys->i_rate )
344     {
345         msg_Info( p_dec, "DTS channels:%d samplerate:%d bitrate:%d",
346                   p_sys->i_channels, p_sys->i_rate, p_sys->i_bit_rate );
347
348         aout_DateInit( &p_sys->end_date, p_sys->i_rate );
349         aout_DateSet( &p_sys->end_date, p_sys->i_pts );
350     }
351
352     p_dec->fmt_out.audio.i_rate     = p_sys->i_rate;
353     p_dec->fmt_out.audio.i_channels = p_sys->i_channels;
354     p_dec->fmt_out.audio.i_bytes_per_frame = p_sys->i_frame_size;
355     p_dec->fmt_out.audio.i_frame_length = p_sys->i_frame_length;
356
357     p_dec->fmt_out.audio.i_original_channels = p_sys->i_channels_conf;
358     p_dec->fmt_out.audio.i_physical_channels =
359         p_sys->i_channels_conf & AOUT_CHAN_PHYSMASK;
360
361     p_dec->fmt_out.i_bitrate = p_sys->i_bit_rate;
362
363     if( p_sys->b_packetizer )
364     {
365         block_t *p_sout_buffer = GetSoutBuffer( p_dec );
366         p_buf = p_sout_buffer ? p_sout_buffer->p_buffer : NULL;
367         *pp_out_buffer = p_sout_buffer;
368     }
369     else
370     {
371         if( !p_sys->i_frames_in_buf )
372         {
373             p_sys->p_aout_buffer = GetAoutBuffer( p_dec );
374         }
375         p_buf = p_sys->p_aout_buffer ? p_sys->p_aout_buffer->p_buffer +
376             p_sys->i_frames_in_buf * p_sys->i_frame_size : NULL;
377         *pp_out_buffer = p_sys->p_aout_buffer;
378     }
379
380     p_sys->i_frames_in_buf++;
381
382     return p_buf;
383 }
384
385 /*****************************************************************************
386  * GetAoutBuffer:
387  *****************************************************************************/
388 static aout_buffer_t *GetAoutBuffer( decoder_t *p_dec )
389 {
390     decoder_sys_t *p_sys = p_dec->p_sys;
391     aout_buffer_t *p_buf;
392
393     p_buf = p_dec->pf_aout_buffer_new( p_dec, p_sys->i_frame_length * 3 );
394     if( p_buf == NULL ) return NULL;
395
396     p_buf->start_date = aout_DateGet( &p_sys->end_date );
397     p_buf->end_date =
398         aout_DateIncrement( &p_sys->end_date, p_sys->i_frame_length * 3 );
399
400     return p_buf;
401 }
402
403 /*****************************************************************************
404  * GetSoutBuffer:
405  *****************************************************************************/
406 static block_t *GetSoutBuffer( decoder_t *p_dec )
407 {
408     decoder_sys_t *p_sys = p_dec->p_sys;
409     block_t *p_block;
410
411     p_block = block_New( p_dec, p_sys->i_frame_size );
412     if( p_block == NULL ) return NULL;
413
414     p_block->i_pts = p_block->i_dts = aout_DateGet( &p_sys->end_date );
415
416     p_block->i_length = aout_DateIncrement( &p_sys->end_date,
417         p_sys->i_frame_length ) - p_block->i_pts;
418
419     return p_block;
420 }
421
422 /*****************************************************************************
423  * SyncInfo: parse DTS sync info
424  *****************************************************************************/
425 static int SyncInfo( const byte_t * p_buf,
426                      unsigned int * pi_channels,
427                      unsigned int * pi_channels_conf,
428                      unsigned int * pi_sample_rate,
429                      unsigned int * pi_bit_rate,
430                      unsigned int * pi_frame_length )
431 {
432     unsigned int i_bit_rate;
433     unsigned int i_audio_mode;
434     unsigned int i_sample_rate;
435     unsigned int i_frame_size;
436     unsigned int i_frame_length;
437
438     static const unsigned int ppi_dts_samplerate[] =
439     {
440         0, 8000, 16000, 32000, 64000, 128000,
441         11025, 22050, 44010, 88020, 176400,
442         12000, 24000, 48000, 96000, 192000
443     };
444
445     static const unsigned int ppi_dts_bitrate[] =
446     {
447         32000, 56000, 64000, 96000, 112000, 128000,
448         192000, 224000, 256000, 320000, 384000,
449         448000, 512000, 576000, 640000, 768000,
450         896000, 1024000, 1152000, 1280000, 1344000,
451         1408000, 1411200, 1472000, 1536000, 1920000,
452         2048000, 3072000, 3840000, 4096000, 0, 0
453     };
454
455     if( (p_buf[0] != 0x7f) || (p_buf[1] != 0xfe) ||
456         (p_buf[2] != 0x80) || (p_buf[3] != 0x01) )
457     {
458         return( 0 );
459     }
460
461     i_frame_length = (p_buf[4] & 0x01) << 6 | (p_buf[5] >> 2);
462     i_frame_size = (p_buf[5] & 0x03) << 12 | (p_buf[6] << 4) |
463                    (p_buf[7] >> 4);
464
465     i_audio_mode = (p_buf[7] & 0x0f) << 2 | (p_buf[8] >> 6);
466     i_sample_rate = (p_buf[8] >> 2) & 0x0f;
467     i_bit_rate = (p_buf[8] & 0x03) << 3 | ((p_buf[9] >> 5) & 0x07);
468
469     switch( i_audio_mode )
470     {
471         case 0x0:
472             /* Mono */
473             *pi_channels_conf = AOUT_CHAN_CENTER;
474             break;
475         case 0x1:
476             /* Dual-mono = stereo + dual-mono */
477             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
478                            AOUT_CHAN_DUALMONO;
479             break;
480         case 0x2:
481         case 0x3:
482         case 0x4:
483             /* Stereo */
484             *pi_channels = 2;
485             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
486             break;
487         case 0x5:
488             /* 3F */
489             *pi_channels = 3;
490             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
491                                 AOUT_CHAN_CENTER;
492             break;
493         case 0x6:
494             /* 2F/LFE */
495             *pi_channels = 3;
496             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
497                                 AOUT_CHAN_LFE;
498             break;
499         case 0x7:
500             /* 3F/LFE */
501             *pi_channels = 4;
502             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
503                                 AOUT_CHAN_CENTER | AOUT_CHAN_LFE;
504             break;
505         case 0x8:
506             /* 2F2R */
507             *pi_channels = 4;
508             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
509                                 AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
510             break;
511         case 0x9:
512             /* 3F2R */
513             *pi_channels = 5;
514             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
515                                 AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT |
516                                 AOUT_CHAN_REARRIGHT;
517             break;
518         case 0xA:
519         case 0xB:
520             /* 2F2M2R */
521             *pi_channels = 6;
522             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
523                                 AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT |
524                                 AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
525             break;
526         case 0xC:
527             /* 3F2M2R */
528             *pi_channels = 7;
529             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
530                                 AOUT_CHAN_CENTER | AOUT_CHAN_MIDDLELEFT |
531                                 AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_REARLEFT |
532                                 AOUT_CHAN_REARRIGHT;
533             break;
534         case 0xD:
535         case 0xE:
536             /* 3F2M2R/LFE */
537             *pi_channels = 8;
538             *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
539                                 AOUT_CHAN_CENTER | AOUT_CHAN_MIDDLELEFT |
540                                 AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_REARLEFT |
541                                 AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE;
542             break;
543
544         default:
545             if( i_audio_mode <= 63 )
546             {
547                 /* User defined */
548                 *pi_channels = 0;
549                 *pi_channels_conf = 0;
550             }
551             else
552             {
553                 return( 0 );
554             }
555             break;
556     }
557
558     if( i_sample_rate >= sizeof( ppi_dts_samplerate ) /
559                          sizeof( ppi_dts_samplerate[0] ) )
560     {
561         return( 0 );
562     }
563
564     *pi_sample_rate = ppi_dts_samplerate[ i_sample_rate ];
565
566     if( i_bit_rate >= sizeof( ppi_dts_bitrate ) /
567                       sizeof( ppi_dts_bitrate[0] ) )
568     {
569         return( 0 );
570     }
571
572     *pi_bit_rate = ppi_dts_bitrate[ i_bit_rate ];
573
574     *pi_frame_length = (i_frame_length + 1) * 32;
575
576     return i_frame_size + 1;
577 }