Commit 796346ac authored by Christophe Massiot's avatar Christophe Massiot

* 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.
parent e6521494
...@@ -62,7 +62,7 @@ ...@@ -62,7 +62,7 @@
#define DEBUG_INTF #define DEBUG_INTF
#define DEBUG_INPUT #define DEBUG_INPUT
#define DEBUG_AUDIO #define DEBUG_AUDIO
#define DEBUG_VIDEO //#define DEBUG_VIDEO
/* Debugging log file - if defined, a file can be used to store all messages. If /* 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 * DEBUG_LOG_ONLY is defined, debug messages will only be printed to the log and
...@@ -285,6 +285,8 @@ ...@@ -285,6 +285,8 @@
#define VPAR_IDLE_SLEEP 100000 #define VPAR_IDLE_SLEEP 100000
#define VPAR_OUTMEM_SLEEP 50000
/* Number of macroblock buffers available. It should be always greater than /* Number of macroblock buffers available. It should be always greater than
* twice the number of macroblocks in a picture. VFIFO_SIZE + 1 should also * twice the number of macroblocks in a picture. VFIFO_SIZE + 1 should also
* be a power of two. */ * be a power of two. */
......
...@@ -19,7 +19,6 @@ struct vpar_thread_s; ...@@ -19,7 +19,6 @@ struct vpar_thread_s;
struct motion_arg_s; struct motion_arg_s;
typedef void (*f_motion_t)( struct macroblock_s* ); typedef void (*f_motion_t)( struct macroblock_s* );
typedef void (*f_chroma_motion_t)( struct macroblock_s*, struct motion_arg_s* );
/***************************************************************************** /*****************************************************************************
* Prototypes * Prototypes
...@@ -29,14 +28,21 @@ typedef void (*f_chroma_motion_t)( struct macroblock_s*, struct motion_arg_s* ); ...@@ -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 ); void vdec_MotionDummy( struct macroblock_s * p_mb );
/* Motion compensation */ /* Motion compensation */
void vdec_MotionFieldField( struct macroblock_s * p_mb ); void vdec_MotionFieldField420( struct macroblock_s * p_mb );
void vdec_MotionField16x8( struct macroblock_s * p_mb ); void vdec_MotionField16x8420( struct macroblock_s * p_mb );
void vdec_MotionFieldDMV( struct macroblock_s * p_mb ); void vdec_MotionFieldDMV( struct macroblock_s * p_mb );
void vdec_MotionFrameFrame( struct macroblock_s * p_mb ); void vdec_MotionFrameFrame420( struct macroblock_s * p_mb );
void vdec_MotionFrameField( struct macroblock_s * p_mb ); void vdec_MotionFrameField420( struct macroblock_s * p_mb );
void vdec_MotionFrameDMV( struct macroblock_s * p_mb );
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 ); void vdec_MotionFrameDMV( struct macroblock_s * p_mb );
\ No newline at end of file
/* 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 );
...@@ -74,13 +74,6 @@ typedef struct vdec_thread_s ...@@ -74,13 +74,6 @@ typedef struct vdec_thread_s
#endif #endif
} vdec_thread_t; } vdec_thread_t;
/*****************************************************************************
* Function pointers
*****************************************************************************/
#ifndef OLD_DECODER
typedef void (*f_addb_t)( vdec_thread_t *, dctelem_t*, yuv_data_t*, int );
#endif
/***************************************************************************** /*****************************************************************************
* Prototypes * Prototypes
*****************************************************************************/ *****************************************************************************/
...@@ -96,7 +89,4 @@ void vdec_DestroyThread ( vdec_thread_t *p_vdec /*, int *pi_sta ...@@ -96,7 +89,4 @@ void vdec_DestroyThread ( vdec_thread_t *p_vdec /*, int *pi_sta
#else #else
vdec_thread_t * vdec_CreateThread ( struct vpar_thread_s *p_vpar /*, int *pi_status */ ); vdec_thread_t * vdec_CreateThread ( struct vpar_thread_s *p_vpar /*, int *pi_status */ );
void vdec_DestroyThread ( vdec_thread_t *p_vdec /*, int *pi_status */ ); void vdec_DestroyThread ( vdec_thread_t *p_vdec /*, int *pi_status */ );
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 #endif
...@@ -27,46 +27,160 @@ ...@@ -27,46 +27,160 @@
& VFIFO_SIZE ) & VFIFO_SIZE )
/***************************************************************************** /*****************************************************************************
* video_fifo_t * vpar_GetMacroblock : return a macroblock to be decoded
*****************************************************************************
* This rotative FIFO contains undecoded macroblocks that are 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 */ macroblock_t * p_mb;
vlc_cond_t wait; /* fifo data conditional variable */
#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 );
}
/* buffer is an array of undec_picture_t pointers */ p_mb = P_buffer.pp_mb_free[ P_buffer.i_index-- ];
macroblock_t * buffer[VFIFO_SIZE + 1];
int i_start;
int i_end;
struct vpar_thread_s * p_vpar; vlc_mutex_unlock( &P_buffer.lock );
} video_fifo_t; #undef P_buffer
return( p_mb );
}
/***************************************************************************** /*****************************************************************************
* video_buffer_t * vpar_DecodeMacroblock : put a macroblock in the video fifo
***************************************************************************** *****************************************************************************/
* This structure enables the parser to maintain a list of free static __inline__ void vpar_DecodeMacroblock( video_fifo_t * p_fifo,
* macroblock_t structures 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]; /* Release the macroblock_t structure */
macroblock_t * pp_mb_free[VFIFO_SIZE+1]; /* this is a LIFO */ #define P_buffer p_fifo->p_vpar->vbuffer
int i_index; vlc_mutex_lock( &P_buffer.lock );
} video_buffer_t; P_buffer.pp_mb_free[ ++P_buffer.i_index ] = p_mb;
vlc_mutex_unlock( &P_buffer.lock );
#undef P_buffer
}
/***************************************************************************** /*****************************************************************************
* Prototypes * Prototypes
*****************************************************************************/ *****************************************************************************/
void vpar_InitFIFO( struct vpar_thread_s * p_vpar ); 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 );
...@@ -16,6 +16,41 @@ ...@@ -16,6 +16,41 @@
* "vpar_headers.h" * "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 * vpar_thread_t: video parser thread descriptor
***************************************************************************** *****************************************************************************
......
...@@ -80,9 +80,9 @@ ...@@ -80,9 +80,9 @@
#include "vdec_motion.h" #include "vdec_motion.h"
#include "vpar_blocks.h" #include "vpar_blocks.h"
#include "vpar_headers.h" #include "vpar_headers.h"
#include "video_fifo.h"
#include "vpar_synchro.h" #include "vpar_synchro.h"
#include "video_parser.h" #include "video_parser.h"
#include "video_fifo.h"
#endif #endif
/* Interface */ /* Interface */
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
typedef struct macroblock_s typedef struct macroblock_s
{ {
int i_mb_type; /* macroblock type */ int i_mb_type; /* macroblock type */
int i_coded_block_pattern;
int i_structure; int i_structure;
int i_current_structure; int i_current_structure;
boolean_t b_P_coding_type; /* Is it P_CODING_TYPE ? */ boolean_t b_P_coding_type; /* Is it P_CODING_TYPE ? */
...@@ -39,7 +40,6 @@ typedef struct macroblock_s ...@@ -39,7 +40,6 @@ typedef struct macroblock_s
/* Motion compensation information */ /* Motion compensation information */
f_motion_t pf_motion; /* function to use for motion comp */ 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_backward;
picture_t * p_forward; picture_t * p_forward;
int ppi_field_select[2][2]; int ppi_field_select[2][2];
...@@ -51,7 +51,6 @@ typedef struct macroblock_s ...@@ -51,7 +51,6 @@ typedef struct macroblock_s
boolean_t b_motion_field; boolean_t b_motion_field;
/* AddBlock information */ /* AddBlock information */
f_addb_t pf_addb[12]; /* pointer to the Add function */
yuv_data_t * p_data[12]; /* pointer to the position yuv_data_t * p_data[12]; /* pointer to the position
* in the final picture */ * in the final picture */
int i_addb_l_stride, i_addb_c_stride; int i_addb_l_stride, i_addb_c_stride;
......
...@@ -34,9 +34,9 @@ ...@@ -34,9 +34,9 @@
#include "vpar_blocks.h" #include "vpar_blocks.h"
#include "vpar_headers.h" #include "vpar_headers.h"
#include "video_fifo.h"
#include "vpar_synchro.h" #include "vpar_synchro.h"
#include "video_parser.h" #include "video_parser.h"
#include "video_fifo.h"
/* /*
* Local prototypes * Local prototypes
......
...@@ -33,24 +33,38 @@ ...@@ -33,24 +33,38 @@
#include "vpar_blocks.h" #include "vpar_blocks.h"
#include "vpar_headers.h" #include "vpar_headers.h"
#include "video_fifo.h"
#include "vpar_synchro.h" #include "vpar_synchro.h"
#include "video_parser.h" #include "video_parser.h"
#include "video_fifo.h"
/***************************************************************************** /*****************************************************************************
* vdec_MotionComponent : last stage of motion compensation * vdec_MotionComponent : last stage of motion compensation
*****************************************************************************/ *****************************************************************************/
static void __inline__ MotionComponent( yuv_data_t * p_src, yuv_data_t * p_dest, static __inline__ void MotionComponent(
int i_width, int i_height, int i_x_step, yuv_data_t * p_src, /* source block */
int i_x_stride, int i_select ) 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; int i_x, i_y, i_x1, i_y1;
unsigned int i_dummy; unsigned int i_dummy;
if( !b_average )
{
/* Please note that b_average will be expanded at compile time */
switch( i_select ) switch( i_select )
{ {
case 4: case 0:
/* !xh, !yh, average */ /* !xh, !yh, !average */
for( i_y = 0; i_y < i_height; i_y += 4 ) for( i_y = 0; i_y < i_height; i_y += 4 )
{ {
for( i_y1 = 0; i_y1 < 4; i_y1++ ) for( i_y1 = 0; i_y1 < 4; i_y1++ )
...@@ -59,18 +73,17 @@ static void __inline__ MotionComponent( yuv_data_t * p_src, yuv_data_t * p_dest, ...@@ -59,18 +73,17 @@ static void __inline__ MotionComponent( yuv_data_t * p_src, yuv_data_t * p_dest,
{ {
for( i_x1 = 0; i_x1 < 8; i_x1++ ) 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] = p_src[i_x+i_x1];
p_dest[i_x + i_x1] = (i_dummy + 1) >> 1;
} }
} }
p_dest += i_x_step; p_dest += i_stride;
p_src += i_x_step; p_src += i_stride;
} }
} }
break; break;
case 0: case 1:
/* !xh, !yh, !average */ /* xh, !yh, !average */
for( i_y = 0; i_y < i_height; i_y += 4 ) for( i_y = 0; i_y < i_height; i_y += 4 )
{ {
for( i_y1 = 0; i_y1 < 4; i_y1++ ) for( i_y1 = 0; i_y1 < 4; i_y1++ )
...@@ -79,17 +92,19 @@ static void __inline__ MotionComponent( yuv_data_t * p_src, yuv_data_t * p_dest, ...@@ -79,17 +92,19 @@ static void __inline__ MotionComponent( yuv_data_t * p_src, yuv_data_t * p_dest,
{ {
for( i_x1 = 0; i_x1 < 8; i_x1++ ) for( i_x1 = 0; i_x1 < 8; i_x1++ )
{ {
p_dest[i_x+i_x1] = p_src[i_x+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_x_step; p_dest += i_stride;
p_src += i_x_step; p_src += i_stride;
} }
} }
break; break;
case 6: case 2:
/* !xh, yh, average */ /* !xh, yh, !average */
for( i_y = 0; i_y < i_height; i_y += 4 ) for( i_y = 0; i_y < i_height; i_y += 4 )
{ {
for( i_y1 = 0; i_y1 < 4; i_y1++ ) for( i_y1 = 0; i_y1 < 4; i_y1++ )
...@@ -98,20 +113,19 @@ static void __inline__ MotionComponent( yuv_data_t * p_src, yuv_data_t * p_dest, ...@@ -98,20 +113,19 @@ static void __inline__ MotionComponent( yuv_data_t * p_src, yuv_data_t * p_dest,
{ {
for( i_x1 = 0; i_x1 < 8; i_x1++ ) for( i_x1 = 0; i_x1 < 8; i_x1++ )
{ {
i_dummy = p_dest[i_x+i_x1] p_dest[i_x+i_x1] = (unsigned int)(p_src[i_x+i_x1] + 1
+ ((unsigned int)(p_src[i_x+i_x1] + 1 + p_src[i_x+i_x1 + i_step])
+ p_src[i_x+i_x1 + i_x_stride]) >> 1); >> 1;
p_dest[i_x + i_x1] = (i_dummy + 1) >> 1;
} }
} }
p_dest += i_x_step; p_dest += i_stride;
p_src += i_x_step; p_src += i_stride;
} }
} }
break; break;
case 2: case 3:
/* !xh, yh, !average */ /* xh, yh, !average (3) */
for( i_y = 0; i_y < i_height; i_y += 4 ) for( i_y = 0; i_y < i_height; i_y += 4 )
{ {
for( i_y1 = 0; i_y1 < 4; i_y1++ ) for( i_y1 = 0; i_y1 < 4; i_y1++ )
...@@ -120,19 +134,30 @@ static void __inline__ MotionComponent( yuv_data_t * p_src, yuv_data_t * p_dest, ...@@ -120,19 +134,30 @@ static void __inline__ MotionComponent( yuv_data_t * p_src, yuv_data_t * p_dest,
{ {
for( i_x1 = 0; i_x1 < 8; i_x1++ ) 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_dest[i_x+i_x1]
+ p_src[i_x+i_x1 + i_x_stride]) = ((unsigned int)(
>> 1; 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_step; p_dest += i_stride;
p_src += i_x_step; p_src += i_stride;
} }
} }
break; break;
}
case 5: }
/* xh, !yh, average */ else
{
/* b_average */
switch( i_select )
{
case 0:
/* !xh, !yh, average */
for( i_y = 0; i_y < i_height; i_y += 4 ) for( i_y = 0; i_y < i_height; i_y += 4 )
{ {
for( i_y1 = 0; i_y1 < 4; i_y1++ ) for( i_y1 = 0; i_y1 < 4; i_y1++ )
...@@ -141,20 +166,18 @@ static void __inline__ MotionComponent( yuv_data_t * p_src, yuv_data_t * p_dest, ...@@ -141,20 +166,18 @@ static void __inline__ MotionComponent( yuv_data_t * p_src, yuv_data_t * p_dest,
{ {
for( i_x1 = 0; i_x1 < 8; i_x1++ ) for( i_x1 = 0; i_x1 < 8; i_x1++ )
{ {
i_dummy = p_dest[i_x+i_x1] i_dummy = p_dest[i_x + i_x1] + p_src[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_x + i_x1] = (i_dummy + 1) >> 1;
} }
} }
p_dest += i_x_step; p_dest += i_stride;
p_src += i_x_step; p_src += i_stride;
} }
} }
break; break;
case 1: case 1:
/* xh, !yh, !average */ /* xh, !yh, average */
for( i_y = 0; i_y < i_height; i_y += 4 ) for( i_y = 0; i_y < i_height; i_y += 4 )
{ {
for( i_y1 = 0; i_y1 < 4; i_y1++ ) for( i_y1 = 0; i_y1 < 4; i_y1++ )
...@@ -163,19 +186,20 @@ static void __inline__ MotionComponent( yuv_data_t * p_src, yuv_data_t * p_dest, ...@@ -163,19 +186,20 @@ static void __inline__ MotionComponent( yuv_data_t * p_src, yuv_data_t * p_dest,
{ {
for( i_x1 = 0; i_x1 < 8; i_x1++ ) for( i_x1 = 0; i_x1 < 8; i_x1++ )
{ {
p_dest[i_x+i_x1] = (unsigned int)(p_src[i_x+i_x1] i_dummy = p_dest[i_x+i_x1]
+ p_src[i_x+i_x1 + 1] + 1) + ((unsigned int)(p_src[i_x+i_x1]
>> 1; + p_src[i_x+i_x1 + 1] + 1) >> 1);
p_dest[i_x + i_x1] = (i_dummy + 1) >> 1;
} }
} }
p_dest += i_x_step; p_dest += i_stride;
p_src += i_x_step; p_src += i_stride;
} }
} }
break; break;
case 7: case 2:
/* xh, yh, average */ /* !xh, yh, average */
for( i_y = 0; i_y < i_height; i_y += 4 ) for( i_y = 0; i_y < i_height; i_y += 4 )
{ {
for( i_y1 = 0; i_y1 < 4; i_y1++ ) for( i_y1 = 0; i_y1 < 4; i_y1++ )
...@@ -185,23 +209,19 @@ static void __inline__ MotionComponent( yuv_data_t * p_src, yuv_data_t * p_dest, ...@@ -185,23 +209,19 @@ static void __inline__ MotionComponent( yuv_data_t * p_src, yuv_data_t * p_dest,
for( i_x1 = 0; i_x1 < 8; i_x1++ ) for( i_x1 = 0; i_x1 < 8; i_x1++ )
{ {
i_dummy = p_dest[i_x+i_x1] i_dummy = p_dest[i_x+i_x1]
+ ((unsigned int)( + ((unsigned int)(p_src[i_x+i_x1] + 1
p_src[i_x+i_x1] + p_src[i_x+i_x1 + i_step]) >> 1);
+ 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; p_dest[i_x + i_x1] = (i_dummy + 1) >> 1;
} }
} }
p_dest += i_x_step; p_dest += i_stride;
p_src += i_x_step; p_src += i_stride;
} }
} }
break; break;
default: case 3:
/* xh, yh, !average (3) */ /* xh, yh, average */
for( i_y = 0; i_y < i_height; i_y += 4 ) for( i_y = 0; i_y < i_height; i_y += 4 )
{ {
for( i_y1 = 0; i_y1 < 4; i_y1++ ) for( i_y1 = 0; i_y1 < 4; i_y1++ )
...@@ -210,27 +230,235 @@ static void __inline__ MotionComponent( yuv_data_t * p_src, yuv_data_t * p_dest, ...@@ -210,27 +230,235 @@ static void __inline__ MotionComponent( yuv_data_t * p_src, yuv_data_t * p_dest,
{ {
for( i_x1 = 0; i_x1 < 8; i_x1++ ) for( i_x1 = 0; i_x1 < 8; i_x1++ )
{ {
p_dest[i_x+i_x1] i_dummy = p_dest[i_x+i_x1]
= ((unsigned int)( + ((unsigned int)(
p_src[i_x+i_x1] p_src[i_x+i_x1]
+ p_src[i_x+i_x1 + 1] + p_src[i_x+i_x1 + 1]
+ p_src[i_x+i_x1 + i_x_stride] + p_src[i_x+i_x1 + i_step]
+ p_src[i_x+i_x1 + i_x_stride + 1] + p_src[i_x+i_x1 + i_step + 1]
+ 2) >> 2); + 2) >> 2);
p_dest[i_x + i_x1] = (i_dummy + 1) >> 1;
} }
} }
p_dest += i_x_step; p_dest += i_stride;
p_src += i_x_step; p_src += i_stride;
} }
} }
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) * 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 ppi_dmv[2][2],
int i_mv_x, int i_mv_y ) int i_mv_x, int i_mv_y )
{ {
...@@ -272,17 +500,6 @@ static void __inline__ DualPrimeArithmetic( macroblock_t * p_mb, ...@@ -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 * vdec_MotionDummy : motion compensation for an intra macroblock
*****************************************************************************/ *****************************************************************************/
...@@ -294,103 +511,141 @@ void vdec_MotionDummy( macroblock_t * p_mb ) ...@@ -294,103 +511,141 @@ void vdec_MotionDummy( macroblock_t * p_mb )
/***************************************************************************** /*****************************************************************************
* vdec_MotionFieldField : motion compensation for field motion type (field) * vdec_MotionFieldField : motion compensation for field motion type (field)
*****************************************************************************/ *****************************************************************************/
void vdec_MotionFieldField( macroblock_t * p_mb ) #define FIELDFIELD( MOTION ) \
{ picture_t * p_pred; \
#if 1 \
motion_arg_t args; if( p_mb->i_mb_type & MB_MOTION_FORWARD ) \
{ \
args.i_height = 16; if( p_mb->b_P_coding_type \
args.b_average = 0; && (p_mb->i_current_structure == FRAME_STRUCTURE) \
args.b_dest_field = p_mb->b_motion_field; && (p_mb->b_motion_field != p_mb->ppi_field_select[0][0]) )\
args.i_offset = 0; p_pred = p_mb->p_picture; \
args.i_l_x_step = p_mb->i_l_stride; else \
args.i_c_x_step = p_mb->i_c_stride; 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 ) void vdec_MotionFieldField420( macroblock_t * p_mb )
{ {
if( p_mb->b_P_coding_type FIELDFIELD( Motion420 )
&& (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 );
args.b_average = 1; void vdec_MotionFieldField422( macroblock_t * p_mb )
} {
FIELDFIELD( Motion422 )
}
if( p_mb->i_mb_type & MB_MOTION_BACKWARD ) void vdec_MotionFieldField444( macroblock_t * p_mb )
{ {
args.b_source_field = p_mb->ppi_field_select[0][1]; FIELDFIELD( Motion444 )
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
} }
/***************************************************************************** /*****************************************************************************
* 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 ) #define FIELD16X8( MOTION ) \
{ { \
#if 1 picture_t * p_pred; \
motion_arg_t args; \
if( p_mb->i_mb_type & MB_MOTION_FORWARD ) \
args.i_height = 8; { \
args.b_average = 0; if( p_mb->b_P_coding_type \
args.b_dest_field = p_mb->b_motion_field; && (p_mb->i_current_structure == FRAME_STRUCTURE) \
args.i_offset = 0; && (p_mb->b_motion_field != p_mb->ppi_field_select[0][0]) )\
args.i_l_x_step = p_mb->i_l_stride; p_pred = p_mb->p_picture; \
args.i_c_x_step = p_mb->i_c_stride; else \
p_pred = p_mb->p_forward; \
if( p_mb->i_mb_type & MB_MOTION_FORWARD ) \
{ MOTION( p_mb, p_pred, p_mb->ppi_field_select[0][0], \
if( p_mb->b_P_coding_type p_mb->b_motion_field, \
&& (p_mb->i_current_structure == FRAME_STRUCTURE) p_mb->pppi_motion_vectors[0][0][0], \
&& (p_mb->b_motion_field != p_mb->ppi_field_select[0][0]) ) p_mb->pppi_motion_vectors[0][0][1], \
args.p_source = p_mb->p_picture; p_mb->i_l_stride, p_mb->i_c_stride, 8, 0, 0 ); \
else \
args.p_source = p_mb->p_forward; if( p_mb->b_P_coding_type \
args.b_source_field = p_mb->ppi_field_select[0][0]; && (p_mb->i_current_structure == FRAME_STRUCTURE) \
args.i_mv_x = p_mb->pppi_motion_vectors[0][0][0]; && (p_mb->b_motion_field != p_mb->ppi_field_select[1][0]) )\
args.i_mv_y = p_mb->pppi_motion_vectors[0][0][1]; p_pred = p_mb->p_picture; \
p_mb->pf_chroma_motion( p_mb, &args ); else \
p_pred = p_mb->p_forward; \
if( p_mb->b_P_coding_type \
&& (p_mb->i_current_structure == FRAME_STRUCTURE) MOTION( p_mb, p_pred, p_mb->ppi_field_select[1][0], \
&& (p_mb->b_motion_field != p_mb->ppi_field_select[1][0]) ) p_mb->b_motion_field, \
args.p_source = p_mb->p_picture; p_mb->pppi_motion_vectors[1][0][0], \
else p_mb->pppi_motion_vectors[1][0][1], \
args.p_source = p_mb->p_forward; p_mb->i_l_stride, p_mb->i_c_stride, 8, 8, 0 ); \
args.b_source_field = p_mb->ppi_field_select[1][0]; \
args.i_mv_x = p_mb->pppi_motion_vectors[1][0][0]; if( p_mb->i_mb_type & MB_MOTION_BACKWARD ) \
args.i_mv_y = p_mb->pppi_motion_vectors[1][0][1]; { \
args.i_offset = 8; MOTION( p_mb, p_mb->p_backward, \
p_mb->pf_chroma_motion( p_mb, &args ); 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.b_average = 1; void vdec_MotionField16x8420( macroblock_t * p_mb )
args.i_offset = 0; {
} FIELD16X8( Motion420 )
}
if( p_mb->i_mb_type & MB_MOTION_BACKWARD ) void vdec_MotionField16x8422( macroblock_t * p_mb )
{ {
args.p_source = p_mb->p_backward; FIELD16X8( Motion422 )
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]; void vdec_MotionField16x8444( macroblock_t * p_mb )
args.i_mv_x = p_mb->pppi_motion_vectors[1][1][0]; {
args.i_mv_y = p_mb->pppi_motion_vectors[1][1][1]; FIELD16X8( Motion444 )
args.i_offset = 8;
p_mb->pf_chroma_motion( p_mb, &args );
}
#endif
} }
/***************************************************************************** /*****************************************************************************
...@@ -398,6 +653,7 @@ void vdec_MotionField16x8( macroblock_t * p_mb ) ...@@ -398,6 +653,7 @@ void vdec_MotionField16x8( macroblock_t * p_mb )
*****************************************************************************/ *****************************************************************************/
void vdec_MotionFieldDMV( macroblock_t * p_mb ) void vdec_MotionFieldDMV( macroblock_t * p_mb )
{ {
#if 0
/* This is necessarily a MOTION_FORWARD only macroblock */ /* This is necessarily a MOTION_FORWARD only macroblock */
motion_arg_t args; motion_arg_t args;
picture_t * p_pred; picture_t * p_pred;
...@@ -430,94 +686,117 @@ void vdec_MotionFieldDMV( macroblock_t * p_mb ) ...@@ -430,94 +686,117 @@ void vdec_MotionFieldDMV( macroblock_t * p_mb )
args.i_mv_x = ppi_dmv[0][0]; args.i_mv_x = ppi_dmv[0][0];
args.i_mv_y = ppi_dmv[0][1]; args.i_mv_y = ppi_dmv[0][1];
p_mb->pf_chroma_motion( p_mb, &args ); 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 FRAMEFRAME( Motion420 )
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 );
args.b_average = 1; void vdec_MotionFrameFrame422( macroblock_t * p_mb )
} {
FRAMEFRAME( Motion422 )
}
if( p_mb->i_mb_type & MB_MOTION_BACKWARD ) void vdec_MotionFrameFrame444( macroblock_t * p_mb )
{ {
args.p_source = p_mb->p_backward; FRAMEFRAME( Motion444 )
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
} }
/***************************************************************************** /*****************************************************************************
* 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 FRAMEFIELD( Motion420 )
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;
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;
}
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]; void vdec_MotionFrameField422( macroblock_t * p_mb )
args.b_dest_field = 0; {
args.i_mv_x = p_mb->pppi_motion_vectors[0][1][0]; FRAMEFIELD( Motion422 )
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]; void vdec_MotionFrameField444( macroblock_t * p_mb )
args.b_dest_field = 1; {
args.i_mv_x = p_mb->pppi_motion_vectors[1][1][0]; FRAMEFIELD( Motion444 )
args.i_mv_y = p_mb->pppi_motion_vectors[1][1][1];
p_mb->pf_chroma_motion( p_mb, &args );
}
#endif
} }
/***************************************************************************** /*****************************************************************************
...@@ -525,6 +804,7 @@ void vdec_MotionFrameField( macroblock_t * p_mb ) ...@@ -525,6 +804,7 @@ void vdec_MotionFrameField( macroblock_t * p_mb )
*****************************************************************************/ *****************************************************************************/
void vdec_MotionFrameDMV( macroblock_t * p_mb ) void vdec_MotionFrameDMV( macroblock_t * p_mb )
{ {
#if 0
/* This is necessarily a MOTION_FORWARD only macroblock */ /* This is necessarily a MOTION_FORWARD only macroblock */
motion_arg_t args; motion_arg_t args;
int ppi_dmv[2][2]; int ppi_dmv[2][2];
...@@ -567,180 +847,6 @@ void vdec_MotionFrameDMV( macroblock_t * p_mb ) ...@@ -567,180 +847,6 @@ void vdec_MotionFrameDMV( macroblock_t * p_mb )
args.i_mv_x = ppi_dmv[1][0]; args.i_mv_x = ppi_dmv[1][0];
args.i_mv_y = ppi_dmv[1][1]; args.i_mv_y = ppi_dmv[1][1];
p_mb->pf_chroma_motion( p_mb, &args ); 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 #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
}
...@@ -37,9 +37,9 @@ ...@@ -37,9 +37,9 @@
#include "vpar_blocks.h" #include "vpar_blocks.h"
#include "vpar_headers.h" #include "vpar_headers.h"
#include "video_fifo.h"
#include "vpar_synchro.h" #include "vpar_synchro.h"
#include "video_parser.h" #include "video_parser.h"
#include "video_fifo.h"
/* /*
* Local prototypes * Local prototypes
...@@ -165,54 +165,6 @@ static int InitThread( vdec_thread_t *p_vdec ) ...@@ -165,54 +165,6 @@ static int InitThread( vdec_thread_t *p_vdec )
return( 0 ); 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 * ErrorThread: RunThread() error loop
******************************************************************************* *******************************************************************************
...@@ -244,60 +196,29 @@ static void EndThread( vdec_thread_t *p_vdec ) ...@@ -244,60 +196,29 @@ 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 ) static __inline__ void AddBlock( vdec_thread_t * p_vdec, dctelem_t * p_block,
yuv_data_t * p_data, int i_incr )
{ {
int i_b; int i_x, i_y;
/*
* Motion Compensation (ISO/IEC 13818-2 section 7.6)
*/
(*p_mb->pf_motion)( p_mb );
/* luminance */ for( i_y = 0; i_y < 8; i_y++ )
for( i_b = 0; i_b < 4; i_b++ )
{ {
/* for( i_x = 0; i_x < 8; i_x++ )
* 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++ )
{ {
/* *p_data = p_vdec->pi_crop[*p_data + *p_block++];
* Inverse DCT (ISO/IEC 13818-2 section Annex A) p_data++;
*/ }
(p_mb->pf_idct[i_b])( p_vdec, p_mb->ppi_blocks[i_b], p_data += i_incr;
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 * CopyBlock : copy 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 CopyBlock( vdec_thread_t * p_vdec, dctelem_t * p_block,
yuv_data_t * p_data, int i_incr )
{ {
int i_x, i_y; int i_x, i_y;
...@@ -305,36 +226,131 @@ void vdec_AddBlock( vdec_thread_t * p_vdec, dctelem_t * p_block, yuv_data_t * p_ ...@@ -305,36 +226,131 @@ void vdec_AddBlock( vdec_thread_t * p_vdec, dctelem_t * p_block, yuv_data_t * p_
{ {
for( i_x = 0; i_x < 8; i_x++ ) for( i_x = 0; i_x < 8; i_x++ )
{ {
*p_data = p_vdec->pi_crop[*p_data + *p_block++]; *p_data++ = p_vdec->pi_crop[*p_block++];
p_data++;
} }
p_data += i_incr; p_data += i_incr;
} }
} }
/******************************************************************************* /*******************************************************************************
* vdec_CopyBlock : copy a block * DecodeMacroblock : decode a macroblock of a picture
*******************************************************************************/ *******************************************************************************/
void vdec_CopyBlock( vdec_thread_t * p_vdec, dctelem_t * p_block, yuv_data_t * p_data, int i_incr ) #define DECODEBLOCKS( OPBLOCK ) \
{ { \
int i_y; 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 ); \
} \
} \
}
for( i_y = 0; i_y < 8; i_y++ ) static __inline__ void DecodeMacroblock( vdec_thread_t *p_vdec, macroblock_t * p_mb )
{
if( !(p_mb->i_mb_type & MB_INTRA) )
{ {
int i_x; /*
* Motion Compensation (ISO/IEC 13818-2 section 7.6)
*/
p_mb->pf_motion( p_mb );
for( i_x = 0; i_x < 8; i_x++ ) DECODEBLOCKS( AddBlock )
{
/* ??? Why does the reference decoder add 128 ??? */
*p_data++ = p_vdec->pi_crop[*p_block++];
} }
p_data += i_incr; else
{
DECODEBLOCKS( CopyBlock )
} }
/*
* Decoding is finished, release the macroblock and free
* unneeded memory.
*/
vpar_ReleaseMacroblock( &p_vdec->p_vpar->vfifo, p_mb );
} }
/******************************************************************************* /*******************************************************************************
* vdec_DummyBlock : dummy function that does nothing * 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;
} }
...@@ -33,9 +33,9 @@ ...@@ -33,9 +33,9 @@
#include "vpar_blocks.h" #include "vpar_blocks.h"
#include "vpar_headers.h" #include "vpar_headers.h"
#include "video_fifo.h"
#include "vpar_synchro.h" #include "vpar_synchro.h"
#include "video_parser.h" #include "video_parser.h"
#include "video_fifo.h"
/***************************************************************************** /*****************************************************************************
* vpar_InitFIFO : initialize the video FIFO * vpar_InitFIFO : initialize the video FIFO
...@@ -61,154 +61,3 @@ void vpar_InitFIFO( vpar_thread_t * p_vpar ) ...@@ -61,154 +61,3 @@ void vpar_InitFIFO( vpar_thread_t * p_vpar )
+ i_dummy; + 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
}
...@@ -35,9 +35,9 @@ ...@@ -35,9 +35,9 @@
#include "vpar_blocks.h" #include "vpar_blocks.h"
#include "vpar_headers.h" #include "vpar_headers.h"
#include "video_fifo.h"
#include "vpar_synchro.h" #include "vpar_synchro.h"
#include "video_parser.h" #include "video_parser.h"
#include "video_fifo.h"
/* /*
* Local prototypes * Local prototypes
......
...@@ -33,9 +33,9 @@ ...@@ -33,9 +33,9 @@
#include "vpar_blocks.h" #include "vpar_blocks.h"
#include "vpar_headers.h" #include "vpar_headers.h"
#include "video_fifo.h"
#include "vpar_synchro.h" #include "vpar_synchro.h"
#include "video_parser.h" #include "video_parser.h"
#include "video_fifo.h"
/* /*
...@@ -571,9 +571,6 @@ void vpar_InitDCTTables( vpar_thread_t * p_vpar ) ...@@ -571,9 +571,6 @@ void vpar_InitDCTTables( vpar_thread_t * p_vpar )
static __inline__ void InitMacroblock( vpar_thread_t * p_vpar, static __inline__ void InitMacroblock( vpar_thread_t * p_vpar,
macroblock_t * p_mb ) 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->p_picture = p_vpar->picture.p_picture;
p_mb->i_structure = p_vpar->picture.i_structure; p_mb->i_structure = p_vpar->picture.i_structure;
p_mb->i_current_structure = p_vpar->picture.i_current_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, ...@@ -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_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_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->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 ); 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) || if( (p_vpar->picture.i_coding_type == P_CODING_TYPE) ||
...@@ -649,9 +645,21 @@ static __inline__ int MacroblockAddressIncrement( vpar_thread_t * p_vpar ) ...@@ -649,9 +645,21 @@ static __inline__ int MacroblockAddressIncrement( vpar_thread_t * p_vpar )
static __inline__ void MacroblockModes( vpar_thread_t * p_vpar, static __inline__ void MacroblockModes( vpar_thread_t * p_vpar,
macroblock_t * p_mb ) macroblock_t * p_mb )
{ {
static f_motion_t pf_motion[2][4] = static f_motion_t pppf_motion[4][2][4] =
{ {NULL, vdec_MotionFieldField, vdec_MotionField16x8, vdec_MotionFieldDMV}, {
{NULL, vdec_MotionFrameField, vdec_MotionFrameFrame, vdec_MotionFrameDMV} }; { {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_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} }; static int ppi_mv_format[2][4] = { {0, 1, 1, 1}, {0, 1, 2, 1} };
...@@ -699,7 +707,8 @@ static __inline__ void MacroblockModes( vpar_thread_t * p_vpar, ...@@ -699,7 +707,8 @@ static __inline__ void MacroblockModes( vpar_thread_t * p_vpar,
} }
else else
{ {
p_mb->pf_motion = pf_motion[p_vpar->picture.b_frame_structure] 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_motion_type];
} }
...@@ -737,7 +746,6 @@ static __inline__ void MacroblockModes( vpar_thread_t * p_vpar, ...@@ -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, void vpar_ParseMacroblock( vpar_thread_t * p_vpar, int * pi_mb_address,
int i_mb_previous, int i_mb_base ) 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] = static f_decode_block_t pppf_decode_block[2][2] =
{ {vpar_DecodeMPEG1Non, vpar_DecodeMPEG1Intra}, { {vpar_DecodeMPEG1Non, vpar_DecodeMPEG1Intra},
{vpar_DecodeMPEG2Non, vpar_DecodeMPEG2Intra} }; {vpar_DecodeMPEG2Non, vpar_DecodeMPEG2Intra} };
...@@ -747,7 +755,6 @@ void vpar_ParseMacroblock( vpar_thread_t * p_vpar, int * pi_mb_address, ...@@ -747,7 +755,6 @@ void vpar_ParseMacroblock( vpar_thread_t * p_vpar, int * pi_mb_address,
int i_mb, i_b, i_mask; int i_mb, i_b, i_mask;
macroblock_t * p_mb; macroblock_t * p_mb;
f_addb_t pf_addb;
yuv_data_t * p_data1; yuv_data_t * p_data1;
yuv_data_t * p_data2; yuv_data_t * p_data2;
...@@ -764,8 +771,13 @@ i_count++; ...@@ -764,8 +771,13 @@ i_count++;
{ {
/* Skipped macroblock (ISO/IEC 13818-2 7.6.6). */ /* Skipped macroblock (ISO/IEC 13818-2 7.6.6). */
static int pi_dc_dct_reinit[4] = {128,256,512,1024}; static int pi_dc_dct_reinit[4] = {128,256,512,1024};
static f_motion_t pf_motion_skipped[4] = {NULL, vdec_MotionFieldField, static f_motion_t pf_motion_skipped[4][4] =
vdec_MotionFieldField, vdec_MotionFrameFrame}; {
{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). */ /* Reset DC predictors (7.2.1). */
p_vpar->slice.pi_dc_dct_pred[0] = p_vpar->slice.pi_dc_dct_pred[1] p_vpar->slice.pi_dc_dct_pred[0] = p_vpar->slice.pi_dc_dct_pred[1]
...@@ -788,16 +800,11 @@ i_count++; ...@@ -788,16 +800,11 @@ i_count++;
InitMacroblock( p_vpar, p_mb ); 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. */ /* 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_mb_type = MB_MOTION_FORWARD;
p_mb->i_coded_block_pattern = 0;
memset( p_mb->pppi_motion_vectors, 0, 8*sizeof(int) ); memset( p_mb->pppi_motion_vectors, 0, 8*sizeof(int) );
/* Set the field we use for motion compensation */ /* Set the field we use for motion compensation */
...@@ -859,17 +866,16 @@ if( 0 ) ...@@ -859,17 +866,16 @@ if( 0 )
if( p_vpar->mb.i_mb_type & MB_PATTERN ) 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 ); //fprintf( stderr, "pattern : %d\n", p_vpar->mb.i_coded_block_pattern );
} }
else else
{ {
int pi_coded_block_pattern[2] = {0, int pi_coded_block_pattern[2] = {0,
(1 << (4+p_vpar->sequence.i_chroma_nb_blocks)) - 1}; (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]; [p_vpar->mb.i_mb_type & MB_INTRA];
} }
pf_addb = ppf_addb_intra[p_vpar->mb.i_mb_type & MB_INTRA];
/* /*
* Effectively decode blocks. * Effectively decode blocks.
...@@ -890,21 +896,12 @@ if( 0 ) ...@@ -890,21 +896,12 @@ if( 0 )
[p_vpar->mb.i_mb_type & MB_INTRA]) [p_vpar->mb.i_mb_type & MB_INTRA])
( p_vpar, p_mb, i_b ); ( 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. */ /* Calculate block coordinates. */
p_mb->p_data[i_b] = p_data1 p_mb->p_data[i_b] = p_data1
+ pi_y[p_vpar->mb.b_dct_type][i_b] + pi_y[p_vpar->mb.b_dct_type][i_b]
* p_vpar->sequence.i_width * p_vpar->sequence.i_width
+ pi_x[i_b]; + 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 */ /* chrominance */
...@@ -929,21 +926,12 @@ if( 0 ) ...@@ -929,21 +926,12 @@ if( 0 )
[p_vpar->mb.i_mb_type & MB_INTRA]) [p_vpar->mb.i_mb_type & MB_INTRA])
( p_vpar, p_mb, i_b ); ( 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. */ /* Calculate block coordinates. */
p_mb->p_data[i_b] = pp_data[i_b & 1] p_mb->p_data[i_b] = pp_data[i_b & 1]
+ pi_y[p_vpar->mb.b_dct_type][i_b] + pi_y[p_vpar->mb.b_dct_type][i_b]
* p_vpar->sequence.i_chroma_width * p_vpar->sequence.i_chroma_width
+ pi_x[i_b]; + 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 ) ) if( !( p_vpar->mb.i_mb_type & MB_INTRA ) )
......
...@@ -33,10 +33,10 @@ ...@@ -33,10 +33,10 @@
#include "vpar_blocks.h" #include "vpar_blocks.h"
#include "vpar_headers.h" #include "vpar_headers.h"
#include "video_fifo.h"
#include "vpar_synchro.h" #include "vpar_synchro.h"
#include "video_parser.h" #include "video_parser.h"
#include "vpar_motion.h" #include "vpar_motion.h"
#include "video_fifo.h"
/* /*
* Local prototypes * Local prototypes
...@@ -681,7 +681,7 @@ static void PictureHeader( vpar_thread_t * p_vpar ) ...@@ -681,7 +681,7 @@ static void PictureHeader( vpar_thread_t * p_vpar )
{ {
return; return;
} }
mwait( VPAR_IDLE_SLEEP ); msleep( VPAR_OUTMEM_SLEEP );
} }
/* Initialize values. */ /* Initialize values. */
...@@ -703,7 +703,7 @@ static void PictureHeader( vpar_thread_t * p_vpar ) ...@@ -703,7 +703,7 @@ static void PictureHeader( vpar_thread_t * p_vpar )
vlc_mutex_init( &p_vpar->picture.p_picture->lock_deccount ); vlc_mutex_init( &p_vpar->picture.p_picture->lock_deccount );
memset( p_vpar->picture.pp_mb, 0, MAX_MB ); memset( p_vpar->picture.pp_mb, 0, MAX_MB );
/* FIXME ! remove asap */ /* FIXME ! remove asap */
memset( P_picture->p_data, 0, (p_vpar->sequence.i_mb_size*384)); //memset( P_picture->p_data, 0, (p_vpar->sequence.i_mb_size*384));
/* Update the reference pointers. */ /* Update the reference pointers. */
ReferenceUpdate( p_vpar, p_vpar->picture.i_coding_type, P_picture ); ReferenceUpdate( p_vpar, p_vpar->picture.i_coding_type, P_picture );
......
...@@ -35,10 +35,10 @@ ...@@ -35,10 +35,10 @@
#include "vpar_blocks.h" #include "vpar_blocks.h"
#include "vpar_headers.h" #include "vpar_headers.h"
#include "video_fifo.h"
#include "vpar_synchro.h" #include "vpar_synchro.h"
#include "video_parser.h" #include "video_parser.h"
#include "vpar_motion.h" #include "vpar_motion.h"
#include "video_fifo.h"
/* /*
......
...@@ -33,9 +33,9 @@ ...@@ -33,9 +33,9 @@
#include "vpar_blocks.h" #include "vpar_blocks.h"
#include "vpar_headers.h" #include "vpar_headers.h"
#include "video_fifo.h"
#include "vpar_synchro.h" #include "vpar_synchro.h"
#include "video_parser.h" #include "video_parser.h"
#include "video_fifo.h"
#define MAX_COUNT 3 #define MAX_COUNT 3
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment