1 /*****************************************************************************
2 * dts.c: DTS basic parser
3 *****************************************************************************
4 * Copyright (C) 2003 VideoLAN
5 * $Id: dts.c,v 1.4 2003/09/02 20:19:25 gbazin 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 *****************************************************************************/
30 #include <string.h> /* memcpy() */
34 #include <vlc/decoder.h>
35 #include <vlc/input.h>
43 #define DTS_HEADER_SIZE 10
45 /*****************************************************************************
46 * decoder_sys_t : decoder descriptor
47 *****************************************************************************/
51 vlc_bool_t b_packetizer;
58 uint8_t p_header[DTS_HEADER_SIZE];
66 * Decoder output properties
68 aout_instance_t * p_aout; /* opaque */
69 aout_input_t * p_aout_input; /* opaque */
70 audio_sample_format_t aout_format;
71 aout_buffer_t * p_aout_buffer; /* current aout buffer being filled */
72 /* This is very hacky. For DTS over S/PDIF we apparently need to send
73 * 3 frames at a time. This should likely be moved to the output stage. */
77 * Packetizer output properties
79 sout_packetizer_input_t *p_sout_input;
80 sout_format_t sout_format;
81 sout_buffer_t * p_sout_buffer; /* current sout buffer */
86 uint8_t *p_out_buffer; /* output buffer */
87 int i_out_buffer; /* position in output buffer */
88 audio_date_t end_date;
100 /****************************************************************************
102 ****************************************************************************/
103 static int OpenDecoder ( vlc_object_t * );
104 static int OpenPacketizer( vlc_object_t * );
106 static int InitDecoder ( decoder_t * );
107 static int RunDecoder ( decoder_t *, block_t * );
108 static int EndDecoder ( decoder_t * );
110 static int SyncInfo ( const byte_t *, unsigned int *, unsigned int *,
111 unsigned int *, unsigned int *, unsigned int * );
113 static int GetOutBuffer ( decoder_t *, uint8_t ** );
114 static int GetAoutBuffer( decoder_t *, aout_buffer_t ** );
115 static int GetSoutBuffer( decoder_t *, sout_buffer_t ** );
116 static int SendOutBuffer( decoder_t * );
118 /*****************************************************************************
120 *****************************************************************************/
122 set_description( _("DTS parser") );
123 set_capability( "decoder", 100 );
124 set_callbacks( OpenDecoder, NULL );
127 set_description( _("DTS audio packetizer") );
128 set_capability( "packetizer", 10 );
129 set_callbacks( OpenPacketizer, NULL );
132 /*****************************************************************************
133 * OpenDecoder: probe the decoder and return score
134 *****************************************************************************/
135 static int OpenDecoder( vlc_object_t *p_this )
137 decoder_t *p_dec = (decoder_t*)p_this;
139 if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('d','t','s',' ')
140 && p_dec->p_fifo->i_fourcc != VLC_FOURCC('d','t','s','b') )
145 p_dec->pf_init = InitDecoder;
146 p_dec->pf_decode = RunDecoder;
147 p_dec->pf_end = EndDecoder;
149 /* Allocate the memory needed to store the decoder's structure */
151 (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
153 msg_Err( p_dec, "out of memory" );
156 p_dec->p_sys->b_packetizer = VLC_FALSE;
161 static int OpenPacketizer( vlc_object_t *p_this )
163 decoder_t *p_dec = (decoder_t*)p_this;
165 int i_ret = OpenDecoder( p_this );
167 if( i_ret == VLC_SUCCESS ) p_dec->p_sys->b_packetizer = VLC_TRUE;
172 /*****************************************************************************
173 * InitDecoder: Initalize the decoder
174 *****************************************************************************/
175 static int InitDecoder( decoder_t *p_dec )
177 p_dec->p_sys->i_state = STATE_NOSYNC;
179 p_dec->p_sys->p_out_buffer = NULL;
180 p_dec->p_sys->i_out_buffer = 0;
181 aout_DateSet( &p_dec->p_sys->end_date, 0 );
183 p_dec->p_sys->p_aout = NULL;
184 p_dec->p_sys->p_aout_input = NULL;
185 p_dec->p_sys->p_aout_buffer = NULL;
186 p_dec->p_sys->aout_format.i_format = VLC_FOURCC('d','t','s',' ');
188 p_dec->p_sys->p_sout_input = NULL;
189 p_dec->p_sys->p_sout_buffer = NULL;
190 p_dec->p_sys->sout_format.i_cat = AUDIO_ES;
191 p_dec->p_sys->sout_format.i_fourcc = VLC_FOURCC('d','t','s',' ');
196 /****************************************************************************
197 * RunDecoder: the whole thing
198 ****************************************************************************
199 * This function is called just after the thread is launched.
200 ****************************************************************************/
201 static int RunDecoder( decoder_t *p_dec, block_t *p_block )
203 decoder_sys_t *p_sys = p_dec->p_sys;
204 int i, i_block_pos = 0;
205 mtime_t i_pts = p_block->i_pts;
207 while( i_block_pos < p_block->i_buffer )
209 switch( p_sys->i_state )
212 /* Look for sync dword - should be 0x7ffe8001 */
213 while( i_block_pos < p_block->i_buffer &&
214 p_block->p_buffer[i_block_pos] != 0x7f )
219 if( i_block_pos < p_block->i_buffer )
221 p_sys->i_state = STATE_PARTIAL_SYNC;
223 p_sys->p_header[0] = 0x7f;
229 case STATE_PARTIAL_SYNC:
230 /* Get the full 4 sync bytes */
231 if( p_sys->i_header < 4 )
233 int i_size = __MIN( 4 - p_sys->i_header,
234 p_block->i_buffer - i_block_pos );
236 memcpy( p_sys->p_header + p_sys->i_header,
237 p_block->p_buffer + i_block_pos, i_size );
238 i_block_pos += i_size;
239 p_sys->i_header += i_size;
242 if( p_sys->i_header < 4 )
245 if( p_sys->p_header[0] == 0x7f && p_sys->p_header[1] == 0xfe &&
246 p_sys->p_header[2] == 0x80 && p_sys->p_header[3] == 0x01 )
248 p_sys->i_state = STATE_SYNC;
252 for( i = 1; i < 4; i++ )
254 if( p_sys->p_header[i] == 0x7f ) break;
257 if( p_sys->p_header[i] == 0x7f )
259 /* Potential new sync */
260 p_sys->i_header -= i;
261 memmove( p_sys->p_header, &p_sys->p_header[i],
267 p_sys->i_state = STATE_NOSYNC;
272 /* New frame, set the Presentation Time Stamp */
273 p_sys->pts = i_pts; i_pts = 0;
274 if( p_sys->pts != 0 &&
275 p_sys->pts != aout_DateGet( &p_sys->end_date ) )
277 aout_DateSet( &p_sys->end_date, p_sys->pts );
279 p_sys->i_state = STATE_HEADER;
283 /* Get DTS frame header (DTS_HEADER_SIZE bytes) */
284 if( p_sys->i_header < DTS_HEADER_SIZE )
286 int i_size = __MIN( DTS_HEADER_SIZE - p_sys->i_header,
287 p_block->i_buffer - i_block_pos );
289 memcpy( p_sys->p_header + p_sys->i_header,
290 p_block->p_buffer + i_block_pos, i_size );
291 i_block_pos += i_size;
292 p_sys->i_header += i_size;
295 if( p_sys->i_header < DTS_HEADER_SIZE )
298 if( GetOutBuffer( p_dec, &p_sys->p_out_buffer )
301 block_Release( p_block );
305 if( !p_sys->p_out_buffer )
307 p_sys->i_state = STATE_NOSYNC;
311 memcpy( p_sys->p_out_buffer, p_sys->p_header, DTS_HEADER_SIZE );
312 p_sys->i_out_buffer = DTS_HEADER_SIZE;
313 p_sys->i_state = STATE_DATA;
317 /* Copy the whole DTS frame into the aout buffer */
318 if( p_sys->i_out_buffer < p_sys->i_frame_size )
320 int i_size = __MIN( p_sys->i_frame_size - p_sys->i_out_buffer,
321 p_block->i_buffer - i_block_pos );
323 memcpy( p_sys->p_out_buffer + p_sys->i_out_buffer,
324 p_block->p_buffer + i_block_pos, i_size );
325 i_block_pos += i_size;
326 p_sys->i_out_buffer += i_size;
329 if( p_sys->i_out_buffer < p_sys->i_frame_size )
330 break; /* Need more data */
332 SendOutBuffer( p_dec );
334 p_sys->i_state = STATE_NOSYNC;
339 block_Release( p_block );
343 /*****************************************************************************
344 * EndDecoder: clean up the decoder
345 *****************************************************************************/
346 static int EndDecoder( decoder_t *p_dec )
348 if( p_dec->p_sys->p_aout_input != NULL )
350 if( p_dec->p_sys->p_aout_buffer )
352 aout_DecDeleteBuffer( p_dec->p_sys->p_aout,
353 p_dec->p_sys->p_aout_input,
354 p_dec->p_sys->p_aout_buffer );
357 aout_DecDelete( p_dec->p_sys->p_aout, p_dec->p_sys->p_aout_input );
360 if( p_dec->p_sys->p_sout_input != NULL )
362 if( p_dec->p_sys->p_sout_buffer )
364 sout_BufferDelete( p_dec->p_sys->p_sout_input->p_sout,
365 p_dec->p_sys->p_sout_buffer );
368 sout_InputDelete( p_dec->p_sys->p_sout_input );
371 free( p_dec->p_sys );
376 /*****************************************************************************
378 *****************************************************************************/
379 static int GetOutBuffer ( decoder_t *p_dec, uint8_t **pp_out_buffer )
381 decoder_sys_t *p_sys = p_dec->p_sys;
384 if( p_sys->b_packetizer )
386 i_ret= GetSoutBuffer( p_dec, &p_sys->p_sout_buffer );
388 p_sys->p_sout_buffer ? p_sys->p_sout_buffer->p_buffer : NULL;
392 i_ret = GetAoutBuffer( p_dec, &p_sys->p_aout_buffer );
393 if( p_sys->i_frames_in_buf == 1 )
394 *pp_out_buffer = p_sys->p_aout_buffer ?
395 p_sys->p_aout_buffer->p_buffer : NULL;
397 *pp_out_buffer = p_sys->p_aout_buffer ?
398 p_sys->p_aout_buffer->p_buffer + p_sys->i_frame_size *
399 (p_sys->i_frames_in_buf - 1) : NULL;
405 /*****************************************************************************
407 *****************************************************************************/
408 static int GetAoutBuffer( decoder_t *p_dec, aout_buffer_t **pp_buffer )
411 unsigned int i_frame_length, i_rate, i_channels, i_channels_conf;
413 decoder_sys_t *p_sys = p_dec->p_sys;
415 /* Check if frame is valid and get frame info */
416 p_sys->i_frame_size = SyncInfo( p_sys->p_header,
417 &i_channels, &i_channels_conf,
418 &i_rate, &i_bit_rate, &i_frame_length );
420 if( !p_sys->i_frame_size )
422 msg_Warn( p_dec, "dts syncinfo failed" );
427 if( p_sys->p_aout_input != NULL && ( p_sys->aout_format.i_rate != i_rate
428 || p_sys->aout_format.i_original_channels != i_channels_conf
429 || (int)p_sys->aout_format.i_bytes_per_frame != p_sys->i_frame_size ) )
431 /* Parameters changed - this should not happen. */
432 aout_DecDelete( p_sys->p_aout, p_sys->p_aout_input );
433 p_sys->p_aout_input = NULL;
436 /* Creating the audio input if not created yet. */
437 if( p_sys->p_aout_input == NULL )
439 p_sys->aout_format.i_rate = i_rate;
440 p_sys->aout_format.i_original_channels = i_channels_conf;
441 p_sys->aout_format.i_physical_channels
442 = i_channels_conf & AOUT_CHAN_PHYSMASK;
443 p_sys->aout_format.i_bytes_per_frame = p_sys->i_frame_size;
444 p_sys->aout_format.i_frame_length = i_frame_length;
445 aout_DateInit( &p_sys->end_date, i_rate );
446 aout_DateSet( &p_sys->end_date, p_sys->pts );
447 p_sys->i_frames_in_buf = 3;
448 p_sys->p_aout_input = aout_DecNew( p_dec,
450 &p_sys->aout_format );
452 if ( p_sys->p_aout_input == NULL )
459 if( !aout_DateGet( &p_sys->end_date ) )
461 /* We've just started the stream, wait for the first PTS. */
466 if( p_sys->i_frames_in_buf == 3 )
468 p_sys->i_frames_in_buf = 0;
469 *pp_buffer = aout_DecNewBuffer( p_sys->p_aout, p_sys->p_aout_input,
470 i_frame_length * 3 );
471 if( *pp_buffer == NULL )
476 (*pp_buffer)->start_date = aout_DateGet( &p_sys->end_date );
477 (*pp_buffer)->end_date =
478 aout_DateIncrement( &p_sys->end_date, i_frame_length * 3 );
481 p_sys->i_frames_in_buf++;
486 /*****************************************************************************
488 *****************************************************************************/
489 static int GetSoutBuffer( decoder_t *p_dec, sout_buffer_t **pp_buffer )
492 unsigned int i_frame_length, i_rate, i_channels, i_channels_conf;
494 decoder_sys_t *p_sys = p_dec->p_sys;
496 /* Check if frame is valid and get frame info */
497 p_sys->i_frame_size = SyncInfo( p_sys->p_header,
498 &i_channels, &i_channels_conf,
499 &i_rate, &i_bit_rate, &i_frame_length );
501 if( !p_sys->i_frame_size )
503 msg_Warn( p_dec, "dts syncinfo failed" );
508 if( p_sys->p_sout_input != NULL &&
509 ( p_sys->sout_format.i_sample_rate != (int)i_rate
510 || p_sys->sout_format.i_channels != (int)i_channels ) )
512 /* Parameters changed - this should not happen. */
515 /* Creating the sout input if not created yet. */
516 if( p_sys->p_sout_input == NULL )
518 p_sys->sout_format.i_sample_rate = i_rate;
519 p_sys->sout_format.i_channels = i_channels;
520 p_sys->sout_format.i_block_align = 0;
521 p_sys->sout_format.i_bitrate = i_bit_rate;
522 p_sys->sout_format.i_extra_data = 0;
523 p_sys->sout_format.p_extra_data = NULL;
525 aout_DateInit( &p_sys->end_date, i_rate );
526 aout_DateSet( &p_sys->end_date, p_sys->pts );
528 p_sys->p_sout_input = sout_InputNew( p_dec,
529 &p_sys->sout_format );
531 if( p_sys->p_sout_input == NULL )
533 msg_Err( p_dec, "cannot add a new stream" );
537 msg_Info( p_dec, "DTS channels:%d samplerate:%d bitrate:%d",
538 i_channels, i_rate, i_bit_rate );
541 if( !aout_DateGet( &p_sys->end_date ) )
543 /* We've just started the stream, wait for the first PTS. */
548 *pp_buffer = sout_BufferNew( p_sys->p_sout_input->p_sout,
549 p_sys->i_frame_size );
550 if( *pp_buffer == NULL )
555 (*pp_buffer)->i_pts =
556 (*pp_buffer)->i_dts = aout_DateGet( &p_sys->end_date );
558 (*pp_buffer)->i_length =
559 aout_DateIncrement( &p_sys->end_date, i_frame_length )
560 - (*pp_buffer)->i_pts;
565 /*****************************************************************************
567 *****************************************************************************/
568 static int SendOutBuffer( decoder_t *p_dec )
570 decoder_sys_t *p_sys = p_dec->p_sys;
572 if( p_sys->b_packetizer )
574 sout_InputSendBuffer( p_sys->p_sout_input, p_sys->p_sout_buffer );
575 p_sys->p_sout_buffer = NULL;
577 else if( p_sys->i_frames_in_buf == 3 )
579 /* We have all we need, send the buffer to the aout core. */
580 aout_DecPlay( p_sys->p_aout, p_sys->p_aout_input,
581 p_sys->p_aout_buffer );
582 p_sys->p_aout_buffer = NULL;
588 /*****************************************************************************
589 * SyncInfo: parse DTS sync info
590 *****************************************************************************/
591 static int SyncInfo( const byte_t * p_buf,
592 unsigned int * pi_channels,
593 unsigned int * pi_channels_conf,
594 unsigned int * pi_sample_rate,
595 unsigned int * pi_bit_rate,
596 unsigned int * pi_frame_length )
598 unsigned int i_bit_rate;
599 unsigned int i_audio_mode;
600 unsigned int i_sample_rate;
601 unsigned int i_frame_size;
602 unsigned int i_frame_length;
604 static const unsigned int ppi_dts_samplerate[] =
606 0, 8000, 16000, 32000, 64000, 128000,
607 11025, 22050, 44010, 88020, 176400,
608 12000, 24000, 48000, 96000, 192000
611 static const unsigned int ppi_dts_bitrate[] =
613 32000, 56000, 64000, 96000, 112000, 128000,
614 192000, 224000, 256000, 320000, 384000,
615 448000, 512000, 576000, 640000, 768000,
616 896000, 1024000, 1152000, 1280000, 1344000,
617 1408000, 1411200, 1472000, 1536000, 1920000,
618 2048000, 3072000, 3840000, 4096000, 0, 0
621 if( (p_buf[0] != 0x7f) || (p_buf[1] != 0xfe) ||
622 (p_buf[2] != 0x80) || (p_buf[3] != 0x01) )
627 i_frame_length = (p_buf[4] & 0x01) << 6 | (p_buf[5] >> 2);
628 i_frame_size = (p_buf[5] & 0x03) << 12 | (p_buf[6] << 4) |
631 i_audio_mode = (p_buf[7] & 0x0f) << 2 | (p_buf[8] >> 6);
632 i_sample_rate = (p_buf[8] >> 2) & 0x0f;
633 i_bit_rate = (p_buf[8] & 0x03) << 3 | ((p_buf[9] >> 5) & 0x07);
635 switch( i_audio_mode )
639 *pi_channels_conf = AOUT_CHAN_CENTER;
642 /* Dual-mono = stereo + dual-mono */
643 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
651 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT;
656 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
662 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
668 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
669 AOUT_CHAN_CENTER | AOUT_CHAN_LFE;
674 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
675 AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
680 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
681 AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT |
688 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
689 AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT |
690 AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT;
695 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
696 AOUT_CHAN_CENTER | AOUT_CHAN_MIDDLELEFT |
697 AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_REARLEFT |
704 *pi_channels_conf = AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT |
705 AOUT_CHAN_CENTER | AOUT_CHAN_MIDDLELEFT |
706 AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_REARLEFT |
707 AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE;
711 if( i_audio_mode <= 63 )
715 *pi_channels_conf = 0;
724 if( i_sample_rate >= sizeof( ppi_dts_samplerate ) /
725 sizeof( ppi_dts_samplerate[0] ) )
730 *pi_sample_rate = ppi_dts_samplerate[ i_sample_rate ];
732 if( i_bit_rate >= sizeof( ppi_dts_bitrate ) /
733 sizeof( ppi_dts_bitrate[0] ) )
738 *pi_bit_rate = ppi_dts_bitrate[ i_bit_rate ];
740 *pi_frame_length = (i_frame_length + 1) * 32;
742 return( i_frame_size + 1 );