From b8d921651c0cda5470cabdfc5204e30c2dbba805 Mon Sep 17 00:00:00 2001 From: Christophe Massiot Date: Tue, 21 Sep 1999 18:55:53 +0000 Subject: [PATCH] * Le video_decoder a desormais une structure qui tourne (copier-coller de l'audio_decoder) ; L'integration du mpeg2decode arrive ! --Meuuh --- include/config.h | 6 +- include/video_decoder.h | 12 ++-- src/input/input.c | 2 +- src/input/input_ctrl.c | 16 ++--- src/interface/intf_msg.c | 12 ++-- src/video_decoder/video_decoder.c | 97 ++++++++++++++++++++++++++++--- 6 files changed, 116 insertions(+), 29 deletions(-) diff --git a/include/config.h b/include/config.h index 49a352ba2f..63720dba45 100644 --- a/include/config.h +++ b/include/config.h @@ -36,7 +36,7 @@ *******************************************************************************/ /* General debugging support */ -//#define DEBUG +#define DEBUG /* Modules specific debugging */ #define DEBUG_INTF @@ -57,7 +57,7 @@ *******************************************************************************/ /* Automagically spawn input, audio and video threads ? */ -//#define AUTO_SPAWN +#define AUTO_SPAWN /* Startup script */ #define INIT_SCRIPT "vlc.init" @@ -268,7 +268,7 @@ /* Filename to log message * Note that messages are only logged when debugging */ -#define INTF_MSG_LOGFILE "vlc.log" +//#define INTF_MSG_LOGFILE "vlc.log" /* * X11 console properties diff --git a/include/video_decoder.h b/include/video_decoder.h index cb3bdd541d..5910ca4b48 100644 --- a/include/video_decoder.h +++ b/include/video_decoder.h @@ -31,13 +31,15 @@ typedef struct vdec_thread_s /* Thread configuration */ /* ?? */ /*??*/ - int *pi_status; +// int *pi_status; /* Input properties */ - input_thread_t * p_input; /* input thread */ decoder_fifo_t fifo; /* PES input fifo */ + /* The bit stream structure handles the PES stream at the bit level */ + bit_stream_t bit_stream; + /* Output properties */ vout_thread_t * p_vout; /* video output thread */ int i_stream; /* video stream id */ @@ -63,9 +65,9 @@ typedef struct vdec_thread_s *******************************************************************************/ /* Thread management functions */ -vdec_thread_t * vdec_CreateThread ( video_cfg_t *p_cfg, input_thread_t *p_input, - vout_thread_t *p_vout, int *pi_status ); -void vdec_DestroyThread ( vdec_thread_t *p_vdec, 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 */ ); +void vdec_DestroyThread ( vdec_thread_t *p_vdec /*, int *pi_status */ ); /* Time management functions */ /* ?? */ diff --git a/src/input/input.c b/src/input/input.c index e6c17d0f2b..76ec1c08f6 100644 --- a/src/input/input.c +++ b/src/input/input.c @@ -234,7 +234,7 @@ void input_DestroyThread( input_thread_t *p_input ) { case MPEG1_VIDEO_ES: case MPEG2_VIDEO_ES: - vdec_DestroyThread( (vdec_thread_t*)(p_input->pp_selected_es[i_es_loop]->p_dec), NULL ); + vdec_DestroyThread( (vdec_thread_t*)(p_input->pp_selected_es[i_es_loop]->p_dec) /*, NULL */ ); break; case MPEG1_AUDIO_ES: case MPEG2_AUDIO_ES: diff --git a/src/input/input_ctrl.c b/src/input/input_ctrl.c index 213ade4f23..6dafad703b 100644 --- a/src/input/input_ctrl.c +++ b/src/input/input_ctrl.c @@ -115,13 +115,13 @@ int input_AddPgrmElem( input_thread_t *p_input, int i_current_id ) case MPEG2_VIDEO_ES: /* Spawn video thread. */ /* Les 2 pointeurs NULL ne doivent pas etre NULL sinon on segfault !!!! */ -// if( ((vdec_thread_t*)(p_input->p_es[i_es_loop].p_dec) = -// vdec_CreateThread( NULL, p_input, NULL )) == NULL ) -// { -// intf_ErrMsg("Could not start video decoder\n"); -// pthread_mutex_unlock( &p_input->es_lock ); -// return( -1 ); -// } + if( ((vdec_thread_t*)(p_input->p_es[i_es_loop].p_dec) = + vdec_CreateThread( p_input )) == NULL ) + { + intf_ErrMsg("Could not start video decoder\n"); + pthread_mutex_unlock( &p_input->es_lock ); + return( -1 ); + } break; default: @@ -199,7 +199,7 @@ int input_DelPgrmElem( input_thread_t *p_input, int i_current_id ) case MPEG1_VIDEO_ES: case MPEG2_VIDEO_ES: - vdec_DestroyThread( (vdec_thread_t*)(p_input->pp_selected_es[i_selected_es_loop]->p_dec), NULL ); + vdec_DestroyThread( (vdec_thread_t*)(p_input->pp_selected_es[i_selected_es_loop]->p_dec) /*, NULL */ ); break; } diff --git a/src/interface/intf_msg.c b/src/interface/intf_msg.c index bc9d9aabf8..766f727588 100644 --- a/src/interface/intf_msg.c +++ b/src/interface/intf_msg.c @@ -306,9 +306,7 @@ static void QueueMsg(interface_msg_t *p_intf_msg, int i_type, char *psz_format, */ msg.i_type = i_type; msg.psz_msg = psz_str; -#ifdef DEBUG msg.date = mdate(); -#endif PrintMsg( &msg ); /* print message */ free( psz_str ); /* free message data */ @@ -373,7 +371,9 @@ static void QueueDbgMsg(interface_msg_t *p_intf_msg, char *psz_file, char *psz_f msg.psz_file = psz_file; msg.psz_function = psz_function; msg.i_line = i_line; - msg.date = mdate(); +#ifdef DEBUG +// msg.date = mdate(); +#endif msg.psz_msg = psz_str; PrintMsg( &msg ); /* print message */ free( psz_str ); /* free message data */ @@ -434,16 +434,18 @@ static void PrintMsg( interface_msg_message_t *p_msg ) break; case INTF_MSG_INTF: /* interface messages */ + case INTF_MSG_DBG: asprintf( &psz_msg, p_msg->psz_msg ); break; - +#if 0 case INTF_MSG_DBG: /* debug messages */ asprintf( &psz_msg, "(%s) " INTF_MSG_DBG_FORMAT "%s", psz_date, p_msg->psz_file, p_msg->psz_function, p_msg->i_line, p_msg->psz_msg ); break; +#endif } - + /* Check if formatting function suceeded */ if( psz_msg == NULL ) { diff --git a/src/video_decoder/video_decoder.c b/src/video_decoder/video_decoder.c index 048fc521d9..3c0c784ded 100644 --- a/src/video_decoder/video_decoder.c +++ b/src/video_decoder/video_decoder.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -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);