1 /*****************************************************************************
2 * dts.c: parse DTS audio sync info and packetize the stream
3 *****************************************************************************
4 * Copyright (C) 2003-2009 VLC authors and VideoLAN
7 * Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
8 * Gildas Bazin <gbazin@netcourrier.com>
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.
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.
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 *****************************************************************************/
25 /*****************************************************************************
27 *****************************************************************************/
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>
40 #include <vlc_modules.h>
43 #include "../packetizer/packetizer_helper.h"
44 #include "dts_header.h"
46 /*****************************************************************************
48 *****************************************************************************/
49 static int OpenDecoder ( vlc_object_t * );
50 static int OpenPacketizer( vlc_object_t * );
51 static void CloseCommon ( vlc_object_t * );
54 set_description( N_("DTS parser") )
55 set_capability( "decoder", 100 )
56 set_callbacks( OpenDecoder, CloseCommon )
59 set_description( N_("DTS audio packetizer") )
60 set_capability( "packetizer", 10 )
61 set_callbacks( OpenPacketizer, CloseCommon )
64 /*****************************************************************************
65 * decoder_sys_t : decoder descriptor
66 *****************************************************************************/
77 block_bytestream_t bytestream;
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;
91 unsigned int i_channels;
92 unsigned int i_channels_conf;
95 /****************************************************************************
97 ****************************************************************************/
98 static int OpenCommon( vlc_object_t *, bool b_packetizer );
99 static block_t *DecodeBlock( decoder_t *, block_t ** );
101 static int SyncInfo( const uint8_t *, bool *, unsigned int *, unsigned int *,
102 unsigned int *, unsigned int *, unsigned int * );
104 static uint8_t *GetOutBuffer ( decoder_t *, block_t ** );
105 static block_t *GetAoutBuffer( decoder_t * );
106 static block_t *GetSoutBuffer( decoder_t * );
108 /*****************************************************************************
109 * OpenDecoder: probe the decoder
110 *****************************************************************************/
111 static int OpenDecoder( vlc_object_t *p_this )
113 /* HACK: Don't use this codec if we don't have an dts audio filter */
114 if( !module_exists( "dtstofloat32" ) )
117 return OpenCommon( p_this, false );
120 /*****************************************************************************
121 * OpenPacketizer: probe the packetizer
122 *****************************************************************************/
123 static int OpenPacketizer( vlc_object_t *p_this )
125 return OpenCommon( p_this, true );
128 /*****************************************************************************
130 *****************************************************************************/
131 static int OpenCommon( vlc_object_t *p_this, bool b_packetizer )
133 decoder_t *p_dec = (decoder_t*)p_this;
134 decoder_sys_t *p_sys;
136 if( p_dec->fmt_in.i_codec != VLC_CODEC_DTS )
139 /* Allocate the memory needed to store the decoder's structure */
140 if( ( p_dec->p_sys = p_sys = malloc(sizeof(*p_sys)) ) == NULL )
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;
150 block_BytestreamInit( &p_sys->bytestream );
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 */
158 p_dec->pf_decode_audio = DecodeBlock;
159 p_dec->pf_packetize = DecodeBlock;
164 /****************************************************************************
165 * DecodeBlock: the whole thing
166 ****************************************************************************/
167 static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
169 decoder_sys_t *p_sys = p_dec->p_sys;
170 uint8_t p_header[DTS_HEADER_SIZE];
172 block_t *p_out_buffer;
174 if( !pp_block || !*pp_block )
177 if( (*pp_block)->i_flags&(BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
179 if( (*pp_block)->i_flags&BLOCK_FLAG_CORRUPTED )
181 p_sys->i_state = STATE_NOSYNC;
182 block_BytestreamEmpty( &p_sys->bytestream );
184 date_Set( &p_sys->end_date, 0 );
185 block_Release( *pp_block );
189 if( !date_Get( &p_sys->end_date ) && (*pp_block)->i_pts <= VLC_TS_INVALID )
191 /* We've just started the stream, wait for the first PTS. */
192 block_Release( *pp_block );
196 block_BytestreamPush( &p_sys->bytestream, *pp_block );
200 switch( p_sys->i_state )
203 /* Look for sync code - should be 0x7ffe8001 */
204 while( block_PeekBytes( &p_sys->bytestream, p_header, 6 )
207 if( SyncCode( p_header ) == VLC_SUCCESS )
209 p_sys->i_state = STATE_SYNC;
212 block_SkipByte( &p_sys->bytestream );
214 if( p_sys->i_state != STATE_SYNC )
216 block_BytestreamFlush( &p_sys->bytestream );
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 ) )
228 date_Set( &p_sys->end_date, p_sys->i_pts );
230 p_sys->i_state = 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 )
241 /* Check if frame is valid and get frame info */
242 p_sys->i_frame_size = SyncInfo( p_header,
245 &p_sys->i_channels_conf,
248 &p_sys->i_frame_length );
249 if( !p_sys->i_frame_size )
251 msg_Dbg( p_dec, "emulated sync word" );
252 block_SkipByte( &p_sys->bytestream );
253 p_sys->i_state = STATE_NOSYNC;
256 p_sys->i_state = STATE_NEXT_SYNC;
258 case STATE_NEXT_SYNC:
259 /* TODO: If pp_block == NULL, flush the buffer without checking the
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 )
271 if( p_sys->b_packetizer &&
272 p_header[0] == 0 && p_header[1] == 0 )
274 /* DTS wav files and audio CD's use stuffing */
275 p_sys->i_state = STATE_SEND_DATA;
279 if( SyncCode( p_header ) != VLC_SUCCESS )
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 );
289 p_sys->i_state = STATE_SEND_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 )
301 p_sys->i_state = STATE_SEND_DATA;
303 case STATE_SEND_DATA:
304 if( p_sys->b_dts_hd )
307 block_SkipBytes( &p_sys->bytestream, p_sys->i_frame_size );
308 p_sys->i_state = STATE_NOSYNC;
312 if( !(p_buf = GetOutBuffer( p_dec, &p_out_buffer )) )
314 //p_dec->b_error = true;
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 ) );
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;
327 p_sys->i_state = STATE_NOSYNC;
329 /* So p_block doesn't get re-added several times */
330 *pp_block = block_BytestreamPop( &p_sys->bytestream );
339 /*****************************************************************************
340 * CloseCommon: clean up the decoder
341 *****************************************************************************/
342 static void CloseCommon( vlc_object_t *p_this )
344 decoder_t *p_dec = (decoder_t*)p_this;
345 decoder_sys_t *p_sys = p_dec->p_sys;
347 block_BytestreamRelease( &p_sys->bytestream );
352 /*****************************************************************************
354 *****************************************************************************/
355 static uint8_t *GetOutBuffer( decoder_t *p_dec, block_t **pp_out_buffer )
357 decoder_sys_t *p_sys = p_dec->p_sys;
360 if( p_dec->fmt_out.audio.i_rate != p_sys->i_rate )
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 );
365 date_Init( &p_sys->end_date, p_sys->i_rate, 1 );
366 date_Set( &p_sys->end_date, p_sys->i_pts );
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;
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;
380 p_dec->fmt_out.i_bitrate = p_sys->i_bit_rate;
382 if( p_sys->b_packetizer )
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;
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;
398 /*****************************************************************************
400 *****************************************************************************/
401 static block_t *GetAoutBuffer( decoder_t *p_dec )
403 decoder_sys_t *p_sys = p_dec->p_sys;
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;
411 p_buf->i_nb_samples = p_sys->i_frame_length;
412 p_buf->i_buffer = p_sys->i_frame_size;
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 )
421 /*****************************************************************************
423 *****************************************************************************/
424 static block_t *GetSoutBuffer( decoder_t *p_dec )
426 decoder_sys_t *p_sys = p_dec->p_sys;
429 p_block = block_Alloc( p_sys->i_frame_size );
430 if( p_block == NULL ) return NULL;
432 p_block->i_pts = p_block->i_dts = date_Get( &p_sys->end_date );
434 p_block->i_length = date_Increment( &p_sys->end_date,
435 p_sys->i_frame_length ) - p_block->i_pts;
440 /*****************************************************************************
441 * SyncInfo: parse DTS sync info
442 *****************************************************************************/
443 static const unsigned int ppi_dts_samplerate[] =
445 0, 8000, 16000, 32000, 0, 0, 11025, 22050, 44100, 0, 0,
446 12000, 24000, 48000, 96000, 192000
449 static const unsigned int ppi_dts_bitrate[] =
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*/
459 static int SyncInfo( const uint8_t *p_buf,
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 )
467 unsigned int i_audio_mode;
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);
472 if( *pb_dts_hd == true )
475 switch( i_audio_mode & 0xFFFF )
480 *pi_channels_conf = AOUT_CHAN_CENTER;
483 /* Dual-mono = stereo + dual-mono */
485 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
493 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
498 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
504 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
505 AOUT_CHAN_REARCENTER;
510 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
511 AOUT_CHAN_CENTER | AOUT_CHAN_REARCENTER;
516 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
517 AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
522 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
523 AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT |
530 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
531 AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT |
532 AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
537 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
538 AOUT_CHAN_CENTER | AOUT_CHAN_MIDDLELEFT |
539 AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_REARLEFT |
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;
554 if( (i_audio_mode & 0xFFFF) >= 0x10 )
558 *pi_channels_conf = 0;
565 if( *pi_channels && (i_audio_mode & 0x10000) )
568 *pi_channels_conf |= AOUT_CHAN_LFE;
571 if( *pi_sample_rate >= sizeof( ppi_dts_samplerate ) /
572 sizeof( ppi_dts_samplerate[0] ) )
576 *pi_sample_rate = ppi_dts_samplerate[ *pi_sample_rate ];
577 if( !*pi_sample_rate ) return 0;
579 if( *pi_bit_rate >= sizeof( ppi_dts_bitrate ) /
580 sizeof( ppi_dts_bitrate[0] ) )
584 *pi_bit_rate = ppi_dts_bitrate[ *pi_bit_rate ];
585 if( !*pi_bit_rate ) return 0;
587 *pi_frame_length = (*pi_frame_length + 1) * 32;