From 723948d941c70e52c47cab0679227e4fee638d36 Mon Sep 17 00:00:00 2001 From: Christophe Massiot Date: Sat, 18 Dec 1999 17:13:55 +0000 Subject: [PATCH] =?UTF-8?q?*=20Patchs=20MPEG1,=20qui=20marchent=20ou=20qui?= =?UTF-8?q?=20ne=20marche=20pas=20;=20*=20Optimisation=20de=20ClearBlock()?= =?UTF-8?q?=20;=20*=20D=EF=BF=BDbut=20du=20video=5Fparser=20;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/video_parser.h | 76 +++++++++ src/video_parser/video_parser.c | 288 ++++++++++++++++++++++++++++++++ 2 files changed, 364 insertions(+) create mode 100644 include/video_parser.h create mode 100644 src/video_parser/video_parser.c diff --git a/include/video_parser.h b/include/video_parser.h new file mode 100644 index 0000000000..0a199e715e --- /dev/null +++ b/include/video_parser.h @@ -0,0 +1,76 @@ +/******************************************************************************* + * video_decoder.h : video decoder thread + * (c)1999 VideoLAN + ******************************************************************************* + ******************************************************************************* + * Requires: + * "config.h" + * "common.h" + * "mtime.h" + * "vlc_thread.h" + * "input.h" + * "video.h" + * "video_output.h" + * "decoder_fifo.h" + *******************************************************************************/ + +/******************************************************************************* + * vdec_thread_t: video decoder thread descriptor + ******************************************************************************* + * ?? + *******************************************************************************/ +typedef struct vdec_thread_s +{ + /* Thread properties and locks */ + boolean_t b_die; /* `die' flag */ + boolean_t b_run; /* `run' flag */ + boolean_t b_error; /* `error' flag */ + boolean_t b_active; /* `active' flag */ + vlc_thread_t thread_id; /* id for thread functions */ + + /* Thread configuration */ + /* ?? */ + /*??*/ +// int *pi_status; + + + /* Input properties */ + 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 */ + + +#ifdef STATS + /* Statistics */ + count_t c_loops; /* number of loops */ + count_t c_idle_loops; /* number of idle loops */ + count_t c_pictures; /* number of pictures read */ + count_t c_i_pictures; /* number of I pictures read */ + count_t c_p_pictures; /* number of P pictures read */ + count_t c_b_pictures; /* number of B pictures read */ + count_t c_decoded_pictures; /* number of pictures decoded */ + count_t c_decoded_i_pictures; /* number of I pictures decoded */ + count_t c_decoded_p_pictures; /* number of P pictures decoded */ + count_t c_decoded_b_pictures; /* number of B pictures decoded */ +#endif +} vdec_thread_t; + +/******************************************************************************* + * Prototypes + *******************************************************************************/ + +/* 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 */ ); + +/* Time management functions */ +/* ?? */ + +/* Dynamic thread settings */ +/* ?? */ diff --git a/src/video_parser/video_parser.c b/src/video_parser/video_parser.c new file mode 100644 index 0000000000..08ccd14669 --- /dev/null +++ b/src/video_parser/video_parser.c @@ -0,0 +1,288 @@ +/******************************************************************************* + * video_decoder.c : video decoder thread + * (c)1999 VideoLAN + *******************************************************************************/ + +/* ?? passer en terminate/destroy avec les signaux supplémentaires */ + +/******************************************************************************* + * Preamble + *******************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "config.h" +#include "common.h" +#include "mtime.h" +#include "vlc_thread.h" + +#include "intf_msg.h" +#include "debug.h" /* ?? temporaire, requis par netlist.h */ + +#include "input.h" +#include "input_netlist.h" +#include "decoder_fifo.h" +#include "video.h" +#include "video_output.h" +#include "video_decoder.h" + +/* + * Local prototypes + */ +//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 ); +static void EndThread ( vdec_thread_t *p_vdec ); + +/******************************************************************************* + * vdec_CreateThread: create a generic decoder thread + ******************************************************************************* + * This function creates a new video decoder thread, and returns a pointer + * to its description. On error, it returns NULL. + * Following configuration properties are used: + * ?? + *******************************************************************************/ +vdec_thread_t * vpar_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 */ + vlc_mutex_init( &p_vdec->fifo.data_lock ); + vlc_cond_init( &p_vdec->fifo.data_wait ); + 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 ( vlc_thread_create(&p_vdec->thread_id, "video decoder", (vlc_thread_func)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 ); +} + +/******************************************************************************* + * vdec_DestroyThread: destroy a generic decoder thread + ******************************************************************************* + * Destroy a terminated thread. This function will return 0 if the thread could + * 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 */ ) +{ + intf_DbgMsg("vdec debug: requesting termination of video decoder thread %p\n", p_vdec); + + /* Ask thread to kill itself */ + p_vdec->b_die = 1; + /* Make sure the decoder thread leaves the GetByte() function */ + vlc_mutex_lock( &(p_vdec->fifo.data_lock) ); + vlc_cond_signal( &(p_vdec->fifo.data_wait) ); + vlc_mutex_unlock( &(p_vdec->fifo.data_lock) ); + + /* Waiting for the decoder thread to exit */ + /* Remove this as soon as the "status" flag is implemented */ + vlc_thread_join( p_vdec->thread_id ); +} + +/* following functions are local */ + +/******************************************************************************* + * CheckConfiguration: check vdec_CreateThread() configuration + ******************************************************************************* + * 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 + ******************************************************************************* + * This function is called from RunThread and performs the second step of the + * initialization. It returns 0 on success. Note that the thread's flag are not + * modified inside this function. + *******************************************************************************/ +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 */ + vlc_mutex_lock( &p_vdec->fifo.data_lock ); + while ( DECODER_FIFO_ISEMPTY(p_vdec->fifo) ) + { + vlc_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; + vlc_mutex_unlock( &p_vdec->fifo.data_lock ); + +#if 0 + /* ?? */ + /* Create video stream */ + p_vdec->i_stream = vout_CreateStream( p_vdec->p_vout ); + if( p_vdec->i_stream < 0 ) /* error */ + { + return( 1 ); + } + + /* Initialize decoding data */ + /* ?? */ +#endif + + /* Initialize other properties */ +#ifdef STATS + p_vdec->c_loops = 0; + p_vdec->c_idle_loops = 0; + p_vdec->c_pictures = 0; + p_vdec->c_i_pictures = 0; + p_vdec->c_p_pictures = 0; + p_vdec->c_b_pictures = 0; + p_vdec->c_decoded_pictures = 0; + p_vdec->c_decoded_i_pictures = 0; + p_vdec->c_decoded_p_pictures = 0; + p_vdec->c_decoded_b_pictures = 0; +#endif + + /* Mark thread as running and return */ + intf_DbgMsg("vdec debug: InitThread(%p) succeeded\n", p_vdec); + return( 0 ); +} + +/******************************************************************************* + * RunThread: generic decoder thread + ******************************************************************************* + * Generic decoder thread. This function does only returns when the thread is + * terminated. + *******************************************************************************/ +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 + */ + p_vdec->b_error = InitThread( p_vdec ); + if( p_vdec->b_error ) + { + return; + } + p_vdec->b_run = 1; + +/* REMOVE ME !!!!! */ +p_vdec->b_error = 1; + + /* + * Main loop - it is not executed if an error occured during + * initialization + */ + while( (!p_vdec->b_die) && (!p_vdec->b_error) ) + { + /* ?? */ + } + + /* + * Error loop + */ + if( p_vdec->b_error ) + { + ErrorThread( p_vdec ); + } + + /* End of thread */ + EndThread( p_vdec ); + p_vdec->b_run = 0; +} + +/******************************************************************************* + * ErrorThread: RunThread() error loop + ******************************************************************************* + * This function is called when an error occured during thread main's loop. The + * thread can still receive feed, but must be ready to terminate as soon as + * possible. + *******************************************************************************/ +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 */ + vlc_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 ); + } + + vlc_mutex_unlock( &p_vdec->fifo.data_lock ); + /* Sleep a while */ + msleep( VDEC_IDLE_SLEEP ); + } +} + +/******************************************************************************* + * EndThread: thread destruction + ******************************************************************************* + * This function is called when the thread ends after a sucessfull + * initialization. + *******************************************************************************/ +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 ); + /* ?? */ + + intf_DbgMsg("vdec debug: EndThread(%p)\n", p_vdec); +}