Commit 93ff7f1c authored by Christophe Massiot's avatar Christophe Massiot

* Optimisation du parseur ;

* R�activation du motion DMV ;

Pour info, on torche largement le d�codeur de r�f�rence (50 %).
parent e05c74bf
......@@ -23,26 +23,21 @@ typedef void (*f_motion_t)( struct macroblock_s* );
/*****************************************************************************
* Prototypes
*****************************************************************************/
/* Empty function for intra macroblocks motion compensation */
void vdec_MotionDummy( struct macroblock_s * p_mb );
/* Motion compensation */
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_MotionFieldDMV420( 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_MotionFrameDMV420( 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_MotionFieldDMV422( 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_MotionFrameDMV422( 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_MotionFieldDMV444( 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
void vdec_MotionFrameDMV444( struct macroblock_s * p_mb );
\ No newline at end of file
......@@ -74,6 +74,10 @@ static __inline__ macroblock_t * vpar_NewMacroblock( video_fifo_t * p_fifo )
/* No more structures available. This should not happen ! */
intf_DbgMsg("vpar debug: macroblock list is empty, delaying\n");
vlc_mutex_unlock( &P_buffer.lock );
if( p_fifo->p_vpar->b_die )
{
return( NULL );
}
msleep(VPAR_OUTMEM_SLEEP);
vlc_mutex_lock( &P_buffer.lock );
}
......
......@@ -15,6 +15,12 @@
* "video_fifo.h"
*****************************************************************************/
/*****************************************************************************
* Function pointers
*****************************************************************************/
typedef void (*f_parse_mb_t)( struct vpar_thread_s*, int *, int, int,
boolean_t, int, int, int, boolean_t);
/*****************************************************************************
* macroblock_t : information on a macroblock
*****************************************************************************/
......@@ -22,16 +28,8 @@ 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 ? */
picture_t * p_picture;
int i_l_x, i_l_y; /* position of macroblock (lum) */
int i_c_x, i_c_y; /* position of macroblock (chroma) */
int i_chroma_nb_blocks; /* nb of bks for a chr comp */
int i_l_stride; /* number of yuv_data_t to ignore
* when changing lines */
int i_c_stride; /* idem, for chroma */
picture_t * p_picture;
/* IDCT information */
dctelem_t ppi_blocks[12][64]; /* blocks */
......@@ -44,16 +42,24 @@ typedef struct macroblock_s
picture_t * p_forward;
int ppi_field_select[2][2];
int pppi_motion_vectors[2][2][2];
int pi_dm_vector[2];
boolean_t b_top_field_first;
int ppi_dmv[2][2];
int i_l_x, i_c_x;
int i_motion_l_y;
int i_motion_c_y;
boolean_t b_motion_field;
int i_l_stride; /* number of yuv_data_t to
* ignore when changing line */
int i_c_stride; /* idem, for chroma */
boolean_t b_P_second; /* Second field of a P picture ?
* (used to determine the predicting
* frame) */
boolean_t b_motion_field; /* Field we are predicting
* (top field or bottom field) */
/* AddBlock information */
yuv_data_t * p_data[12]; /* pointer to the position
* in the final picture */
int i_addb_l_stride, i_addb_c_stride;
/* nb of coeffs to jump when changing lines */
} macroblock_t;
/*****************************************************************************
......@@ -61,12 +67,8 @@ typedef struct macroblock_s
*****************************************************************************/
typedef struct
{
int i_mb_type, i_motion_type, i_mv_count, i_mv_format;
boolean_t b_dmv;
/* Macroblock Type */
int i_coded_block_pattern;
boolean_t b_dct_type;
int i_motion_type, i_mv_count, i_mv_format;
boolean_t b_dmv, b_dct_type;
int i_l_x, i_l_y, i_c_x, i_c_y;
} macroblock_parsing_t;
......@@ -139,12 +141,53 @@ void vpar_InitPMBType( struct vpar_thread_s * p_vpar );
void vpar_InitBMBType( struct vpar_thread_s * p_vpar );
void vpar_InitCodedPattern( struct vpar_thread_s * p_vpar );
void vpar_InitDCTTables( struct vpar_thread_s * p_vpar );
void vpar_ParseMacroblock( struct vpar_thread_s * p_vpar, int * pi_mb_address,
int i_mb_previous, int i_mb_base );
int vpar_CodedPattern420( struct vpar_thread_s* p_vpar );
int vpar_CodedPattern422( struct vpar_thread_s* p_vpar );
int vpar_CodedPattern444( struct vpar_thread_s* p_vpar );
int vpar_IMBType( struct vpar_thread_s* p_vpar );
int vpar_PMBType( struct vpar_thread_s* p_vpar );
int vpar_BMBType( struct vpar_thread_s* p_vpar );
int vpar_DMBType( struct vpar_thread_s* p_vpar );
void vpar_ParseMacroblockGENERIC( struct vpar_thread_s* p_vpar, int * pi_mb_address,
int i_mb_previous, int i_mb_base,
boolean_t b_mpeg2, int i_coding_type,
int i_chroma_format, int i_structure,
boolean_t b_second_field );
void vpar_ParseMacroblock2I420F0( struct vpar_thread_s* p_vpar, int * pi_mb_address,
int i_mb_previous, int i_mb_base,
boolean_t b_mpeg2, int i_coding_type,
int i_chroma_format, int i_structure,
boolean_t b_second_field );
void vpar_ParseMacroblock2P420F0( struct vpar_thread_s* p_vpar, int * pi_mb_address,
int i_mb_previous, int i_mb_base,
boolean_t b_mpeg2, int i_coding_type,
int i_chroma_format, int i_structure,
boolean_t b_second_field );
void vpar_ParseMacroblock2B420F0( struct vpar_thread_s* p_vpar, int * pi_mb_address,
int i_mb_previous, int i_mb_base,
boolean_t b_mpeg2, int i_coding_type,
int i_chroma_format, int i_structure,
boolean_t b_second_field );
void vpar_ParseMacroblock2I420T0( struct vpar_thread_s* p_vpar, int * pi_mb_address,
int i_mb_previous, int i_mb_base,
boolean_t b_mpeg2, int i_coding_type,
int i_chroma_format, int i_structure,
boolean_t b_second_field );
void vpar_ParseMacroblock2P420T0( struct vpar_thread_s* p_vpar, int * pi_mb_address,
int i_mb_previous, int i_mb_base,
boolean_t b_mpeg2, int i_coding_type,
int i_chroma_format, int i_structure,
boolean_t b_second_field );
void vpar_ParseMacroblock2B420T0( struct vpar_thread_s* p_vpar, int * pi_mb_address,
int i_mb_previous, int i_mb_base,
boolean_t b_mpeg2, int i_coding_type,
int i_chroma_format, int i_structure,
boolean_t b_second_field );
void vpar_ParseMacroblock2I420B1( struct vpar_thread_s* p_vpar, int * pi_mb_address,
int i_mb_previous, int i_mb_base,
boolean_t b_mpeg2, int i_coding_type,
int i_chroma_format, int i_structure,
boolean_t b_second_field );
void vpar_ParseMacroblock2P420B1( struct vpar_thread_s* p_vpar, int * pi_mb_address,
int i_mb_previous, int i_mb_base,
boolean_t b_mpeg2, int i_coding_type,
int i_chroma_format, int i_structure,
boolean_t b_second_field );
void vpar_ParseMacroblock2B420B1( struct vpar_thread_s* p_vpar, int * pi_mb_address,
int i_mb_previous, int i_mb_base,
boolean_t b_mpeg2, int i_coding_type,
int i_chroma_format, int i_structure,
boolean_t b_second_field );
......@@ -19,11 +19,8 @@
* Function pointers
*****************************************************************************/
struct vpar_thread_s;
struct macroblock_s;
typedef void (*f_slice_header_t)( struct vpar_thread_s*, int*, int, u32);
typedef int (*f_chroma_pattern_t)( struct vpar_thread_s* );
typedef int (*f_macroblock_type_t)( struct vpar_thread_s* );
/*****************************************************************************
* quant_matrix_t : Quantization Matrix
......@@ -50,8 +47,6 @@ typedef struct sequence_s
f_slice_header_t pf_slice_header;
quant_matrix_t intra_quant, nonintra_quant;
quant_matrix_t chroma_intra_quant, chroma_nonintra_quant;
void (*pf_decode_mv)( struct vpar_thread_s *, struct macroblock_s *, int );
f_chroma_pattern_t pf_decode_pattern;
/* Chromatic information */
unsigned int i_chroma_format;
......@@ -64,12 +59,12 @@ typedef struct sequence_s
picture_t * p_backward;
/* Copyright extension */
boolean_t b_copyright_flag; /* Whether the following
information is significant
or not. */
u8 i_copyright_id;
boolean_t b_original;
u64 i_copyright_nb;
boolean_t b_copyright_flag; /* Whether the following
information is significant
or not. */
u8 i_copyright_id;
boolean_t b_original;
u64 i_copyright_nb;
} sequence_t;
/*****************************************************************************
......@@ -89,6 +84,8 @@ typedef struct picture_parsing_s
boolean_t b_repeat_first_field;
int i_l_stride, i_c_stride;
f_parse_mb_t pf_parse_mb;
/* Used for second field management */
int i_current_structure;
......@@ -100,8 +97,6 @@ typedef struct picture_parsing_s
/* Relative to the current field */
int i_coding_type, i_structure;
boolean_t b_frame_structure;
boolean_t b_motion_field;
f_macroblock_type_t pf_macroblock_type;
boolean_t b_error;
} picture_parsing_t;
......
......@@ -455,59 +455,6 @@ static __inline__ void Motion444(
i_select, b_average );
}
/*****************************************************************************
* DualPrimeArithmetic : Dual Prime Additional arithmetic (7.6.3.6)
*****************************************************************************/
static __inline__ void DualPrimeArithmetic( macroblock_t * p_mb,
int ppi_dmv[2][2],
int i_mv_x, int i_mv_y )
{
if( p_mb->i_structure == FRAME_STRUCTURE )
{
if( p_mb->b_top_field_first )
{
/* vector for prediction of top field from bottom field */
ppi_dmv[0][0] = ((i_mv_x + (i_mv_x > 0)) >> 1) + p_mb->pi_dm_vector[0];
ppi_dmv[0][1] = ((i_mv_y + (i_mv_y > 0)) >> 1) + p_mb->pi_dm_vector[1] - 1;
/* vector for prediction of bottom field from top field */
ppi_dmv[1][0] = ((3*i_mv_x + (i_mv_x > 0)) >> 1) + p_mb->pi_dm_vector[0];
ppi_dmv[1][1] = ((3*i_mv_y + (i_mv_y > 0)) >> 1) + p_mb->pi_dm_vector[1] + 1;
}
else
{
/* vector for prediction of top field from bottom field */
ppi_dmv[0][0] = ((3*i_mv_x + (i_mv_x > 0)) >> 1) + p_mb->pi_dm_vector[0];
ppi_dmv[0][1] = ((3*i_mv_y + (i_mv_y > 0)) >> 1) + p_mb->pi_dm_vector[1] - 1;
/* vector for prediction of bottom field from top field */
ppi_dmv[1][0] = ((i_mv_x + (i_mv_x > 0)) >> 1) + p_mb->pi_dm_vector[0];
ppi_dmv[1][1] = ((i_mv_y + (i_mv_y > 0)) >> 1) + p_mb->pi_dm_vector[1] + 1;
}
}
else
{
/* vector for prediction from field of opposite 'parity' */
ppi_dmv[0][0] = ((i_mv_x + (i_mv_x > 0)) >> 1) + p_mb->pi_dm_vector[0];
ppi_dmv[0][1] = ((i_mv_y + (i_mv_y > 0)) >> 1) + p_mb->pi_dm_vector[1];
/* correct for vertical field shift */
if( p_mb->i_structure == TOP_FIELD )
ppi_dmv[0][1]--;
else
ppi_dmv[0][1]++;
}
}
/*****************************************************************************
* vdec_MotionDummy : motion compensation for an intra macroblock
*****************************************************************************/
void vdec_MotionDummy( macroblock_t * p_mb )
{
/* Nothing to do :) */
}
/*****************************************************************************
* vdec_MotionFieldField : motion compensation for field motion type (field)
*****************************************************************************/
......@@ -516,8 +463,7 @@ void vdec_MotionDummy( macroblock_t * p_mb )
\
if( p_mb->i_mb_type & MB_MOTION_FORWARD ) \
{ \
if( p_mb->b_P_coding_type \
&& (p_mb->i_current_structure == FRAME_STRUCTURE) \
if( p_mb->b_P_second \
&& (p_mb->b_motion_field != p_mb->ppi_field_select[0][0]) )\
p_pred = p_mb->p_picture; \
else \
......@@ -573,8 +519,7 @@ void vdec_MotionFieldField444( macroblock_t * p_mb )
\
if( p_mb->i_mb_type & MB_MOTION_FORWARD ) \
{ \
if( p_mb->b_P_coding_type \
&& (p_mb->i_current_structure == FRAME_STRUCTURE) \
if( p_mb->b_P_second \
&& (p_mb->b_motion_field != p_mb->ppi_field_select[0][0]) )\
p_pred = p_mb->p_picture; \
else \
......@@ -586,8 +531,7 @@ void vdec_MotionFieldField444( macroblock_t * p_mb )
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) \
if( p_mb->b_P_second \
&& (p_mb->b_motion_field != p_mb->ppi_field_select[1][0]) )\
p_pred = p_mb->p_picture; \
else \
......@@ -649,44 +593,45 @@ void vdec_MotionField16x8444( macroblock_t * p_mb )
}
/*****************************************************************************
* vdec_MotionFieldDMV : motion compensation for dmv motion type (field)
* vdec_MotionFieldDMVXXX : motion compensation for dmv motion type (field)
*****************************************************************************/
void vdec_MotionFieldDMV( macroblock_t * p_mb )
#define FIELDDMV( MOTION ) \
{ \
/* This is necessarily a MOTION_FORWARD only macroblock, in a P \
* picture. */ \
picture_t * p_pred; \
\
/* predict from field of same parity */ \
MOTION( p_mb, p_mb->p_forward, \
p_mb->b_motion_field, 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->b_P_second ) \
p_pred = p_mb->p_picture; \
else \
p_pred = p_mb->p_forward; \
\
/* predict from field of opposite parity */ \
MOTION( p_mb, p_pred, !p_mb->b_motion_field, p_mb->b_motion_field, \
p_mb->ppi_dmv[0][0], p_mb->ppi_dmv[0][1], \
p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 1 ); \
} /* FIELDDMV */
void vdec_MotionFieldDMV420( macroblock_t * p_mb )
{
#if 0
/* This is necessarily a MOTION_FORWARD only macroblock */
motion_arg_t args;
picture_t * p_pred;
int ppi_dmv[2][2];
args.i_height = 16;
args.b_average = 0;
args.b_dest_field = p_mb->b_motion_field;
args.i_offset = 0;
if( p_mb->i_current_structure == FRAME_STRUCTURE )
p_pred = p_mb->p_picture;
else
p_pred = p_mb->p_forward;
DualPrimeArithmetic( p_mb, ppi_dmv, p_mb->pppi_motion_vectors[0][0][0],
p_mb->pppi_motion_vectors[0][0][1] );
/* predict from field of same parity */
args.p_source = p_mb->p_forward;
args.b_source_field = p_mb->b_motion_field;
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 );
/* predict from field of opposite parity */
args.b_average = 1;
args.p_source = p_pred;
args.b_source_field = !p_mb->b_motion_field;
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
FIELDDMV( Motion420 )
}
void vdec_MotionFieldDMV422( macroblock_t * p_mb )
{
FIELDDMV( Motion422 )
}
void vdec_MotionFieldDMV444( macroblock_t * p_mb )
{
FIELDDMV( Motion444 )
}
/*****************************************************************************
......@@ -800,53 +745,49 @@ void vdec_MotionFrameField444( macroblock_t * p_mb )
}
/*****************************************************************************
* vdec_MotionFrameDMV : motion compensation for dmv motion type (frame)
* vdec_MotionFrameDMVXXX : motion compensation for dmv motion type (frame)
*****************************************************************************/
void vdec_MotionFrameDMV( macroblock_t * p_mb )
#define FRAMEDMV( MOTION ) \
{ \
/* This is necessarily a MOTION_FORWARD only macroblock, in a P \
* picture. */ \
\
/* predict top field from top field */ \
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], \
/* ????? >> 1 ? */ \
p_mb->i_l_stride << 1, p_mb->i_c_stride << 1, 8, 0, 0 ); \
\
/* predict and add to top field from bottom field */ \
MOTION( p_mb, p_mb->p_forward, 1, 0, \
p_mb->ppi_dmv[0][0], p_mb->ppi_dmv[0][1], \
p_mb->i_l_stride << 1, p_mb->i_c_stride << 1, 8, 0, 1 ); \
\
/* predict bottom field from bottom field */ \
MOTION( p_mb, p_mb->p_forward, 1, 1, \
p_mb->pppi_motion_vectors[0][0][0], \
p_mb->pppi_motion_vectors[0][0][1], \
/* ????? >> 1 ? */ \
p_mb->i_l_stride << 1, p_mb->i_c_stride << 1, 8, 0, 0 ); \
\
/* predict and add to bottom field from top field */ \
MOTION( p_mb, p_mb->p_forward, 1, 0, \
p_mb->ppi_dmv[1][0], p_mb->ppi_dmv[1][1], \
p_mb->i_l_stride << 1, p_mb->i_c_stride << 1, 8, 0, 1 ); \
} /* FRAMEDMV */
void vdec_MotionFrameDMV420( macroblock_t * p_mb )
{
#if 0
/* This is necessarily a MOTION_FORWARD only macroblock */
motion_arg_t args;
int ppi_dmv[2][2];
args.i_l_x_step = p_mb->i_l_stride << 1;
args.i_c_x_step = p_mb->i_c_stride << 1;
args.i_height = 8;
args.b_average = 0;
args.b_dest_field = 0;
args.i_offset = 0;
args.p_source = p_mb->p_forward;
DualPrimeArithmetic( p_mb, ppi_dmv, p_mb->pppi_motion_vectors[0][0][0],
p_mb->pppi_motion_vectors[0][0][1] );
/* predict top field from top field */
args.b_source_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] >> 1;
p_mb->pf_chroma_motion( p_mb, &args );
/* predict and add to top field from bottom field */
args.b_average = 1;
args.b_source_field = 1;
args.i_mv_x = ppi_dmv[0][0];
args.i_mv_y = ppi_dmv[0][1];
p_mb->pf_chroma_motion( p_mb, &args );
/* predict bottom field from bottom field */
args.b_average = 0;
args.b_dest_field = 1;
args.b_source_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] >> 1;
p_mb->pf_chroma_motion( p_mb, &args );
/* predict and add to bottom field from top field */
args.b_average = 1;
args.b_source_field = 1;
args.i_mv_x = ppi_dmv[1][0];
args.i_mv_y = ppi_dmv[1][1];
p_mb->pf_chroma_motion( p_mb, &args );
#endif
FRAMEDMV( Motion420 )
}
void vdec_MotionFrameDMV422( macroblock_t * p_mb )
{
FRAMEDMV( Motion422 )
}
void vdec_MotionFrameDMV444( macroblock_t * p_mb )
{
FRAMEDMV( Motion444 )
}
This diff is collapsed.
......@@ -389,9 +389,6 @@ static void SequenceHeader( vpar_thread_t * p_vpar )
if( ShowBits( &p_vpar->bit_stream, 32 ) == EXTENSION_START_CODE )
{
int i_dummy;
static f_chroma_pattern_t ppf_chroma_pattern[4] =
{NULL, vpar_CodedPattern420,
vpar_CodedPattern422, vpar_CodedPattern444};
/* Turn the MPEG2 flag on */
p_vpar->sequence.b_mpeg2 = 1;
......@@ -402,8 +399,6 @@ static void SequenceHeader( vpar_thread_t * p_vpar )
RemoveBits( &p_vpar->bit_stream, 12 );
p_vpar->sequence.b_progressive = GetBits( &p_vpar->bit_stream, 1 );
p_vpar->sequence.i_chroma_format = GetBits( &p_vpar->bit_stream, 2 );
p_vpar->sequence.pf_decode_pattern = ppf_chroma_pattern
[p_vpar->sequence.i_chroma_format];
p_vpar->sequence.i_width |= GetBits( &p_vpar->bit_stream, 2 ) << 12;
p_vpar->sequence.i_height |= GetBits( &p_vpar->bit_stream, 2 ) << 12;
/* bit_rate_extension, marker_bit, vbv_buffer_size_extension, low_delay */
......@@ -413,8 +408,6 @@ static void SequenceHeader( vpar_thread_t * p_vpar )
/* frame_rate_extension_d */
p_vpar->sequence.r_frame_rate *= (i_dummy + 1)
/ (GetBits( &p_vpar->bit_stream, 5 ) + 1);
p_vpar->sequence.pf_decode_mv = vpar_MPEG2MotionVector;
}
else
{
......@@ -423,9 +416,6 @@ static void SequenceHeader( vpar_thread_t * p_vpar )
p_vpar->sequence.b_mpeg2 = 0;
p_vpar->sequence.b_progressive = 1;
p_vpar->sequence.i_chroma_format = CHROMA_420;
p_vpar->sequence.pf_decode_pattern = vpar_CodedPattern420;
p_vpar->sequence.pf_decode_mv = vpar_MPEG1MotionVector;
}
/* Update sizes */
......@@ -513,9 +503,33 @@ static void GroupHeader( vpar_thread_t * p_vpar )
*****************************************************************************/
static void PictureHeader( vpar_thread_t * p_vpar )
{
static f_macroblock_type_t ppf_macroblock_type[5] = {NULL,
vpar_IMBType, vpar_PMBType,
vpar_BMBType, vpar_DMBType};
static f_parse_mb_t ppf_parse_mb[4][4][2] =
{
{
{NULL, NULL}, {NULL, NULL}, {NULL, NULL}, {NULL, NULL}
},
{
/* I_CODING_TYPE */
{NULL, NULL},
{vpar_ParseMacroblock2I420T0, vpar_ParseMacroblockGENERIC},
{vpar_ParseMacroblockGENERIC, vpar_ParseMacroblock2I420B1},
{vpar_ParseMacroblock2I420F0, vpar_ParseMacroblock2I420F0}
},
{
/* P_CODING_TYPE */
{NULL, NULL},
{vpar_ParseMacroblock2P420T0, vpar_ParseMacroblockGENERIC},
{vpar_ParseMacroblockGENERIC, vpar_ParseMacroblock2P420B1},
{vpar_ParseMacroblock2P420F0, vpar_ParseMacroblock2P420F0}
},
{
/* B_CODING_TYPE */
{NULL, NULL},
{vpar_ParseMacroblock2B420T0, vpar_ParseMacroblockGENERIC},
{vpar_ParseMacroblockGENERIC, vpar_ParseMacroblock2B420B1},
{vpar_ParseMacroblock2B420F0, vpar_ParseMacroblock2B420F0}
}
};
int i_structure;
int i_mb_address, i_mb_base;
......@@ -527,11 +541,10 @@ static void PictureHeader( vpar_thread_t * p_vpar )
RemoveBits( &p_vpar->bit_stream, 10 ); /* temporal_reference */
p_vpar->picture.i_coding_type = GetBits( &p_vpar->bit_stream, 3 );
p_vpar->picture.pf_macroblock_type = ppf_macroblock_type
[p_vpar->picture.i_coding_type];
RemoveBits( &p_vpar->bit_stream, 16 ); /* vbv_delay */
if( p_vpar->picture.i_coding_type == P_CODING_TYPE || p_vpar->picture.i_coding_type == B_CODING_TYPE )
if( p_vpar->picture.i_coding_type == P_CODING_TYPE
|| p_vpar->picture.i_coding_type == B_CODING_TYPE )
{
p_vpar->picture.pb_full_pel_vector[0] = GetBits( &p_vpar->bit_stream, 1 );
p_vpar->picture.i_forward_f_code = GetBits( &p_vpar->bit_stream, 3 );
......@@ -733,7 +746,7 @@ static void PictureHeader( vpar_thread_t * p_vpar )
p_vpar->picture.i_structure = i_structure;
/* Initialize picture data for decoding. */
if( (p_vpar->picture.b_motion_field = (i_structure == BOTTOM_FIELD)) )
if( i_structure == BOTTOM_FIELD )
{
i_mb_base = p_vpar->sequence.i_mb_size >> 1;
p_vpar->mb.i_l_y = 1;
......@@ -750,10 +763,25 @@ static void PictureHeader( vpar_thread_t * p_vpar )
/* Extension and User data. */
ExtensionAndUserData( p_vpar );
/* Macroblock parsing function. */
if( p_vpar->sequence.i_chroma_format != CHROMA_420
|| !p_vpar->sequence.b_mpeg2 )
{
p_vpar->picture.pf_parse_mb = vpar_ParseMacroblockGENERIC;
}
else
{
p_vpar->picture.pf_parse_mb =
ppf_parse_mb[p_vpar->picture.i_coding_type]
[p_vpar->picture.i_structure]
[(p_vpar->picture.i_structure !=
p_vpar->picture.i_current_structure)];
}
/* Picture data (ISO/IEC 13818-2 6.2.3.7). */
NextStartCode( p_vpar );
while( i_mb_address+i_mb_base < p_vpar->sequence.i_mb_size
&& !p_vpar->picture.b_error && !p_vpar->b_die )
&& !p_vpar->b_die )
{
if( ((i_dummy = ShowBits( &p_vpar->bit_stream, 32 ))
< SLICE_START_CODE_MIN) ||
......@@ -768,7 +796,12 @@ static void PictureHeader( vpar_thread_t * p_vpar )
/* Decode slice data. */
p_vpar->sequence.pf_slice_header( p_vpar, &i_mb_address, i_mb_base, i_dummy & 255 );
}
if( p_vpar->b_die || p_vpar->b_error )
{
return;
}
if( p_vpar->picture.b_error )
{
/* Trash picture. */
......@@ -826,7 +859,9 @@ static __inline__ void SliceHeader( vpar_thread_t * p_vpar,
static int pi_dc_dct_reinit[4] = {128,256,512,1024};
int i_mb_address_save = *pi_mb_address;
p_vpar->picture.b_error = 0;
/* slice_vertical_position_extension and priority_breakpoint already done */
LoadQuantizerScale( p_vpar );
......@@ -853,11 +888,18 @@ static __inline__ void SliceHeader( vpar_thread_t * p_vpar,
do
{
vpar_ParseMacroblock( p_vpar, pi_mb_address, i_mb_address_save,
i_mb_base );
p_vpar->picture.pf_parse_mb( p_vpar, pi_mb_address,
i_mb_address_save, i_mb_base,
p_vpar->sequence.b_mpeg2,
p_vpar->picture.i_coding_type,
p_vpar->sequence.i_chroma_format,
p_vpar->picture.i_structure,
(p_vpar->picture.i_structure !=
p_vpar->picture.i_current_structure) );
i_mb_address_save = *pi_mb_address;
}
while( ShowBits( &p_vpar->bit_stream, 23 ) && !p_vpar->b_die );
while( ShowBits( &p_vpar->bit_stream, 23 ) && !p_vpar->picture.b_error
&& !p_vpar->b_die );
NextStartCode( p_vpar );
}
......
......@@ -126,6 +126,7 @@ void vpar_MotionVector( vpar_thread_t * p_vpar, macroblock_t * p_mb, int i_r,
{
int i_motion_code, i_motion_residual;
int i_r_size;
int pi_dm_vector[2];
i_r_size = p_vpar->picture.ppi_f_code[i_s][0]-1;
i_motion_code = vpar_MotionCode( p_vpar );
......@@ -140,11 +141,11 @@ void vpar_MotionVector( vpar_thread_t * p_vpar, macroblock_t * p_mb, int i_r,
{
if( GetBits(&p_vpar->bit_stream, 1) )
{
p_mb->pi_dm_vector[0] = GetBits( &p_vpar->bit_stream, 1 ) ? -1 : 1;
pi_dm_vector[0] = GetBits( &p_vpar->bit_stream, 1 ) ? -1 : 1;
}
else
{
p_mb->pi_dm_vector[0] = 0;
pi_dm_vector[0] = 0;
}
}
......@@ -172,12 +173,55 @@ void vpar_MotionVector( vpar_thread_t * p_vpar, macroblock_t * p_mb, int i_r,
{
if( GetBits(&p_vpar->bit_stream, 1) )
{
p_mb->pi_dm_vector[1] = GetBits( &p_vpar->bit_stream, 1 ) ? -1 : 1;
pi_dm_vector[1] = GetBits( &p_vpar->bit_stream, 1 ) ? -1 : 1;
}
else
{
p_mb->pi_dm_vector[1] = 0;
pi_dm_vector[1] = 0;
}
/* Dual Prime Arithmetic (ISO/IEC 13818-2 section 7.6.3.6) */
#define i_mv_x p_mb->pppi_motion_vectors[0][0][0]
if( p_vpar->picture.i_structure == FRAME_STRUCTURE )
{
#define i_mv_y (p_mb->pppi_motion_vectors[0][0][1] << 1)
if( p_vpar->picture.b_top_field_first )
{
/* vector for prediction of top field from bottom field */
p_mb->ppi_dmv[0][0] = ((i_mv_x + (i_mv_x > 0)) >> 1) + pi_dm_vector[0];
p_mb->ppi_dmv[0][1] = ((i_mv_y + (i_mv_y > 0)) >