Commit 5d7967a8 authored by Christophe Massiot's avatar Christophe Massiot

* Ajout d'un flag VDEC_SMP � commenter si on n'a qu'un seul

microprocesseur.
parent 57f09822
...@@ -285,8 +285,11 @@ ...@@ -285,8 +285,11 @@
#define VPAR_IDLE_SLEEP 100000 #define VPAR_IDLE_SLEEP 100000
/* Time to sleep when waiting for a buffer (from vout or the video fifo). */
#define VPAR_OUTMEM_SLEEP 50000 #define VPAR_OUTMEM_SLEEP 50000
/* The following directives only apply if you define VDEC_SMP below. */
/* Number of macroblock buffers available. It should be always greater than /* Number of macroblock buffers available. It should be always greater than
* twice the number of macroblocks in a picture. VFIFO_SIZE + 1 should also * twice the number of macroblocks in a picture. VFIFO_SIZE + 1 should also
* be a power of two. */ * be a power of two. */
...@@ -299,15 +302,16 @@ ...@@ -299,15 +302,16 @@
* Video decoder configuration * Video decoder configuration
*******************************************************************************/ *******************************************************************************/
//#define VDEC_SMP
#define VDEC_IDLE_SLEEP 100000 #define VDEC_IDLE_SLEEP 100000
/* Number of video_decoder threads to launch on startup of the video_parser. /* Number of video_decoder threads to launch on startup of the video_parser.
* It should always be less than half the number of macroblocks of a * It should always be less than half the number of macroblocks of a
* picture. */ * picture. Only available if you defined VDEC_SMP above. */
#define NB_VDEC 1 #define NB_VDEC 1
/* Maximum range of values out of the IDCT + motion compensation. Only /* Maximum range of values out of the IDCT + motion compensation. */
* used if you define MPEG2_COMPLIANT above. */
#define VDEC_CROPRANGE 2048 #define VDEC_CROPRANGE 2048
/******************************************************************************* /*******************************************************************************
......
...@@ -79,6 +79,7 @@ typedef struct vdec_thread_s ...@@ -79,6 +79,7 @@ typedef struct vdec_thread_s
*****************************************************************************/ *****************************************************************************/
#ifndef OLD_DECODER #ifndef OLD_DECODER
struct vpar_thread_s; struct vpar_thread_s;
struct macroblock_s;
#endif #endif
/* Thread management functions */ /* Thread management functions */
...@@ -87,6 +88,10 @@ p_vdec_thread_t vdec_CreateThread ( /* video_cfg_t *p_cfg, */ input_threa ...@@ -87,6 +88,10 @@ p_vdec_thread_t vdec_CreateThread ( /* video_cfg_t *p_cfg, */ input_threa
vout_thread_t *p_vout, int *pi_status */ ); vout_thread_t *p_vout, int *pi_status */ );
void vdec_DestroyThread ( vdec_thread_t *p_vdec /*, int *pi_status */ ); void vdec_DestroyThread ( vdec_thread_t *p_vdec /*, int *pi_status */ );
#else #else
#ifndef VDEC_SMP
int vdec_InitThread ( struct vdec_thread_s *p_vdec );
void vdec_DecodeMacroblock ( struct vdec_thread_s *p_vdec, struct macroblock_s *p_mb );
#endif
vdec_thread_t * vdec_CreateThread ( struct vpar_thread_s *p_vpar /*, int *pi_status */ ); vdec_thread_t * vdec_CreateThread ( struct vpar_thread_s *p_vpar /*, int *pi_status */ );
void vdec_DestroyThread ( vdec_thread_t *p_vdec /*, int *pi_status */ ); void vdec_DestroyThread ( vdec_thread_t *p_vdec /*, int *pi_status */ );
#endif #endif
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
* Macros * Macros
*****************************************************************************/ *****************************************************************************/
#ifdef VDEC_SMP
/* ?? move to inline functions */ /* ?? move to inline functions */
#define VIDEO_FIFO_ISEMPTY( fifo ) ( (fifo).i_start == (fifo).i_end ) #define VIDEO_FIFO_ISEMPTY( fifo ) ( (fifo).i_start == (fifo).i_end )
#define VIDEO_FIFO_ISFULL( fifo ) ( ( ( (fifo).i_end + 1 - (fifo).i_start ) \ #define VIDEO_FIFO_ISFULL( fifo ) ( ( ( (fifo).i_end + 1 - (fifo).i_start ) \
...@@ -25,12 +26,14 @@ ...@@ -25,12 +26,14 @@
#define VIDEO_FIFO_END( fifo ) ( (fifo).buffer[ (fifo).i_end ] ) #define VIDEO_FIFO_END( fifo ) ( (fifo).buffer[ (fifo).i_end ] )
#define VIDEO_FIFO_INCEND( fifo ) ( (fifo).i_end = ((fifo).i_end + 1) \ #define VIDEO_FIFO_INCEND( fifo ) ( (fifo).i_end = ((fifo).i_end + 1) \
& VFIFO_SIZE ) & VFIFO_SIZE )
#endif
/***************************************************************************** /*****************************************************************************
* vpar_GetMacroblock : return a macroblock to be decoded * vpar_GetMacroblock : return a macroblock to be decoded
*****************************************************************************/ *****************************************************************************/
static __inline__ macroblock_t * vpar_GetMacroblock( video_fifo_t * p_fifo ) static __inline__ macroblock_t * vpar_GetMacroblock( video_fifo_t * p_fifo )
{ {
#ifdef VDEC_SMP
macroblock_t * p_mb; macroblock_t * p_mb;
vlc_mutex_lock( &p_fifo->lock ); vlc_mutex_lock( &p_fifo->lock );
...@@ -50,6 +53,10 @@ static __inline__ macroblock_t * vpar_GetMacroblock( video_fifo_t * p_fifo ) ...@@ -50,6 +53,10 @@ static __inline__ macroblock_t * vpar_GetMacroblock( video_fifo_t * p_fifo )
vlc_mutex_unlock( &p_fifo->lock ); vlc_mutex_unlock( &p_fifo->lock );
return( p_mb ); return( p_mb );
#else
/* Shouldn't normally be used without SMP. */
return NULL;
#endif
} }
/***************************************************************************** /*****************************************************************************
...@@ -57,6 +64,7 @@ static __inline__ macroblock_t * vpar_GetMacroblock( video_fifo_t * p_fifo ) ...@@ -57,6 +64,7 @@ static __inline__ macroblock_t * vpar_GetMacroblock( video_fifo_t * p_fifo )
*****************************************************************************/ *****************************************************************************/
static __inline__ macroblock_t * vpar_NewMacroblock( video_fifo_t * p_fifo ) static __inline__ macroblock_t * vpar_NewMacroblock( video_fifo_t * p_fifo )
{ {
#ifdef VDEC_SMP
macroblock_t * p_mb; macroblock_t * p_mb;
#define P_buffer p_fifo->p_vpar->vbuffer #define P_buffer p_fifo->p_vpar->vbuffer
...@@ -75,6 +83,9 @@ static __inline__ macroblock_t * vpar_NewMacroblock( video_fifo_t * p_fifo ) ...@@ -75,6 +83,9 @@ static __inline__ macroblock_t * vpar_NewMacroblock( video_fifo_t * p_fifo )
vlc_mutex_unlock( &P_buffer.lock ); vlc_mutex_unlock( &P_buffer.lock );
#undef P_buffer #undef P_buffer
return( p_mb ); return( p_mb );
#else
return( &p_fifo->buffer );
#endif
} }
/***************************************************************************** /*****************************************************************************
...@@ -83,6 +94,7 @@ static __inline__ macroblock_t * vpar_NewMacroblock( video_fifo_t * p_fifo ) ...@@ -83,6 +94,7 @@ static __inline__ macroblock_t * vpar_NewMacroblock( video_fifo_t * p_fifo )
static __inline__ void vpar_DecodeMacroblock( video_fifo_t * p_fifo, static __inline__ void vpar_DecodeMacroblock( video_fifo_t * p_fifo,
macroblock_t * p_mb ) macroblock_t * p_mb )
{ {
#ifdef VDEC_SMP
/* Place picture in the video FIFO */ /* Place picture in the video FIFO */
vlc_mutex_lock( &p_fifo->lock ); vlc_mutex_lock( &p_fifo->lock );
...@@ -91,6 +103,8 @@ static __inline__ void vpar_DecodeMacroblock( video_fifo_t * p_fifo, ...@@ -91,6 +103,8 @@ static __inline__ void vpar_DecodeMacroblock( video_fifo_t * p_fifo,
VIDEO_FIFO_INCEND( *p_fifo ); VIDEO_FIFO_INCEND( *p_fifo );
vlc_mutex_unlock( &p_fifo->lock ); vlc_mutex_unlock( &p_fifo->lock );
#endif
/* Shouldn't normally be used without SMP. */
} }
/***************************************************************************** /*****************************************************************************
...@@ -100,6 +114,7 @@ static __inline__ void vpar_DecodeMacroblock( video_fifo_t * p_fifo, ...@@ -100,6 +114,7 @@ static __inline__ void vpar_DecodeMacroblock( video_fifo_t * p_fifo,
static __inline__ void vpar_ReleaseMacroblock( video_fifo_t * p_fifo, static __inline__ void vpar_ReleaseMacroblock( video_fifo_t * p_fifo,
macroblock_t * p_mb ) macroblock_t * p_mb )
{ {
#ifdef VDEC_SMP
boolean_t b_finished; boolean_t b_finished;
/* Unlink picture buffer */ /* Unlink picture buffer */
...@@ -135,6 +150,18 @@ static __inline__ void vpar_ReleaseMacroblock( video_fifo_t * p_fifo, ...@@ -135,6 +150,18 @@ static __inline__ void vpar_ReleaseMacroblock( video_fifo_t * p_fifo,
P_buffer.pp_mb_free[ ++P_buffer.i_index ] = p_mb; P_buffer.pp_mb_free[ ++P_buffer.i_index ] = p_mb;
vlc_mutex_unlock( &P_buffer.lock ); vlc_mutex_unlock( &P_buffer.lock );
#undef P_buffer #undef P_buffer
#else
p_mb->p_picture->i_deccount--;
if( p_mb->p_picture->i_deccount == 1 )
{
/* Mark the picture to be displayed */
vout_DisplayPicture( p_fifo->p_vpar->p_vout, p_mb->p_picture );
/* Warn Synchro for its records. */
vpar_SynchroEnd( p_fifo->p_vpar );
}
#endif
} }
/***************************************************************************** /*****************************************************************************
...@@ -143,19 +170,20 @@ static __inline__ void vpar_ReleaseMacroblock( video_fifo_t * p_fifo, ...@@ -143,19 +170,20 @@ static __inline__ void vpar_ReleaseMacroblock( video_fifo_t * p_fifo,
static __inline__ void vpar_DestroyMacroblock( video_fifo_t * p_fifo, static __inline__ void vpar_DestroyMacroblock( video_fifo_t * p_fifo,
macroblock_t * p_mb ) macroblock_t * p_mb )
{ {
#ifdef VDEC_SMP
boolean_t b_finished; boolean_t b_finished;
/* Unlink picture buffer */ /* Unlink picture buffer */
vlc_mutex_lock( &p_mb->p_picture->lock_deccount ); vlc_mutex_lock( &p_mb->p_picture->lock_deccount );
p_mb->p_picture->i_deccount--; p_mb->p_picture->i_deccount--;
b_finished = (p_mb->p_picture->i_deccount == 0); b_finished = (p_mb->p_picture->i_deccount == 1);
vlc_mutex_unlock( &p_mb->p_picture->lock_deccount ); vlc_mutex_unlock( &p_mb->p_picture->lock_deccount );
/* Test if it was the last block of the picture */ /* Test if it was the last block of the picture */
if( b_finished ) if( b_finished )
{ {
fprintf(stderr, "Image trashee\n"); fprintf(stderr, "Image trashee\n");
/* Mark the picture to be displayed */ /* Mark the picture to be trashed */
vout_DestroyPicture( p_fifo->p_vpar->p_vout, p_mb->p_picture ); vout_DestroyPicture( p_fifo->p_vpar->p_vout, p_mb->p_picture );
/* Warn Synchro for its records. */ /* Warn Synchro for its records. */
...@@ -178,6 +206,18 @@ fprintf(stderr, "Image trashee\n"); ...@@ -178,6 +206,18 @@ fprintf(stderr, "Image trashee\n");
P_buffer.pp_mb_free[ ++P_buffer.i_index ] = p_mb; P_buffer.pp_mb_free[ ++P_buffer.i_index ] = p_mb;
vlc_mutex_unlock( &P_buffer.lock ); vlc_mutex_unlock( &P_buffer.lock );
#undef P_buffer #undef P_buffer
#else
p_mb->p_picture->i_deccount--;
if( p_mb->p_picture->i_deccount == 1 )
{
/* Mark the picture to be trashed */
vout_DestroyPicture( p_fifo->p_vpar->p_vout, p_mb->p_picture );
/* Warn Synchro for its records. */
vpar_SynchroEnd( p_fifo->p_vpar );
}
#endif
} }
/***************************************************************************** /*****************************************************************************
......
...@@ -25,6 +25,7 @@ struct vpar_thread_s; ...@@ -25,6 +25,7 @@ struct vpar_thread_s;
typedef struct video_fifo_s typedef struct video_fifo_s
{ {
#ifdef VDEC_SMP
vlc_mutex_t lock; /* fifo data lock */ vlc_mutex_t lock; /* fifo data lock */
vlc_cond_t wait; /* fifo data conditional variable */ vlc_cond_t wait; /* fifo data conditional variable */
...@@ -32,6 +33,9 @@ typedef struct video_fifo_s ...@@ -32,6 +33,9 @@ typedef struct video_fifo_s
macroblock_t * buffer[VFIFO_SIZE + 1]; macroblock_t * buffer[VFIFO_SIZE + 1];
int i_start; int i_start;
int i_end; int i_end;
#else
macroblock_t buffer;
#endif
struct vpar_thread_s * p_vpar; struct vpar_thread_s * p_vpar;
} video_fifo_t; } video_fifo_t;
...@@ -42,6 +46,7 @@ typedef struct video_fifo_s ...@@ -42,6 +46,7 @@ typedef struct video_fifo_s
* This structure enables the parser to maintain a list of free * This structure enables the parser to maintain a list of free
* macroblock_t structures * macroblock_t structures
*****************************************************************************/ *****************************************************************************/
#ifdef VDEC_SMP
typedef struct video_buffer_s typedef struct video_buffer_s
{ {
vlc_mutex_t lock; /* buffer data lock */ vlc_mutex_t lock; /* buffer data lock */
...@@ -50,6 +55,7 @@ typedef struct video_buffer_s ...@@ -50,6 +55,7 @@ typedef struct video_buffer_s
macroblock_t * pp_mb_free[VFIFO_SIZE+1]; /* this is a LIFO */ macroblock_t * pp_mb_free[VFIFO_SIZE+1]; /* this is a LIFO */
int i_index; int i_index;
} video_buffer_t; } video_buffer_t;
#endif
/***************************************************************************** /*****************************************************************************
* vpar_thread_t: video parser thread descriptor * vpar_thread_t: video parser thread descriptor
...@@ -79,12 +85,13 @@ typedef struct vpar_thread_s ...@@ -79,12 +85,13 @@ typedef struct vpar_thread_s
/* Output properties */ /* Output properties */
vout_thread_t * p_vout; /* video output thread */ vout_thread_t * p_vout; /* video output thread */
int i_stream; /* video stream id */
/* Decoder properties */ /* Decoder properties */
struct vdec_thread_s * p_vdec[NB_VDEC]; struct vdec_thread_s * pp_vdec[NB_VDEC];
video_fifo_t vfifo; video_fifo_t vfifo;
#ifdef VDEC_SMP
video_buffer_t vbuffer; video_buffer_t vbuffer;
#endif
/* Parser properties */ /* Parser properties */
sequence_t sequence; sequence_t sequence;
......
...@@ -93,7 +93,9 @@ typedef struct picture_parsing_s ...@@ -93,7 +93,9 @@ typedef struct picture_parsing_s
int i_current_structure; int i_current_structure;
picture_t * p_picture; picture_t * p_picture;
#ifdef VDEC_SMP
macroblock_t * pp_mb[MAX_MB]; macroblock_t * pp_mb[MAX_MB];
#endif
/* Relative to the current field */ /* Relative to the current field */
int i_coding_type, i_structure; int i_coding_type, i_structure;
......
...@@ -44,12 +44,14 @@ ...@@ -44,12 +44,14 @@
/* /*
* Local prototypes * Local prototypes
*/ */
static int InitThread ( vdec_thread_t *p_vdec ); #ifdef VDEC_SMP
static int vdec_InitThread ( vdec_thread_t *p_vdec );
static void vdec_DecodeMacroblock( vdec_thread_t *p_vdec,
macroblock_t * p_mb );
#endif
static void RunThread ( vdec_thread_t *p_vdec ); static void RunThread ( vdec_thread_t *p_vdec );
static void ErrorThread ( vdec_thread_t *p_vdec ); static void ErrorThread ( vdec_thread_t *p_vdec );
static void EndThread ( vdec_thread_t *p_vdec ); static void EndThread ( vdec_thread_t *p_vdec );
static void DecodeMacroblock ( vdec_thread_t *p_vdec,
macroblock_t * p_mb );
/******************************************************************************* /*******************************************************************************
* vdec_CreateThread: create a video decoder thread * vdec_CreateThread: create a video decoder thread
...@@ -109,11 +111,13 @@ void vdec_DestroyThread( vdec_thread_t *p_vdec /*, int *pi_status */ ) ...@@ -109,11 +111,13 @@ void vdec_DestroyThread( vdec_thread_t *p_vdec /*, int *pi_status */ )
/* Ask thread to kill itself */ /* Ask thread to kill itself */
p_vdec->b_die = 1; p_vdec->b_die = 1;
/* Make sure the parser thread leaves the GetByte() function */
#ifdef VDEC_SMP
/* Make sure the decoder thread leaves the vpar_GetMacroblock() function */
vlc_mutex_lock( &(p_vdec->p_vpar->vfifo.lock) ); vlc_mutex_lock( &(p_vdec->p_vpar->vfifo.lock) );
vlc_cond_signal( &(p_vdec->p_vpar->vfifo.wait) ); vlc_cond_signal( &(p_vdec->p_vpar->vfifo.wait) );
vlc_mutex_unlock( &(p_vdec->p_vpar->vfifo.lock) ); vlc_mutex_unlock( &(p_vdec->p_vpar->vfifo.lock) );
#endif
/* Waiting for the decoder thread to exit */ /* Waiting for the decoder thread to exit */
/* Remove this as soon as the "status" flag is implemented */ /* Remove this as soon as the "status" flag is implemented */
...@@ -123,13 +127,17 @@ void vdec_DestroyThread( vdec_thread_t *p_vdec /*, int *pi_status */ ) ...@@ -123,13 +127,17 @@ void vdec_DestroyThread( vdec_thread_t *p_vdec /*, int *pi_status */ )
/* following functions are local */ /* following functions are local */
/******************************************************************************* /*******************************************************************************
* InitThread: initialize video decoder thread * vdec_InitThread: initialize video decoder thread
******************************************************************************* *******************************************************************************
* This function is called from RunThread and performs the second step of the * 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 * initialization. It returns 0 on success. Note that the thread's flag are not
* modified inside this function. * modified inside this function.
*******************************************************************************/ *******************************************************************************/
static int InitThread( vdec_thread_t *p_vdec ) #ifdef VDEC_SMP
static int vdec_InitThread( vdec_thread_t *p_vdec )
#else
int vdec_InitThread( vdec_thread_t *p_vdec )
#endif
{ {
int i_dummy; int i_dummy;
...@@ -233,7 +241,7 @@ static __inline__ void CopyBlock( vdec_thread_t * p_vdec, dctelem_t * p_block, ...@@ -233,7 +241,7 @@ static __inline__ void CopyBlock( vdec_thread_t * p_vdec, dctelem_t * p_block,
} }
/******************************************************************************* /*******************************************************************************
* DecodeMacroblock : decode a macroblock of a picture * vdec_DecodeMacroblock : decode a macroblock of a picture
*******************************************************************************/ *******************************************************************************/
#define DECODEBLOCKS( OPBLOCK ) \ #define DECODEBLOCKS( OPBLOCK ) \
{ \ { \
...@@ -283,7 +291,11 @@ static __inline__ void CopyBlock( vdec_thread_t * p_vdec, dctelem_t * p_block, ...@@ -283,7 +291,11 @@ static __inline__ void CopyBlock( vdec_thread_t * p_vdec, dctelem_t * p_block,
} \ } \
} }
static __inline__ void DecodeMacroblock( vdec_thread_t *p_vdec, macroblock_t * p_mb ) #ifdef VDEC_SMP
static __inline__ void vdec_DecodeMacroblock( vdec_thread_t *p_vdec, macroblock_t * p_mb )
#else
void vdec_DecodeMacroblock( vdec_thread_t *p_vdec, macroblock_t * p_mb )
#endif
{ {
if( !(p_mb->i_mb_type & MB_INTRA) ) if( !(p_mb->i_mb_type & MB_INTRA) )
{ {
...@@ -321,7 +333,7 @@ static void RunThread( vdec_thread_t *p_vdec ) ...@@ -321,7 +333,7 @@ static void RunThread( vdec_thread_t *p_vdec )
/* /*
* Initialize thread and free configuration * Initialize thread and free configuration
*/ */
p_vdec->b_error = InitThread( p_vdec ); p_vdec->b_error = vdec_InitThread( p_vdec );
if( p_vdec->b_error ) if( p_vdec->b_error )
{ {
return; return;
...@@ -338,7 +350,7 @@ static void RunThread( vdec_thread_t *p_vdec ) ...@@ -338,7 +350,7 @@ static void RunThread( vdec_thread_t *p_vdec )
if( (p_mb = vpar_GetMacroblock( &p_vdec->p_vpar->vfifo )) != NULL ) if( (p_mb = vpar_GetMacroblock( &p_vdec->p_vpar->vfifo )) != NULL )
{ {
DecodeMacroblock( p_vdec, p_mb ); vdec_DecodeMacroblock( p_vdec, p_mb );
} }
} }
......
...@@ -42,8 +42,13 @@ ...@@ -42,8 +42,13 @@
*****************************************************************************/ *****************************************************************************/
void vpar_InitFIFO( vpar_thread_t * p_vpar ) void vpar_InitFIFO( vpar_thread_t * p_vpar )
{ {
#ifdef VDEC_SMP
int i_dummy; int i_dummy;
#endif
p_vpar->vfifo.p_vpar = p_vpar;
#ifdef VDEC_SMP
/* Initialize mutex and cond */ /* Initialize mutex and cond */
vlc_mutex_init( &p_vpar->vfifo.lock ); vlc_mutex_init( &p_vpar->vfifo.lock );
vlc_cond_init( &p_vpar->vfifo.wait ); vlc_cond_init( &p_vpar->vfifo.wait );
...@@ -51,7 +56,6 @@ void vpar_InitFIFO( vpar_thread_t * p_vpar ) ...@@ -51,7 +56,6 @@ void vpar_InitFIFO( vpar_thread_t * p_vpar )
/* Initialize FIFO properties */ /* Initialize FIFO properties */
p_vpar->vfifo.i_start = p_vpar->vfifo.i_end = 0; p_vpar->vfifo.i_start = p_vpar->vfifo.i_end = 0;
p_vpar->vfifo.p_vpar = p_vpar;
/* Initialize buffer properties */ /* Initialize buffer properties */
p_vpar->vbuffer.i_index = VFIFO_SIZE; /* all structures are available */ p_vpar->vbuffer.i_index = VFIFO_SIZE; /* all structures are available */
...@@ -60,4 +64,5 @@ void vpar_InitFIFO( vpar_thread_t * p_vpar ) ...@@ -60,4 +64,5 @@ void vpar_InitFIFO( vpar_thread_t * p_vpar )
p_vpar->vbuffer.pp_mb_free[i_dummy] = p_vpar->vbuffer.p_macroblocks p_vpar->vbuffer.pp_mb_free[i_dummy] = p_vpar->vbuffer.p_macroblocks
+ i_dummy; + i_dummy;
} }
#endif
} }
...@@ -207,17 +207,29 @@ static int InitThread( vpar_thread_t *p_vpar ) ...@@ -207,17 +207,29 @@ static int InitThread( vpar_thread_t *p_vpar )
/* Initialize video FIFO */ /* Initialize video FIFO */
vpar_InitFIFO( p_vpar ); vpar_InitFIFO( p_vpar );
bzero( p_vpar->p_vdec, NB_VDEC*sizeof(vdec_thread_t *) ); memset( p_vpar->pp_vdec, 0, NB_VDEC*sizeof(vdec_thread_t *) );
#ifdef VDEC_SMP
/* Spawn video_decoder threads */ /* Spawn video_decoder threads */
/* ??? modify the number of vdecs at runtime ? */ /* ??? modify the number of vdecs at runtime ? */
for( i_dummy = 0; i_dummy < NB_VDEC; i_dummy++ ) for( i_dummy = 0; i_dummy < NB_VDEC; i_dummy++ )
{ {
if( (p_vpar->p_vdec[i_dummy] = vdec_CreateThread( p_vpar )) == NULL ) if( (p_vpar->pp_vdec[i_dummy] = vdec_CreateThread( p_vpar )) == NULL )
{ {
return( 1 ); return( 1 );
} }
} }
#else
/* Fake a video_decoder thread */
if( (p_vpar->pp_vdec[0] = (vdec_thread_t *)malloc(sizeof( vdec_thread_t ))) == NULL
|| vdec_InitThread( p_vpar->pp_vdec[0] ) )
{
return( 1 );
}
p_vpar->pp_vdec[0]->b_die = 0;
p_vpar->pp_vdec[0]->b_error = 0;
p_vpar->pp_vdec[0]->p_vpar = p_vpar;
#endif
/* Initialize lookup tables */ /* Initialize lookup tables */
#if defined(MPEG2_COMPLIANT) && !defined(VDEC_DFT) #if defined(MPEG2_COMPLIANT) && !defined(VDEC_DFT)
...@@ -354,7 +366,9 @@ static void ErrorThread( vpar_thread_t *p_vpar ) ...@@ -354,7 +366,9 @@ static void ErrorThread( vpar_thread_t *p_vpar )
*******************************************************************************/ *******************************************************************************/
static void EndThread( vpar_thread_t *p_vpar ) static void EndThread( vpar_thread_t *p_vpar )
{ {
#ifdef VDEC_SMP
int i_dummy; int i_dummy;
#endif
intf_DbgMsg("vpar debug: destroying video parser thread %p\n", p_vpar); intf_DbgMsg("vpar debug: destroying video parser thread %p\n", p_vpar);
...@@ -385,14 +399,18 @@ static void EndThread( vpar_thread_t *p_vpar ) ...@@ -385,14 +399,18 @@ static void EndThread( vpar_thread_t *p_vpar )
free( p_vpar->sequence.chroma_nonintra_quant.pi_matrix ); free( p_vpar->sequence.chroma_nonintra_quant.pi_matrix );
} }
#ifdef VDEC_SMP
/* Destroy vdec threads */ /* Destroy vdec threads */
for( i_dummy = 0; i_dummy < NB_VDEC; i_dummy++ ) for( i_dummy = 0; i_dummy < NB_VDEC; i_dummy++ )
{ {
if( p_vpar->p_vdec[i_dummy] != NULL ) if( p_vpar->pp_vdec[i_dummy] != NULL )
vdec_DestroyThread( p_vpar->p_vdec[i_dummy] ); vdec_DestroyThread( p_vpar->pp_vdec[i_dummy] );
else else
break; break;
} }
#else
free( p_vpar->pp_vdec[0] );
#endif
intf_DbgMsg("vpar debug: EndThread(%p)\n", p_vpar); intf_DbgMsg("vpar debug: EndThread(%p)\n", p_vpar);
} }
...@@ -37,7 +37,6 @@ ...@@ -37,7 +37,6 @@
#include "video_parser.h" #include "video_parser.h"
#include "video_fifo.h" #include "video_fifo.h"
/* /*
* Local prototypes * Local prototypes
*/ */
...@@ -790,13 +789,15 @@ i_count++; ...@@ -790,13 +789,15 @@ i_count++;
memset( p_vpar->slice.pppi_pmv, 0, 8*sizeof(int) ); memset( p_vpar->slice.pppi_pmv, 0, 8*sizeof(int) );
} }
if( (p_mb = p_vpar->picture.pp_mb[i_mb_base + i_mb] = if( (p_mb = vpar_NewMacroblock( &p_vpar->vfifo )) == NULL )
vpar_NewMacroblock( &p_vpar->vfifo )) == NULL )
{ {
p_vpar->picture.b_error = 1; p_vpar->picture.b_error = 1;
intf_ErrMsg("vpar error: macroblock list is empty !\n"); intf_ErrMsg("vpar error: macroblock list is empty !\n");
return; return;
} }
#ifdef VDEC_SMP
p_vpar->picture.pp_mb[i_mb_base + i_mb] = p_mb;
#endif
InitMacroblock( p_vpar, p_mb ); InitMacroblock( p_vpar, p_mb );
...@@ -810,16 +811,23 @@ i_count++; ...@@ -810,16 +811,23 @@ i_count++;
/* Set the field we use for motion compensation */ /* Set the field we use for motion compensation */
p_mb->ppi_field_select[0][0] = p_mb->ppi_field_select[0][1] p_mb->ppi_field_select[0][0] = p_mb->ppi_field_select[0][1]
= ( p_vpar->picture.i_current_structure == BOTTOM_FIELD ); = ( p_vpar->picture.i_current_structure == BOTTOM_FIELD );
#ifndef VDEC_SMP
/* Decode the macroblock NOW ! */
vdec_DecodeMacroblock( p_vpar->pp_vdec[0], p_mb );
#endif
} }
/* Get a macroblock structure. */ /* Get a macroblock structure. */
if( (p_mb = p_vpar->picture.pp_mb[i_mb_base + *pi_mb_address] = if( (p_mb = vpar_NewMacroblock( &p_vpar->vfifo )) == NULL )
vpar_NewMacroblock( &p_vpar->vfifo )) == NULL )
{ {
p_vpar->picture.b_error = 1; p_vpar->picture.b_error = 1;
intf_ErrMsg("vpar error: macroblock list is empty !\n"); intf_ErrMsg("vpar error: macroblock list is empty !\n");
return; return;
} }
#ifdef VDEC_SMP
p_vpar->picture.pp_mb[i_mb_base + *pi_mb_address] = p_mb;
#endif
InitMacroblock( p_vpar, p_mb ); InitMacroblock( p_vpar, p_mb );
...@@ -953,6 +961,12 @@ if( 0 ) ...@@ -953,6 +961,12 @@ if( 0 )
{ {
p_mb->i_mb_type |= MB_MOTION_FORWARD; p_mb->i_mb_type |= MB_MOTION_FORWARD;
} }
#ifndef VDEC_SMP
/* Decode the macroblock NOW ! */
vdec_DecodeMacroblock( p_vpar->pp_vdec[0], p_mb );
#endif
/* /*
if( p_vpar->picture.i_coding_type != I_CODING_TYPE )//!(p_mb->b_P_coding_type & MB_INTRA) ) if( p_vpar->picture.i_coding_type != I_CODING_TYPE )//!(p_mb->b_P_coding_type & MB_INTRA) )
{ {
...@@ -1260,7 +1274,7 @@ if( i_parse >= 64 ) ...@@ -1260,7 +1274,7 @@ if( i_parse >= 64 )
p_mb->ppi_blocks[i_b][i_pos] = b_sign ? -i_level : i_level; p_mb->ppi_blocks[i_b][i_pos] = b_sign ? -i_level : i_level;
} }
fprintf( stderr, "Non intra MPEG2 end (%d)\n", i_b ); fprintf( stderr, "Non intra MPEG2 end (%d)\n", i_b );
//p_vpar->picture.b_error = 1; p_vpar->picture.b_error = 1;
} }
/***************************************************************************** /*****************************************************************************
...@@ -1500,5 +1514,5 @@ if( i_parse >= 64 ) ...@@ -1500,5 +1514,5 @@ if( i_parse >= 64 )
} }
fprintf( stderr, "MPEG2 end (%d)\n", i_b ); fprintf( stderr, "MPEG2 end (%d)\n", i_b );
//p_vpar->b_error = 1; p_vpar->picture.b_error = 1;
} }
...@@ -518,9 +518,12 @@ static void PictureHeader( vpar_thread_t * p_vpar ) ...@@ -518,9 +518,12 @@ static void PictureHeader( vpar_thread_t * p_vpar )
vpar_BMBType, vpar_DMBType}; vpar_BMBType, vpar_DMBType};
int i_structure; int i_structure;
int i_mb_address, i_mb_base, i_mb; int i_mb_address, i_mb_base;
boolean_t b_parsable; boolean_t b_parsable;
u32 i_dummy; u32 i_dummy;
#ifdef VDEC_SMP
int i_mb;
#endif
RemoveBits( &p_vpar->bit_stream, 10 ); /* temporal_reference */ RemoveBits( &p_vpar->bit_stream, 10 ); /* temporal_reference */
p_vpar->picture.i_coding_type = GetBits( &p_vpar->bit_stream, 3 ); p_vpar->picture.i_coding_type = GetBits( &p_vpar->bit_stream, 3 );
...@@ -609,11 +612,13 @@ static void PictureHeader( vpar_thread_t * p_vpar ) ...@@ -609,11 +612,13 @@ static void PictureHeader( vpar_thread_t * p_vpar )
p_vpar->picture.i_coding_type, p_vpar->picture.i_coding_type,
NULL ); NULL );
#ifdef VDEC_SMP
for( i_mb = 0; p_vpar->picture.pp_mb[i_mb] != NULL; i_mb++ ) for( i_mb = 0; p_vpar->picture.pp_mb[i_mb] != NULL; i_mb++ )
{ {
vpar_DestroyMacroblock( &p_vpar->vfifo, vpar_DestroyMacroblock( &p_vpar->vfifo,
p_vpar->picture.pp_mb[i_mb] ); p_vpar->picture.pp_mb[i_mb] );
} }
#endif
vout_DestroyPicture( p_vpar->p_vout, p_vpar->picture.p_picture ); vout_DestroyPicture( p_vpar->p_vout, p_vpar->picture.p_picture );
} }
...@@ -701,18 +706,34 @@ static void PictureHeader( vpar_thread_t * p_vpar ) ...@@ -701,18 +706,34 @@ static void PictureHeader( vpar_thread_t * p_vpar )
P_picture->i_deccount = p_vpar->sequence.i_mb_size; P_picture->i_deccount = p_vpar->sequence.i_mb_size;
vlc_mutex_init( &p_vpar->picture.p_picture->lock_deccount ); vlc_mutex_init( &p_vpar->picture.p_picture->lock_deccount );
memset( p_vpar->picture.pp_mb, 0, MAX_MB ); #ifdef VDEC_SMP
memset( p_vpar->picture.pp_mb, 0, MAX_MB*sizeof(macroblock_t *) );
#endif
/* FIXME ! remove asap */ /* FIXME ! remove asap */
//memset( P_picture->p_data, 0, (p_vpar->sequence.i_mb_size*384)); //memset( P_picture->p_data, 0, (p_vpar->sequence.i_mb_size*384));
/* Update the reference pointers. */ /* Update the reference pointers. */
ReferenceUpdate( p_vpar, p_vpar->picture.i_coding_type, P_picture ); ReferenceUpdate( p_vpar, p_vpar->picture.i_coding_type, P_picture );
#ifdef VDEC_SMP
/* Link referenced pictures for the decoder
* They are unlinked in vpar_ReleaseMacroblock() & vpar_DestroyMacroblock() */
if( p_vpar->picture.i_coding_type == P_CODING_TYPE ||
p_vpar->picture.i_coding_type == B_CODING_TYPE )
{
vout_LinkPicture( p_vpar->p_vout, p_vpar->sequence.p_forward );
}
if( p_vpar->picture.i_coding_type == B_CODING_TYPE )
{
vout_LinkPicture( p_vpar->p_vout, p_vpar->sequence.p_backward );
}
#endif
} }
p_vpar->picture.i_current_structure |= i_structure; p_vpar->picture.i_current_structure |= i_structure;
p_vpar->picture.i_structure = i_structure; p_vpar->picture.i_structure = i_structure;
/* Initialize picture data for decoding. */ /* Initialize picture data for decoding. */
if( p_vpar->picture.b_motion_field = (i_structure == BOTTOM_FIELD) ) if( (p_vpar->picture.b_motion_field = (i_structure == BOTTOM_FIELD)) )
{ {
i_mb_base = p_vpar->sequence.i_mb_size >> 1; i_mb_base = p_vpar->sequence.i_mb_size >> 1;
p_vpar->mb.i_l_y = 1; p_vpar->mb.i_l_y = 1;
...@@ -752,11 +773,17 @@ static void PictureHeader( vpar_thread_t * p_vpar ) ...@@ -752,11 +773,17 @@ static void PictureHeader( vpar_thread_t * p_vpar )
{ {
/* Trash picture. */ /* Trash picture. */
//fprintf(stderr, "Image trashee\n"); //fprintf(stderr, "Image trashee\n");
for( i_mb = 1; p_vpar->picture.pp_mb[i_mb]; i_mb++ ) #ifdef VDEC_SMP
for( i_mb = 1; p_vpar->picture.pp_mb[i_mb] != NULL; i_mb++ )
{ {
vpar_DestroyMacroblock( &p_vpar->vfifo, p_vpar->picture.pp_mb[i_mb] ); vpar_DestroyMacroblock( &p_vpar->vfifo, p_vpar->picture.pp_mb[i_mb] );
} }
vout_DestroyPicture( p_vpar->p_vout, p_vpar->picture.p_picture ); #endif
if( P_picture->i_deccount != 1 )
{
vout_DestroyPicture( p_vpar->p_vout, P_picture );
}
ReferenceReplace( p_vpar, p_vpar->picture.i_coding_type, NULL ); ReferenceReplace( p_vpar, p_vpar->picture.i_coding_type, NULL );
...@@ -769,27 +796,17 @@ static void PictureHeader( vpar_thread_t * p_vpar ) ...@@ -769,27 +796,17 @@ static void PictureHeader( vpar_thread_t * p_vpar )
{ {
//fprintf(stderr, "Image parsee (%d)\n", p_vpar->picture.i_coding_type); //fprintf(stderr, "Image parsee (%d)\n", p_vpar->picture.i_coding_type);
/* Frame completely parsed. */ /* Frame completely parsed. */
#ifdef VDEC_SMP
for( i_mb = 1; p_vpar->picture.pp_mb[i_mb] != NULL; i_mb++ ) for( i_mb = 1; p_vpar->picture.pp_mb[i_mb] != NULL; i_mb++ )
{ {
vpar_DecodeMacroblock( &p_vpar->vfifo, p_vpar->picture.pp_mb[i_mb] ); vpar_DecodeMacroblock( &p_vpar->vfifo, p_vpar->picture.pp_mb[i_mb] );
} }
/* Link referenced pictures for the decoder
* They are unlinked in vpar_ReleaseMacroblock() & vpar_DestroyMacroblock() */
if( p_vpar->picture.i_coding_type == P_CODING_TYPE ||
p_vpar->picture.i_coding_type == B_CODING_TYPE )
{
vout_LinkPicture( p_vpar->p_vout, p_vpar->sequence.p_forward );
}
if( p_vpar->picture.i_coding_type == B_CODING_TYPE )
{
vout_LinkPicture( p_vpar->p_vout, p_vpar->sequence.p_backward );
}
/* Send signal to the video_decoder. */ /* Send signal to the video_decoder. */
vlc_mutex_lock( &p_vpar->vfifo.lock ); vlc_mutex_lock( &p_vpar->vfifo.lock );
vlc_cond_signal( &p_vpar->vfifo.wait ); vlc_cond_signal( &p_vpar->vfifo.wait );
vlc_mutex_unlock( &p_vpar->vfifo.lock ); vlc_mutex_unlock( &p_vpar->vfifo.lock );
#endif
/* Prepare context for the next picture. */ /* Prepare context for the next picture. */
P_picture = NULL; P_picture = NULL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment