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 @@
#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. */
......
......@@ -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 );
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
/* 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
#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
......@@ -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;
#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 */
macroblock_t * buffer[VFIFO_SIZE + 1];
int i_start;
int i_end;
p_mb = P_buffer.pp_mb_free[ P_buffer.i_index-- ];
struct vpar_thread_s * p_vpar;
} video_fifo_t;
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 );
......@@ -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
*****************************************************************************
......
......@@ -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 */
......
......@@ -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;
......
......@@ -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
......
......@@ -33,24 +33,38 @@
#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;
if( !b_average )
{
/* Please note that b_average will be expanded at compile time */
switch( i_select )
{
case 4:
/* !xh, !yh, average */
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++ )
......@@ -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++ )
{
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_x+i_x1] = p_src[i_x+i_x1];
}
}
p_dest += i_x_step;
p_src += i_x_step;
p_dest += i_stride;
p_src += i_stride;
}
}
break;
case 0:
/* !xh, !yh, !average */
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++ )
......@@ -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++ )
{
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_src += i_x_step;
p_dest += i_stride;
p_src += i_stride;
}
}
break;
case 6:
/* !xh, yh, average */
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++ )
......@@ -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++ )
{
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;
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_step;
p_src += i_x_step;
p_dest += i_stride;
p_src += i_stride;
}
}
break;
case 2:
/* !xh, yh, !average */
case 3:
/* xh, yh, !average (3) */
for( i_y = 0; i_y < i_height; i_y += 4 )
{
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,
{
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;
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_step;
p_src += i_x_step;
p_dest += i_stride;
p_src += i_stride;
}
}
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_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,
{
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);
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_x_step;
p_src += i_x_step;
p_dest += i_stride;
p_src += i_stride;
}
}
break;
case 1:
/* xh, !yh, !average */
/* xh, !yh, average */
for( i_y = 0; i_y < i_height; i_y += 4 )
{
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,
{
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;
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_x_step;
p_src += i_x_step;
p_dest += i_stride;
p_src += i_stride;
}
}
break;
case 7:
/* xh, yh, average */
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++ )
......@@ -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++ )
{
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);
+ ((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_x_step;
p_src += i_x_step;
p_dest += i_stride;
p_src += i_stride;
}
}
break;
default:
/* xh, yh, !average (3) */
case 3:
/* xh, yh, average */
for( i_y = 0; i_y < i_height; i_y += 4 )
{
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,
{
for( i_x1 = 0; i_x1 < 8; i_x1++ )
{
p_dest[i_x+i_x1]
= ((unsigned int)(
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]
+ 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_x_step;
p_src += i_x_step;
p_dest += i_stride;
p_src += i_stride;
}
}
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;
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;
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 );
#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.b_average = 1;
args.i_offset = 0;
}
void vdec_MotionField16x8420( macroblock_t * p_mb )
{
FIELD16X8( Motion420 )
}
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 );
void vdec_MotionField16x8422( macroblock_t * p_mb )
{
FIELD16X8( Motion422 )
}
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;
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;
FRAMEFIELD( Motion420 )
}
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 );
void vdec_MotionFrameField422( macroblock_t * p_mb )
{
FRAMEFIELD( Motion422 )
}
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
}
......@@ -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,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;
/*
* Motion Compensation (ISO/IEC 13818-2 section 7.6)
*/
(*p_mb->pf_motion)( p_mb );
int i_x, i_y;
/* luminance */
for( i_b = 0; i_b < 4; i_b++ )
for( i_y = 0; i_y < 8; i_y++ )
{
/*
* 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++ )
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_c_stride );
*p_data = p_vdec->pi_crop[*p_data + *p_block++];
p_data++;
}
p_data += i_incr;
}
/*
* 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;
......@@ -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++ )
{
*p_data = p_vdec->pi_crop[*p_data + *p_block++];
p_data++;
*p_data++ = p_vdec->pi_crop[*p_block++];
}
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 )
{
int i_y;
#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 ); \
} \
} \
}
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++ )
{
/* ??? Why does the reference decoder add 128 ??? */
*p_data++ = p_vdec->pi_crop[*p_block++];
DECODEBLOCKS( AddBlock )
}
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 @@
#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
}
......@@ -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
......
......@@ -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,7 +707,8 @@ static __inline__ void MacroblockModes( vpar_thread_t * p_vpar,
}
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];
}
......@@ -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.
......@@ -890,21 +896,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] = p_data1
+ pi_y[p_vpar->mb.b_dct_type][i_b]
* 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 ) )
......
......@@ -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 );
......
......@@ -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"
/*
......
......@@ -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
......
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