|
|
|
@ -12,6 +12,7 @@ |
|
|
|
#include <pthread.h> |
|
|
|
#include <stdlib.h> |
|
|
|
#include <stdio.h> |
|
|
|
#include <unistd.h> |
|
|
|
#include <string.h> |
|
|
|
#include <sys/uio.h> |
|
|
|
#include <X11/Xlib.h> |
|
|
|
@ -34,7 +35,7 @@ |
|
|
|
/*
|
|
|
|
* Local prototypes |
|
|
|
*/ |
|
|
|
static int CheckConfiguration ( video_cfg_t *p_cfg ); |
|
|
|
//static int CheckConfiguration ( video_cfg_t *p_cfg );
|
|
|
|
static int InitThread ( vdec_thread_t *p_vdec ); |
|
|
|
static void RunThread ( vdec_thread_t *p_vdec ); |
|
|
|
static void ErrorThread ( vdec_thread_t *p_vdec ); |
|
|
|
@ -48,10 +49,50 @@ static void EndThread ( vdec_thread_t *p_vdec ); |
|
|
|
* Following configuration properties are used: |
|
|
|
* ?? |
|
|
|
*******************************************************************************/ |
|
|
|
vdec_thread_t * vdec_CreateThread( video_cfg_t *p_cfg, input_thread_t *p_input, |
|
|
|
vout_thread_t *p_vout, int *pi_status ) |
|
|
|
vdec_thread_t * vdec_CreateThread( /* video_cfg_t *p_cfg, */ input_thread_t *p_input /*,
|
|
|
|
vout_thread_t *p_vout, int *pi_status */ ) |
|
|
|
{ |
|
|
|
/* ?? */ |
|
|
|
vdec_thread_t * p_vdec; |
|
|
|
|
|
|
|
intf_DbgMsg("vdec debug: creating video decoder thread\n"); |
|
|
|
|
|
|
|
/* Allocate the memory needed to store the thread's structure */ |
|
|
|
if ( (p_vdec = (vdec_thread_t *)malloc( sizeof(vdec_thread_t) )) == NULL ) |
|
|
|
{ |
|
|
|
intf_ErrMsg("adec error: not enough memory for vdec_CreateThread() to create the new thread\n"); |
|
|
|
return( NULL ); |
|
|
|
} |
|
|
|
|
|
|
|
/*
|
|
|
|
* Initialize the thread properties |
|
|
|
*/ |
|
|
|
p_vdec->b_die = 0; |
|
|
|
p_vdec->b_error = 0; |
|
|
|
|
|
|
|
/*
|
|
|
|
* Initialize the input properties |
|
|
|
*/ |
|
|
|
/* Initialize the decoder fifo's data lock and conditional variable and set * its buffer as empty */ |
|
|
|
pthread_mutex_init( &p_vdec->fifo.data_lock, NULL ); |
|
|
|
pthread_cond_init( &p_vdec->fifo.data_wait, NULL ); |
|
|
|
p_vdec->fifo.i_start = 0; |
|
|
|
p_vdec->fifo.i_end = 0; |
|
|
|
/* Initialize the bit stream structure */ |
|
|
|
p_vdec->bit_stream.p_input = p_input; |
|
|
|
p_vdec->bit_stream.p_decoder_fifo = &p_vdec->fifo; |
|
|
|
p_vdec->bit_stream.fifo.buffer = 0; |
|
|
|
p_vdec->bit_stream.fifo.i_available = 0; |
|
|
|
|
|
|
|
/* Spawn the video decoder thread */ |
|
|
|
if ( pthread_create(&p_vdec->thread_id, NULL, (void *)RunThread, (void *)p_vdec) ) |
|
|
|
{ |
|
|
|
intf_ErrMsg("vdec error: can't spawn video decoder thread\n"); |
|
|
|
free( p_vdec ); |
|
|
|
return( NULL ); |
|
|
|
} |
|
|
|
|
|
|
|
intf_DbgMsg("vdec debug: video decoder thread (%p) created\n", p_vdec); |
|
|
|
return( p_vdec ); |
|
|
|
} |
|
|
|
|
|
|
|
/*******************************************************************************
|
|
|
|
@ -61,9 +102,15 @@ vdec_thread_t * vdec_CreateThread( video_cfg_t *p_cfg, input_thread_t *p_input, |
|
|
|
* be destroyed, and non 0 else. The last case probably means that the thread |
|
|
|
* was still active, and another try may succeed. |
|
|
|
*******************************************************************************/ |
|
|
|
void vdec_DestroyThread( vdec_thread_t *p_vdec, int *pi_status ) |
|
|
|
void vdec_DestroyThread( vdec_thread_t *p_vdec /*, int *pi_status */ ) |
|
|
|
{ |
|
|
|
/* ?? */ |
|
|
|
intf_DbgMsg("vdec debug: requesting termination of video decoder thread %p\n", p_vdec); |
|
|
|
|
|
|
|
/* Ask thread to kill itself */ |
|
|
|
p_vdec->b_die = 1; |
|
|
|
|
|
|
|
/* Remove this as soon as the "status" flag is implemented */ |
|
|
|
pthread_join( p_vdec->thread_id, NULL ); /* wait until it's done */ |
|
|
|
} |
|
|
|
|
|
|
|
/* following functions are local */ |
|
|
|
@ -74,12 +121,14 @@ void vdec_DestroyThread( vdec_thread_t *p_vdec, int *pi_status ) |
|
|
|
* Set default parameters where required. In DEBUG mode, check if configuration |
|
|
|
* is valid. |
|
|
|
*******************************************************************************/ |
|
|
|
#if 0 |
|
|
|
static int CheckConfiguration( video_cfg_t *p_cfg ) |
|
|
|
{ |
|
|
|
/* ?? */ |
|
|
|
|
|
|
|
return( 0 ); |
|
|
|
} |
|
|
|
#endif |
|
|
|
|
|
|
|
/*******************************************************************************
|
|
|
|
* InitThread: initialize vdec output thread |
|
|
|
@ -90,6 +139,21 @@ static int CheckConfiguration( video_cfg_t *p_cfg ) |
|
|
|
*******************************************************************************/ |
|
|
|
static int InitThread( vdec_thread_t *p_vdec ) |
|
|
|
{ |
|
|
|
|
|
|
|
intf_DbgMsg("vdec debug: initializing video decoder thread %p\n", p_vdec); |
|
|
|
|
|
|
|
/* Our first job is to initialize the bit stream structure with the
|
|
|
|
* beginning of the input stream */ |
|
|
|
pthread_mutex_lock( &p_vdec->fifo.data_lock ); |
|
|
|
while ( DECODER_FIFO_ISEMPTY(p_vdec->fifo) ) |
|
|
|
{ |
|
|
|
pthread_cond_wait( &p_vdec->fifo.data_wait, &p_vdec->fifo.data_lock ); |
|
|
|
} |
|
|
|
p_vdec->bit_stream.p_ts = DECODER_FIFO_START( p_vdec->fifo )->p_first_ts; |
|
|
|
p_vdec->bit_stream.i_byte = p_vdec->bit_stream.p_ts->i_payload_start; |
|
|
|
pthread_mutex_unlock( &p_vdec->fifo.data_lock ); |
|
|
|
|
|
|
|
#if 0 |
|
|
|
/* ?? */ |
|
|
|
/* Create video stream */ |
|
|
|
p_vdec->i_stream = vout_CreateStream( p_vdec->p_vout ); |
|
|
|
@ -100,6 +164,7 @@ static int InitThread( vdec_thread_t *p_vdec ) |
|
|
|
|
|
|
|
/* Initialize decoding data */ |
|
|
|
/* ?? */ |
|
|
|
#endif |
|
|
|
|
|
|
|
/* Initialize other properties */ |
|
|
|
#ifdef STATS |
|
|
|
@ -128,6 +193,9 @@ static int InitThread( vdec_thread_t *p_vdec ) |
|
|
|
*******************************************************************************/ |
|
|
|
static void RunThread( vdec_thread_t *p_vdec ) |
|
|
|
{ |
|
|
|
|
|
|
|
intf_DbgMsg("vdec debug: running video decoder thread (%p) (pid == %i)\n", p_vdec, getpid()); |
|
|
|
|
|
|
|
/*
|
|
|
|
* Initialize thread and free configuration |
|
|
|
*/ |
|
|
|
@ -138,6 +206,9 @@ static void RunThread( vdec_thread_t *p_vdec ) |
|
|
|
} |
|
|
|
p_vdec->b_run = 1; |
|
|
|
|
|
|
|
/* REMOVE ME !!!!! */ |
|
|
|
p_vdec->b_error = 1; |
|
|
|
|
|
|
|
/*
|
|
|
|
* Main loop - it is not executed if an error occured during |
|
|
|
* initialization |
|
|
|
@ -172,8 +243,18 @@ static void ErrorThread( vdec_thread_t *p_vdec ) |
|
|
|
/* Wait until a `die' order */ |
|
|
|
while( !p_vdec->b_die ) |
|
|
|
{ |
|
|
|
/* We take the lock, because we are going to read/write the start/end
|
|
|
|
* indexes of the decoder fifo */ |
|
|
|
pthread_mutex_lock( &p_vdec->fifo.data_lock ); |
|
|
|
|
|
|
|
/* ?? trash all trashable PES packets */ |
|
|
|
while( !DECODER_FIFO_ISEMPTY(p_vdec->fifo) ) |
|
|
|
{ |
|
|
|
input_NetlistFreePES( p_vdec->bit_stream.p_input, DECODER_FIFO_START(p_vdec->fifo) ); |
|
|
|
DECODER_FIFO_INCSTART( p_vdec->fifo ); |
|
|
|
} |
|
|
|
|
|
|
|
pthread_mutex_unlock( &p_vdec->fifo.data_lock ); |
|
|
|
/* Sleep a while */ |
|
|
|
msleep( VDEC_IDLE_SLEEP ); |
|
|
|
} |
|
|
|
@ -187,13 +268,15 @@ static void ErrorThread( vdec_thread_t *p_vdec ) |
|
|
|
*******************************************************************************/ |
|
|
|
static void EndThread( vdec_thread_t *p_vdec ) |
|
|
|
{ |
|
|
|
intf_DbgMsg("vdec debug: destroying video decoder thread %p\n", p_vdec); |
|
|
|
|
|
|
|
#ifdef DEBUG |
|
|
|
/* Check for remaining PES packets */ |
|
|
|
/* ?? */ |
|
|
|
#endif |
|
|
|
|
|
|
|
/* Destroy thread structures allocated by InitThread */ |
|
|
|
vout_DestroyStream( p_vdec->p_vout, p_vdec->i_stream ); |
|
|
|
// vout_DestroyStream( p_vdec->p_vout, p_vdec->i_stream );
|
|
|
|
/* ?? */ |
|
|
|
|
|
|
|
intf_DbgMsg("vdec debug: EndThread(%p)\n", p_vdec); |
|
|
|
|