diff --git a/include/config.h b/include/config.h index 96979fada7..c9fdc11c31 100644 --- a/include/config.h +++ b/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. */ diff --git a/include/vdec_motion.h b/include/vdec_motion.h index 01baaee83f..a0ab149bca 100644 --- a/include/vdec_motion.h +++ b/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 ); \ No newline at end of file diff --git a/include/video_decoder.h b/include/video_decoder.h index 3dc1ad9aa7..19907486cb 100644 --- a/include/video_decoder.h +++ b/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 diff --git a/include/video_fifo.h b/include/video_fifo.h index d72c728ee0..347d8edf61 100644 --- a/include/video_fifo.h +++ b/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 ); diff --git a/include/video_parser.h b/include/video_parser.h index e267ed2e93..a1649e764f 100644 --- a/include/video_parser.h +++ b/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 ***************************************************************************** diff --git a/include/vlc.h b/include/vlc.h index 5337ff4a85..b62157b5a1 100644 --- a/include/vlc.h +++ b/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 */ diff --git a/include/vpar_blocks.h b/include/vpar_blocks.h index 6fd6955ca9..a9d658f3d1 100644 --- a/include/vpar_blocks.h +++ b/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; diff --git a/src/video_decoder/vdec_idct.c b/src/video_decoder/vdec_idct.c index da8c934b1c..68d4c8b08e 100644 --- a/src/video_decoder/vdec_idct.c +++ b/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 diff --git a/src/video_decoder/vdec_motion.c b/src/video_decoder/vdec_motion.c index 1fd1c30564..ad9738c3ed 100644 --- a/src/video_decoder/vdec_motion.c +++ b/src/video_decoder/vdec_motion.c @@ -33,204 +33,432 @@ #include "vpar_blocks.h" #include "vpar_headers.h" -#include "video_fifo.h" #include "vpar_synchro.h" #include "video_parser.h" +#include "video_fifo.h" /***************************************************************************** * vdec_MotionComponent : last stage of motion compensation *****************************************************************************/ -static void __inline__ MotionComponent( yuv_data_t * p_src, yuv_data_t * p_dest, - int i_width, int i_height, int i_x_step, - int i_x_stride, int i_select ) +static __inline__ void MotionComponent( + yuv_data_t * p_src, /* source block */ + yuv_data_t * p_dest, /* dest block */ + int i_width, /* (explicit) width of block */ + int i_height, /* (explicit) height of block */ + int i_stride, /* number of coeffs to jump + * between each predicted line */ + int i_step, /* number of coeffs to jump to + * go to the next line of the + * field */ + int i_select, /* half-pel vectors */ + boolean_t b_average /* (explicit) averaging of several + * predictions */ ) { int i_x, i_y, i_x1, i_y1; unsigned int i_dummy; - switch( i_select ) + if( !b_average ) { - case 4: - /* !xh, !yh, average */ - for( i_y = 0; i_y < i_height; i_y += 4 ) + /* Please note that b_average will be expanded at compile time */ + + switch( i_select ) { - for( i_y1 = 0; i_y1 < 4; i_y1++ ) + case 0: + /* !xh, !yh, !average */ + for( i_y = 0; i_y < i_height; i_y += 4 ) { - for( i_x = 0; i_x < i_width; i_x += 8 ) + for( i_y1 = 0; i_y1 < 4; i_y1++ ) { - for( i_x1 = 0; i_x1 < 8; i_x1++ ) - { - i_dummy = p_dest[i_x + i_x1] + p_src[i_x + i_x1]; - p_dest[i_x + i_x1] = (i_dummy + 1) >> 1; - } + for( i_x = 0; i_x < i_width; i_x += 8 ) + { + for( i_x1 = 0; i_x1 < 8; i_x1++ ) + { + p_dest[i_x+i_x1] = p_src[i_x+i_x1]; + } + } + p_dest += i_stride; + p_src += i_stride; } - p_dest += i_x_step; - p_src += i_x_step; } - } - break; + break; - case 0: - /* !xh, !yh, !average */ - for( i_y = 0; i_y < i_height; i_y += 4 ) - { - for( i_y1 = 0; i_y1 < 4; i_y1++ ) + case 1: + /* xh, !yh, !average */ + for( i_y = 0; i_y < i_height; i_y += 4 ) { - for( i_x = 0; i_x < i_width; i_x += 8 ) + for( i_y1 = 0; i_y1 < 4; i_y1++ ) { - for( i_x1 = 0; i_x1 < 8; i_x1++ ) - { - p_dest[i_x+i_x1] = p_src[i_x+i_x1]; - } + for( i_x = 0; i_x < i_width; i_x += 8 ) + { + for( i_x1 = 0; i_x1 < 8; i_x1++ ) + { + p_dest[i_x+i_x1] = (unsigned int)(p_src[i_x+i_x1] + + p_src[i_x+i_x1 + 1] + 1) + >> 1; + } + } + p_dest += i_stride; + p_src += i_stride; } - p_dest += i_x_step; - p_src += i_x_step; } - } - break; + break; - case 6: - /* !xh, yh, average */ - for( i_y = 0; i_y < i_height; i_y += 4 ) - { - for( i_y1 = 0; i_y1 < 4; i_y1++ ) + case 2: + /* !xh, yh, !average */ + for( i_y = 0; i_y < i_height; i_y += 4 ) { - for( i_x = 0; i_x < i_width; i_x += 8 ) + for( i_y1 = 0; i_y1 < 4; i_y1++ ) { - for( i_x1 = 0; i_x1 < 8; i_x1++ ) - { - i_dummy = p_dest[i_x+i_x1] - + ((unsigned int)(p_src[i_x+i_x1] + 1 - + p_src[i_x+i_x1 + i_x_stride]) >> 1); - p_dest[i_x + i_x1] = (i_dummy + 1) >> 1; - } + for( i_x = 0; i_x < i_width; i_x += 8 ) + { + for( i_x1 = 0; i_x1 < 8; i_x1++ ) + { + p_dest[i_x+i_x1] = (unsigned int)(p_src[i_x+i_x1] + 1 + + p_src[i_x+i_x1 + i_step]) + >> 1; + } + } + p_dest += i_stride; + p_src += i_stride; } - p_dest += i_x_step; - p_src += i_x_step; } - } - break; + break; - case 2: - /* !xh, yh, !average */ - for( i_y = 0; i_y < i_height; i_y += 4 ) - { - for( i_y1 = 0; i_y1 < 4; i_y1++ ) + case 3: + /* xh, yh, !average (3) */ + for( i_y = 0; i_y < i_height; i_y += 4 ) { - for( i_x = 0; i_x < i_width; i_x += 8 ) + for( i_y1 = 0; i_y1 < 4; i_y1++ ) { - for( i_x1 = 0; i_x1 < 8; i_x1++ ) - { - p_dest[i_x+i_x1] = (unsigned int)(p_src[i_x+i_x1] + 1 - + p_src[i_x+i_x1 + i_x_stride]) - >> 1; - } + for( i_x = 0; i_x < i_width; i_x += 8 ) + { + for( i_x1 = 0; i_x1 < 8; i_x1++ ) + { + p_dest[i_x+i_x1] + = ((unsigned int)( + p_src[i_x+i_x1] + + p_src[i_x+i_x1 + 1] + + p_src[i_x+i_x1 + i_step] + + p_src[i_x+i_x1 + i_step + 1] + + 2) >> 2); + } + } + p_dest += i_stride; + p_src += i_stride; } - p_dest += i_x_step; - p_src += i_x_step; } + break; } - break; - case 5: - /* xh, !yh, average */ - for( i_y = 0; i_y < i_height; i_y += 4 ) + } + else + { + /* b_average */ + switch( i_select ) { - for( i_y1 = 0; i_y1 < 4; i_y1++ ) + case 0: + /* !xh, !yh, average */ + for( i_y = 0; i_y < i_height; i_y += 4 ) { - for( i_x = 0; i_x < i_width; i_x += 8 ) + for( i_y1 = 0; i_y1 < 4; i_y1++ ) { - for( i_x1 = 0; i_x1 < 8; i_x1++ ) - { - i_dummy = p_dest[i_x+i_x1] - + ((unsigned int)(p_src[i_x+i_x1] - + p_src[i_x+i_x1 + 1] + 1) >> 1); - p_dest[i_x + i_x1] = (i_dummy + 1) >> 1; - } + for( i_x = 0; i_x < i_width; i_x += 8 ) + { + for( i_x1 = 0; i_x1 < 8; i_x1++ ) + { + i_dummy = p_dest[i_x + i_x1] + p_src[i_x + i_x1]; + p_dest[i_x + i_x1] = (i_dummy + 1) >> 1; + } + } + p_dest += i_stride; + p_src += i_stride; } - p_dest += i_x_step; - p_src += i_x_step; } - } - break; + break; - case 1: - /* xh, !yh, !average */ - for( i_y = 0; i_y < i_height; i_y += 4 ) - { - for( i_y1 = 0; i_y1 < 4; i_y1++ ) + case 1: + /* xh, !yh, average */ + for( i_y = 0; i_y < i_height; i_y += 4 ) { - for( i_x = 0; i_x < i_width; i_x += 8 ) + for( i_y1 = 0; i_y1 < 4; i_y1++ ) { - for( i_x1 = 0; i_x1 < 8; i_x1++ ) - { - p_dest[i_x+i_x1] = (unsigned int)(p_src[i_x+i_x1] - + p_src[i_x+i_x1 + 1] + 1) - >> 1; - } + for( i_x = 0; i_x < i_width; i_x += 8 ) + { + for( i_x1 = 0; i_x1 < 8; i_x1++ ) + { + i_dummy = p_dest[i_x+i_x1] + + ((unsigned int)(p_src[i_x+i_x1] + + p_src[i_x+i_x1 + 1] + 1) >> 1); + p_dest[i_x + i_x1] = (i_dummy + 1) >> 1; + } + } + p_dest += i_stride; + p_src += i_stride; } - p_dest += i_x_step; - p_src += i_x_step; } - } - break; + break; - case 7: - /* xh, yh, average */ - for( i_y = 0; i_y < i_height; i_y += 4 ) - { - for( i_y1 = 0; i_y1 < 4; i_y1++ ) + case 2: + /* !xh, yh, average */ + for( i_y = 0; i_y < i_height; i_y += 4 ) { - for( i_x = 0; i_x < i_width; i_x += 8 ) + for( i_y1 = 0; i_y1 < 4; i_y1++ ) { - for( i_x1 = 0; i_x1 < 8; i_x1++ ) - { - i_dummy = p_dest[i_x+i_x1] - + ((unsigned int)( - p_src[i_x+i_x1] - + p_src[i_x+i_x1 + 1] - + p_src[i_x+i_x1 + i_x_stride] - + p_src[i_x+i_x1 + i_x_stride + 1] - + 2) >> 2); - p_dest[i_x + i_x1] = (i_dummy + 1) >> 1; - } + for( i_x = 0; i_x < i_width; i_x += 8 ) + { + for( i_x1 = 0; i_x1 < 8; i_x1++ ) + { + i_dummy = p_dest[i_x+i_x1] + + ((unsigned int)(p_src[i_x+i_x1] + 1 + + p_src[i_x+i_x1 + i_step]) >> 1); + p_dest[i_x + i_x1] = (i_dummy + 1) >> 1; + } + } + p_dest += i_stride; + p_src += i_stride; } - p_dest += i_x_step; - p_src += i_x_step; } - } - break; + break; - default: - /* xh, yh, !average (3) */ - for( i_y = 0; i_y < i_height; i_y += 4 ) - { - for( i_y1 = 0; i_y1 < 4; i_y1++ ) + case 3: + /* xh, yh, average */ + for( i_y = 0; i_y < i_height; i_y += 4 ) { - for( i_x = 0; i_x < i_width; i_x += 8 ) + for( i_y1 = 0; i_y1 < 4; i_y1++ ) { - for( i_x1 = 0; i_x1 < 8; i_x1++ ) - { - p_dest[i_x+i_x1] - = ((unsigned int)( - p_src[i_x+i_x1] - + p_src[i_x+i_x1 + 1] - + p_src[i_x+i_x1 + i_x_stride] - + p_src[i_x+i_x1 + i_x_stride + 1] - + 2) >> 2); - } + for( i_x = 0; i_x < i_width; i_x += 8 ) + { + for( i_x1 = 0; i_x1 < 8; i_x1++ ) + { + i_dummy = p_dest[i_x+i_x1] + + ((unsigned int)( + p_src[i_x+i_x1] + + p_src[i_x+i_x1 + 1] + + p_src[i_x+i_x1 + i_step] + + p_src[i_x+i_x1 + i_step + 1] + + 2) >> 2); + p_dest[i_x + i_x1] = (i_dummy + 1) >> 1; + } + } + p_dest += i_stride; + p_src += i_stride; } - p_dest += i_x_step; - p_src += i_x_step; } + break; } - break; } } +/***************************************************************************** + * Motion420 : motion compensation for a 4:2:0 macroblock + *****************************************************************************/ +static __inline__ void Motion420( + macroblock_t * p_mb, /* destination macroblock */ + picture_t * p_source, /* source picture */ + boolean_t b_source_field, /* source field */ + boolean_t b_dest_field, /* destination field */ + int i_mv_x, int i_mv_y, /* motion vector coordinates, + * in half pels */ + int i_l_stride, /* number of coeffs to jump to + * go to the next predicted + * line */ + int i_c_stride, + int i_height, /* height of the block to + * predict, in luminance + * (explicit) */ + int i_offset, /* position of the first + * predicted line (explicit) */ + boolean_t b_average /* (explicit) averaging of + * several predictions */ ) +{ + /* Temporary variables to avoid recalculating things twice */ + int i_source_offset, i_dest_offset, i_c_height, i_c_select; + + /* Luminance */ + MotionComponent( /* source */ + p_source->p_y + + (p_mb->i_l_x + (i_mv_x >> 1)) + + (p_mb->i_motion_l_y + i_offset + + (i_mv_y >> 1) + + b_source_field) + * p_mb->p_picture->i_width, + /* destination */ + p_mb->p_picture->p_y + + (p_mb->i_l_x) + + (p_mb->i_motion_l_y + b_dest_field) + * p_mb->p_picture->i_width, + /* prediction width and height */ + 16, i_height, + /* stride */ + i_l_stride, p_mb->i_l_stride, + /* select */ + ((i_mv_y & 1) << 1) | (i_mv_x & 1), + b_average ); + + i_source_offset = (p_mb->i_c_x + ((i_mv_x/2) >> 1)) + + ((p_mb->i_motion_c_y + (i_offset >> 1) + + ((i_mv_y/2) >> 1)) + + b_source_field) + * p_mb->p_picture->i_chroma_width; + i_dest_offset = (p_mb->i_c_x) + + (p_mb->i_motion_c_y + b_dest_field) + * p_mb->p_picture->i_chroma_width; + i_c_height = i_height >> 1; + i_c_select = (((i_mv_y/2) & 1) << 1) | ((i_mv_x/2) & 1); + + /* Chrominance Cr */ + MotionComponent( p_source->p_u + + i_source_offset, + p_mb->p_picture->p_u + + i_dest_offset, + 8, i_c_height, i_c_stride, p_mb->i_c_stride, + i_c_select, b_average ); + + /* Chrominance Cb */ + MotionComponent( p_source->p_v + + i_source_offset, + p_mb->p_picture->p_v + + i_dest_offset, + 8, i_c_height, i_c_stride, p_mb->i_c_stride, + i_c_select, b_average ); +} + +/***************************************************************************** + * Motion422 : motion compensation for a 4:2:2 macroblock + *****************************************************************************/ +static __inline__ void Motion422( + macroblock_t * p_mb, /* destination macroblock */ + picture_t * p_source, /* source picture */ + boolean_t b_source_field, /* source field */ + boolean_t b_dest_field, /* destination field */ + int i_mv_x, int i_mv_y, /* motion vector coordinates, + * in half pels */ + int i_l_stride, /* number of coeffs to jump to + * go to the next predicted + * line */ + int i_c_stride, + int i_height, /* height of the block to + * predict, in luminance + * (explicit) */ + int i_offset, /* position of the first + * predicted line (explicit) */ + boolean_t b_average /* (explicit) averaging of + * several predictions */ ) +{ + int i_source_offset, i_dest_offset, i_c_select; + + /* Luminance */ + MotionComponent( /* source */ + p_source->p_y + + (p_mb->i_l_x + (i_mv_x >> 1)) + + (p_mb->i_motion_l_y + i_offset + + (i_mv_y >> 1) + + b_source_field) + * p_mb->p_picture->i_width, + /* destination */ + p_mb->p_picture->p_y + + (p_mb->i_l_x) + + (p_mb->i_motion_l_y + b_dest_field) + * p_mb->p_picture->i_width, + /* prediction width and height */ + 16, i_height, + /* stride */ + i_l_stride, p_mb->i_l_stride, + /* select */ + ((i_mv_y & 1) << 1) | (i_mv_x & 1), + b_average ); + + i_source_offset = (p_mb->i_c_x + ((i_mv_x/2) >> 1)) + + ((p_mb->i_motion_c_y + (i_offset) + + ((i_mv_y) >> 1)) + + b_source_field) + * p_mb->p_picture->i_chroma_width; + i_dest_offset = (p_mb->i_c_x) + + (p_mb->i_motion_c_y + b_dest_field) + * p_mb->p_picture->i_chroma_width; + i_c_select = ((i_mv_y & 1) << 1) | ((i_mv_x/2) & 1); + + /* Chrominance Cr */ + MotionComponent( p_source->p_u + + i_source_offset, + p_mb->p_picture->p_u + + i_dest_offset, + 8, i_height, i_c_stride, p_mb->i_c_stride, + i_c_select, b_average ); + + /* Chrominance Cb */ + MotionComponent( p_source->p_v + + i_source_offset, + p_mb->p_picture->p_u + + i_dest_offset, + 8, i_height, i_c_stride, p_mb->i_c_stride, + i_c_select, b_average ); +} + +/***************************************************************************** + * Motion444 : motion compensation for a 4:4:4 macroblock + *****************************************************************************/ +static __inline__ void Motion444( + macroblock_t * p_mb, /* destination macroblock */ + picture_t * p_source, /* source picture */ + boolean_t b_source_field, /* source field */ + boolean_t b_dest_field, /* destination field */ + int i_mv_x, int i_mv_y, /* motion vector coordinates, + * in half pels */ + int i_l_stride, /* number of coeffs to jump to + * go to the next predicted + * line */ + int i_c_stride, + int i_height, /* height of the block to + * predict, in luminance + * (explicit) */ + int i_offset, /* position of the first + * predicted line (explicit) */ + boolean_t b_average /* (explicit) averaging of + * several predictions */ ) +{ + int i_source_offset, i_dest_offset, i_select; + + i_source_offset = (p_mb->i_l_x + (i_mv_x >> 1)) + + (p_mb->i_motion_l_y + i_offset + + (i_mv_y >> 1) + + b_source_field) + * p_mb->p_picture->i_width; + i_dest_offset = (p_mb->i_l_x) + + (p_mb->i_motion_l_y + b_dest_field) + * p_mb->p_picture->i_width; + i_select = ((i_mv_y & 1) << 1) | (i_mv_x & 1); + + + /* Luminance */ + MotionComponent( p_source->p_y + + i_source_offset, + p_mb->p_picture->p_y + + i_dest_offset, + 16, i_height, i_l_stride, p_mb->i_l_stride, + i_select, b_average ); + + /* Chrominance Cr */ + MotionComponent( p_source->p_u + + i_source_offset, + p_mb->p_picture->p_u + + i_dest_offset, + 16, i_height, i_l_stride, p_mb->i_l_stride, + i_select, b_average ); + + /* Chrominance Cb */ + MotionComponent( p_source->p_v + + i_source_offset, + p_mb->p_picture->p_v + + i_dest_offset, + 16, i_height, i_l_stride, p_mb->i_l_stride, + i_select, b_average ); +} + /***************************************************************************** * DualPrimeArithmetic : Dual Prime Additional arithmetic (7.6.3.6) *****************************************************************************/ -static void __inline__ DualPrimeArithmetic( macroblock_t * p_mb, +static __inline__ void DualPrimeArithmetic( macroblock_t * p_mb, int ppi_dmv[2][2], int i_mv_x, int i_mv_y ) { @@ -272,17 +500,6 @@ static void __inline__ DualPrimeArithmetic( macroblock_t * p_mb, } -typedef struct motion_arg_s -{ - picture_t * p_source; - boolean_t b_source_field; - boolean_t b_dest_field; - int i_height, i_offset; - int i_mv_x, i_mv_y; - boolean_t b_average; - int i_l_x_step, i_c_x_step; -} motion_arg_t; - /***************************************************************************** * vdec_MotionDummy : motion compensation for an intra macroblock *****************************************************************************/ @@ -294,103 +511,141 @@ void vdec_MotionDummy( macroblock_t * p_mb ) /***************************************************************************** * vdec_MotionFieldField : motion compensation for field motion type (field) *****************************************************************************/ -void vdec_MotionFieldField( macroblock_t * p_mb ) -{ -#if 1 - motion_arg_t args; - - args.i_height = 16; - args.b_average = 0; - args.b_dest_field = p_mb->b_motion_field; - args.i_offset = 0; - args.i_l_x_step = p_mb->i_l_stride; - args.i_c_x_step = p_mb->i_c_stride; +#define FIELDFIELD( MOTION ) \ + picture_t * p_pred; \ + \ + if( p_mb->i_mb_type & MB_MOTION_FORWARD ) \ + { \ + if( p_mb->b_P_coding_type \ + && (p_mb->i_current_structure == FRAME_STRUCTURE) \ + && (p_mb->b_motion_field != p_mb->ppi_field_select[0][0]) )\ + p_pred = p_mb->p_picture; \ + else \ + p_pred = p_mb->p_forward; \ + \ + MOTION( p_mb, p_pred, p_mb->ppi_field_select[0][0], \ + p_mb->b_motion_field, \ + p_mb->pppi_motion_vectors[0][0][0], \ + p_mb->pppi_motion_vectors[0][0][1], \ + p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 ); \ + \ + if( p_mb->i_mb_type & MB_MOTION_BACKWARD ) \ + { \ + MOTION( p_mb, p_mb->p_backward, \ + p_mb->ppi_field_select[0][1], \ + p_mb->b_motion_field, \ + p_mb->pppi_motion_vectors[0][1][0], \ + p_mb->pppi_motion_vectors[0][1][1], \ + p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 1 ); \ + } \ + \ + else /* MB_MOTION_BACKWARD */ \ + { \ + MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[0][1], \ + p_mb->b_motion_field, \ + p_mb->pppi_motion_vectors[0][1][0], \ + p_mb->pppi_motion_vectors[0][1][1], \ + p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 ); \ + } \ +} - if( p_mb->i_mb_type & MB_MOTION_FORWARD ) - { - if( p_mb->b_P_coding_type - && (p_mb->i_current_structure == FRAME_STRUCTURE) - && (p_mb->b_motion_field != p_mb->ppi_field_select[0][0]) ) - args.p_source = p_mb->p_picture; - else - args.p_source = p_mb->p_forward; - args.b_source_field = p_mb->ppi_field_select[0][0]; - args.i_mv_x = p_mb->pppi_motion_vectors[0][0][0]; - args.i_mv_y = p_mb->pppi_motion_vectors[0][0][1]; - p_mb->pf_chroma_motion( p_mb, &args ); +void vdec_MotionFieldField420( macroblock_t * p_mb ) +{ + FIELDFIELD( Motion420 ) +} - args.b_average = 1; - } +void vdec_MotionFieldField422( macroblock_t * p_mb ) +{ + FIELDFIELD( Motion422 ) +} - if( p_mb->i_mb_type & MB_MOTION_BACKWARD ) - { - args.b_source_field = p_mb->ppi_field_select[0][1]; - args.i_mv_x = p_mb->pppi_motion_vectors[0][1][0]; - args.i_mv_y = p_mb->pppi_motion_vectors[0][1][1]; - p_mb->pf_chroma_motion( p_mb, &args ); - } -#endif +void vdec_MotionFieldField444( macroblock_t * p_mb ) +{ + FIELDFIELD( Motion444 ) } /***************************************************************************** - * vdec_MotionField16x8 : motion compensation for 16x8 motion type (field) + * vdec_MotionField16x8XXX : motion compensation for 16x8 motion type (field) *****************************************************************************/ -void vdec_MotionField16x8( macroblock_t * p_mb ) -{ -#if 1 - motion_arg_t args; +#define FIELD16X8( MOTION ) \ +{ \ + picture_t * p_pred; \ + \ + if( p_mb->i_mb_type & MB_MOTION_FORWARD ) \ + { \ + if( p_mb->b_P_coding_type \ + && (p_mb->i_current_structure == FRAME_STRUCTURE) \ + && (p_mb->b_motion_field != p_mb->ppi_field_select[0][0]) )\ + p_pred = p_mb->p_picture; \ + else \ + p_pred = p_mb->p_forward; \ + \ + MOTION( p_mb, p_pred, p_mb->ppi_field_select[0][0], \ + p_mb->b_motion_field, \ + p_mb->pppi_motion_vectors[0][0][0], \ + p_mb->pppi_motion_vectors[0][0][1], \ + p_mb->i_l_stride, p_mb->i_c_stride, 8, 0, 0 ); \ + \ + if( p_mb->b_P_coding_type \ + && (p_mb->i_current_structure == FRAME_STRUCTURE) \ + && (p_mb->b_motion_field != p_mb->ppi_field_select[1][0]) )\ + p_pred = p_mb->p_picture; \ + else \ + p_pred = p_mb->p_forward; \ + \ + MOTION( p_mb, p_pred, p_mb->ppi_field_select[1][0], \ + p_mb->b_motion_field, \ + p_mb->pppi_motion_vectors[1][0][0], \ + p_mb->pppi_motion_vectors[1][0][1], \ + p_mb->i_l_stride, p_mb->i_c_stride, 8, 8, 0 ); \ + \ + if( p_mb->i_mb_type & MB_MOTION_BACKWARD ) \ + { \ + MOTION( p_mb, p_mb->p_backward, \ + p_mb->ppi_field_select[0][1], \ + p_mb->b_motion_field, \ + p_mb->pppi_motion_vectors[0][1][0], \ + p_mb->pppi_motion_vectors[0][1][1], \ + p_mb->i_l_stride, p_mb->i_c_stride, 8, 0, 1 ); \ + \ + MOTION( p_mb, p_mb->p_backward, \ + p_mb->ppi_field_select[1][1], \ + p_mb->b_motion_field, \ + p_mb->pppi_motion_vectors[1][1][0], \ + p_mb->pppi_motion_vectors[1][1][1], \ + p_mb->i_l_stride, p_mb->i_c_stride, 8, 8, 1 ); \ + } \ + } \ + \ + else /* MB_MOTION_BACKWARD */ \ + { \ + MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[0][1], \ + p_mb->b_motion_field, \ + p_mb->pppi_motion_vectors[0][1][0], \ + p_mb->pppi_motion_vectors[0][1][1], \ + p_mb->i_l_stride, p_mb->i_c_stride, 8, 0, 0 ); \ + \ + MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[1][1], \ + p_mb->b_motion_field, \ + p_mb->pppi_motion_vectors[1][1][0], \ + p_mb->pppi_motion_vectors[1][1][1], \ + p_mb->i_l_stride, p_mb->i_c_stride, 8, 8, 0 ); \ + } \ +} - args.i_height = 8; - args.b_average = 0; - args.b_dest_field = p_mb->b_motion_field; - args.i_offset = 0; - args.i_l_x_step = p_mb->i_l_stride; - args.i_c_x_step = p_mb->i_c_stride; +void vdec_MotionField16x8420( macroblock_t * p_mb ) +{ + FIELD16X8( Motion420 ) +} - if( p_mb->i_mb_type & MB_MOTION_FORWARD ) - { - if( p_mb->b_P_coding_type - && (p_mb->i_current_structure == FRAME_STRUCTURE) - && (p_mb->b_motion_field != p_mb->ppi_field_select[0][0]) ) - args.p_source = p_mb->p_picture; - else - args.p_source = p_mb->p_forward; - args.b_source_field = p_mb->ppi_field_select[0][0]; - args.i_mv_x = p_mb->pppi_motion_vectors[0][0][0]; - args.i_mv_y = p_mb->pppi_motion_vectors[0][0][1]; - p_mb->pf_chroma_motion( p_mb, &args ); - - if( p_mb->b_P_coding_type - && (p_mb->i_current_structure == FRAME_STRUCTURE) - && (p_mb->b_motion_field != p_mb->ppi_field_select[1][0]) ) - args.p_source = p_mb->p_picture; - else - args.p_source = p_mb->p_forward; - args.b_source_field = p_mb->ppi_field_select[1][0]; - args.i_mv_x = p_mb->pppi_motion_vectors[1][0][0]; - args.i_mv_y = p_mb->pppi_motion_vectors[1][0][1]; - args.i_offset = 8; - p_mb->pf_chroma_motion( p_mb, &args ); - - args.b_average = 1; - args.i_offset = 0; - } +void vdec_MotionField16x8422( macroblock_t * p_mb ) +{ + FIELD16X8( Motion422 ) +} - if( p_mb->i_mb_type & MB_MOTION_BACKWARD ) - { - args.p_source = p_mb->p_backward; - args.b_source_field = p_mb->ppi_field_select[0][1]; - args.i_mv_x = p_mb->pppi_motion_vectors[0][1][0]; - args.i_mv_y = p_mb->pppi_motion_vectors[0][1][1]; - p_mb->pf_chroma_motion( p_mb, &args ); - - args.b_source_field = p_mb->ppi_field_select[1][1]; - args.i_mv_x = p_mb->pppi_motion_vectors[1][1][0]; - args.i_mv_y = p_mb->pppi_motion_vectors[1][1][1]; - args.i_offset = 8; - p_mb->pf_chroma_motion( p_mb, &args ); - } -#endif +void vdec_MotionField16x8444( macroblock_t * p_mb ) +{ + FIELD16X8( Motion444 ) } /***************************************************************************** @@ -398,6 +653,7 @@ void vdec_MotionField16x8( macroblock_t * p_mb ) *****************************************************************************/ void vdec_MotionFieldDMV( macroblock_t * p_mb ) { +#if 0 /* This is necessarily a MOTION_FORWARD only macroblock */ motion_arg_t args; picture_t * p_pred; @@ -430,94 +686,117 @@ void vdec_MotionFieldDMV( macroblock_t * p_mb ) args.i_mv_x = ppi_dmv[0][0]; args.i_mv_y = ppi_dmv[0][1]; p_mb->pf_chroma_motion( p_mb, &args ); +#endif } /***************************************************************************** - * vdec_MotionFrameFrame : motion compensation for frame motion type (frame) + * vdec_MotionFrameFrameXXX : motion compensation for frame motion type (frame) *****************************************************************************/ -void vdec_MotionFrameFrame( macroblock_t * p_mb ) +#define FRAMEFRAME( MOTION ) \ +{ \ + if( p_mb->i_mb_type & MB_MOTION_FORWARD ) \ + { \ + MOTION( p_mb, p_mb->p_forward, 0, 0, \ + p_mb->pppi_motion_vectors[0][0][0], \ + p_mb->pppi_motion_vectors[0][0][1], \ + p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 ); \ + \ + if( p_mb->i_mb_type & MB_MOTION_BACKWARD ) \ + { \ + MOTION( p_mb, p_mb->p_backward, 0, 0, \ + p_mb->pppi_motion_vectors[0][1][0], \ + p_mb->pppi_motion_vectors[0][1][1], \ + p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 1 ); \ + } \ + } \ + \ + else /* MB_MOTION_BACKWARD */ \ + { \ + MOTION( p_mb, p_mb->p_backward, 0, 0, \ + p_mb->pppi_motion_vectors[0][1][0], \ + p_mb->pppi_motion_vectors[0][1][1], \ + p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 ); \ + } \ +} /* FRAMEFRAME */ + +void vdec_MotionFrameFrame420( macroblock_t * p_mb ) { -#if 1 - motion_arg_t args; - - args.b_source_field = args.b_dest_field = 0; - args.i_height = 16; - args.b_average = 0; - args.i_offset = 0; - args.i_l_x_step = p_mb->i_l_stride; - args.i_c_x_step = p_mb->i_c_stride; - - if( p_mb->i_mb_type & MB_MOTION_FORWARD ) - { - args.p_source = p_mb->p_forward; - args.i_mv_x = p_mb->pppi_motion_vectors[0][0][0]; - args.i_mv_y = p_mb->pppi_motion_vectors[0][0][1]; - p_mb->pf_chroma_motion( p_mb, &args ); + FRAMEFRAME( Motion420 ) +} - args.b_average = 1; - } +void vdec_MotionFrameFrame422( macroblock_t * p_mb ) +{ + FRAMEFRAME( Motion422 ) +} - if( p_mb->i_mb_type & MB_MOTION_BACKWARD ) - { - args.p_source = p_mb->p_backward; - args.i_mv_x = p_mb->pppi_motion_vectors[0][1][0]; - args.i_mv_y = p_mb->pppi_motion_vectors[0][1][1]; - p_mb->pf_chroma_motion( p_mb, &args ); - } -#endif +void vdec_MotionFrameFrame444( macroblock_t * p_mb ) +{ + FRAMEFRAME( Motion444 ) } /***************************************************************************** - * vdec_MotionFrameField : motion compensation for field motion type (frame) + * vdec_MotionFrameFieldXXX : motion compensation for field motion type (frame) *****************************************************************************/ -void vdec_MotionFrameField( macroblock_t * p_mb ) +#define FRAMEFIELD( MOTION ) \ +{ \ + int i_l_stride = p_mb->i_l_stride << 1; \ + int i_c_stride = p_mb->i_c_stride << 1; \ + \ + if( p_mb->i_mb_type & MB_MOTION_FORWARD ) \ + { \ + MOTION( p_mb, p_mb->p_forward, p_mb->ppi_field_select[0][0], 0, \ + p_mb->pppi_motion_vectors[0][0][0], \ + p_mb->pppi_motion_vectors[0][0][1], \ + i_l_stride, i_c_stride, 8, 0, 0 ); \ + \ + MOTION( p_mb, p_mb->p_forward, p_mb->ppi_field_select[1][0], 1, \ + p_mb->pppi_motion_vectors[1][0][0], \ + p_mb->pppi_motion_vectors[1][0][1], \ + i_l_stride, i_c_stride, 8, 0, 0 ); \ + \ + if( p_mb->i_mb_type & MB_MOTION_BACKWARD ) \ + { \ + MOTION( p_mb, p_mb->p_backward, \ + p_mb->ppi_field_select[0][1], 0, \ + p_mb->pppi_motion_vectors[0][1][0], \ + p_mb->pppi_motion_vectors[0][1][1], \ + i_l_stride, i_c_stride, 8, 0, 1 ); \ + \ + MOTION( p_mb, p_mb->p_backward, \ + p_mb->ppi_field_select[1][1], 1, \ + p_mb->pppi_motion_vectors[1][1][0], \ + p_mb->pppi_motion_vectors[1][1][1], \ + i_l_stride, i_c_stride, 8, 0, 1 ); \ + } \ + } \ + \ + else /* MB_MOTION_BACKWARD only */ \ + { \ + MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[0][1], 0,\ + p_mb->pppi_motion_vectors[0][1][0], \ + p_mb->pppi_motion_vectors[0][1][1], \ + i_l_stride, i_c_stride, 8, 0, 0 ); \ + \ + MOTION( p_mb, p_mb->p_backward, p_mb->ppi_field_select[1][1], 1,\ + p_mb->pppi_motion_vectors[1][1][0], \ + p_mb->pppi_motion_vectors[1][1][1], \ + i_l_stride, i_c_stride, 8, 0, 0 ); \ + } \ +} /* FRAMEFIELD */ + +void vdec_MotionFrameField420( macroblock_t * p_mb ) { -#if 1 - motion_arg_t args; - - args.i_height = 8; - args.b_average = 0; - args.i_offset = 0; - args.i_l_x_step = p_mb->i_l_stride << 1; - args.i_c_x_step = p_mb->i_c_stride << 1; + FRAMEFIELD( Motion420 ) +} - if( p_mb->i_mb_type & MB_MOTION_FORWARD ) - { - args.p_source = p_mb->p_forward; -#if 1 - args.b_source_field = p_mb->ppi_field_select[0][0]; - args.b_dest_field = 0; - args.i_mv_x = p_mb->pppi_motion_vectors[0][0][0]; - args.i_mv_y = p_mb->pppi_motion_vectors[0][0][1]; - p_mb->pf_chroma_motion( p_mb, &args ); -#endif -#if 1 - args.b_source_field = p_mb->ppi_field_select[1][0]; - args.b_dest_field = 1; - args.i_mv_x = p_mb->pppi_motion_vectors[1][0][0]; - args.i_mv_y = p_mb->pppi_motion_vectors[1][0][1]; - p_mb->pf_chroma_motion( p_mb, &args ); -#endif - args.b_average = 1; - } +void vdec_MotionFrameField422( macroblock_t * p_mb ) +{ + FRAMEFIELD( Motion422 ) +} - if( p_mb->i_mb_type & MB_MOTION_BACKWARD ) - { - args.p_source = p_mb->p_backward; - - args.b_source_field = p_mb->ppi_field_select[0][1]; - args.b_dest_field = 0; - args.i_mv_x = p_mb->pppi_motion_vectors[0][1][0]; - args.i_mv_y = p_mb->pppi_motion_vectors[0][1][1]; - p_mb->pf_chroma_motion( p_mb, &args ); - - args.b_source_field = p_mb->ppi_field_select[1][1]; - args.b_dest_field = 1; - args.i_mv_x = p_mb->pppi_motion_vectors[1][1][0]; - args.i_mv_y = p_mb->pppi_motion_vectors[1][1][1]; - p_mb->pf_chroma_motion( p_mb, &args ); - } -#endif +void vdec_MotionFrameField444( macroblock_t * p_mb ) +{ + FRAMEFIELD( Motion444 ) } /***************************************************************************** @@ -525,6 +804,7 @@ void vdec_MotionFrameField( macroblock_t * p_mb ) *****************************************************************************/ void vdec_MotionFrameDMV( macroblock_t * p_mb ) { +#if 0 /* This is necessarily a MOTION_FORWARD only macroblock */ motion_arg_t args; int ppi_dmv[2][2]; @@ -567,180 +847,6 @@ void vdec_MotionFrameDMV( macroblock_t * p_mb ) args.i_mv_x = ppi_dmv[1][0]; args.i_mv_y = ppi_dmv[1][1]; p_mb->pf_chroma_motion( p_mb, &args ); -} - -/***************************************************************************** - * vdec_Motion420 : motion compensation for a 4:2:0 macroblock - *****************************************************************************/ -void vdec_Motion420( macroblock_t * p_mb, motion_arg_t * p_motion ) -{ -// p_motion->i_mv_x = p_motion->i_mv_y = 0; -//fprintf( stderr, " x %d, y %d \n", p_motion->i_mv_x, p_motion->i_mv_y ); - /* Luminance */ - MotionComponent( /* source */ - p_motion->p_source->p_y - + (p_mb->i_l_x + (p_motion->i_mv_x >> 1)) - + (p_mb->i_motion_l_y + p_motion->i_offset - + (p_motion->i_mv_y >> 1) - + p_motion->b_source_field) - * p_mb->p_picture->i_width, - /* destination */ - p_mb->p_picture->p_y - + (p_mb->i_l_x) - + (p_mb->i_motion_l_y + p_motion->b_dest_field) - * p_mb->p_picture->i_width, - /* prediction width and height */ - 16, p_motion->i_height, - /* step */ - p_motion->i_l_x_step, p_mb->i_l_stride, - /* select */ - (p_motion->b_average << 2) - | ((p_motion->i_mv_y & 1) << 1) - | (p_motion->i_mv_x & 1) ); - - /* Chrominance Cr */ - MotionComponent( p_motion->p_source->p_u - + (p_mb->i_c_x + ((p_motion->i_mv_x/2) >> 1)) - + ((p_mb->i_motion_c_y + (p_motion->i_offset >> 1) - + ((p_motion->i_mv_y/2) >> 1)) - + p_motion->b_source_field) - * p_mb->p_picture->i_chroma_width, - p_mb->p_picture->p_u - + (p_mb->i_c_x) - + (p_mb->i_motion_c_y + p_motion->b_dest_field) - * p_mb->p_picture->i_chroma_width, - 8, p_motion->i_height >> 1, p_motion->i_c_x_step, - p_mb->i_c_stride, - (p_motion->b_average << 2) - | (((p_motion->i_mv_y/2) & 1) << 1) - | ((p_motion->i_mv_x/2) & 1) ); - - /* Chrominance Cb */ - MotionComponent( p_motion->p_source->p_v - + (p_mb->i_c_x + ((p_motion->i_mv_x/2) >> 1)) - + ((p_mb->i_motion_c_y + (p_motion->i_offset >> 1) - + ((p_motion->i_mv_y/2) >> 1)) - + p_motion->b_source_field) - * p_mb->p_picture->i_chroma_width, - p_mb->p_picture->p_v - + (p_mb->i_c_x) - + (p_mb->i_motion_c_y + p_motion->b_dest_field) - * p_mb->p_picture->i_chroma_width, - 8, p_motion->i_height >> 1, p_motion->i_c_x_step, - p_mb->i_c_stride, - (p_motion->b_average << 2) - | (((p_motion->i_mv_y/2) & 1) << 1) - | ((p_motion->i_mv_x/2) & 1) ); -} - -/***************************************************************************** - * vdec_Motion422 : motion compensation for a 4:2:2 macroblock - *****************************************************************************/ -void vdec_Motion422( macroblock_t * p_mb, motion_arg_t * p_motion ) -{ -#if 0 - /* Luminance */ - MotionComponent( p_motion->p_source->p_y - + (p_mb->i_l_x + (p_motion->i_mv_x >> 1)) - + (p_mb->i_motion_l_y + p_motion->i_offset - + (p_motion->i_mv_y >> 1) - + p_motion->b_source_field) - * p_mb->p_picture->i_width, - p_mb->p_picture->p_y - + (p_mb->i_l_x) - + (p_mb->i_motion_l_y + p_motion->b_dest_field) - * p_mb->p_picture->i_width, - 16, p_motion->i_height, p_mb->i_l_stride, - (p_motion->b_average << 2) - | ((p_motion->i_mv_y & 1) << 1) - | (p_motion->i_mv_x & 1) ); - - /* Chrominance Cr */ - MotionComponent( p_motion->p_source->p_u - + (p_mb->i_c_x + ((p_motion->i_mv_x/2) >> 1)) - + ((p_mb->i_motion_c_y + p_motion->i_offset - + ((p_motion->i_mv_y) >> 1)) - + p_motion->b_source_field) - * p_mb->p_picture->i_chroma_width, - p_mb->p_picture->p_u - + (p_mb->i_c_x) - + (p_mb->i_motion_c_y + p_motion->b_dest_field) - * p_mb->p_picture->i_chroma_width, - 8, p_motion->i_height, p_mb->i_c_stride, - (p_motion->b_average << 2) - | ((p_motion->i_mv_y & 1) << 1) - | ((p_motion->i_mv_x/2) & 1) ); - - /* Chrominance Cb */ - MotionComponent( p_motion->p_source->p_v - + (p_mb->i_c_x + ((p_motion->i_mv_x/2) >> 1)) - + ((p_mb->i_motion_c_y + p_motion->i_offset - + ((p_motion->i_mv_y) >> 1)) - + p_motion->b_source_field) - * p_mb->p_picture->i_chroma_width, - p_mb->p_picture->p_v - + (p_mb->i_c_x) - + (p_mb->i_motion_c_y + p_motion->b_dest_field) - * p_mb->p_picture->i_chroma_width, - 8, p_motion->i_height, p_mb->i_c_stride, - (p_motion->b_average << 2) - | ((p_motion->i_mv_y & 1) << 1) - | ((p_motion->i_mv_x/2) & 1) ); #endif } -/***************************************************************************** - * vdec_Motion444 : motion compensation for a 4:4:4 macroblock - *****************************************************************************/ -void vdec_Motion444( macroblock_t * p_mb, motion_arg_t * p_motion ) -{ -#if 0 - /* Luminance */ - MotionComponent( p_motion->p_source->p_y - + (p_mb->i_l_x + (p_motion->i_mv_x >> 1)) - + (p_mb->i_motion_l_y + p_motion->i_offset - + (p_motion->i_mv_y >> 1) - + p_motion->b_source_field) - * p_mb->p_picture->i_width, - p_mb->p_picture->p_y - + (p_mb->i_l_x) - + (p_mb->i_motion_l_y + p_motion->b_dest_field) - * p_mb->p_picture->i_width, - 16, p_motion->i_height, p_mb->i_l_stride, - (p_motion->b_average << 2) - | ((p_motion->i_mv_y & 1) << 1) - | (p_motion->i_mv_x & 1) ); - - /* Chrominance Cr */ - MotionComponent( p_motion->p_source->p_u - + (p_mb->i_c_x + (p_motion->i_mv_x >> 1)) - + ((p_mb->i_motion_c_y + p_motion->i_offset - + (p_motion->i_mv_y >> 1)) - + p_motion->b_source_field) - * p_mb->p_picture->i_chroma_width, - p_mb->p_picture->p_u - + (p_mb->i_c_x) - + (p_mb->i_motion_c_y + p_motion->b_dest_field) - * p_mb->p_picture->i_chroma_width, - 16, p_motion->i_height, p_mb->i_c_stride, - (p_motion->b_average << 2) - | ((p_motion->i_mv_y & 1) << 1) - | (p_motion->i_mv_x & 1) ); - - /* Chrominance Cb */ - MotionComponent( p_motion->p_source->p_v - + (p_mb->i_c_x + (p_motion->i_mv_x >> 1)) - + ((p_mb->i_motion_c_y + p_motion->i_offset - + (p_motion->i_mv_y >> 1)) - + p_motion->b_source_field) - * p_mb->p_picture->i_chroma_width, - p_mb->p_picture->p_v - + (p_mb->i_c_x) - + (p_mb->i_motion_c_y + p_motion->b_dest_field) - * p_mb->p_picture->i_chroma_width, - 16, p_motion->i_height, p_mb->i_c_stride, - (p_motion->b_average << 2) - | ((p_motion->i_mv_y & 1) << 1) - | (p_motion->i_mv_x & 1) ); -#endif -} diff --git a/src/video_decoder/video_decoder.c b/src/video_decoder/video_decoder.c index 06fa5f789c..7732b096e6 100644 --- a/src/video_decoder/video_decoder.c +++ b/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; } diff --git a/src/video_parser/video_fifo.c b/src/video_parser/video_fifo.c index 5cb176b3c6..3922355641 100644 --- a/src/video_parser/video_fifo.c +++ b/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 -} diff --git a/src/video_parser/video_parser.c b/src/video_parser/video_parser.c index 3177681bb3..6a6d32035f 100644 --- a/src/video_parser/video_parser.c +++ b/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 diff --git a/src/video_parser/vpar_blocks.c b/src/video_parser/vpar_blocks.c index 2ac9a05945..e7d68d37cf 100644 --- a/src/video_parser/vpar_blocks.c +++ b/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 ) ) diff --git a/src/video_parser/vpar_headers.c b/src/video_parser/vpar_headers.c index 159f3dbca2..44d46c63b0 100644 --- a/src/video_parser/vpar_headers.c +++ b/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 ); diff --git a/src/video_parser/vpar_motion.c b/src/video_parser/vpar_motion.c index dfd6475050..9f8de1c75d 100644 --- a/src/video_parser/vpar_motion.c +++ b/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" /* diff --git a/src/video_parser/vpar_synchro.c b/src/video_parser/vpar_synchro.c index a92079c041..c684b2250d 100644 --- a/src/video_parser/vpar_synchro.c +++ b/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