* lpcm.c: lpcm decoder module
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: lpcm.c,v 1.4 2002/09/18 01:28:05 henri Exp $
+ * $Id: lpcm.c,v 1.1 2002/09/20 23:27:03 massiot Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
* Henri Fallon <henri@videolan.org>
# include <unistd.h> /* getpid() */
#endif
-#include "lpcm.h"
+#define LPCM_FRAME_NB 502
+
+/*****************************************************************************
+ * dec_thread_t : lpcm decoder thread descriptor
+ *****************************************************************************/
+typedef struct dec_thread_t
+{
+ /*
+ * Thread properties
+ */
+ vlc_thread_t thread_id; /* id for thread functions */
+
+ /*
+ * Input properties
+ */
+ decoder_fifo_t * p_fifo; /* stores the PES stream data */
+ bit_stream_t bit_stream;
+ int sync_ptr; /* sync ptr from lpcm magic header */
+
+ /*
+ * Output properties
+ */
+ aout_instance_t *p_aout;
+ aout_input_t *p_aout_input;
+ audio_sample_format_t output_format;
+ audio_date_t end_date;
+} dec_thread_t;
+
/*****************************************************************************
* Local prototypes
*****************************************************************************/
static int OpenDecoder ( vlc_object_t * );
static int RunDecoder ( decoder_fifo_t * );
- void DecodeFrame ( lpcmdec_thread_t * );
-// static int InitThread ( lpcmdec_thread_t * );
-static void EndThread ( lpcmdec_thread_t * );
+ void DecodeFrame ( dec_thread_t * );
+// static int InitThread ( dec_thread_t * );
+static void EndThread ( dec_thread_t * );
/*****************************************************************************
* Module descriptor
*****************************************************************************/
vlc_module_begin();
- set_description( _("linear PCM audio decoder") );
+ set_description( _("linear PCM audio parser") );
set_capability( "decoder", 100 );
set_callbacks( OpenDecoder, NULL );
vlc_module_end();
*****************************************************************************/
static int RunDecoder( decoder_fifo_t * p_fifo )
{
- lpcmdec_thread_t * p_lpcmdec;
+ dec_thread_t * p_dec;
/* Allocate the memory needed to store the thread's structure */
- if( (p_lpcmdec = (lpcmdec_thread_t *)malloc (sizeof(lpcmdec_thread_t)) )
+ if( (p_dec = (dec_thread_t *)malloc (sizeof(dec_thread_t)) )
== NULL)
{
msg_Err( p_fifo, "out of memory" );
DecoderError( p_fifo );
- return( -1 );
+ return -1;
}
- /*
- * Initialize the thread properties
- */
- p_lpcmdec->p_fifo = p_fifo;
+ /* Initialize the thread properties */
+ p_dec->p_fifo = p_fifo;
- /* Init the BitStream */
- InitBitstream( &p_lpcmdec->bit_stream, p_lpcmdec->p_fifo,
+ /* Init the bitstream */
+ InitBitstream( &p_dec->bit_stream, p_dec->p_fifo,
NULL, NULL );
- /* FIXME : I suppose the number of channel ans sampling rate
- * are someway in the headers */
- p_lpcmdec->output_format.i_format = AOUT_FMT_S16_BE;
- p_lpcmdec->output_format.i_channels = 2;
- p_lpcmdec->output_format.i_rate = 48000;
+ /* FIXME : I suppose the number of channel and sampling rate
+ * are somewhere in the headers */
+ p_dec->output_format.i_format = AOUT_FMT_S16_BE;
+ p_dec->output_format.i_channels = 2;
+ p_dec->output_format.i_rate = 48000;
- aout_DateInit( &p_lpcmdec->end_date, 48000 );
- p_lpcmdec->p_aout_input = aout_InputNew( p_lpcmdec->p_fifo,
- &p_lpcmdec->p_aout,
- &p_lpcmdec->output_format );
+ aout_DateInit( &p_dec->end_date, 48000 );
+ p_dec->p_aout_input = aout_InputNew( p_dec->p_fifo,
+ &p_dec->p_aout,
+ &p_dec->output_format );
- if( p_lpcmdec->p_aout_input == NULL )
+ if ( p_dec->p_aout_input == NULL )
{
- msg_Err( p_lpcmdec->p_fifo, "failed to create aout fifo" );
- p_lpcmdec->p_fifo->b_error = 1;
+ msg_Err( p_dec->p_fifo, "failed to create aout fifo" );
+ p_dec->p_fifo->b_error = 1;
return( -1 );
}
/* lpcm decoder thread's main loop */
- while ((!p_lpcmdec->p_fifo->b_die) && (!p_lpcmdec->p_fifo->b_error))
+ while ( (!p_dec->p_fifo->b_die) && (!p_dec->p_fifo->b_error) )
{
- DecodeFrame(p_lpcmdec);
+ DecodeFrame(p_dec);
}
/* If b_error is set, the lpcm decoder thread enters the error loop */
- if (p_lpcmdec->p_fifo->b_error)
+ if ( p_dec->p_fifo->b_error )
{
- DecoderError( p_lpcmdec->p_fifo );
+ DecoderError( p_dec->p_fifo );
}
/* End of the lpcm decoder thread */
- EndThread (p_lpcmdec);
+ EndThread( p_dec );
- return( 0 );
+ return 0;
}
/*****************************************************************************
* DecodeFrame: decodes a frame.
*****************************************************************************/
-void DecodeFrame( lpcmdec_thread_t * p_lpcmdec )
+void DecodeFrame( dec_thread_t * p_dec )
{
- byte_t buffer[LPCMDEC_FRAME_SIZE];
-
aout_buffer_t * p_aout_buffer;
mtime_t i_pts;
- vlc_bool_t b_sync;
- int i_loop;
- NextPTS( &p_lpcmdec->bit_stream, &i_pts, NULL );
+ NextPTS( &p_dec->bit_stream, &i_pts, NULL );
- if( i_pts != 0 && i_pts != aout_DateGet( &p_lpcmdec->end_date ) )
+ if( i_pts != 0 && i_pts != aout_DateGet( &p_dec->end_date ) )
{
- aout_DateSet( &p_lpcmdec->end_date, i_pts );
+ aout_DateSet( &p_dec->end_date, i_pts );
}
- p_aout_buffer = aout_BufferNew( p_lpcmdec->p_aout,
- p_lpcmdec->p_aout_input,
- LPCMDEC_FRAME_SIZE/4 );
+ p_aout_buffer = aout_BufferNew( p_dec->p_aout,
+ p_dec->p_aout_input,
+ LPCM_FRAME_NB );
if( !p_aout_buffer )
{
- msg_Err( p_lpcmdec->p_fifo, "cannot get aout buffer" );
- p_lpcmdec->p_fifo->b_error = 1;
+ msg_Err( p_dec->p_fifo, "cannot get aout buffer" );
+ p_dec->p_fifo->b_error = 1;
return;
}
- p_aout_buffer->start_date = aout_DateGet( &p_lpcmdec->end_date );
-
- p_aout_buffer->end_date = aout_DateIncrement( &p_lpcmdec->end_date,
- LPCMDEC_FRAME_SIZE/4 );
+ p_aout_buffer->start_date = aout_DateGet( &p_dec->end_date );
+ p_aout_buffer->end_date = aout_DateIncrement( &p_dec->end_date,
+ LPCM_FRAME_NB );
- b_sync = 0;
- while( ( !p_lpcmdec->p_fifo->b_die ) &&
- ( !p_lpcmdec->p_fifo->b_error ) &&
- ( !b_sync ) )
- {
- while( ( !p_lpcmdec->p_fifo->b_die ) &&
- ( !p_lpcmdec->p_fifo->b_error ) &&
- ( GetBits( &p_lpcmdec->bit_stream, 8 ) != 0x01 ) );
- b_sync = ( ShowBits( &p_lpcmdec->bit_stream, 8 ) == 0x80 );
- }
-
- RemoveBits( &p_lpcmdec->bit_stream, 8 );
-
- GetChunk( &p_lpcmdec->bit_stream, p_aout_buffer->p_buffer,
- LPCMDEC_FRAME_SIZE);
+ /* Look for sync word - should be 0x0180 */
+ RealignBits( &p_dec->bit_stream );
+ while ( (GetBits( &p_dec->bit_stream, 16 ) ) != 0x0180 &&
+ (!p_dec->p_fifo->b_die) && (!p_dec->p_fifo->b_error));
+
+ GetChunk( &p_dec->bit_stream, p_aout_buffer->p_buffer,
+ LPCM_FRAME_NB * 4);
- if( p_lpcmdec->p_fifo->b_die || p_lpcmdec->p_fifo->b_error )
+ if( p_dec->p_fifo->b_die )
+ {
+ aout_BufferDelete( p_dec->p_aout, p_dec->p_aout_input,
+ p_aout_buffer );
return;
+ }
- aout_BufferPlay( p_lpcmdec->p_aout, p_lpcmdec->p_aout_input,
+ aout_BufferPlay( p_dec->p_aout, p_dec->p_aout_input,
p_aout_buffer );
-
}
/*****************************************************************************
* EndThread : lpcm decoder thread destruction
*****************************************************************************/
-static void EndThread( lpcmdec_thread_t * p_lpcmdec )
+static void EndThread( dec_thread_t * p_dec )
{
- /* If the audio output fifo was created, we destroy it */
- if( p_lpcmdec->p_aout_input )
+ if( p_dec->p_aout_input != NULL )
{
- aout_InputDelete( p_lpcmdec->p_aout, p_lpcmdec->p_aout_input );
-
+ aout_InputDelete( p_dec->p_aout, p_dec->p_aout_input );
}
- /* Destroy descriptor */
- free( p_lpcmdec );
+ free( p_dec );
}