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 $
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., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
23 *****************************************************************************/
25 /*****************************************************************************
27 *****************************************************************************/
29 #include <vlc/decoder.h>
31 #include "vlc_block_helper.h"
33 #define DTS_HEADER_SIZE 10
35 /*****************************************************************************
36 * decoder_sys_t : decoder descriptor
37 *****************************************************************************/
41 vlc_bool_t b_packetizer;
48 block_bytestream_t bytestream;
53 audio_date_t end_date;
57 int i_frame_size, i_bit_rate;
58 unsigned int i_frame_length, i_rate, i_channels, i_channels_conf;
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. */
63 aout_buffer_t *p_aout_buffer; /* current aout buffer being filled */
77 /****************************************************************************
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 ** );
85 static int SyncInfo ( const byte_t *, unsigned int *, unsigned int *,
86 unsigned int *, unsigned int *, unsigned int * );
88 static uint8_t *GetOutBuffer ( decoder_t *, void ** );
89 static aout_buffer_t *GetAoutBuffer( decoder_t * );
90 static block_t *GetSoutBuffer( decoder_t * );
92 /*****************************************************************************
94 *****************************************************************************/
96 set_description( _("DTS parser") );
97 set_capability( "decoder", 100 );
98 set_callbacks( OpenDecoder, CloseDecoder );
101 set_description( _("DTS audio packetizer") );
102 set_capability( "packetizer", 10 );
103 set_callbacks( OpenPacketizer, NULL );
106 /*****************************************************************************
107 * OpenDecoder: probe the decoder and return score
108 *****************************************************************************/
109 static int OpenDecoder( vlc_object_t *p_this )
111 decoder_t *p_dec = (decoder_t*)p_this;
112 decoder_sys_t *p_sys;
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') )
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 )
124 msg_Err( p_dec, "out of memory" );
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;
134 p_sys->bytestream = block_BytestreamInit( p_dec );
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',' ');
141 p_dec->pf_decode_audio = (aout_buffer_t *(*)(decoder_t *, block_t **))
143 p_dec->pf_packetize = (block_t *(*)(decoder_t *, block_t **))
149 static int OpenPacketizer( vlc_object_t *p_this )
151 decoder_t *p_dec = (decoder_t*)p_this;
153 int i_ret = OpenDecoder( p_this );
155 if( i_ret == VLC_SUCCESS ) p_dec->p_sys->b_packetizer = VLC_TRUE;
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 )
167 decoder_sys_t *p_sys = p_dec->p_sys;
168 uint8_t p_header[DTS_HEADER_SIZE];
172 if( !pp_block || !*pp_block ) return NULL;
174 if( !aout_DateGet( &p_sys->end_date ) && !(*pp_block)->i_pts )
176 /* We've just started the stream, wait for the first PTS. */
177 block_Release( *pp_block );
181 if( (*pp_block)->b_discontinuity )
183 p_sys->i_state = STATE_NOSYNC;
186 block_BytestreamPush( &p_sys->bytestream, *pp_block );
190 switch( p_sys->i_state )
193 /* Look for sync dword - should be 0x7ffe8001 */
194 while( block_PeekBytes( &p_sys->bytestream, p_header, 4 )
197 if( p_header[0] == 0x7f && p_header[1] == 0xfe &&
198 p_header[2] == 0x80 && p_header[3] == 0x01 )
200 p_sys->i_state = STATE_SYNC;
203 block_SkipByte( &p_sys->bytestream );
205 if( p_sys->i_state != STATE_SYNC )
207 block_BytestreamFlush( &p_sys->bytestream );
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 ) )
219 aout_DateSet( &p_sys->end_date, p_sys->i_pts );
221 p_sys->i_state = 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 )
232 /* Check if frame is valid and get frame info */
233 p_sys->i_frame_size = SyncInfo( p_header,
235 &p_sys->i_channels_conf,
238 &p_sys->i_frame_length );
239 if( !p_sys->i_frame_size )
241 msg_Dbg( p_dec, "emulated sync word" );
242 block_SkipByte( &p_sys->bytestream );
243 p_sys->i_state = STATE_NOSYNC;
246 p_sys->i_state = STATE_NEXT_SYNC;
248 case STATE_NEXT_SYNC:
249 /* TODO: If pp_block == NULL, flush the buffer without checking the
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 )
261 if( p_header[0] == 0x7f && p_header[1] == 0xfe &&
262 p_header[2] == 0x80 && p_header[3] == 0x01 )
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 );
270 p_sys->i_state = STATE_SEND_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 )
282 p_sys->i_state = STATE_SEND_DATA;
284 case STATE_SEND_DATA:
285 if( !(p_buf = GetOutBuffer( p_dec, &p_out_buffer )) )
287 //p_dec->b_error = VLC_TRUE;
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 );
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;
299 /* So p_block doesn't get re-added several times */
300 *pp_block = block_BytestreamPop( &p_sys->bytestream );
302 p_sys->i_state = STATE_NOSYNC;
304 if( !p_sys->b_packetizer )
306 if( p_sys->i_frames_in_buf != 3 ) return NULL;
309 p_sys->i_frames_in_buf = 0;
310 p_sys->p_aout_buffer = 0;
321 /*****************************************************************************
322 * CloseDecoder: clean up the decoder
323 *****************************************************************************/
324 static void CloseDecoder( vlc_object_t *p_this )
326 decoder_t *p_dec = (decoder_t*)p_this;
327 decoder_sys_t *p_sys = p_dec->p_sys;
329 block_BytestreamRelease( &p_sys->bytestream );
334 /*****************************************************************************
336 *****************************************************************************/
337 static uint8_t *GetOutBuffer( decoder_t *p_dec, void **pp_out_buffer )
339 decoder_sys_t *p_sys = p_dec->p_sys;
342 if( p_dec->fmt_out.audio.i_rate != p_sys->i_rate )
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 );
347 aout_DateInit( &p_sys->end_date, p_sys->i_rate );
348 aout_DateSet( &p_sys->end_date, p_sys->i_pts );
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;
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;
360 p_dec->fmt_out.i_bitrate = p_sys->i_bit_rate;
362 if( p_sys->b_packetizer )
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;
370 if( !p_sys->i_frames_in_buf )
372 p_sys->p_aout_buffer = GetAoutBuffer( p_dec );
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;
379 p_sys->i_frames_in_buf++;
384 /*****************************************************************************
386 *****************************************************************************/
387 static aout_buffer_t *GetAoutBuffer( decoder_t *p_dec )
389 decoder_sys_t *p_sys = p_dec->p_sys;
390 aout_buffer_t *p_buf;
392 p_buf = p_dec->pf_aout_buffer_new( p_dec, p_sys->i_frame_length * 3 );
393 if( p_buf == NULL ) return NULL;
395 p_buf->start_date = aout_DateGet( &p_sys->end_date );
397 aout_DateIncrement( &p_sys->end_date, p_sys->i_frame_length * 3 );
402 /*****************************************************************************
404 *****************************************************************************/
405 static block_t *GetSoutBuffer( decoder_t *p_dec )
407 decoder_sys_t *p_sys = p_dec->p_sys;
410 p_block = block_New( p_dec, p_sys->i_frame_size );
411 if( p_block == NULL ) return NULL;
413 p_block->i_pts = p_block->i_dts = aout_DateGet( &p_sys->end_date );
415 p_block->i_length = aout_DateIncrement( &p_sys->end_date,
416 p_sys->i_frame_length ) - p_block->i_pts;
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 )
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;
437 static const unsigned int ppi_dts_samplerate[] =
439 0, 8000, 16000, 32000, 64000, 128000,
440 11025, 22050, 44010, 88020, 176400,
441 12000, 24000, 48000, 96000, 192000
444 static const unsigned int ppi_dts_bitrate[] =
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
454 if( (p_buf[0] != 0x7f) || (p_buf[1] != 0xfe) ||
455 (p_buf[2] != 0x80) || (p_buf[3] != 0x01) )
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) |
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);
468 switch( i_audio_mode )
472 *pi_channels_conf = AOUT_CHAN_CENTER;
475 /* Dual-mono = stereo + dual-mono */
476 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
484 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
489 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
495 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
501 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
502 AOUT_CHAN_CENTER | AOUT_CHAN_LFE;
507 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
508 AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
513 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
514 AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT |
521 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
522 AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT |
523 AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
528 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
529 AOUT_CHAN_CENTER | AOUT_CHAN_MIDDLELEFT |
530 AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_REARLEFT |
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;
544 if( i_audio_mode <= 63 )
548 *pi_channels_conf = 0;
557 if( i_sample_rate >= sizeof( ppi_dts_samplerate ) /
558 sizeof( ppi_dts_samplerate[0] ) )
563 *pi_sample_rate = ppi_dts_samplerate[ i_sample_rate ];
565 if( i_bit_rate >= sizeof( ppi_dts_bitrate ) /
566 sizeof( ppi_dts_bitrate[0] ) )
571 *pi_bit_rate = ppi_dts_bitrate[ i_bit_rate ];
573 *pi_frame_length = (i_frame_length + 1) * 32;
575 return( i_frame_size + 1 );