Browse Source

* Optimisation de vdec_motion.c et video_decoder.c ;

* Passage des fonctions de la video_fifo en inline ;
* Correction d'un bug provoquant un overflow des messages dans
vpar_headers.c.
pull/2/head
Christophe Massiot 27 years ago
parent
commit
796346ac80
  1. 4
      include/config.h
  2. 26
      include/vdec_motion.h
  3. 10
      include/video_decoder.h
  4. 170
      include/video_fifo.h
  5. 35
      include/video_parser.h
  6. 2
      include/vlc.h
  7. 3
      include/vpar_blocks.h
  8. 2
      src/video_decoder/vdec_idct.c
  9. 1074
      src/video_decoder/vdec_motion.c
  10. 236
      src/video_decoder/video_decoder.c
  11. 153
      src/video_parser/video_fifo.c
  12. 2
      src/video_parser/video_parser.c
  13. 74
      src/video_parser/vpar_blocks.c
  14. 6
      src/video_parser/vpar_headers.c
  15. 2
      src/video_parser/vpar_motion.c
  16. 2
      src/video_parser/vpar_synchro.c

4
include/config.h

@ -62,7 +62,7 @@
#define DEBUG_INTF
#define DEBUG_INPUT
#define DEBUG_AUDIO
#define DEBUG_VIDEO
//#define DEBUG_VIDEO
/* Debugging log file - if defined, a file can be used to store all messages. If
* DEBUG_LOG_ONLY is defined, debug messages will only be printed to the log and
@ -285,6 +285,8 @@
#define VPAR_IDLE_SLEEP 100000
#define VPAR_OUTMEM_SLEEP 50000
/* Number of macroblock buffers available. It should be always greater than
* twice the number of macroblocks in a picture. VFIFO_SIZE + 1 should also
* be a power of two. */

26
include/vdec_motion.h

@ -19,7 +19,6 @@ struct vpar_thread_s;
struct motion_arg_s;
typedef void (*f_motion_t)( struct macroblock_s* );
typedef void (*f_chroma_motion_t)( struct macroblock_s*, struct motion_arg_s* );
/*****************************************************************************
* Prototypes
@ -29,14 +28,21 @@ typedef void (*f_chroma_motion_t)( struct macroblock_s*, struct motion_arg_s* );
void vdec_MotionDummy( struct macroblock_s * p_mb );
/* Motion compensation */
void vdec_MotionFieldField( struct macroblock_s * p_mb );
void vdec_MotionField16x8( struct macroblock_s * p_mb );
void vdec_MotionFieldField420( struct macroblock_s * p_mb );
void vdec_MotionField16x8420( struct macroblock_s * p_mb );
void vdec_MotionFieldDMV( struct macroblock_s * p_mb );
void vdec_MotionFrameFrame( struct macroblock_s * p_mb );
void vdec_MotionFrameField( struct macroblock_s * p_mb );
void vdec_MotionFrameFrame420( struct macroblock_s * p_mb );
void vdec_MotionFrameField420( struct macroblock_s * p_mb );
void vdec_MotionFrameDMV( struct macroblock_s * p_mb );
/* Motion compensation functions for the 3 chroma formats */
void vdec_Motion420( struct macroblock_s * p_mb, struct motion_arg_s * p_motion );
void vdec_Motion422( struct macroblock_s * p_mb, struct motion_arg_s * p_motion );
void vdec_Motion444( struct macroblock_s * p_mb, struct motion_arg_s * p_motion );
void vdec_MotionFieldField422( struct macroblock_s * p_mb );
void vdec_MotionField16x8422( struct macroblock_s * p_mb );
void vdec_MotionFieldDMV( struct macroblock_s * p_mb );
void vdec_MotionFrameFrame422( struct macroblock_s * p_mb );
void vdec_MotionFrameField422( struct macroblock_s * p_mb );
void vdec_MotionFrameDMV( struct macroblock_s * p_mb );
void vdec_MotionFieldField444( struct macroblock_s * p_mb );
void vdec_MotionField16x8444( struct macroblock_s * p_mb );
void vdec_MotionFieldDMV( struct macroblock_s * p_mb );
void vdec_MotionFrameFrame444( struct macroblock_s * p_mb );
void vdec_MotionFrameField444( struct macroblock_s * p_mb );
void vdec_MotionFrameDMV( struct macroblock_s * p_mb );

10
include/video_decoder.h

@ -74,13 +74,6 @@ typedef struct vdec_thread_s
#endif
} vdec_thread_t;
/*****************************************************************************
* Function pointers
*****************************************************************************/
#ifndef OLD_DECODER
typedef void (*f_addb_t)( vdec_thread_t *, dctelem_t*, yuv_data_t*, int );
#endif
/*****************************************************************************
* Prototypes
*****************************************************************************/
@ -96,7 +89,4 @@ void vdec_DestroyThread ( vdec_thread_t *p_vdec /*, int *pi_sta
#else
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_AddBlock( vdec_thread_t *, dctelem_t*, yuv_data_t*, int );
void vdec_CopyBlock( vdec_thread_t *, dctelem_t*, yuv_data_t*, int );
void vdec_DummyBlock( vdec_thread_t *, dctelem_t*, yuv_data_t*, int );
#endif

170
include/video_fifo.h

@ -27,46 +27,160 @@
& VFIFO_SIZE )
/*****************************************************************************
* video_fifo_t
*****************************************************************************
* This rotative FIFO contains undecoded macroblocks that are to be decoded
* vpar_GetMacroblock : return a macroblock to be decoded
*****************************************************************************/
struct vpar_thread_s;
static __inline__ macroblock_t * vpar_GetMacroblock( video_fifo_t * p_fifo )
{
macroblock_t * p_mb;
vlc_mutex_lock( &p_fifo->lock );
while( VIDEO_FIFO_ISEMPTY( *p_fifo ) )
{
vlc_cond_wait( &p_fifo->wait, &p_fifo->lock );
if( p_fifo->p_vpar->b_die )
{
vlc_mutex_unlock( &p_fifo->lock );
return( NULL );
}
}
p_mb = VIDEO_FIFO_START( *p_fifo );
VIDEO_FIFO_INCSTART( *p_fifo );
typedef struct video_fifo_s
vlc_mutex_unlock( &p_fifo->lock );
return( p_mb );
}
/*****************************************************************************
* vpar_NewMacroblock : return a buffer for the parser
*****************************************************************************/
static __inline__ macroblock_t * vpar_NewMacroblock( video_fifo_t * p_fifo )
{
vlc_mutex_t lock; /* fifo data lock */
vlc_cond_t wait; /* fifo data conditional variable */
macroblock_t * p_mb;
/* buffer is an array of undec_picture_t pointers */
macroblock_t * buffer[VFIFO_SIZE + 1];
int i_start;
int i_end;
#define P_buffer p_fifo->p_vpar->vbuffer
vlc_mutex_lock( &P_buffer.lock );
while( P_buffer.i_index == -1 )
{
/* No more structures available. This should not happen ! */
intf_DbgMsg("vpar debug: macroblock list is empty, delaying\n");
vlc_mutex_unlock( &P_buffer.lock );
msleep(VPAR_OUTMEM_SLEEP);
vlc_mutex_lock( &P_buffer.lock );
}
struct vpar_thread_s * p_vpar;
} video_fifo_t;
p_mb = P_buffer.pp_mb_free[ P_buffer.i_index-- ];
vlc_mutex_unlock( &P_buffer.lock );
#undef P_buffer
return( p_mb );
}
/*****************************************************************************
* video_buffer_t
*****************************************************************************
* This structure enables the parser to maintain a list of free
* macroblock_t structures
* vpar_DecodeMacroblock : put a macroblock in the video fifo
*****************************************************************************/
static __inline__ void vpar_DecodeMacroblock( video_fifo_t * p_fifo,
macroblock_t * p_mb )
{
/* Place picture in the video FIFO */
vlc_mutex_lock( &p_fifo->lock );
/* By construction, the video FIFO cannot be full */
VIDEO_FIFO_END( *p_fifo ) = p_mb;
VIDEO_FIFO_INCEND( *p_fifo );
vlc_mutex_unlock( &p_fifo->lock );
}
/*****************************************************************************
* vpar_ReleaseMacroblock : release a macroblock and put the picture in the
* video output heap, if it is finished
*****************************************************************************/
static __inline__ void vpar_ReleaseMacroblock( video_fifo_t * p_fifo,
macroblock_t * p_mb )
{
boolean_t b_finished;
/* Unlink picture buffer */
vlc_mutex_lock( &p_mb->p_picture->lock_deccount );
p_mb->p_picture->i_deccount--;
b_finished = (p_mb->p_picture->i_deccount == 1);
vlc_mutex_unlock( &p_mb->p_picture->lock_deccount );
//fprintf(stderr, "%d ", p_mb->p_picture->i_deccount);
/* Test if it was the last block of the picture */
if( b_finished )
{
//fprintf(stderr, "Image decodee\n");
/* 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 );
/* Unlink referenced pictures */
if( p_mb->p_forward != NULL )
{
vout_UnlinkPicture( p_fifo->p_vpar->p_vout, p_mb->p_forward );
}
if( p_mb->p_backward != NULL )
{
vout_UnlinkPicture( p_fifo->p_vpar->p_vout, p_mb->p_backward );
}
}
/* Release the macroblock_t structure */
#define P_buffer p_fifo->p_vpar->vbuffer
vlc_mutex_lock( &P_buffer.lock );
P_buffer.pp_mb_free[ ++P_buffer.i_index ] = p_mb;
vlc_mutex_unlock( &P_buffer.lock );
#undef P_buffer
}
/*****************************************************************************
* vpar_DestroyMacroblock : destroy a macroblock in case of error
*****************************************************************************/
typedef struct video_buffer_s
static __inline__ void vpar_DestroyMacroblock( video_fifo_t * p_fifo,
macroblock_t * p_mb )
{
vlc_mutex_t lock; /* buffer data lock */
boolean_t b_finished;
/* Unlink picture buffer */
vlc_mutex_lock( &p_mb->p_picture->lock_deccount );
p_mb->p_picture->i_deccount--;
b_finished = (p_mb->p_picture->i_deccount == 0);
vlc_mutex_unlock( &p_mb->p_picture->lock_deccount );
/* Test if it was the last block of the picture */
if( b_finished )
{
fprintf(stderr, "Image trashee\n");
/* Mark the picture to be displayed */
vout_DestroyPicture( p_fifo->p_vpar->p_vout, p_mb->p_picture );
/* Warn Synchro for its records. */
vpar_SynchroEnd( p_fifo->p_vpar );
/* Unlink referenced pictures */
if( p_mb->p_forward != NULL )
{
vout_UnlinkPicture( p_fifo->p_vpar->p_vout, p_mb->p_forward );
}
if( p_mb->p_backward != NULL )
{
vout_UnlinkPicture( p_fifo->p_vpar->p_vout, p_mb->p_backward );
}
}
macroblock_t p_macroblocks[VFIFO_SIZE + 1];
macroblock_t * pp_mb_free[VFIFO_SIZE+1]; /* this is a LIFO */
int i_index;
} video_buffer_t;
/* Release the macroblock_t structure */
#define P_buffer p_fifo->p_vpar->vbuffer
vlc_mutex_lock( &P_buffer.lock );
P_buffer.pp_mb_free[ ++P_buffer.i_index ] = p_mb;
vlc_mutex_unlock( &P_buffer.lock );
#undef P_buffer
}
/*****************************************************************************
* Prototypes
*****************************************************************************/
void vpar_InitFIFO( struct vpar_thread_s * p_vpar );
macroblock_t * vpar_GetMacroblock( video_fifo_t * p_fifo );
macroblock_t * vpar_NewMacroblock( video_fifo_t * p_fifo );
void vpar_DecodeMacroblock( video_fifo_t * p_fifo, macroblock_t * p_mb );
void vpar_ReleaseMacroblock( video_fifo_t * p_fifo, macroblock_t * p_mb );
void vpar_DestroyMacroblock( video_fifo_t * p_fifo, macroblock_t * p_mb );

35
include/video_parser.h

@ -16,6 +16,41 @@
* "vpar_headers.h"
*****************************************************************************/
/*****************************************************************************
* video_fifo_t
*****************************************************************************
* This rotative FIFO contains undecoded macroblocks that are to be decoded
*****************************************************************************/
struct vpar_thread_s;
typedef struct video_fifo_s
{
vlc_mutex_t lock; /* fifo data lock */
vlc_cond_t wait; /* fifo data conditional variable */
/* buffer is an array of undec_picture_t pointers */
macroblock_t * buffer[VFIFO_SIZE + 1];
int i_start;
int i_end;
struct vpar_thread_s * p_vpar;
} video_fifo_t;
/*****************************************************************************
* video_buffer_t
*****************************************************************************
* This structure enables the parser to maintain a list of free
* macroblock_t structures
*****************************************************************************/
typedef struct video_buffer_s
{
vlc_mutex_t lock; /* buffer data lock */
macroblock_t p_macroblocks[VFIFO_SIZE + 1];
macroblock_t * pp_mb_free[VFIFO_SIZE+1]; /* this is a LIFO */
int i_index;
} video_buffer_t;
/*****************************************************************************
* vpar_thread_t: video parser thread descriptor
*****************************************************************************

2
include/vlc.h

@ -80,9 +80,9 @@
#include "vdec_motion.h"
#include "vpar_blocks.h"
#include "vpar_headers.h"
#include "video_fifo.h"
#include "vpar_synchro.h"
#include "video_parser.h"
#include "video_fifo.h"
#endif
/* Interface */

3
include/vpar_blocks.h

@ -21,6 +21,7 @@
typedef struct macroblock_s
{
int i_mb_type; /* macroblock type */
int i_coded_block_pattern;
int i_structure;
int i_current_structure;
boolean_t b_P_coding_type; /* Is it P_CODING_TYPE ? */
@ -39,7 +40,6 @@ typedef struct macroblock_s
/* Motion compensation information */
f_motion_t pf_motion; /* function to use for motion comp */
f_chroma_motion_t pf_chroma_motion;
picture_t * p_backward;
picture_t * p_forward;
int ppi_field_select[2][2];
@ -51,7 +51,6 @@ typedef struct macroblock_s
boolean_t b_motion_field;
/* AddBlock information */
f_addb_t pf_addb[12]; /* pointer to the Add function */
yuv_data_t * p_data[12]; /* pointer to the position
* in the final picture */
int i_addb_l_stride, i_addb_c_stride;

2
src/video_decoder/vdec_idct.c

@ -34,9 +34,9 @@
#include "vpar_blocks.h"
#include "vpar_headers.h"
#include "video_fifo.h"
#include "vpar_synchro.h"
#include "video_parser.h"
#include "video_fifo.h"
/*
* Local prototypes

1074
src/video_decoder/vdec_motion.c

File diff suppressed because it is too large

236
src/video_decoder/video_decoder.c

@ -37,9 +37,9 @@
#include "vpar_blocks.h"
#include "vpar_headers.h"
#include "video_fifo.h"
#include "vpar_synchro.h"
#include "video_parser.h"
#include "video_fifo.h"
/*
* Local prototypes
@ -165,54 +165,6 @@ static int InitThread( vdec_thread_t *p_vdec )
return( 0 );
}
/*******************************************************************************
* RunThread: video decoder thread
*******************************************************************************
* Video decoder thread. This function does only return 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;
/*
* Main loop - it is not executed if an error occured during
* initialization
*/
while( (!p_vdec->b_die) && (!p_vdec->b_error) )
{
macroblock_t * p_mb;
if( (p_mb = vpar_GetMacroblock( &p_vdec->p_vpar->vfifo )) != NULL )
{
DecodeMacroblock( p_vdec, p_mb );
}
}
/*
* 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
*******************************************************************************
@ -244,60 +196,10 @@ static void EndThread( vdec_thread_t *p_vdec )
}
/*******************************************************************************
* DecodeMacroblock : decode a macroblock of a picture
* AddBlock : add a block
*******************************************************************************/
static void DecodeMacroblock( vdec_thread_t *p_vdec, macroblock_t * p_mb )
{
int i_b;
/*
* Motion Compensation (ISO/IEC 13818-2 section 7.6)
*/
(*p_mb->pf_motion)( p_mb );
/* luminance */
for( i_b = 0; i_b < 4; i_b++ )
{
/*
* Inverse DCT (ISO/IEC 13818-2 section Annex A)
*/
(p_mb->pf_idct[i_b])( p_vdec, p_mb->ppi_blocks[i_b],
p_mb->pi_sparse_pos[i_b] );
/*
* Adding prediction and coefficient data (ISO/IEC 13818-2 section 7.6.8)
*/
(p_mb->pf_addb[i_b])( p_vdec, p_mb->ppi_blocks[i_b],
p_mb->p_data[i_b], p_mb->i_addb_l_stride );
}
/* chrominance */
for( i_b = 4; i_b < 4 + p_mb->i_chroma_nb_blocks; i_b++ )
{
/*
* Inverse DCT (ISO/IEC 13818-2 section Annex A)
*/
(p_mb->pf_idct[i_b])( p_vdec, p_mb->ppi_blocks[i_b],
p_mb->pi_sparse_pos[i_b] );
/*
* Adding prediction and coefficient data (ISO/IEC 13818-2 section 7.6.8)
*/
(p_mb->pf_addb[i_b])( p_vdec, p_mb->ppi_blocks[i_b],
p_mb->p_data[i_b], p_mb->i_addb_c_stride );
}
/*
* Decoding is finished, release the macroblock and free
* unneeded memory.
*/
vpar_ReleaseMacroblock( &p_vdec->p_vpar->vfifo, p_mb );
}
/*******************************************************************************
* vdec_AddBlock : add a block
*******************************************************************************/
void vdec_AddBlock( vdec_thread_t * p_vdec, dctelem_t * p_block, yuv_data_t * p_data, int i_incr )
static __inline__ void AddBlock( vdec_thread_t * p_vdec, dctelem_t * p_block,
yuv_data_t * p_data, int i_incr )
{
int i_x, i_y;
@ -313,19 +215,17 @@ void vdec_AddBlock( vdec_thread_t * p_vdec, dctelem_t * p_block, yuv_data_t * p_
}
/*******************************************************************************
* vdec_CopyBlock : copy a block
* CopyBlock : copy a block
*******************************************************************************/
void vdec_CopyBlock( vdec_thread_t * p_vdec, dctelem_t * p_block, yuv_data_t * p_data, int i_incr )
static __inline__ void CopyBlock( vdec_thread_t * p_vdec, dctelem_t * p_block,
yuv_data_t * p_data, int i_incr )
{
int i_y;
int i_x, i_y;
for( i_y = 0; i_y < 8; i_y++ )
{
int i_x;
for( i_x = 0; i_x < 8; i_x++ )
{
/* ??? Why does the reference decoder add 128 ??? */
*p_data++ = p_vdec->pi_crop[*p_block++];
}
p_data += i_incr;
@ -333,8 +233,124 @@ void vdec_CopyBlock( vdec_thread_t * p_vdec, dctelem_t * p_block, yuv_data_t * p
}
/*******************************************************************************
* vdec_DummyBlock : dummy function that does nothing
* DecodeMacroblock : decode a macroblock of a picture
*******************************************************************************/
#define DECODEBLOCKS( OPBLOCK ) \
{ \
int i_b, i_mask; \
\
i_mask = 1 << (3 + p_mb->i_chroma_nb_blocks); \
\
/* luminance */ \
for( i_b = 0; i_b < 4; i_b++, i_mask >>= 1 ) \
{ \
if( p_mb->i_coded_block_pattern & i_mask ) \
{ \
/* \
* Inverse DCT (ISO/IEC 13818-2 section Annex A) \
*/ \
(p_mb->pf_idct[i_b])( p_vdec, p_mb->ppi_blocks[i_b], \
p_mb->pi_sparse_pos[i_b] ); \
\
/* \
* Adding prediction and coefficient data (ISO/IEC 13818-2 \
* section 7.6.8) \
*/ \
OPBLOCK( p_vdec, p_mb->ppi_blocks[i_b], \
p_mb->p_data[i_b], p_mb->i_addb_l_stride ); \
} \
} \
\
/* chrominance */ \
for( i_b = 4; i_b < 4 + p_mb->i_chroma_nb_blocks; \
i_b++, i_mask >>= 1 ) \
{ \
if( p_mb->i_coded_block_pattern & i_mask ) \
{ \
/* \
* Inverse DCT (ISO/IEC 13818-2 section Annex A) \
*/ \
(p_mb->pf_idct[i_b])( p_vdec, p_mb->ppi_blocks[i_b], \
p_mb->pi_sparse_pos[i_b] ); \
\
/* \
* Adding prediction and coefficient data (ISO/IEC 13818-2 \
* section 7.6.8) \
*/ \
OPBLOCK( p_vdec, p_mb->ppi_blocks[i_b], \
p_mb->p_data[i_b], p_mb->i_addb_c_stride ); \
} \
} \
}
static __inline__ void DecodeMacroblock( vdec_thread_t *p_vdec, macroblock_t * p_mb )
{
if( !(p_mb->i_mb_type & MB_INTRA) )
{
/*
* Motion Compensation (ISO/IEC 13818-2 section 7.6)
*/
p_mb->pf_motion( p_mb );
DECODEBLOCKS( AddBlock )
}
else
{
DECODEBLOCKS( CopyBlock )
}
/*
* Decoding is finished, release the macroblock and free
* unneeded memory.
*/
vpar_ReleaseMacroblock( &p_vdec->p_vpar->vfifo, p_mb );
}
/*******************************************************************************
* RunThread: video decoder thread
*******************************************************************************
* Video decoder thread. This function does only return when the thread is
* terminated.
*******************************************************************************/
void vdec_DummyBlock( vdec_thread_t * p_vdec, dctelem_t * p_block, yuv_data_t * p_data, int i_incr )
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;
/*
* Main loop - it is not executed if an error occured during
* initialization
*/
while( (!p_vdec->b_die) && (!p_vdec->b_error) )
{
macroblock_t * p_mb;
if( (p_mb = vpar_GetMacroblock( &p_vdec->p_vpar->vfifo )) != NULL )
{
DecodeMacroblock( p_vdec, p_mb );
}
}
/*
* Error loop
*/
if( p_vdec->b_error )
{
ErrorThread( p_vdec );
}
/* End of thread */
EndThread( p_vdec );
p_vdec->b_run = 0;
}

153
src/video_parser/video_fifo.c

@ -33,9 +33,9 @@
#include "vpar_blocks.h"
#include "vpar_headers.h"
#include "video_fifo.h"
#include "vpar_synchro.h"
#include "video_parser.h"
#include "video_fifo.h"
/*****************************************************************************
* vpar_InitFIFO : initialize the video FIFO
@ -61,154 +61,3 @@ void vpar_InitFIFO( vpar_thread_t * p_vpar )
+ i_dummy;
}
}
/*****************************************************************************
* vpar_GetMacroblock : return a macroblock to be decoded
*****************************************************************************/
macroblock_t * vpar_GetMacroblock( video_fifo_t * p_fifo )
{
macroblock_t * p_mb;
vlc_mutex_lock( &p_fifo->lock );
while( VIDEO_FIFO_ISEMPTY( *p_fifo ) )
{
vlc_cond_wait( &p_fifo->wait, &p_fifo->lock );
if( p_fifo->p_vpar->b_die )
{
vlc_mutex_unlock( &p_fifo->lock );
return( NULL );
}
}
p_mb = VIDEO_FIFO_START( *p_fifo );
VIDEO_FIFO_INCSTART( *p_fifo );
vlc_mutex_unlock( &p_fifo->lock );
return( p_mb );
}
/*****************************************************************************
* vpar_NewMacroblock : return a buffer for the parser
*****************************************************************************/
macroblock_t * vpar_NewMacroblock( video_fifo_t * p_fifo )
{
macroblock_t * p_mb;
#define P_buffer p_fifo->p_vpar->vbuffer
vlc_mutex_lock( &P_buffer.lock );
while( P_buffer.i_index == -1 )
{
/* No more structures available. This should not happen ! */
intf_DbgMsg("vpar debug: macroblock list is empty, delaying\n");
vlc_mutex_unlock( &P_buffer.lock );
msleep(VPAR_IDLE_SLEEP);
vlc_mutex_lock( &P_buffer.lock );
}
p_mb = P_buffer.pp_mb_free[ P_buffer.i_index-- ];
vlc_mutex_unlock( &P_buffer.lock );
#undef P_buffer
return( p_mb );
}
/*****************************************************************************
* vpar_DecodeMacroblock : put a macroblock in the video fifo
*****************************************************************************/
void vpar_DecodeMacroblock( video_fifo_t * p_fifo, macroblock_t * p_mb )
{
/* Place picture in the video FIFO */
vlc_mutex_lock( &p_fifo->lock );
/* By construction, the video FIFO cannot be full */
VIDEO_FIFO_END( *p_fifo ) = p_mb;
VIDEO_FIFO_INCEND( *p_fifo );
vlc_mutex_unlock( &p_fifo->lock );
}
/*****************************************************************************
* vpar_ReleaseMacroblock : release a macroblock and put the picture in the
* video output heap, if it is finished
*****************************************************************************/
void vpar_ReleaseMacroblock( video_fifo_t * p_fifo, macroblock_t * p_mb )
{
boolean_t b_finished;
/* Unlink picture buffer */
vlc_mutex_lock( &p_mb->p_picture->lock_deccount );
p_mb->p_picture->i_deccount--;
b_finished = (p_mb->p_picture->i_deccount == 1);
vlc_mutex_unlock( &p_mb->p_picture->lock_deccount );
//fprintf(stderr, "%d ", p_mb->p_picture->i_deccount);
/* Test if it was the last block of the picture */
if( b_finished )
{
//fprintf(stderr, "Image decodee\n");
/* 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 );
/* Unlink referenced pictures */
if( p_mb->p_forward != NULL )
{
vout_UnlinkPicture( p_fifo->p_vpar->p_vout, p_mb->p_forward );
}
if( p_mb->p_backward != NULL )
{
vout_UnlinkPicture( p_fifo->p_vpar->p_vout, p_mb->p_backward );
}
}
/* Release the macroblock_t structure */
#define P_buffer p_fifo->p_vpar->vbuffer
vlc_mutex_lock( &P_buffer.lock );
P_buffer.pp_mb_free[ ++P_buffer.i_index ] = p_mb;
vlc_mutex_unlock( &P_buffer.lock );
#undef P_buffer
}
/*****************************************************************************
* vpar_DestroyMacroblock : destroy a macroblock in case of error
*****************************************************************************/
void vpar_DestroyMacroblock( video_fifo_t * p_fifo, macroblock_t * p_mb )
{
boolean_t b_finished;
/* Unlink picture buffer */
vlc_mutex_lock( &p_mb->p_picture->lock_deccount );
p_mb->p_picture->i_deccount--;
b_finished = (p_mb->p_picture->i_deccount == 0);
vlc_mutex_unlock( &p_mb->p_picture->lock_deccount );
/* Test if it was the last block of the picture */
if( b_finished )
{
fprintf(stderr, "Image trashee\n");
/* Mark the picture to be displayed */
vout_DestroyPicture( p_fifo->p_vpar->p_vout, p_mb->p_picture );
/* Warn Synchro for its records. */
vpar_SynchroEnd( p_fifo->p_vpar );
/* Unlink referenced pictures */
if( p_mb->p_forward != NULL )
{
vout_UnlinkPicture( p_fifo->p_vpar->p_vout, p_mb->p_forward );
}
if( p_mb->p_backward != NULL )
{
vout_UnlinkPicture( p_fifo->p_vpar->p_vout, p_mb->p_backward );
}
}
/* Release the macroblock_t structure */
#define P_buffer p_fifo->p_vpar->vbuffer
vlc_mutex_lock( &P_buffer.lock );
P_buffer.pp_mb_free[ ++P_buffer.i_index ] = p_mb;
vlc_mutex_unlock( &P_buffer.lock );
#undef P_buffer
}

2
src/video_parser/video_parser.c

@ -35,9 +35,9 @@
#include "vpar_blocks.h"
#include "vpar_headers.h"
#include "video_fifo.h"
#include "vpar_synchro.h"
#include "video_parser.h"
#include "video_fifo.h"
/*
* Local prototypes

74
src/video_parser/vpar_blocks.c

@ -33,9 +33,9 @@
#include "vpar_blocks.h"
#include "vpar_headers.h"
#include "video_fifo.h"
#include "vpar_synchro.h"
#include "video_parser.h"
#include "video_fifo.h"
/*
@ -571,9 +571,6 @@ void vpar_InitDCTTables( vpar_thread_t * p_vpar )
static __inline__ void InitMacroblock( vpar_thread_t * p_vpar,
macroblock_t * p_mb )
{
static f_chroma_motion_t pf_chroma_motion[4] =
{ NULL, vdec_Motion420, vdec_Motion422, vdec_Motion444 };
p_mb->p_picture = p_vpar->picture.p_picture;
p_mb->i_structure = p_vpar->picture.i_structure;
p_mb->i_current_structure = p_vpar->picture.i_current_structure;
@ -583,7 +580,6 @@ static __inline__ void InitMacroblock( vpar_thread_t * p_vpar,
p_mb->i_c_x = p_vpar->mb.i_c_x;
p_mb->i_motion_c_y = p_mb->i_c_y = p_vpar->mb.i_c_y;
p_mb->i_chroma_nb_blocks = p_vpar->sequence.i_chroma_nb_blocks;
p_mb->pf_chroma_motion = pf_chroma_motion[p_vpar->sequence.i_chroma_format];
p_mb->b_P_coding_type = ( p_vpar->picture.i_coding_type == P_CODING_TYPE );
if( (p_vpar->picture.i_coding_type == P_CODING_TYPE) ||
@ -649,9 +645,21 @@ static __inline__ int MacroblockAddressIncrement( vpar_thread_t * p_vpar )
static __inline__ void MacroblockModes( vpar_thread_t * p_vpar,
macroblock_t * p_mb )
{
static f_motion_t pf_motion[2][4] =
{ {NULL, vdec_MotionFieldField, vdec_MotionField16x8, vdec_MotionFieldDMV},
{NULL, vdec_MotionFrameField, vdec_MotionFrameFrame, vdec_MotionFrameDMV} };
static f_motion_t pppf_motion[4][2][4] =
{
{ {NULL, NULL, NULL, NULL},
{NULL, NULL, NULL, NULL}
},
{ {NULL, vdec_MotionFieldField420, vdec_MotionField16x8420, vdec_MotionFieldDMV},
{NULL, vdec_MotionFrameField420, vdec_MotionFrameFrame420, vdec_MotionFrameDMV}
},
{ {NULL, vdec_MotionFieldField422, vdec_MotionField16x8422, vdec_MotionFieldDMV},
{NULL, vdec_MotionFrameField422, vdec_MotionFrameFrame422, vdec_MotionFrameDMV}
},
{ {NULL, vdec_MotionFieldField444, vdec_MotionField16x8444, vdec_MotionFieldDMV},
{NULL, vdec_MotionFrameField444, vdec_MotionFrameFrame444, vdec_MotionFrameDMV}
}
};
static int ppi_mv_count[2][4] = { {0, 1, 2, 1}, {0, 2, 1, 1} };
static int ppi_mv_format[2][4] = { {0, 1, 1, 1}, {0, 1, 2, 1} };
@ -699,8 +707,9 @@ static __inline__ void MacroblockModes( vpar_thread_t * p_vpar,
}
else
{
p_mb->pf_motion = pf_motion[p_vpar->picture.b_frame_structure]
[p_vpar->mb.i_motion_type];
p_mb->pf_motion = pppf_motion[p_vpar->sequence.i_chroma_format]
[p_vpar->picture.b_frame_structure]
[p_vpar->mb.i_motion_type];
}
p_vpar->mb.i_mv_count = ppi_mv_count[p_vpar->picture.b_frame_structure]
@ -737,7 +746,6 @@ static __inline__ void MacroblockModes( vpar_thread_t * p_vpar,
void vpar_ParseMacroblock( vpar_thread_t * p_vpar, int * pi_mb_address,
int i_mb_previous, int i_mb_base )
{
static f_addb_t ppf_addb_intra[2] = {vdec_AddBlock, vdec_CopyBlock};
static f_decode_block_t pppf_decode_block[2][2] =
{ {vpar_DecodeMPEG1Non, vpar_DecodeMPEG1Intra},
{vpar_DecodeMPEG2Non, vpar_DecodeMPEG2Intra} };
@ -747,7 +755,6 @@ void vpar_ParseMacroblock( vpar_thread_t * p_vpar, int * pi_mb_address,
int i_mb, i_b, i_mask;
macroblock_t * p_mb;
f_addb_t pf_addb;
yuv_data_t * p_data1;
yuv_data_t * p_data2;
@ -764,8 +771,13 @@ i_count++;
{
/* Skipped macroblock (ISO/IEC 13818-2 7.6.6). */
static int pi_dc_dct_reinit[4] = {128,256,512,1024};
static f_motion_t pf_motion_skipped[4] = {NULL, vdec_MotionFieldField,
vdec_MotionFieldField, vdec_MotionFrameFrame};
static f_motion_t pf_motion_skipped[4][4] =
{
{NULL, NULL, NULL, NULL},
{NULL, vdec_MotionFieldField420, vdec_MotionFieldField420, vdec_MotionFrameFrame420},
{NULL, vdec_MotionFieldField422, vdec_MotionFieldField422, vdec_MotionFrameFrame422},
{NULL, vdec_MotionFieldField444, vdec_MotionFieldField444, vdec_MotionFrameFrame444},
};
/* Reset DC predictors (7.2.1). */
p_vpar->slice.pi_dc_dct_pred[0] = p_vpar->slice.pi_dc_dct_pred[1]
@ -788,16 +800,11 @@ i_count++;
InitMacroblock( p_vpar, p_mb );
/* No IDCT nor AddBlock. */
for( i_b = 0; i_b < 12; i_b++ )
{
p_mb->pf_idct[i_b] = vdec_DummyIDCT;
p_mb->pf_addb[i_b] = vdec_DummyBlock;
}
/* Motion type is picture structure. */
p_mb->pf_motion = pf_motion_skipped[p_vpar->picture.i_structure];
p_mb->pf_motion = pf_motion_skipped[p_vpar->sequence.i_chroma_format]
[p_vpar->picture.i_structure];
p_mb->i_mb_type = MB_MOTION_FORWARD;
p_mb->i_coded_block_pattern = 0;
memset( p_mb->pppi_motion_vectors, 0, 8*sizeof(int) );
/* Set the field we use for motion compensation */
@ -859,17 +866,16 @@ if( 0 )
if( p_vpar->mb.i_mb_type & MB_PATTERN )
{
p_vpar->mb.i_coded_block_pattern = (*p_vpar->sequence.pf_decode_pattern)( p_vpar );
p_mb->i_coded_block_pattern = p_vpar->mb.i_coded_block_pattern = (*p_vpar->sequence.pf_decode_pattern)( p_vpar );
//fprintf( stderr, "pattern : %d\n", p_vpar->mb.i_coded_block_pattern );
}
else
{
int pi_coded_block_pattern[2] = {0,
(1 << (4+p_vpar->sequence.i_chroma_nb_blocks)) - 1};
p_vpar->mb.i_coded_block_pattern = pi_coded_block_pattern
p_mb->i_coded_block_pattern = p_vpar->mb.i_coded_block_pattern = pi_coded_block_pattern
[p_vpar->mb.i_mb_type & MB_INTRA];
}
pf_addb = ppf_addb_intra[p_vpar->mb.i_mb_type & MB_INTRA];
/*
* Effectively decode blocks.
@ -889,9 +895,6 @@ if( 0 )
(*pppf_decode_block[p_vpar->sequence.b_mpeg2]
[p_vpar->mb.i_mb_type & MB_INTRA])
( p_vpar, p_mb, i_b );
/* decode_block has already set pf_idct and pi_sparse_pos. */
p_mb->pf_addb[i_b] = pf_addb;
/* Calculate block coordinates. */
p_mb->p_data[i_b] = p_data1
@ -899,12 +902,6 @@ if( 0 )
* p_vpar->sequence.i_width
+ pi_x[i_b];
}
else
{
/* Block not coded, so no IDCT, nor AddBlock */
p_mb->pf_addb[i_b] = vdec_DummyBlock;
p_mb->pf_idct[i_b] = vdec_DummyIDCT;
}
}
/* chrominance */
@ -929,21 +926,12 @@ if( 0 )
[p_vpar->mb.i_mb_type & MB_INTRA])
( p_vpar, p_mb, i_b );
/* decode_block has already set pf_idct and pi_sparse_pos. */
p_mb->pf_addb[i_b] = pf_addb;
/* Calculate block coordinates. */
p_mb->p_data[i_b] = pp_data[i_b & 1]
+ pi_y[p_vpar->mb.b_dct_type][i_b]
* p_vpar->sequence.i_chroma_width
+ pi_x[i_b];
}
else
{
/* Block not coded, so no IDCT, nor AddBlock */
p_mb->pf_addb[i_b] = vdec_DummyBlock;
p_mb->pf_idct[i_b] = vdec_DummyIDCT;
}
}
if( !( p_vpar->mb.i_mb_type & MB_INTRA ) )

6
src/video_parser/vpar_headers.c

@ -33,10 +33,10 @@
#include "vpar_blocks.h"
#include "vpar_headers.h"
#include "video_fifo.h"
#include "vpar_synchro.h"
#include "video_parser.h"
#include "vpar_motion.h"
#include "video_fifo.h"
/*
* Local prototypes
@ -681,7 +681,7 @@ static void PictureHeader( vpar_thread_t * p_vpar )
{
return;
}
mwait( VPAR_IDLE_SLEEP );
msleep( VPAR_OUTMEM_SLEEP );
}
/* Initialize values. */
@ -703,7 +703,7 @@ static void PictureHeader( vpar_thread_t * p_vpar )
vlc_mutex_init( &p_vpar->picture.p_picture->lock_deccount );
memset( p_vpar->picture.pp_mb, 0, MAX_MB );
/* 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. */
ReferenceUpdate( p_vpar, p_vpar->picture.i_coding_type, P_picture );

2
src/video_parser/vpar_motion.c

@ -35,10 +35,10 @@
#include "vpar_blocks.h"
#include "vpar_headers.h"
#include "video_fifo.h"
#include "vpar_synchro.h"
#include "video_parser.h"
#include "vpar_motion.h"
#include "video_fifo.h"
/*

2
src/video_parser/vpar_synchro.c

@ -33,9 +33,9 @@
#include "vpar_blocks.h"
#include "vpar_headers.h"
#include "video_fifo.h"
#include "vpar_synchro.h"
#include "video_parser.h"
#include "video_fifo.h"
#define MAX_COUNT 3

Loading…
Cancel
Save