******************************************************************************/
#include <unistd.h>
-#include <pthread.h>
#include <stdio.h> /* "intf_msg.h" */
#include <stdlib.h> /* malloc(), free() */
+#include <sys/types.h>
+#include <sys/socket.h>
#include <netinet/in.h> /* ntohl() */
#include <sys/soundcard.h> /* "audio_output.h" */
#include <sys/uio.h> /* "input.h" */
#include "common.h"
#include "config.h"
#include "mtime.h"
+#include "vlc_thread.h"
#include "debug.h" /* "input_netlist.h" */
#include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */
static void ErrorThread ( adec_thread_t * p_adec );
static void EndThread ( adec_thread_t * p_adec );
+/*
static int adec_Layer1_Mono ( adec_thread_t * p_adec );
static int adec_Layer1_Stereo ( adec_thread_t * p_adec );
static int adec_Layer2_Mono ( adec_thread_t * p_adec );
static void NeedBits ( bit_stream_t * p_bit_stream, int i_bits );
static void DumpBits ( bit_stream_t * p_bit_stream, int i_bits );
static int FindHeader ( adec_thread_t * p_adec );
+*/
/******************************************************************************
* adec_CreateThread: creates an audio decoder thread
*/
/* Initialize the decoder fifo's data lock and conditional variable and set
* its buffer as empty */
- pthread_mutex_init( &p_adec->fifo.data_lock, NULL );
- pthread_cond_init( &p_adec->fifo.data_wait, NULL );
+ vlc_mutex_init( &p_adec->fifo.data_lock );
+ vlc_cond_init( &p_adec->fifo.data_wait );
p_adec->fifo.i_start = 0;
p_adec->fifo.i_end = 0;
/* Initialize the bit stream structure */
p_adec->p_aout_fifo = NULL;
/* Spawn the audio decoder thread */
- if ( pthread_create(&p_adec->thread_id, NULL, (void *)RunThread, (void *)p_adec) )
+ if ( vlc_thread_create(&p_adec->thread_id, "audio decoder", (vlc_thread_func_t)RunThread, (void *)p_adec) )
{
intf_ErrMsg("adec error: can't spawn audio decoder thread\n");
free( p_adec );
/* Ask thread to kill itself */
p_adec->b_die = 1;
+ /* Make sure the decoder thread leaves the GetByte() function */
+ vlc_mutex_lock( &(p_adec->fifo.data_lock) );
+ vlc_cond_signal( &(p_adec->fifo.data_wait) );
+ vlc_mutex_unlock( &(p_adec->fifo.data_lock) );
+ /* Waiting for the decoder thread to exit */
/* Remove this as soon as the "status" flag is implemented */
- pthread_join( p_adec->thread_id, NULL ); /* wait until it's done */
+ vlc_thread_join( p_adec->thread_id );
}
/* Following functions are local */
NeedBits( &p_adec->bit_stream, 32 );
if ( (p_adec->bit_stream.fifo.buffer & ADEC_HEADER_SYNCWORD_MASK) == ADEC_HEADER_SYNCWORD_MASK )
{
-#ifdef DEBUG
-// fprintf(stderr, "H");
-#endif
return( 0 );
}
-#ifdef DEBUG
-// fprintf(stderr, "!");
-#endif
DumpBits( &p_adec->bit_stream, 8 );
}
#define NEXT_BUF \
/* fprintf(stderr, "%p\n", p_adec->p_aout_fifo->buffer); */ \
/* fprintf(stderr, "l_end_frame == %li, %p\n", l_end_frame, (aout_frame_t *)p_adec->p_aout_fifo->buffer + l_end_frame); */ \
- p_s16 = ((aout_frame_t *)p_adec->p_aout_fifo->buffer)[ l_end_frame ]; \
+ p_s16 = ((adec_frame_t *)p_adec->p_aout_fifo->buffer)[ l_end_frame ]; \
/* fprintf(stderr, "p_s16 == %p\n", p_s16); */ \
l_end_frame += 1; \
l_end_frame &= AOUT_FIFO_SIZE;
/* Our first job is to initialize the bit stream structure with the
* beginning of the input stream */
- pthread_mutex_lock( &p_adec->fifo.data_lock );
+ vlc_mutex_lock( &p_adec->fifo.data_lock );
while ( DECODER_FIFO_ISEMPTY(p_adec->fifo) )
{
- pthread_cond_wait( &p_adec->fifo.data_wait, &p_adec->fifo.data_lock );
+ vlc_cond_wait( &p_adec->fifo.data_wait, &p_adec->fifo.data_lock );
}
p_adec->bit_stream.p_ts = DECODER_FIFO_START( p_adec->fifo )->p_first_ts;
p_adec->bit_stream.i_byte = p_adec->bit_stream.p_ts->i_payload_start;
- pthread_mutex_unlock( &p_adec->fifo.data_lock );
+ vlc_mutex_unlock( &p_adec->fifo.data_lock );
/* Now we look for an audio frame header in the input stream */
if ( FindHeader(p_adec) )
return( -1 );
}
+ aout_fifo.l_frame_size = ADEC_FRAME_SIZE;
+
/* Creating the audio output fifo */
if ( (p_adec->p_aout_fifo = aout_CreateFifo(p_adec->p_aout, &aout_fifo)) == NULL )
{
// int i_header;
// int i_framesize;
// int i_dummy;
- mtime_t adec_date = 0;
intf_DbgMsg("adec debug: running audio decoder thread (%p) (pid == %i)\n", p_adec, getpid());
{
switch ( (p_adec->bit_stream.fifo.buffer & ADEC_HEADER_LAYER_MASK) >> ADEC_HEADER_LAYER_SHIFT )
{
+ /* Reserved */
case 0:
intf_DbgMsg("adec debug: layer == 0 (reserved)\n");
p_adec->bit_stream.fifo.buffer = 0;
p_adec->bit_stream.fifo.i_available = 0;
break;
+ /* Layer III */
case 1:
p_adec->bit_stream.fifo.buffer = 0;
p_adec->bit_stream.fifo.i_available = 0;
break;
+ /* Layer II */
case 2:
if ( (p_adec->bit_stream.fifo.buffer & ADEC_HEADER_MODE_MASK) == ADEC_HEADER_MODE_MASK )
{
}
else
{
-// i_header = p_adec->bit_stream.fifo.buffer;
-// i_framesize = pi_framesize[ 128*((i_header & ADEC_HEADER_LAYER_MASK) >> ADEC_HEADER_LAYER_SHIFT) +
-// 64*((i_header & ADEC_HEADER_PADDING_BIT_MASK) >> ADEC_HEADER_PADDING_BIT_SHIFT) +
-// 16*((i_header & ADEC_HEADER_SAMPLING_FREQUENCY_MASK) >> ADEC_HEADER_SAMPLING_FREQUENCY_SHIFT) +
-// 1*((i_header & ADEC_HEADER_BITRATE_INDEX_MASK) >> ADEC_HEADER_BITRATE_INDEX_SHIFT) ];
-// for ( i_dummy = 0; i_dummy < i_framesize; i_dummy++ )
-// {
-// GetByte( &p_adec->bit_stream );
-// }
-// for ( i_dummy = 0; i_dummy < 512; i_dummy++ )
-// {
-// p_adec->bank_0.v1[ i_dummy ] = .0;
-// p_adec->bank_1.v1[ i_dummy ] = .0;
-// p_adec->bank_0.v2[ i_dummy ] = .0;
-// p_adec->bank_1.v2[ i_dummy ] = .0;
-// }
-
- pthread_mutex_lock( &p_adec->p_aout_fifo->data_lock );
+ /* Waiting until there is enough free space in the audio output fifo
+ * in order to store the new decoded frames */
+ vlc_mutex_lock( &p_adec->p_aout_fifo->data_lock );
+ /* adec_Layer2_Stereo() produces 6 output frames (2*1152/384)...
+ * If these 6 frames were recorded in the audio output fifo, the
+ * l_end_frame index would be incremented 6 times. But, if after
+ * this operation the audio output fifo contains less than 6 frames,
+ * it would mean that we had not enough room to store the 6 frames :-P */
while ( (((p_adec->p_aout_fifo->l_end_frame + 6) - p_adec->p_aout_fifo->l_start_frame) & AOUT_FIFO_SIZE) < 6 ) /* !! */
{
- pthread_cond_wait( &p_adec->p_aout_fifo->data_wait, &p_adec->p_aout_fifo->data_lock );
+ vlc_cond_wait( &p_adec->p_aout_fifo->data_wait, &p_adec->p_aout_fifo->data_lock );
}
- pthread_mutex_unlock( &p_adec->p_aout_fifo->data_lock );
+ if ( DECODER_FIFO_START(p_adec->fifo)->b_has_pts )
+ {
+ p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->l_end_frame] = DECODER_FIFO_START(p_adec->fifo)->i_pts;
+ DECODER_FIFO_START(p_adec->fifo)->b_has_pts = 0;
+ }
+ else
+ {
+ p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->l_end_frame] = LAST_MDATE;
+ }
+ vlc_mutex_unlock( &p_adec->p_aout_fifo->data_lock );
+ /* Decoding the frames */
if ( adec_Layer2_Stereo(p_adec) )
{
- pthread_mutex_lock( &p_adec->p_aout_fifo->data_lock );
+ vlc_mutex_lock( &p_adec->p_aout_fifo->data_lock );
/* Frame 1 */
- p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->l_end_frame] = adec_date;
- p_adec->p_aout_fifo->l_end_frame += 1;
- p_adec->p_aout_fifo->l_end_frame &= AOUT_FIFO_SIZE;
+ p_adec->p_aout_fifo->l_end_frame = (p_adec->p_aout_fifo->l_end_frame + 1) & AOUT_FIFO_SIZE;
/* Frame 2 */
p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->l_end_frame] = LAST_MDATE;
- p_adec->p_aout_fifo->l_end_frame += 1;
- p_adec->p_aout_fifo->l_end_frame &= AOUT_FIFO_SIZE;
+ p_adec->p_aout_fifo->l_end_frame = (p_adec->p_aout_fifo->l_end_frame + 1) & AOUT_FIFO_SIZE;
/* Frame 3 */
p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->l_end_frame] = LAST_MDATE;
- p_adec->p_aout_fifo->l_end_frame += 1;
- p_adec->p_aout_fifo->l_end_frame &= AOUT_FIFO_SIZE;
+ p_adec->p_aout_fifo->l_end_frame = (p_adec->p_aout_fifo->l_end_frame + 1) & AOUT_FIFO_SIZE;
/* Frame 4 */
p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->l_end_frame] = LAST_MDATE;
- p_adec->p_aout_fifo->l_end_frame += 1;
- p_adec->p_aout_fifo->l_end_frame &= AOUT_FIFO_SIZE;
+ p_adec->p_aout_fifo->l_end_frame = (p_adec->p_aout_fifo->l_end_frame + 1) & AOUT_FIFO_SIZE;
/* Frame 5 */
p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->l_end_frame] = LAST_MDATE;
- p_adec->p_aout_fifo->l_end_frame += 1;
- p_adec->p_aout_fifo->l_end_frame &= AOUT_FIFO_SIZE;
+ p_adec->p_aout_fifo->l_end_frame = (p_adec->p_aout_fifo->l_end_frame + 1) & AOUT_FIFO_SIZE;
/* Frame 6 */
p_adec->p_aout_fifo->date[p_adec->p_aout_fifo->l_end_frame] = LAST_MDATE;
- p_adec->p_aout_fifo->l_end_frame += 1;
- p_adec->p_aout_fifo->l_end_frame &= AOUT_FIFO_SIZE;
- pthread_mutex_unlock( &p_adec->p_aout_fifo->data_lock );
- adec_date += 24000; /* !! */
+ p_adec->p_aout_fifo->l_end_frame = (p_adec->p_aout_fifo->l_end_frame + 1) & AOUT_FIFO_SIZE;
+ vlc_mutex_unlock( &p_adec->p_aout_fifo->data_lock );
}
}
break;
+ /* Layer I */
case 3:
if ( (p_adec->bit_stream.fifo.buffer & ADEC_HEADER_MODE_MASK) == ADEC_HEADER_MODE_MASK )
{
{
/* We take the lock, because we are going to read/write the start/end
* indexes of the decoder fifo */
- pthread_mutex_lock( &p_adec->fifo.data_lock );
+ vlc_mutex_lock( &p_adec->fifo.data_lock );
/* Wait until a `die' order is sent */
while( !p_adec->b_die )
{
input_NetlistFreePES( p_adec->bit_stream.p_input, DECODER_FIFO_START(p_adec->fifo) );
DECODER_FIFO_INCSTART( p_adec->fifo );
-#ifdef DEBUG
-// fprintf(stderr, "*");
-#endif
}
/* Waiting for the input thread to put new PES packets in the fifo */
- pthread_cond_wait( &p_adec->fifo.data_wait, &p_adec->fifo.data_lock );
+ vlc_cond_wait( &p_adec->fifo.data_wait, &p_adec->fifo.data_lock );
}
/* We can release the lock before leaving */
- pthread_mutex_unlock( &p_adec->fifo.data_lock );
+ vlc_mutex_unlock( &p_adec->fifo.data_lock );
}
/******************************************************************************