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* ); ...@@ -23,26 +23,21 @@ typedef void (*f_motion_t)( struct macroblock_s* );
/***************************************************************************** /*****************************************************************************
* Prototypes * 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_MotionFieldField420( struct macroblock_s * p_mb );
void vdec_MotionField16x8420( 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_MotionFrameFrame420( struct macroblock_s * p_mb );
void vdec_MotionFrameField420( 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_MotionFieldField422( struct macroblock_s * p_mb );
void vdec_MotionField16x8422( 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_MotionFrameFrame422( struct macroblock_s * p_mb );
void vdec_MotionFrameField422( 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_MotionFieldField444( struct macroblock_s * p_mb );
void vdec_MotionField16x8444( 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_MotionFrameFrame444( struct macroblock_s * p_mb );
void vdec_MotionFrameField444( struct macroblock_s * p_mb ); void vdec_MotionFrameField444( struct macroblock_s * p_mb );
void vdec_MotionFrameDMV( struct macroblock_s * p_mb ); void vdec_MotionFrameDMV444( struct macroblock_s * p_mb );
\ No newline at end of file \ No newline at end of file
...@@ -74,6 +74,10 @@ static __inline__ macroblock_t * vpar_NewMacroblock( video_fifo_t * p_fifo ) ...@@ -74,6 +74,10 @@ static __inline__ macroblock_t * vpar_NewMacroblock( video_fifo_t * p_fifo )
/* No more structures available. This should not happen ! */ /* No more structures available. This should not happen ! */
intf_DbgMsg("vpar debug: macroblock list is empty, delaying\n"); intf_DbgMsg("vpar debug: macroblock list is empty, delaying\n");
vlc_mutex_unlock( &P_buffer.lock ); vlc_mutex_unlock( &P_buffer.lock );
if( p_fifo->p_vpar->b_die )
{
return( NULL );
}
msleep(VPAR_OUTMEM_SLEEP); msleep(VPAR_OUTMEM_SLEEP);
vlc_mutex_lock( &P_buffer.lock ); vlc_mutex_lock( &P_buffer.lock );
} }
......
...@@ -15,6 +15,12 @@ ...@@ -15,6 +15,12 @@
* "video_fifo.h" * "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 * macroblock_t : information on a macroblock
*****************************************************************************/ *****************************************************************************/
...@@ -22,16 +28,8 @@ typedef struct macroblock_s ...@@ -22,16 +28,8 @@ typedef struct macroblock_s
{ {
int i_mb_type; /* macroblock type */ int i_mb_type; /* macroblock type */
int i_coded_block_pattern; 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_chroma_nb_blocks; /* nb of bks for a chr comp */
int i_l_stride; /* number of yuv_data_t to ignore picture_t * p_picture;
* when changing lines */
int i_c_stride; /* idem, for chroma */
/* IDCT information */ /* IDCT information */
dctelem_t ppi_blocks[12][64]; /* blocks */ dctelem_t ppi_blocks[12][64]; /* blocks */
...@@ -44,16 +42,24 @@ typedef struct macroblock_s ...@@ -44,16 +42,24 @@ typedef struct macroblock_s
picture_t * p_forward; picture_t * p_forward;
int ppi_field_select[2][2]; int ppi_field_select[2][2];
int pppi_motion_vectors[2][2][2]; int pppi_motion_vectors[2][2][2];
int pi_dm_vector[2]; int ppi_dmv[2][2];
boolean_t b_top_field_first; int i_l_x, i_c_x;
int i_motion_l_y; int i_motion_l_y;
int i_motion_c_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 */ /* AddBlock information */
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;
/* nb of coeffs to jump when changing lines */
} macroblock_t; } macroblock_t;
/***************************************************************************** /*****************************************************************************
...@@ -61,12 +67,8 @@ typedef struct macroblock_s ...@@ -61,12 +67,8 @@ typedef struct macroblock_s
*****************************************************************************/ *****************************************************************************/
typedef struct typedef struct
{ {
int i_mb_type, i_motion_type, i_mv_count, i_mv_format; int i_motion_type, i_mv_count, i_mv_format;
boolean_t b_dmv; boolean_t b_dmv, b_dct_type;
/* Macroblock Type */
int i_coded_block_pattern;
boolean_t b_dct_type;
int i_l_x, i_l_y, i_c_x, i_c_y; int i_l_x, i_l_y, i_c_x, i_c_y;
} macroblock_parsing_t; } macroblock_parsing_t;
...@@ -139,12 +141,53 @@ void vpar_InitPMBType( struct vpar_thread_s * p_vpar ); ...@@ -139,12 +141,53 @@ void vpar_InitPMBType( struct vpar_thread_s * p_vpar );
void vpar_InitBMBType( 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_InitCodedPattern( struct vpar_thread_s * p_vpar );
void vpar_InitDCTTables( 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, void vpar_ParseMacroblockGENERIC( struct vpar_thread_s* p_vpar, int * pi_mb_address,
int i_mb_previous, int i_mb_base ); int i_mb_previous, int i_mb_base,
int vpar_CodedPattern420( struct vpar_thread_s* p_vpar ); boolean_t b_mpeg2, int i_coding_type,
int vpar_CodedPattern422( struct vpar_thread_s* p_vpar ); int i_chroma_format, int i_structure,
int vpar_CodedPattern444( struct vpar_thread_s* p_vpar ); boolean_t b_second_field );
int vpar_IMBType( struct vpar_thread_s* p_vpar ); void vpar_ParseMacroblock2I420F0( struct vpar_thread_s* p_vpar, int * pi_mb_address,
int vpar_PMBType( struct vpar_thread_s* p_vpar ); int i_mb_previous, int i_mb_base,
int vpar_BMBType( struct vpar_thread_s* p_vpar ); boolean_t b_mpeg2, int i_coding_type,
int vpar_DMBType( struct vpar_thread_s* p_vpar ); 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 @@ ...@@ -19,11 +19,8 @@
* Function pointers * Function pointers
*****************************************************************************/ *****************************************************************************/
struct vpar_thread_s; struct vpar_thread_s;
struct macroblock_s;
typedef void (*f_slice_header_t)( struct vpar_thread_s*, int*, int, u32); 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 * quant_matrix_t : Quantization Matrix
...@@ -50,8 +47,6 @@ typedef struct sequence_s ...@@ -50,8 +47,6 @@ typedef struct sequence_s
f_slice_header_t pf_slice_header; f_slice_header_t pf_slice_header;
quant_matrix_t intra_quant, nonintra_quant; quant_matrix_t intra_quant, nonintra_quant;
quant_matrix_t chroma_intra_quant, chroma_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 */ /* Chromatic information */
unsigned int i_chroma_format; unsigned int i_chroma_format;
...@@ -89,6 +84,8 @@ typedef struct picture_parsing_s ...@@ -89,6 +84,8 @@ typedef struct picture_parsing_s
boolean_t b_repeat_first_field; boolean_t b_repeat_first_field;
int i_l_stride, i_c_stride; int i_l_stride, i_c_stride;
f_parse_mb_t pf_parse_mb;
/* Used for second field management */ /* Used for second field management */
int i_current_structure; int i_current_structure;
...@@ -100,8 +97,6 @@ typedef struct picture_parsing_s ...@@ -100,8 +97,6 @@ typedef struct picture_parsing_s
/* Relative to the current field */ /* Relative to the current field */
int i_coding_type, i_structure; int i_coding_type, i_structure;
boolean_t b_frame_structure; boolean_t b_frame_structure;
boolean_t b_motion_field;
f_macroblock_type_t pf_macroblock_type;
boolean_t b_error; boolean_t b_error;
} picture_parsing_t; } picture_parsing_t;
......
...@@ -455,59 +455,6 @@ static __inline__ void Motion444( ...@@ -455,59 +455,6 @@ static __inline__ void Motion444(
i_select, b_average ); 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) * vdec_MotionFieldField : motion compensation for field motion type (field)
*****************************************************************************/ *****************************************************************************/
...@@ -516,8 +463,7 @@ void vdec_MotionDummy( macroblock_t * p_mb ) ...@@ -516,8 +463,7 @@ void vdec_MotionDummy( macroblock_t * p_mb )
\ \
if( p_mb->i_mb_type & MB_MOTION_FORWARD ) \ if( p_mb->i_mb_type & MB_MOTION_FORWARD ) \
{ \ { \
if( p_mb->b_P_coding_type \ if( p_mb->b_P_second \
&& (p_mb->i_current_structure == FRAME_STRUCTURE) \
&& (p_mb->b_motion_field != p_mb->ppi_field_select[0][0]) )\ && (p_mb->b_motion_field != p_mb->ppi_field_select[0][0]) )\
p_pred = p_mb->p_picture; \ p_pred = p_mb->p_picture; \
else \ else \
...@@ -573,8 +519,7 @@ void vdec_MotionFieldField444( macroblock_t * p_mb ) ...@@ -573,8 +519,7 @@ void vdec_MotionFieldField444( macroblock_t * p_mb )
\ \
if( p_mb->i_mb_type & MB_MOTION_FORWARD ) \ if( p_mb->i_mb_type & MB_MOTION_FORWARD ) \
{ \ { \
if( p_mb->b_P_coding_type \ if( p_mb->b_P_second \
&& (p_mb->i_current_structure == FRAME_STRUCTURE) \
&& (p_mb->b_motion_field != p_mb->ppi_field_select[0][0]) )\ && (p_mb->b_motion_field != p_mb->ppi_field_select[0][0]) )\
p_pred = p_mb->p_picture; \ p_pred = p_mb->p_picture; \
else \ else \
...@@ -586,8 +531,7 @@ void vdec_MotionFieldField444( macroblock_t * p_mb ) ...@@ -586,8 +531,7 @@ void vdec_MotionFieldField444( macroblock_t * p_mb )
p_mb->pppi_motion_vectors[0][0][1], \ p_mb->pppi_motion_vectors[0][0][1], \
p_mb->i_l_stride, p_mb->i_c_stride, 8, 0, 0 ); \ p_mb->i_l_stride, p_mb->i_c_stride, 8, 0, 0 ); \
\ \
if( p_mb->b_P_coding_type \ if( p_mb->b_P_second \
&& (p_mb->i_current_structure == FRAME_STRUCTURE) \
&& (p_mb->b_motion_field != p_mb->ppi_field_select[1][0]) )\ && (p_mb->b_motion_field != p_mb->ppi_field_select[1][0]) )\
p_pred = p_mb->p_picture; \ p_pred = p_mb->p_picture; \
else \ else \
...@@ -649,44 +593,45 @@ void vdec_MotionField16x8444( macroblock_t * p_mb ) ...@@ -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 FIELDDMV( Motion420 )
/* This is necessarily a MOTION_FORWARD only macroblock */ }
motion_arg_t args;
picture_t * p_pred; void vdec_MotionFieldDMV422( macroblock_t * p_mb )
int ppi_dmv[2][2]; {
FIELDDMV( Motion422 )
args.i_height = 16; }
args.b_average = 0;
args.b_dest_field = p_mb->b_motion_field; void vdec_MotionFieldDMV444( macroblock_t * p_mb )
args.i_offset = 0; {
FIELDDMV( Motion444 )
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
} }
/***************************************************************************** /*****************************************************************************
...@@ -800,53 +745,49 @@ void vdec_MotionFrameField444( macroblock_t * p_mb ) ...@@ -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 FRAMEDMV( Motion420 )
/* 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
} }
void vdec_MotionFrameDMV422( macroblock_t * p_mb )
{
FRAMEDMV( Motion422 )
}
void vdec_MotionFrameDMV444( macroblock_t * p_mb )
{
FRAMEDMV( Motion444 )
}
...@@ -47,8 +47,20 @@ static void vpar_DecodeMPEG2Non( vpar_thread_t * p_vpar, macroblock_t * p_mb, in ...@@ -47,8 +47,20 @@ static void vpar_DecodeMPEG2Non( vpar_thread_t * p_vpar, macroblock_t * p_mb, in
static void vpar_DecodeMPEG2Intra( vpar_thread_t * p_vpar, macroblock_t * p_mb, int i_b ); static void vpar_DecodeMPEG2Intra( vpar_thread_t * p_vpar, macroblock_t * p_mb, int i_b );
/* /*
* Initialisation tables * Welcome to vpar_blocks.c ! Here's where the heavy processor-critical parsing
* task is done. This file is divided in several parts :
* - Initialization of the lookup tables
* - Decoding of coded blocks
* - Decoding of motion vectors
* - Decoding of the other macroblock structures
* It's a pretty long file. Good luck !
*/ */
/*
* Initialization tables
*/
/* Table for coded_block_pattern resolution */ /* Table for coded_block_pattern resolution */
static lookup_t pl_coded_pattern_init_table[512] = static lookup_t pl_coded_pattern_init_table[512] =
{ {MB_ERROR, 0}, {0, 9}, {39, 9}, {27, 9}, {59, 9}, {55, 9}, {47, 9}, {31, 9}, { {MB_ERROR, 0}, {0, 9}, {39, 9}, {27, 9}, {59, 9}, {55, 9}, {47, 9}, {31, 9},
...@@ -347,6 +359,8 @@ static dct_lookup_t pl_DCT_tab6[16] = ...@@ -347,6 +359,8 @@ static dct_lookup_t pl_DCT_tab6[16] =
{13,2,16}, {12,2,16}, {11,2,16}, {31,1,16}, {13,2,16}, {12,2,16}, {11,2,16}, {31,1,16},
{30,1,16}, {29,1,16}, {28,1,16}, {27,1,16} {30,1,16}, {29,1,16}, {28,1,16}, {27,1,16}
}; };
/* /*
* Initialization of lookup tables * Initialization of lookup tables
*/ */
...@@ -378,7 +392,7 @@ void vpar_InitCrop( vpar_thread_t * p_vpar ) ...@@ -378,7 +392,7 @@ void vpar_InitCrop( vpar_thread_t * p_vpar )
#endif #endif
/***************************************************************************** /*****************************************************************************
* InitMbAddrInc : Initialize the lookup table for mb_addr_inc * vpar_InitMbAddrInc : Initialize the lookup table for mb_addr_inc
*****************************************************************************/ *****************************************************************************/
/* Function for filling up the lookup table for mb_addr_inc */ /* Function for filling up the lookup table for mb_addr_inc */
...@@ -441,7 +455,7 @@ void vpar_InitMbAddrInc( vpar_thread_t * p_vpar ) ...@@ -441,7 +455,7 @@ void vpar_InitMbAddrInc( vpar_thread_t * p_vpar )
} }
/***************************************************************************** /*****************************************************************************
* Init*MBType : Initialize lookup table for the Macroblock type * vpar_Init*MBType : Initialize lookup table for the Macroblock type
*****************************************************************************/ *****************************************************************************/
/* Fonction for filling up the tables */ /* Fonction for filling up the tables */
...@@ -500,7 +514,7 @@ void vpar_InitBMBType( vpar_thread_t * p_vpar ) ...@@ -500,7 +514,7 @@ void vpar_InitBMBType( vpar_thread_t * p_vpar )
} }
/***************************************************************************** /*****************************************************************************
* InitCodedPattern : Initialize the lookup table for decoding * vpar_InitCodedPattern : Initialize the lookup table for decoding
* coded block pattern * coded block pattern
*****************************************************************************/ *****************************************************************************/
void vpar_InitCodedPattern( vpar_thread_t * p_vpar ) void vpar_InitCodedPattern( vpar_thread_t * p_vpar )
...@@ -509,8 +523,8 @@ void vpar_InitCodedPattern( vpar_thread_t * p_vpar ) ...@@ -509,8 +523,8 @@ void vpar_InitCodedPattern( vpar_thread_t * p_vpar )
} }
/***************************************************************************** /*****************************************************************************
* InitDCT : Initialize tables giving the length of the dct coefficient * vpar_InitDCTTables : Initialize tables giving the length of the dct
* from the vlc code * coefficient from the vlc code
*****************************************************************************/ *****************************************************************************/
/* First fonction for filling the table */ /* First fonction for filling the table */
...@@ -560,441 +574,650 @@ void vpar_InitDCTTables( vpar_thread_t * p_vpar ) ...@@ -560,441 +574,650 @@ void vpar_InitDCTTables( vpar_thread_t * p_vpar )
FillDCTTable( ppl_dct_coef[1], pl_DCT_tab6, 1, 16, 16 ); FillDCTTable( ppl_dct_coef[1], pl_DCT_tab6, 1, 16, 16 );
} }
/* /*
* Macroblock parsing functions * Block parsing
*/ */
/***************************************************************************** /*****************************************************************************
* InitMacroblock : Initialize macroblock values * vpar_DecodeMPEG1Non : decode MPEG-1 non-intra blocks
*****************************************************************************/ *****************************************************************************/
static __inline__ void InitMacroblock( vpar_thread_t * p_vpar, static void vpar_DecodeMPEG1Non( vpar_thread_t * p_vpar, macroblock_t * p_mb, int i_b )
macroblock_t * p_mb )
{ {
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;
p_mb->b_top_field_first = p_vpar->picture.b_top_field_first;
p_mb->i_l_x = p_vpar->mb.i_l_x;
p_mb->i_motion_l_y = p_mb->i_l_y = p_vpar->mb.i_l_y;
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->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 == D_CODING_TYPE )
(p_vpar->picture.i_coding_type == B_CODING_TYPE) )
p_mb->p_forward = p_vpar->sequence.p_forward;
else
p_mb->p_forward = NULL;
if( p_vpar->picture.i_coding_type == B_CODING_TYPE )
p_mb->p_backward = p_vpar->sequence.p_backward;
else
p_mb->p_backward = NULL;
p_mb->i_addb_l_stride = (p_mb->i_l_stride = p_vpar->picture.i_l_stride) - 8;
p_mb->i_addb_c_stride = (p_mb->i_c_stride = p_vpar->picture.i_c_stride) - 8;
/* Update macroblock real position. */
p_vpar->mb.i_l_x += 16;
p_vpar->mb.i_l_y += (p_vpar->mb.i_l_x / p_vpar->sequence.i_width)
* (2 - p_vpar->picture.b_frame_structure) * 16;
p_vpar->mb.i_l_x %= p_vpar->sequence.i_width;
p_vpar->mb.i_c_x += p_vpar->sequence.i_chroma_mb_width;
p_vpar->mb.i_c_y += (p_vpar->mb.i_c_x / p_vpar->sequence.i_chroma_width)
* (2 - p_vpar->picture.b_frame_structure)
* p_vpar->sequence.i_chroma_mb_height;
p_vpar->mb.i_c_x %= p_vpar->sequence.i_chroma_width;
if( (p_mb->b_motion_field = p_vpar->picture.b_motion_field) )
{ {
p_mb->i_motion_l_y--; /* Remove end_of_macroblock (always 1, prevents startcode emulation)
p_mb->i_motion_c_y--; * ISO/IEC 11172-2 section 2.4.2.7 and 2.4.3.6 */
RemoveBits( &p_vpar->bit_stream, 1 );
} }
} }
/***************************************************************************** /*****************************************************************************
* MacroblockAddressIncrement : Get the macroblock_address_increment field * vpar_DecodeMPEG1Intra : decode MPEG-1 intra blocks
*****************************************************************************/ *****************************************************************************/
static __inline__ int MacroblockAddressIncrement( vpar_thread_t * p_vpar ) static void vpar_DecodeMPEG1Intra( vpar_thread_t * p_vpar, macroblock_t * p_mb, int i_b )
{ {
int i_addr_inc = 0;
/* Index in the lookup table mb_addr_inc */
int i_index = ShowBits( &p_vpar->bit_stream, 11 );
/* Test the presence of the escape character */ if( p_vpar->picture.i_coding_type == D_CODING_TYPE )
while( i_index == 8 )
{ {
RemoveBits( &p_vpar->bit_stream, 11 ); /* Remove end_of_macroblock (always 1, prevents startcode emulation)
i_addr_inc += 33; * ISO/IEC 11172-2 section 2.4.2.7 and 2.4.3.6 */
i_index = ShowBits( &p_vpar->bit_stream, 11 ); RemoveBits( &p_vpar->bit_stream, 1 );
} }
/* Affect the value from the lookup table */
i_addr_inc += p_vpar->pl_mb_addr_inc[i_index].i_value;
/* Dump the good number of bits */
RemoveBits( &p_vpar->bit_stream, p_vpar->pl_mb_addr_inc[i_index].i_length );
return i_addr_inc;
} }
/***************************************************************************** /*****************************************************************************
* MacroblockModes : Get the macroblock_modes structure * vpar_DecodeMPEG2Non : decode MPEG-2 non-intra blocks
*****************************************************************************/ *****************************************************************************/
static __inline__ void MacroblockModes( vpar_thread_t * p_vpar, static void vpar_DecodeMPEG2Non( vpar_thread_t * p_vpar, macroblock_t * p_mb, int i_b )
macroblock_t * p_mb )
{ {
static f_motion_t pppf_motion[4][2][4] = int i_parse;
{ int i_nc;
{ {NULL, NULL, NULL, NULL}, int i_cc;
{NULL, NULL, NULL, NULL} int i_coef;
}, int i_type;
{ {NULL, vdec_MotionFieldField420, vdec_MotionField16x8420, vdec_MotionFieldDMV}, int i_code;
{NULL, vdec_MotionFrameField420, vdec_MotionFrameFrame420, vdec_MotionFrameDMV} int i_length;
}, int i_pos;
{ {NULL, vdec_MotionFieldField422, vdec_MotionField16x8422, vdec_MotionFieldDMV}, int i_run;
{NULL, vdec_MotionFrameField422, vdec_MotionFrameFrame422, vdec_MotionFrameDMV} int i_level;
}, int i_quant_type;
{ {NULL, vdec_MotionFieldField444, vdec_MotionField16x8444, vdec_MotionFieldDMV}, boolean_t b_sign;
{NULL, vdec_MotionFrameField444, vdec_MotionFrameFrame444, vdec_MotionFrameDMV} int * ppi_quant[2];
}
};
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} };
/* Get macroblock_type. */ /* Lookup Table for the chromatic component */
p_vpar->mb.i_mb_type = (p_vpar->picture.pf_macroblock_type)( p_vpar ); static int pi_cc_index[12] = { 0, 0, 0, 0, 1, 2, 1, 2, 1, 2 };
p_mb->i_mb_type = p_vpar->mb.i_mb_type;
/* SCALABILITY : warning, we don't know if spatial_temporal_weight_code i_cc = pi_cc_index[i_b];
* has to be dropped, take care if you use scalable streams. */
/* RemoveBits( &p_vpar->bit_stream, 2 ); */ /* Determine whether it is luminance or not (chrominance) */
i_type = ( i_cc + 1 ) >> 1;
i_quant_type = (!i_type) || (p_vpar->sequence.i_chroma_format == CHROMA_420);
if( !(p_vpar->mb.i_mb_type & (MB_MOTION_FORWARD | MB_MOTION_BACKWARD)) ) /* Give a pointer to the quantization matrices for intra blocks */
ppi_quant[1] = p_vpar->sequence.nonintra_quant.pi_matrix;
ppi_quant[0] = p_vpar->sequence.chroma_nonintra_quant.pi_matrix;
/* Decoding of the AC coefficients */
i_nc = 0;
i_coef = 0;
for( i_parse = 0; ; i_parse++ )
{ {
/* If mb_type has neither MOTION_FORWARD nor MOTION_BACKWARD, this i_code = ShowBits( &p_vpar->bit_stream, 16 );
* is useless, but also harmless. */ if( i_code >= 16384 )
p_vpar->mb.i_motion_type = MOTION_FRAME;
}
else
{ {
if( p_vpar->picture.i_structure == FRAME_STRUCTURE if( i_parse == 0 )
&& p_vpar->picture.b_frame_pred_frame_dct )
{ {
p_vpar->mb.i_motion_type = MOTION_FRAME; i_run = pl_DCT_tab_dc[(i_code>>12)-4].i_run;
i_level = pl_DCT_tab_dc[(i_code>>12)-4].i_level;
i_length = pl_DCT_tab_dc[(i_code>>12)-4].i_length;
} }
else else
{ {
p_vpar->mb.i_motion_type = GetBits( &p_vpar->bit_stream, 2 ); i_run = pl_DCT_tab_ac[(i_code>>12)-4].i_run;
} i_level = pl_DCT_tab_ac[(i_code>>12)-4].i_level;
i_length = pl_DCT_tab_ac[(i_code>>12)-4].i_length;
} }
if( p_mb->b_P_coding_type && !(p_vpar->mb.i_mb_type & (MB_MOTION_FORWARD|MB_INTRA)) )
{
/* Special No-MC macroblock in P pictures (7.6.3.5). */
memset( p_vpar->slice.pppi_pmv, 0, 8*sizeof(int) );
memset( p_mb->pppi_motion_vectors, 0, 8*sizeof(int) );
p_vpar->mb.i_motion_type = MOTION_FRAME;
p_mb->ppi_field_select[0][0] = ( p_vpar->picture.i_current_structure == BOTTOM_FIELD );
} }
else if( i_code >= 1024 )
if( p_vpar->mb.i_mb_type & MB_INTRA )
{ {
/* For the intra macroblocks, we use an empty motion i_run = pl_DCT_tab0[(i_code>>8)-4].i_run;
* compensation function */ i_length = pl_DCT_tab0[(i_code>>8)-4].i_length;
p_mb->pf_motion = vdec_MotionDummy; i_level = pl_DCT_tab0[(i_code>>8)-4].i_level;
} }
else else
{ {
p_mb->pf_motion = pppf_motion[p_vpar->sequence.i_chroma_format] i_run = ppl_dct_coef[0][i_code].i_run;
[p_vpar->picture.b_frame_structure] i_length = ppl_dct_coef[0][i_code].i_length;
[p_vpar->mb.i_motion_type]; i_level = ppl_dct_coef[0][i_code].i_level;
} }
p_vpar->mb.i_mv_count = ppi_mv_count[p_vpar->picture.b_frame_structure]
[p_vpar->mb.i_motion_type];
p_vpar->mb.i_mv_format = ppi_mv_format[p_vpar->picture.b_frame_structure]
[p_vpar->mb.i_motion_type];
RemoveBits( &p_vpar->bit_stream, i_length );
p_vpar->mb.b_dct_type = 0; switch( i_run )
if( (p_vpar->picture.i_structure == FRAME_STRUCTURE) &&
(!p_vpar->picture.b_frame_pred_frame_dct) &&
(p_vpar->mb.i_mb_type & (MB_PATTERN|MB_INTRA)) )
{ {
if( (p_vpar->mb.b_dct_type = GetBits( &p_vpar->bit_stream, 1 )) ) case DCT_ESCAPE:
i_run = GetBits( &p_vpar->bit_stream, 6 );
i_level = GetBits( &p_vpar->bit_stream, 12 );
i_level = (b_sign = ( i_level > 2047 )) ? 4096 - i_level
: i_level;
break;
case DCT_EOB:
if( i_nc <= 1 )
{ {
/* The DCT is coded on fields. Jump one line between each p_mb->pf_idct[i_b] = vdec_SparseIDCT;
* sample. */ p_mb->pi_sparse_pos[i_b] = i_coef;
p_mb->i_addb_l_stride <<= 1; }
p_mb->i_addb_l_stride += 8; else
/* With CHROMA_420, the DCT is necessarily frame-coded. */
if( p_vpar->sequence.i_chroma_format != CHROMA_420 )
{ {
p_mb->i_addb_c_stride <<= 1; p_mb->pf_idct[i_b] = vdec_IDCT;
p_mb->i_addb_c_stride += 8; }
return;
break;
default:
b_sign = GetBits( &p_vpar->bit_stream, 1 );
} }
i_coef = i_parse;
i_parse += i_run;
i_nc ++;
if( i_parse >= 64 )
{
break;
} }
i_pos = pi_scan[p_vpar->picture.b_alternate_scan][i_parse];
i_level = ( ((i_level << 1) + 1) * p_vpar->slice.i_quantizer_scale
* ppi_quant[i_quant_type][i_pos] ) >> 5;
p_mb->ppi_blocks[i_b][i_pos] = b_sign ? -i_level : i_level;
} }
p_vpar->mb.b_dmv = p_vpar->mb.i_motion_type == MOTION_DMV;
intf_ErrMsg("vpar error: DCT coeff (non-intra) is out of bounds\n");
p_vpar->picture.b_error = 1;
} }
/***************************************************************************** /*****************************************************************************
* vpar_ParseMacroblock : Parse the next macroblock * vpar_DecodeMPEG2Intra : decode MPEG-2 intra blocks
*****************************************************************************/ *****************************************************************************/
void vpar_ParseMacroblock( vpar_thread_t * p_vpar, int * pi_mb_address, static void vpar_DecodeMPEG2Intra( vpar_thread_t * p_vpar, macroblock_t * p_mb, int i_b )
int i_mb_previous, int i_mb_base )
{ {
static f_decode_block_t pppf_decode_block[2][2] = int i_parse;
{ {vpar_DecodeMPEG1Non, vpar_DecodeMPEG1Intra}, int i_nc;
{vpar_DecodeMPEG2Non, vpar_DecodeMPEG2Intra} }; int i_cc;
static int pi_x[12] = {0,8,0,8,0,0,0,0,8,8,8,8}; int i_coef;
static int pi_y[2][12] = { {0,0,8,8,0,0,8,8,0,0,8,8}, int i_type, i_quant_type;
{0,0,1,1,0,0,1,1,0,0,1,1} }; int i_code;
int i_length;
int i_pos;
int i_dct_dc_size;
int i_dct_dc_diff;
int i_run;
int i_level;
boolean_t b_vlc_intra;
boolean_t b_sign;
int * ppi_quant[2];
int i_mb, i_b, i_mask; /* Lookup Table for the chromatic component */
macroblock_t * p_mb; static int pi_cc_index[12] = { 0, 0, 0, 0, 1, 2, 1, 2, 1, 2 };
yuv_data_t * p_data1; i_cc = pi_cc_index[i_b];
yuv_data_t * p_data2;
/************* DEBUG *************/ /* Determine whether it is luminance or not (chrominance) */
int i_inc; i_type = ( i_cc + 1 ) >> 1;
static int i_count; i_quant_type = (!i_type) | (p_vpar->sequence.i_chroma_format == CHROMA_420);
i_count++;
i_inc = MacroblockAddressIncrement( p_vpar ); /* Give a pointer to the quantization matrices for intra blocks */
*pi_mb_address += i_inc; ppi_quant[1] = p_vpar->sequence.intra_quant.pi_matrix;
//*pi_mb_address += MacroblockAddressIncrement( p_vpar ); ppi_quant[0] = p_vpar->sequence.chroma_intra_quant.pi_matrix;
for( i_mb = i_mb_previous + 1; i_mb < *pi_mb_address; i_mb++ ) #if 0
{ /* Decoding of the DC intra coefficient */
/* Skipped macroblock (ISO/IEC 13818-2 7.6.6). */ /* The nb of bits to parse depends on i_type */
static int pi_dc_dct_reinit[4] = {128,256,512,1024}; i_code = ShowBits( &p_vpar->bit_stream, 9 + i_type );
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). */ /* To reduce memory occupation, there are two lookup tables
p_vpar->slice.pi_dc_dct_pred[0] = p_vpar->slice.pi_dc_dct_pred[1] * See InitDCT above */
= p_vpar->slice.pi_dc_dct_pred[2] i_code5 = i_code >> (4+i_type);
= pi_dc_dct_reinit[p_vpar->picture.i_intra_dc_precision];
if( p_vpar->picture.i_coding_type == P_CODING_TYPE ) /* Shall we lookup in the first or in the second table ? */
{ i_select = ( i_code5 == 31 );
/* Reset motion vector predictors (ISO/IEC 13818-2 7.6.3.4). */ /* Offset value for looking in the second table */
memset( p_vpar->slice.pppi_pmv, 0, 8*sizeof(int) ); i_offset = 0x1f0 + ( i_type * 0x1f0 );
} i_pos = ( i_code5 * ( ! i_select ) ) + ( ( i_code - i_offset ) * i_select );
i_dct_dc_size = p_vpar->pppl_dct_dc_size[i_type][i_select][i_pos].i_value;
#endif
if( (p_mb = vpar_NewMacroblock( &p_vpar->vfifo )) == NULL ) if( !i_type/*i_b < 4*/ )
{ {
p_vpar->picture.b_error = 1; /* decode length */
intf_ErrMsg("vpar error: macroblock list is empty !\n"); i_code = ShowBits(&p_vpar->bit_stream, 5);
return; if (i_code<31)
{
i_dct_dc_size = pl_dct_dc_lum_init_table_1[i_code].i_value;
i_length = pl_dct_dc_lum_init_table_1[i_code].i_length;
RemoveBits( &p_vpar->bit_stream, i_length);
}
else
{
i_code = ShowBits(&p_vpar->bit_stream, 9) - 0x1f0;
i_dct_dc_size = pl_dct_dc_lum_init_table_2[i_code].i_value;
i_length = pl_dct_dc_lum_init_table_2[i_code].i_length;
RemoveBits( &p_vpar->bit_stream, i_length);
}
}
else
{
/* decode length */
i_code = ShowBits(&p_vpar->bit_stream, 5);
if (i_code<31)
{
i_dct_dc_size = pl_dct_dc_chrom_init_table_1[i_code].i_value;
i_length = pl_dct_dc_chrom_init_table_1[i_code].i_length;
RemoveBits(&p_vpar->bit_stream, i_length);
}
else
{
i_code = ShowBits(&p_vpar->bit_stream, 10) - 0x3e0;
i_dct_dc_size = pl_dct_dc_chrom_init_table_2[i_code].i_value;
i_length = pl_dct_dc_chrom_init_table_2[i_code].i_length;
RemoveBits( &p_vpar->bit_stream, i_length);
}
}
if (i_dct_dc_size==0)
i_dct_dc_diff = 0;
else
{
i_dct_dc_diff = GetBits( &p_vpar->bit_stream, i_dct_dc_size);
if ((i_dct_dc_diff & (1<<(i_dct_dc_size-1)))==0)
i_dct_dc_diff-= (1<<i_dct_dc_size) - 1;
} }
#ifdef VDEC_SMP
p_vpar->picture.pp_mb[i_mb_base + i_mb] = p_mb;
#endif
InitMacroblock( p_vpar, p_mb ); /* Dump the variable length code */
//RemoveBits( &p_vpar->bit_stream,
// p_vpar->pppl_dct_dc_size[i_type][i_select][i_pos].i_length );
/* Motion type is picture structure. */ /* Read the actual code with the good length */
p_mb->pf_motion = pf_motion_skipped[p_vpar->sequence.i_chroma_format] p_vpar->slice.pi_dc_dct_pred[i_cc] += i_dct_dc_diff;
[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 */ p_mb->ppi_blocks[i_b][0] = ( p_vpar->slice.pi_dc_dct_pred[i_cc] <<
p_mb->ppi_field_select[0][0] = p_mb->ppi_field_select[0][1] ( 3 - p_vpar->picture.i_intra_dc_precision ) );
= ( p_vpar->picture.i_current_structure == BOTTOM_FIELD ); i_nc = ( p_vpar->slice.pi_dc_dct_pred[i_cc] != 0 );
#ifndef VDEC_SMP /* Decoding of the AC coefficients */
/* Decode the macroblock NOW ! */
vdec_DecodeMacroblock( p_vpar->pp_vdec[0], p_mb ); i_coef = 0;
#endif b_vlc_intra = p_vpar->picture.b_intra_vlc_format;
for( i_parse = 1; /*i_parse < 64*/; i_parse++ )
{
i_code = ShowBits( &p_vpar->bit_stream, 16 );
if( i_code >= 16384 )
{
if( b_vlc_intra )
{
i_run = pl_DCT_tab0a[(i_code>>8)-4].i_run;
i_level = pl_DCT_tab0a[(i_code>>8)-4].i_level;
i_length = pl_DCT_tab0a[(i_code>>8)-4].i_length;
//fprintf( stderr, "**********> %d, %d, %d *******\n", i_run, i_level, (i_code>>8)-4 );
}
else
{
i_run = pl_DCT_tab_ac[(i_code>>12)-4].i_run;
i_level = pl_DCT_tab_ac[(i_code>>12)-4].i_level;
i_length = pl_DCT_tab_ac[(i_code>>12)-4].i_length;
}
}
else
{
i_run = ppl_dct_coef[b_vlc_intra][i_code].i_run;
i_length = ppl_dct_coef[b_vlc_intra][i_code].i_length;
i_level = ppl_dct_coef[b_vlc_intra][i_code].i_level;
} }
/* Get a macroblock structure. */ #if 0
if( (p_mb = vpar_NewMacroblock( &p_vpar->vfifo )) == NULL )
{ {
p_vpar->picture.b_error = 1; int code = i_code;
intf_ErrMsg("vpar error: macroblock list is empty !\n"); int intra_vlc_format = b_vlc_intra;
return; dct_lookup_t tab;
if (code>=16384 && !intra_vlc_format)
tab = pl_DCT_tab_ac[(code>>12)-4];
else if (code>=1024)
{
if (intra_vlc_format)
tab = pl_DCT_tab0a[(code>>8)-4];
else
tab = pl_DCT_tab0[(code>>8)-4];
}
else if (code>=512)
{
if (intra_vlc_format)
tab = pl_DCT_tab1a[(code>>6)-8];
else
tab = pl_DCT_tab1[(code>>6)-8];
}
else if (code>=256)
tab = pl_DCT_tab2[(code>>4)-16];
else if (code>=128)
tab = pl_DCT_tab3[(code>>3)-16];
else if (code>=64)
tab = pl_DCT_tab4[(code>>2)-16];
else if (code>=32)
tab = pl_DCT_tab5[(code>>1)-16];
else if (code>=16)
tab = pl_DCT_tab6[code-16];
else
{
fprintf( stderr, "invalid Huffman code in Decode_MPEG2_Intra_Block()\n");
}
if( (i_run != tab.i_run) || (i_length != tab.i_length) || (i_level != tab.i_level) )
{
fprintf( stderr, "ET M....... !!!\n" );
exit(0);
}
} }
#ifdef VDEC_SMP
p_vpar->picture.pp_mb[i_mb_base + *pi_mb_address] = p_mb;
#endif #endif
InitMacroblock( p_vpar, p_mb );
/* Parse off macroblock_modes structure. */
MacroblockModes( p_vpar, p_mb );
if( p_vpar->mb.i_mb_type & MB_QUANT )
RemoveBits( &p_vpar->bit_stream, i_length );
switch( i_run )
{ {
LoadQuantizerScale( p_vpar ); case DCT_ESCAPE:
i_run = GetBits( &p_vpar->bit_stream, 6 );
i_level = GetBits( &p_vpar->bit_stream, 12 );
/*p_mb->ppi_blocks[i_b][i_parse] = ( b_sign = ( i_level > 2047 ) )
? ( -4096 + i_level )
: i_level;*/
i_level = (b_sign = ( i_level > 2047 )) ? 4096 - i_level
: i_level;
break;
case DCT_EOB:
if( i_nc <= 1 )
{
p_mb->pf_idct[i_b] = vdec_SparseIDCT;
p_mb->pi_sparse_pos[i_b] = i_coef;
}
else
{
p_mb->pf_idct[i_b] = vdec_IDCT;
} }
return;
break;
default:
b_sign = GetBits( &p_vpar->bit_stream, 1 );
}
i_coef = i_parse;
i_parse += i_run;
i_nc ++;
if( i_parse >= 64 )
{
break;
}
i_pos = pi_scan[p_vpar->picture.b_alternate_scan][i_parse];
i_level = ( i_level *
p_vpar->slice.i_quantizer_scale *
ppi_quant[i_quant_type][i_pos] ) >> 4;
p_mb->ppi_blocks[i_b][i_pos] = b_sign ? -i_level : i_level;
}
intf_ErrMsg("vpar error: DCT coeff (intra) is out of bounds\n");
p_vpar->picture.b_error = 1;
}
/*
* Motion vectors
*/
/****************************************************************************
* MotionCode : Parse the next motion code
****************************************************************************/
static __inline__ int MotionCode( vpar_thread_t * p_vpar )
{
int i_code;
static lookup_t pl_mv_tab0[8] =
{ {-1,0}, {3,3}, {2,2}, {2,2}, {1,1}, {1,1}, {1,1}, {1,1} };
/* Table B-10, motion_code, codes 0000011 ... 000011x */
static lookup_t pl_mv_tab1[8] =
{ {-1,0}, {-1,0}, {-1,0}, {7,6}, {6,6}, {5,6}, {4,5}, {4,5} };
/* Table B-10, motion_code, codes 0000001100 ... 000001011x */
static lookup_t pl_mv_tab2[12] = {
{16,9}, {15,9}, {14,9}, {13,9},
{12,9}, {11,9}, {10,8}, {10,8},
{9,8}, {9,8}, {8,8}, {8,8} };
if( p_vpar->mb.i_mb_type & MB_MOTION_FORWARD ) if( GetBits( &p_vpar->bit_stream, 1 ) )
{ {
//fprintf( stderr, "motion !\n" ); return 0;
(*p_vpar->sequence.pf_decode_mv)( p_vpar, p_mb, 0 ); }
if( (i_code = ShowBits( &p_vpar->bit_stream, 9) ) >= 64 )
{
i_code >>= 6;
RemoveBits( &p_vpar->bit_stream, pl_mv_tab0[i_code].i_length );
return( GetBits( &p_vpar->bit_stream, 1 ) ?
-pl_mv_tab0[i_code].i_value : pl_mv_tab0[i_code].i_value );
} }
if( p_vpar->mb.i_mb_type & MB_MOTION_BACKWARD ) if( i_code >= 24 )
{ {
//fprintf( stderr, "motion2 !\n" ); i_code >>= 3;
(*p_vpar->sequence.pf_decode_mv)( p_vpar, p_mb, 1 ); RemoveBits( &p_vpar->bit_stream, pl_mv_tab1[i_code].i_length );
return( GetBits( &p_vpar->bit_stream, 1 ) ?
-pl_mv_tab1[i_code].i_value : pl_mv_tab1[i_code].i_value );
} }
if( p_vpar->picture.b_concealment_mv && (p_vpar->mb.i_mb_type & MB_INTRA) ) if( (i_code -= 12) < 0 )
{ {
RemoveBits( &p_vpar->bit_stream, 1 ); p_vpar->picture.b_error = 1;
intf_DbgMsg( "vpar debug: Invalid motion_vector code\n" );
return 0;
} }
if( 0 )
//i_count == 1231 && RemoveBits( &p_vpar->bit_stream, pl_mv_tab2[i_code].i_length );
// i_count != *pi_mb_address) return( GetBits( &p_vpar->bit_stream, 1 ) ?
//p_vpar->picture.i_coding_type == P_CODING_TYPE ) -pl_mv_tab2[i_code].i_value : pl_mv_tab2[i_code].i_value );
}
/****************************************************************************
* DecodeMotionVector : Decode a motion_vector
****************************************************************************/
static __inline__ void DecodeMotionVector( int * pi_prediction, int i_r_size,
int i_motion_code, int i_motion_residual, int i_full_pel )
{ {
fprintf( stderr, "i_count = %d (%d)\n", i_count, p_vpar->mb.i_mb_type ); int i_limit, i_vector;
fprintf( stderr, "%x", GetBits( &p_vpar->bit_stream, 16 ) );
fprintf( stderr, "%x ", GetBits( &p_vpar->bit_stream, 16 ) ); /* ISO/IEC 13818-1 section 7.6.3.1 */
fprintf( stderr, "%x", GetBits( &p_vpar->bit_stream, 16 ) ); i_limit = 16 << i_r_size;
fprintf( stderr, "%x\n", GetBits( &p_vpar->bit_stream, 16 ) ); i_vector = *pi_prediction >> i_full_pel;
fprintf( stderr, "%x", GetBits( &p_vpar->bit_stream, 16 ) );
fprintf( stderr, "%x ", GetBits( &p_vpar->bit_stream, 16 ) ); if( i_motion_code > 0 )
fprintf( stderr, "%x", GetBits( &p_vpar->bit_stream, 16 ) ); {
fprintf( stderr, "%x\n", GetBits( &p_vpar->bit_stream, 16 ) ); i_vector += ((i_motion_code-1) << i_r_size) + i_motion_residual + 1;
exit(0); if( i_vector >= i_limit )
i_vector -= i_limit + i_limit;
}
else if( i_motion_code < 0 )
{
i_vector -= ((-i_motion_code-1) << i_r_size) + i_motion_residual + 1;
if( i_vector < -i_limit )
i_vector += i_limit + i_limit;
}
*pi_prediction = i_vector << i_full_pel;
} }
if( p_vpar->mb.i_mb_type & MB_PATTERN ) /****************************************************************************
* MotionVector : Parse the next motion_vector field
****************************************************************************/
static __inline__ void MotionVector( vpar_thread_t * p_vpar,
macroblock_t * p_mb, int i_r,
int i_s, int i_full_pel, int i_structure )
{
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 = MotionCode( p_vpar );
i_motion_residual = (i_r_size != 0 && i_motion_code != 0) ?
GetBits( &p_vpar->bit_stream, i_r_size) : 0;
DecodeMotionVector( &p_vpar->slice.pppi_pmv[i_r][i_s][0], i_r_size,
i_motion_code, i_motion_residual, i_full_pel );
p_mb->pppi_motion_vectors[i_r][i_s][0] = p_vpar->slice.pppi_pmv[i_r][i_s][0];
if( p_vpar->mb.b_dmv )
{
if( GetBits(&p_vpar->bit_stream, 1) )
{ {
p_mb->i_coded_block_pattern = p_vpar->mb.i_coded_block_pattern = (*p_vpar->sequence.pf_decode_pattern)( p_vpar ); pi_dm_vector[0] = GetBits( &p_vpar->bit_stream, 1 ) ? -1 : 1;
//fprintf( stderr, "pattern : %d\n", p_vpar->mb.i_coded_block_pattern );
} }
else else
{ {
int pi_coded_block_pattern[2] = {0, pi_dm_vector[0] = 0;
(1 << (4+p_vpar->sequence.i_chroma_nb_blocks)) - 1}; }
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];
} }
/* i_r_size = p_vpar->picture.ppi_f_code[i_s][1]-1;
* Effectively decode blocks. i_motion_code = MotionCode( p_vpar );
*/ i_motion_residual = (i_r_size != 0 && i_motion_code != 0) ?
GetBits( &p_vpar->bit_stream, i_r_size) : 0;
i_mask = 1 << (3 + p_vpar->sequence.i_chroma_nb_blocks);
/* luminance */ if( (p_vpar->mb.i_mv_format == MOTION_FIELD)
p_data1 = p_mb->p_picture->p_y && (i_structure == FRAME_STRUCTURE) )
+ p_mb->i_l_x + p_mb->i_l_y*(p_vpar->sequence.i_width); {
p_vpar->slice.pppi_pmv[i_r][i_s][1] >>= 1;
}
for( i_b = 0 ; i_b < 4 ; i_b++, i_mask >>= 1 ) DecodeMotionVector( &p_vpar->slice.pppi_pmv[i_r][i_s][1], i_r_size,
i_motion_code, i_motion_residual, i_full_pel );
if( (p_vpar->mb.i_mv_format == MOTION_FIELD)
&& (i_structure == FRAME_STRUCTURE) )
p_vpar->slice.pppi_pmv[i_r][i_s][1] <<= 1;
p_mb->pppi_motion_vectors[i_r][i_s][1] = p_vpar->slice.pppi_pmv[i_r][i_s][1];
if( p_vpar->mb.b_dmv )
{ {
if( p_vpar->mb.i_coded_block_pattern & i_mask ) if( GetBits(&p_vpar->bit_stream, 1) )
{ {
memset( p_mb->ppi_blocks[i_b], 0, 64*sizeof(dctelem_t) ); pi_dm_vector[1] = GetBits( &p_vpar->bit_stream, 1 ) ? -1 : 1;
(*pppf_decode_block[p_vpar->sequence.b_mpeg2]
[p_vpar->mb.i_mb_type & MB_INTRA])
( p_vpar, p_mb, i_b );
/* 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
{
pi_dm_vector[1] = 0;
} }
/* chrominance */ /* Dual Prime Arithmetic (ISO/IEC 13818-2 section 7.6.3.6). */
p_data1 = p_mb->p_picture->p_u
+ p_mb->i_c_x
+ p_mb->i_c_y
* (p_vpar->sequence.i_chroma_width);
p_data2 = p_mb->p_picture->p_v
+ p_mb->i_c_x
+ p_mb->i_c_y
* (p_vpar->sequence.i_chroma_width);
for( i_b = 4; i_b < 4 + p_vpar->sequence.i_chroma_nb_blocks; #define i_mv_x p_mb->pppi_motion_vectors[0][0][0]
i_b++, i_mask >>= 1 ) if( i_structure == FRAME_STRUCTURE )
{ {
yuv_data_t * pp_data[2] = {p_data1, p_data2}; #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)) >> 1) + pi_dm_vector[1] - 1;
if( p_vpar->mb.i_coded_block_pattern & i_mask ) /* vector for prediction of bottom field from top field */
p_mb->ppi_dmv[1][0] = ((3*i_mv_x + (i_mv_x > 0)) >> 1) + pi_dm_vector[0];
p_mb->ppi_dmv[1][1] = ((3*i_mv_y + (i_mv_y > 0)) >> 1) + pi_dm_vector[1] + 1;
}
else
{ {
memset( p_mb->ppi_blocks[i_b], 0, 64*sizeof(dctelem_t) ); /* vector for prediction of top field from bottom field */
(*pppf_decode_block[p_vpar->sequence.b_mpeg2] p_mb->ppi_dmv[0][0] = ((3*i_mv_x + (i_mv_x > 0)) >> 1) + pi_dm_vector[0];
[p_vpar->mb.i_mb_type & MB_INTRA]) p_mb->ppi_dmv[0][1] = ((3*i_mv_y + (i_mv_y > 0)) >> 1) + pi_dm_vector[1] - 1;
( p_vpar, p_mb, i_b );
/* Calculate block coordinates. */ /* vector for prediction of bottom field from top field */
p_mb->p_data[i_b] = pp_data[i_b & 1] p_mb->ppi_dmv[1][0] = ((i_mv_x + (i_mv_x > 0)) >> 1) + pi_dm_vector[0];
+ pi_y[p_vpar->mb.b_dct_type][i_b] p_mb->ppi_dmv[1][1] = ((i_mv_y + (i_mv_y > 0)) >> 1) + pi_dm_vector[1] + 1;
* p_vpar->sequence.i_chroma_width
+ pi_x[i_b];
} }
#undef i_mv_y
} }
else
if( !( p_vpar->mb.i_mb_type & MB_INTRA ) )
{ {
static int pi_dc_dct_reinit[4] = {128,256,512,1024}; #define i_mv_y p_mb->pppi_motion_vectors[0][0][1]
/* vector for prediction from field of opposite 'parity' */
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)) >> 1) + pi_dm_vector[1];
/* Reset DC predictors (7.2.1). */ /* correct for vertical field shift */
p_vpar->slice.pi_dc_dct_pred[0] = p_vpar->slice.pi_dc_dct_pred[1] if( p_vpar->picture.i_structure == TOP_FIELD )
= p_vpar->slice.pi_dc_dct_pred[2] p_mb->ppi_dmv[0][1]--;
= pi_dc_dct_reinit[p_vpar->picture.i_intra_dc_precision]; else
p_mb->ppi_dmv[0][1]++;
#undef i_mv_y
} }
else if( !p_vpar->picture.b_concealment_mv ) #undef i_mv_x
{
/* Reset MV predictors. */
memset( p_vpar->slice.pppi_pmv, 0, 8*sizeof(int) );
} }
}
/*****************************************************************************
* DecodeMVMPEG1 : Parse the next MPEG-1 motion vectors
*****************************************************************************/
static __inline__ void DecodeMVMPEG1( vpar_thread_t * p_vpar,
macroblock_t * p_mb, int i_s, int i_structure )
{
MotionVector( p_vpar, p_mb, 0, i_s,
p_vpar->picture.pb_full_pel_vector[i_s], i_structure );
}
if( p_mb->b_P_coding_type && !(p_vpar->mb.i_mb_type & (MB_MOTION_FORWARD|MB_INTRA)) ) /*****************************************************************************
* DecodeMVMPEG2 : Parse the next MPEG-2 motion_vectors field
*****************************************************************************/
static __inline__ void DecodeMVMPEG2( vpar_thread_t * p_vpar,
macroblock_t * p_mb, int i_s, int i_structure )
{
if( p_vpar->mb.i_mv_count == 1 )
{ {
p_mb->i_mb_type |= MB_MOTION_FORWARD; if( p_vpar->mb.i_mv_format == MOTION_FIELD && !p_vpar->mb.b_dmv )
{
p_mb->ppi_field_select[0][i_s] = p_mb->ppi_field_select[1][i_s]
= GetBits( &p_vpar->bit_stream, 1 );
} }
MotionVector( p_vpar, p_mb, 0, i_s, 0, i_structure );
p_vpar->slice.pppi_pmv[1][i_s][0] = p_vpar->slice.pppi_pmv[0][i_s][0];
p_vpar->slice.pppi_pmv[1][i_s][1] = p_vpar->slice.pppi_pmv[0][i_s][1];
p_mb->pppi_motion_vectors[1][i_s][0] = p_vpar->slice.pppi_pmv[0][i_s][0];
p_mb->pppi_motion_vectors[1][i_s][1] = p_vpar->slice.pppi_pmv[0][i_s][1];
}
else
{
p_mb->ppi_field_select[0][i_s] = GetBits( &p_vpar->bit_stream, 1 );
MotionVector( p_vpar, p_mb, 0, i_s, 0, i_structure );
p_mb->ppi_field_select[1][i_s] = GetBits( &p_vpar->bit_stream, 1 );
MotionVector( p_vpar, p_mb, 1, i_s, 0, i_structure );
}
}
#ifndef VDEC_SMP
/* Decode the macroblock NOW ! */
vdec_DecodeMacroblock( p_vpar->pp_vdec[0], p_mb );
#endif
/* /*
if( p_vpar->picture.i_coding_type != I_CODING_TYPE )//!(p_mb->b_P_coding_type & MB_INTRA) ) * Macroblock information structures
{ */
p_mb->i_mb_type |= MB_MOTION_FORWARD;
} /*****************************************************************************
*/ * MacroblockAddressIncrement : Get the macroblock_address_increment field
if( 0 ) *****************************************************************************/
//i_count == 249) static __inline__ int MacroblockAddressIncrement( vpar_thread_t * p_vpar )
// i_count != *pi_mb_address)
//b_stop )
{ {
fprintf( stderr, "i_count = %d (%d)\n", i_count, i_inc ); int i_addr_inc = 0;
fprintf( stderr, "%x", GetBits( &p_vpar->bit_stream, 16 ) ); /* Index in the lookup table mb_addr_inc */
fprintf( stderr, "%x ", GetBits( &p_vpar->bit_stream, 16 ) ); int i_index = ShowBits( &p_vpar->bit_stream, 11 );
fprintf( stderr, "%x", GetBits( &p_vpar->bit_stream, 16 ) );
fprintf( stderr, "%x\n", GetBits( &p_vpar->bit_stream, 16 ) ); /* Test the presence of the escape character */
fprintf( stderr, "%x", GetBits( &p_vpar->bit_stream, 16 ) ); while( i_index == 8 )
fprintf( stderr, "%x ", GetBits( &p_vpar->bit_stream, 16 ) ); {
fprintf( stderr, "%x", GetBits( &p_vpar->bit_stream, 16 ) ); RemoveBits( &p_vpar->bit_stream, 11 );
fprintf( stderr, "%x\n", GetBits( &p_vpar->bit_stream, 16 ) ); i_addr_inc += 33;
exit(0); i_index = ShowBits( &p_vpar->bit_stream, 11 );
} }
/* Affect the value from the lookup table */
i_addr_inc += p_vpar->pl_mb_addr_inc[i_index].i_value;
/* Dump the good number of bits */
RemoveBits( &p_vpar->bit_stream, p_vpar->pl_mb_addr_inc[i_index].i_length );
return i_addr_inc;
} }
/***************************************************************************** /*****************************************************************************
* vpar_IMBType : macroblock_type in I pictures * IMBType : macroblock_type in I pictures
*****************************************************************************/ *****************************************************************************/
int vpar_IMBType( vpar_thread_t * p_vpar ) static __inline__ int IMBType( vpar_thread_t * p_vpar )
{ {
/* Take two bits for testing */ /* Take two bits for testing */
int i_type = ShowBits( &p_vpar->bit_stream, 2 ); int i_type = ShowBits( &p_vpar->bit_stream, 2 );
...@@ -1010,50 +1233,13 @@ int vpar_IMBType( vpar_thread_t * p_vpar ) ...@@ -1010,50 +1233,13 @@ int vpar_IMBType( vpar_thread_t * p_vpar )
} }
/***************************************************************************** /*****************************************************************************
* vpar_PMBType : macroblock_type in P pictures * PMBType : macroblock_type in P pictures
*****************************************************************************/ *****************************************************************************/
int vpar_PMBType( vpar_thread_t * p_vpar ) static __inline__ int PMBType( vpar_thread_t * p_vpar )
{ {
/* Testing on 6 bits */ /* Testing on 6 bits */
int i_type = ShowBits( &p_vpar->bit_stream, 6 ); int i_type = ShowBits( &p_vpar->bit_stream, 6 );
#if 0
/* Table B-3, macroblock_type in P-pictures, codes 001..1xx */
static lookup_t PMBtab0[8] = {
{-1,0},
{MB_MOTION_FORWARD,3},
{MB_PATTERN,2}, {MB_PATTERN,2},
{MB_MOTION_FORWARD|MB_PATTERN,1},
{MB_MOTION_FORWARD|MB_PATTERN,1},
{MB_MOTION_FORWARD|MB_PATTERN,1},
{MB_MOTION_FORWARD|MB_PATTERN,1}
};
/* Table B-3, macroblock_type in P-pictures, codes 000001..00011x */
static lookup_t PMBtab1[8] = {
{-1,0},
{MB_QUANT|MB_INTRA,6},
{MB_QUANT|MB_PATTERN,5}, {MB_QUANT|MB_PATTERN,5},
{MB_QUANT|MB_MOTION_FORWARD|MB_PATTERN,5}, {MB_QUANT|MB_MOTION_FORWARD|MB_PATTERN,5},
{MB_INTRA,5}, {MB_INTRA,5}
};
if(i_type >= 8)
{
i_type >>= 3;
RemoveBits( &p_vpar->bit_stream,PMBtab0[i_type].i_length );
return PMBtab0[i_type].i_value;
}
if (i_type==0)
{
printf("Invalid P macroblock_type code\n");
return -1;
}
RemoveBits( &p_vpar->bit_stream,PMBtab1[i_type].i_length );
return PMBtab1[i_type].i_value;
#endif
/* Dump the good number of bits */ /* Dump the good number of bits */
RemoveBits( &p_vpar->bit_stream, p_vpar->ppl_mb_type[0][i_type].i_length ); RemoveBits( &p_vpar->bit_stream, p_vpar->ppl_mb_type[0][i_type].i_length );
/* return the value from the lookup table for P type */ /* return the value from the lookup table for P type */
...@@ -1061,9 +1247,9 @@ static lookup_t PMBtab1[8] = { ...@@ -1061,9 +1247,9 @@ static lookup_t PMBtab1[8] = {
} }
/***************************************************************************** /*****************************************************************************
* vpar_BMBType : macroblock_type in B pictures * BMBType : macroblock_type in B pictures
*****************************************************************************/ *****************************************************************************/
int vpar_BMBType( vpar_thread_t * p_vpar ) static __inline__ int BMBType( vpar_thread_t * p_vpar )
{ {
/* Testing on 6 bits */ /* Testing on 6 bits */
int i_type = ShowBits( &p_vpar->bit_stream, 6 ); int i_type = ShowBits( &p_vpar->bit_stream, 6 );
...@@ -1076,23 +1262,17 @@ int vpar_BMBType( vpar_thread_t * p_vpar ) ...@@ -1076,23 +1262,17 @@ int vpar_BMBType( vpar_thread_t * p_vpar )
} }
/***************************************************************************** /*****************************************************************************
* vpar_DMBType : macroblock_type in D pictures * DMBType : macroblock_type in D pictures
*****************************************************************************/ *****************************************************************************/
int vpar_DMBType( vpar_thread_t * p_vpar ) static __inline__ int DMBType( vpar_thread_t * p_vpar )
{ {
/* Taking 1 bit */ return GetBits( &p_vpar->bit_stream, 1 );
int i_type = GetBits( &p_vpar->bit_stream, 1 );
/* Lookup table */
static int pi_mb_Dtype[2] = { MB_ERROR, 1 };
return pi_mb_Dtype[i_type];
} }
/***************************************************************************** /*****************************************************************************
* vpar_CodedPattern420 : coded_block_pattern with 420 chroma * CodedPattern420 : coded_block_pattern with 4:2:0 chroma
*****************************************************************************/ *****************************************************************************/
int vpar_CodedPattern420( vpar_thread_t * p_vpar ) static __inline__ int CodedPattern420( vpar_thread_t * p_vpar )
{ {
/* Take the max 9 bits length vlc code for testing */ /* Take the max 9 bits length vlc code for testing */
int i_vlc = ShowBits( &p_vpar->bit_stream, 9 ); int i_vlc = ShowBits( &p_vpar->bit_stream, 9 );
...@@ -1105,414 +1285,600 @@ int vpar_CodedPattern420( vpar_thread_t * p_vpar ) ...@@ -1105,414 +1285,600 @@ int vpar_CodedPattern420( vpar_thread_t * p_vpar )
} }
/***************************************************************************** /*****************************************************************************
* vpar_CodedPattern422 : coded_block_pattern with 422 chroma * CodedPattern422 : coded_block_pattern with 4:2:2 chroma
*****************************************************************************/ *****************************************************************************/
int vpar_CodedPattern422( vpar_thread_t * p_vpar ) static __inline__ int CodedPattern422( vpar_thread_t * p_vpar )
{ {
int i_vlc = ShowBits( &p_vpar->bit_stream, 9 ); int i_vlc = ShowBits( &p_vpar->bit_stream, 9 );
/* Supplementary 2 bits long code for 422 format */
int i_coded_block_pattern_1;
RemoveBits( &p_vpar->bit_stream, p_vpar->pl_coded_pattern[i_vlc].i_length ); RemoveBits( &p_vpar->bit_stream, p_vpar->pl_coded_pattern[i_vlc].i_length );
i_coded_block_pattern_1 = GetBits( &p_vpar->bit_stream, 2 );
/* the code is just to be added to the value found in the table */ /* Supplementary 2 bits long code for 4:2:2 format */
return p_vpar->pl_coded_pattern[i_vlc].i_value | return p_vpar->pl_coded_pattern[i_vlc].i_value |
(i_coded_block_pattern_1 << 6); (GetBits( &p_vpar->bit_stream, 2 ) << 6);
} }
/***************************************************************************** /*****************************************************************************
* vpar_CodedPattern444 : coded_block_pattern with 444 chroma * CodedPattern444 : coded_block_pattern with 4:4:4 chroma
*****************************************************************************/ *****************************************************************************/
int vpar_CodedPattern444( vpar_thread_t * p_vpar ) static __inline__ int CodedPattern444( vpar_thread_t * p_vpar )
{ {
int i_vlc = ShowBits( &p_vpar->bit_stream, 9 ); int i_vlc = ShowBits( &p_vpar->bit_stream, 9 );
int i_coded_block_pattern_2;
RemoveBits( &p_vpar->bit_stream, p_vpar->pl_coded_pattern[i_vlc].i_length ); RemoveBits( &p_vpar->bit_stream, p_vpar->pl_coded_pattern[i_vlc].i_length );
i_coded_block_pattern_2 = GetBits( &p_vpar->bit_stream, 6 );
return p_vpar->pl_coded_pattern[i_vlc].i_value | return p_vpar->pl_coded_pattern[i_vlc].i_value |
( i_coded_block_pattern_2 << 6 ); (GetBits( &p_vpar->bit_stream, 6 ) << 6);
} }
/***************************************************************************** /*****************************************************************************
* vpar_DecodeMPEG1Non : decode MPEG-1 non-intra blocks * InitMacroblock : Initialize macroblock values
*****************************************************************************/ *****************************************************************************/
static void vpar_DecodeMPEG1Non( vpar_thread_t * p_vpar, macroblock_t * p_mb, int i_b ) static __inline__ void InitMacroblock( vpar_thread_t * p_vpar,
macroblock_t * p_mb, int i_coding_type,
int i_structure,
boolean_t b_second_field )
{ {
p_mb->i_chroma_nb_blocks = p_vpar->sequence.i_chroma_nb_blocks;
p_mb->p_picture = p_vpar->picture.p_picture;
if( p_vpar->picture.i_coding_type == D_CODING_TYPE ) if( i_coding_type == B_CODING_TYPE )
p_mb->p_backward = p_vpar->sequence.p_backward;
else
p_mb->p_backward = NULL;
if( (i_coding_type == P_CODING_TYPE) || (i_coding_type == B_CODING_TYPE) )
p_mb->p_forward = p_vpar->sequence.p_forward;
else
p_mb->p_forward = NULL;
p_mb->i_l_x = p_vpar->mb.i_l_x;
p_mb->i_c_x = p_vpar->mb.i_c_x;
p_mb->i_motion_l_y = p_vpar->mb.i_l_y;
p_mb->i_motion_c_y = p_vpar->mb.i_c_y;
if( (p_mb->b_motion_field = (i_structure == BOTTOM_FIELD)) )
{ {
/* Remove end_of_macroblock (always 1, prevents startcode emulation) p_mb->i_motion_l_y--;
* ISO/IEC 11172-2 section 2.4.2.7 and 2.4.3.6 */ p_mb->i_motion_c_y--;
RemoveBits( &p_vpar->bit_stream, 1 );
} }
p_mb->i_addb_l_stride = (p_mb->i_l_stride = p_vpar->picture.i_l_stride) - 8;
p_mb->i_addb_c_stride = (p_mb->i_c_stride = p_vpar->picture.i_c_stride) - 8;
p_mb->b_P_second = ( b_second_field && i_coding_type == P_CODING_TYPE );
} }
/***************************************************************************** /*****************************************************************************
* vpar_DecodeMPEG1Intra : decode MPEG-1 intra blocks * UpdateContext : Update the p_vpar contextual values
*****************************************************************************/ *****************************************************************************/
static void vpar_DecodeMPEG1Intra( vpar_thread_t * p_vpar, macroblock_t * p_mb, int i_b ) static __inline__ void UpdateContext( vpar_thread_t * p_vpar, int i_structure )
{ {
/* Update macroblock real position. */
p_vpar->mb.i_l_x += 16;
p_vpar->mb.i_l_y += (p_vpar->mb.i_l_x / p_vpar->sequence.i_width)
* (2 - (i_structure == FRAME_STRUCTURE)) * 16;
p_vpar->mb.i_l_x %= p_vpar->sequence.i_width;
if( p_vpar->picture.i_coding_type == D_CODING_TYPE ) p_vpar->mb.i_c_x += p_vpar->sequence.i_chroma_mb_width;
{ p_vpar->mb.i_c_y += (p_vpar->mb.i_c_x / p_vpar->sequence.i_chroma_width)
/* Remove end_of_macroblock (always 1, prevents startcode emulation) * (2 - (i_structure == FRAME_STRUCTURE))
* ISO/IEC 11172-2 section 2.4.2.7 and 2.4.3.6 */ * p_vpar->sequence.i_chroma_mb_height;
RemoveBits( &p_vpar->bit_stream, 1 ); p_vpar->mb.i_c_x %= p_vpar->sequence.i_chroma_width;
}
} }
/***************************************************************************** /*****************************************************************************
* vpar_DecodeMPEG2Non : decode MPEG-2 non-intra blocks * SkippedMacroblock : Generate a skipped macroblock with NULL motion vector
*****************************************************************************/ *****************************************************************************/
static void vpar_DecodeMPEG2Non( vpar_thread_t * p_vpar, macroblock_t * p_mb, int i_b ) static __inline__ void SkippedMacroblock( vpar_thread_t * p_vpar, int i_mb,
int i_mb_base, int i_coding_type,
int i_chroma_format,
int i_structure,
boolean_t b_second_field )
{ {
int i_parse; macroblock_t * p_mb;
int i_nc;
int i_cc;
int i_coef;
int i_type;
int i_code;
int i_length;
int i_pos;
int i_run;
int i_level;
int i_quant_type;
boolean_t b_sign;
int * ppi_quant[2];
/* Lookup Table for the chromatic component */ static f_motion_t pf_motion_skipped[4][4] =
static int pi_cc_index[12] = { 0, 0, 0, 0, 1, 2, 1, 2, 1, 2 }; {
{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},
};
i_cc = pi_cc_index[i_b]; if( (p_mb = vpar_NewMacroblock( &p_vpar->vfifo )) == NULL )
{
/* b_die == 1 */
return;
}
#ifdef VDEC_SMP
p_vpar->picture.pp_mb[i_mb_base + i_mb] = p_mb;
#endif
/* Determine whether it is luminance or not (chrominance) */ InitMacroblock( p_vpar, p_mb, i_coding_type, i_structure, b_second_field );
i_type = ( i_cc + 1 ) >> 1;
i_quant_type = (!i_type) || (p_vpar->sequence.i_chroma_format == CHROMA_420);
/* Give a pointer to the quantization matrices for intra blocks */ /* Motion type is picture structure. */
ppi_quant[1] = p_vpar->sequence.nonintra_quant.pi_matrix; p_mb->pf_motion = pf_motion_skipped[i_chroma_format]
ppi_quant[0] = p_vpar->sequence.chroma_nonintra_quant.pi_matrix; [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) );
/* Decoding of the AC coefficients */ /* Set the field we use for motion compensation */
p_mb->ppi_field_select[0][0] = p_mb->ppi_field_select[0][1]
= ( i_structure == BOTTOM_FIELD );
i_nc = 0; UpdateContext( p_vpar, i_structure );
i_coef = 0;
for( i_parse = 0; ; i_parse++ ) #ifndef VDEC_SMP
/* Decode the macroblock NOW ! */
vdec_DecodeMacroblock( p_vpar->pp_vdec[0], p_mb );
#endif
}
/*****************************************************************************
* MacroblockModes : Get the macroblock_modes structure
*****************************************************************************/
static __inline__ void MacroblockModes( vpar_thread_t * p_vpar,
macroblock_t * p_mb,
int i_chroma_format,
int i_coding_type,
int i_structure )
{
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} };
/* Get macroblock_type. */
switch( i_coding_type )
{ {
i_code = ShowBits( &p_vpar->bit_stream, 16 ); case P_CODING_TYPE:
if( i_code >= 16384 ) p_mb->i_mb_type = PMBType( p_vpar );
break;
case B_CODING_TYPE:
p_mb->i_mb_type = BMBType( p_vpar );
break;
case I_CODING_TYPE:
p_mb->i_mb_type = IMBType( p_vpar );
break;
case D_CODING_TYPE:
p_mb->i_mb_type = DMBType( p_vpar );
}
/* SCALABILITY : warning, we don't know if spatial_temporal_weight_code
* has to be dropped, take care if you use scalable streams. */
/* RemoveBits( &p_vpar->bit_stream, 2 ); */
if( p_mb->i_mb_type & (MB_MOTION_FORWARD | MB_MOTION_BACKWARD) )
{ {
if( i_parse == 0 ) if( !(i_structure == FRAME_STRUCTURE
&& p_vpar->picture.b_frame_pred_frame_dct) )
{ {
i_run = pl_DCT_tab_dc[(i_code>>12)-4].i_run; p_vpar->mb.i_motion_type = GetBits( &p_vpar->bit_stream, 2 );
i_level = pl_DCT_tab_dc[(i_code>>12)-4].i_level;
i_length = pl_DCT_tab_dc[(i_code>>12)-4].i_length;
} }
else else
{ {
i_run = pl_DCT_tab_ac[(i_code>>12)-4].i_run; p_vpar->mb.i_motion_type = MOTION_FRAME;
i_level = pl_DCT_tab_ac[(i_code>>12)-4].i_level;
i_length = pl_DCT_tab_ac[(i_code>>12)-4].i_length;
} }
} }
else if( i_code >= 1024 )
/* ???? */
p_vpar->mb.i_mv_count = ppi_mv_count[i_structure == FRAME_STRUCTURE]
[p_vpar->mb.i_motion_type];
p_vpar->mb.i_mv_format = ppi_mv_format[i_structure == FRAME_STRUCTURE]
[p_vpar->mb.i_motion_type];
p_vpar->mb.b_dmv = p_vpar->mb.i_motion_type == MOTION_DMV;
p_vpar->mb.b_dct_type = 0;
if( (i_structure == FRAME_STRUCTURE) &&
(!p_vpar->picture.b_frame_pred_frame_dct) &&
(p_mb->i_mb_type & (MB_PATTERN|MB_INTRA)) )
{ {
i_run = pl_DCT_tab0[(i_code>>8)-4].i_run; if( (p_vpar->mb.b_dct_type = GetBits( &p_vpar->bit_stream, 1 )) )
i_length = pl_DCT_tab0[(i_code>>8)-4].i_length; {
i_level = pl_DCT_tab0[(i_code>>8)-4].i_level; /* The DCT is coded on fields. Jump one line between each
* sample. */
p_mb->i_addb_l_stride <<= 1;
p_mb->i_addb_l_stride += 8;
/* With CHROMA_420, the DCT is necessarily frame-coded. */
if( i_chroma_format != CHROMA_420 )
{
p_mb->i_addb_c_stride <<= 1;
p_mb->i_addb_c_stride += 8;
} }
else }
}
}
/*****************************************************************************
* ParseMacroblock : Parse the next macroblock
*****************************************************************************/
static __inline__ void ParseMacroblock(
vpar_thread_t * p_vpar,
int * pi_mb_address, /* previous address to be
* used for mb_addr_incr */
int i_mb_previous, /* actual previous mb */
int i_mb_base, /* non-zero if field structure */
/* The following parameters are explicit in
* optimized routines : */
boolean_t b_mpeg2, /* you know what ? */
int i_coding_type, /* I, P, B or D */
int i_chroma_format, /* 4:2:0, 4:2:2 or 4:4:4 */
int i_structure, /* T(OP), B(OTTOM) or F(RAME) */
boolean_t b_second_field ) /* second field of a
* field picture */
{
static f_motion_t pppf_motion[4][2][4] =
{ {
i_run = ppl_dct_coef[0][i_code].i_run; { {NULL, NULL, NULL, NULL},
i_length = ppl_dct_coef[0][i_code].i_length; {NULL, NULL, NULL, NULL}
i_level = ppl_dct_coef[0][i_code].i_level; },
{ {NULL, vdec_MotionFieldField420, vdec_MotionField16x8420,
vdec_MotionFieldDMV420},
{NULL, vdec_MotionFrameField420, vdec_MotionFrameFrame420,
vdec_MotionFrameDMV420}
},
{ {NULL, vdec_MotionFieldField422, vdec_MotionField16x8422,
vdec_MotionFieldDMV422},
{NULL, vdec_MotionFrameField422, vdec_MotionFrameFrame422,
vdec_MotionFrameDMV422}
},
{ {NULL, vdec_MotionFieldField444, vdec_MotionField16x8444,
vdec_MotionFieldDMV444},
{NULL, vdec_MotionFrameField444, vdec_MotionFrameFrame444,
vdec_MotionFrameDMV444}
} }
};
static f_decode_block_t pppf_decode_block[2][2] =
{ {vpar_DecodeMPEG1Non, vpar_DecodeMPEG1Intra},
{vpar_DecodeMPEG2Non, vpar_DecodeMPEG2Intra} };
static int pi_x[12] = {0,8,0,8,0,0,0,0,8,8,8,8};
static int pi_y[2][12] = { {0,0,8,8,0,0,8,8,0,0,8,8},
{0,0,1,1,0,0,1,1,0,0,1,1} };
static int pi_dc_dct_reinit[4] = {128,256,512,1024};
int i_mb, i_b, i_mask;
macroblock_t * p_mb;
yuv_data_t * p_data1;
yuv_data_t * p_data2;
RemoveBits( &p_vpar->bit_stream, i_length ); *pi_mb_address += MacroblockAddressIncrement( p_vpar );
switch( i_run ) if( *pi_mb_address - i_mb_previous - 1 )
{ {
case DCT_ESCAPE: /* Skipped macroblock (ISO/IEC 13818-2 7.6.6). */
i_run = GetBits( &p_vpar->bit_stream, 6 );
i_level = GetBits( &p_vpar->bit_stream, 12 ); /* Reset DC predictors (7.2.1). */
i_level = (b_sign = ( i_level > 2047 )) ? 4096 - i_level p_vpar->slice.pi_dc_dct_pred[0] = p_vpar->slice.pi_dc_dct_pred[1]
: i_level; = p_vpar->slice.pi_dc_dct_pred[2]
break; = pi_dc_dct_reinit[p_vpar->picture.i_intra_dc_precision];
case DCT_EOB:
if( i_nc <= 1 ) if( i_coding_type == P_CODING_TYPE )
{ {
p_mb->pf_idct[i_b] = vdec_SparseIDCT; /* Reset motion vector predictors (ISO/IEC 13818-2 7.6.3.4). */
p_mb->pi_sparse_pos[i_b] = i_coef; memset( p_vpar->slice.pppi_pmv, 0, 8*sizeof(int) );
} }
else
for( i_mb = i_mb_previous + 1; i_mb < *pi_mb_address; i_mb++ )
{ {
p_mb->pf_idct[i_b] = vdec_IDCT; SkippedMacroblock( p_vpar, i_mb, i_mb_base, i_coding_type,
i_chroma_format, i_structure, b_second_field );
} }
return;
break;
default:
b_sign = GetBits( &p_vpar->bit_stream, 1 );
} }
i_coef = i_parse;
i_parse += i_run;
i_nc ++;
if( i_parse >= 64 )
{
break;
}
i_pos = pi_scan[p_vpar->picture.b_alternate_scan][i_parse]; /* Get a macroblock structure. */
i_level = ( ((i_level << 1) + 1) * p_vpar->slice.i_quantizer_scale if( (p_mb = vpar_NewMacroblock( &p_vpar->vfifo )) == NULL )
* ppi_quant[i_quant_type][i_pos] ) >> 5; {
p_mb->ppi_blocks[i_b][i_pos] = b_sign ? -i_level : i_level; /* b_die == 1 */
return;
} }
fprintf( stderr, "Non intra MPEG2 end (%d)\n", i_b ); #ifdef VDEC_SMP
p_vpar->picture.b_error = 1; p_vpar->picture.pp_mb[i_mb_base + *pi_mb_address] = p_mb;
} #endif
/*****************************************************************************
* vpar_DecodeMPEG2Intra : decode MPEG-2 intra blocks
*****************************************************************************/
static void vpar_DecodeMPEG2Intra( vpar_thread_t * p_vpar, macroblock_t * p_mb, int i_b )
{
int i_parse;
int i_nc;
int i_cc;
int i_coef;
int i_type, i_quant_type;
int i_code;
int i_length;
int i_pos;
int i_dct_dc_size;
int i_dct_dc_diff;
int i_run;
int i_level;
boolean_t b_vlc_intra;
boolean_t b_sign;
int * ppi_quant[2];
/* Lookup Table for the chromatic component */ InitMacroblock( p_vpar, p_mb, i_coding_type, i_structure, b_second_field );
static int pi_cc_index[12] = { 0, 0, 0, 0, 1, 2, 1, 2, 1, 2 };
i_cc = pi_cc_index[i_b];
/* Determine whether it is luminance or not (chrominance) */ /* Parse off macroblock_modes structure. */
i_type = ( i_cc + 1 ) >> 1; MacroblockModes( p_vpar, p_mb, i_chroma_format, i_coding_type,
i_quant_type = (!i_type) | (p_vpar->sequence.i_chroma_format == CHROMA_420); i_structure );
/* Give a pointer to the quantization matrices for intra blocks */ if( p_mb->i_mb_type & MB_QUANT )
ppi_quant[1] = p_vpar->sequence.intra_quant.pi_matrix; {
ppi_quant[0] = p_vpar->sequence.chroma_intra_quant.pi_matrix; LoadQuantizerScale( p_vpar );
}
#if 0 if( (i_coding_type == P_CODING_TYPE || i_coding_type == B_CODING_TYPE)
/* Decoding of the DC intra coefficient */ && (p_mb->i_mb_type & MB_MOTION_FORWARD) )
/* The nb of bits to parse depends on i_type */ {
i_code = ShowBits( &p_vpar->bit_stream, 9 + i_type ); if( b_mpeg2 )
DecodeMVMPEG2( p_vpar, p_mb, 0, i_structure );
else
DecodeMVMPEG1( p_vpar, p_mb, 0, i_structure );
}
/* To reduce memory occupation, there are two lookup tables if( (i_coding_type == B_CODING_TYPE)
* See InitDCT above */ && (p_mb->i_mb_type & MB_MOTION_BACKWARD) )
i_code5 = i_code >> (4+i_type); {
if( b_mpeg2 )
DecodeMVMPEG2( p_vpar, p_mb, 1, i_structure );
else
DecodeMVMPEG1( p_vpar, p_mb, 1, i_structure );
}
/* Shall we lookup in the first or in the second table ? */ if( i_coding_type == P_CODING_TYPE
i_select = ( i_code5 == 31 ); && !(p_mb->i_mb_type & (MB_MOTION_FORWARD|MB_INTRA)) )
/* Offset value for looking in the second table */ {
i_offset = 0x1f0 + ( i_type * 0x1f0 ); /* Special No-MC macroblock in P pictures (7.6.3.5). */
i_pos = ( i_code5 * ( ! i_select ) ) + ( ( i_code - i_offset ) * i_select ); p_mb->i_mb_type |= MB_MOTION_FORWARD;
i_dct_dc_size = p_vpar->pppl_dct_dc_size[i_type][i_select][i_pos].i_value; memset( p_vpar->slice.pppi_pmv, 0, 8*sizeof(int) );
#endif memset( p_mb->pppi_motion_vectors, 0, 8*sizeof(int) );
p_vpar->mb.i_motion_type = 1 + (i_structure == FRAME_STRUCTURE);
p_mb->ppi_field_select[0][0] = (i_structure == BOTTOM_FIELD);
}
if( !i_type/*i_b < 4*/ ) if( !(p_mb->i_mb_type & MB_INTRA) )
{ {
/* decode length */ /* Reset DC predictors (7.2.1). */
i_code = ShowBits(&p_vpar->bit_stream, 5); p_vpar->slice.pi_dc_dct_pred[0] = p_vpar->slice.pi_dc_dct_pred[1]
if (i_code<31) = p_vpar->slice.pi_dc_dct_pred[2]
= pi_dc_dct_reinit[p_vpar->picture.i_intra_dc_precision];
/* Motion function pointer. */
p_mb->pf_motion = pppf_motion[i_chroma_format]
[i_structure == FRAME_STRUCTURE]
[p_vpar->mb.i_motion_type];
if( p_mb->i_mb_type & MB_PATTERN )
{ {
i_dct_dc_size = pl_dct_dc_lum_init_table_1[i_code].i_value; switch( i_chroma_format )
i_length = pl_dct_dc_lum_init_table_1[i_code].i_length; {
RemoveBits( &p_vpar->bit_stream, i_length); case CHROMA_420:
p_mb->i_coded_block_pattern = CodedPattern420( p_vpar );
break;
case CHROMA_422:
p_mb->i_coded_block_pattern = CodedPattern422( p_vpar );
break;
case CHROMA_444:
p_mb->i_coded_block_pattern = CodedPattern444( p_vpar );
}
} }
else else
{ {
i_code = ShowBits(&p_vpar->bit_stream, 9) - 0x1f0; p_mb->i_coded_block_pattern = 0;
i_dct_dc_size = pl_dct_dc_lum_init_table_2[i_code].i_value;
i_length = pl_dct_dc_lum_init_table_2[i_code].i_length;
RemoveBits( &p_vpar->bit_stream, i_length);
} }
} }
else else
{ {
/* decode length */ if( !p_vpar->picture.b_concealment_mv )
i_code = ShowBits(&p_vpar->bit_stream, 5);
if (i_code<31)
{ {
i_dct_dc_size = pl_dct_dc_chrom_init_table_1[i_code].i_value; /* Reset MV predictors. */
i_length = pl_dct_dc_chrom_init_table_1[i_code].i_length; memset( p_vpar->slice.pppi_pmv, 0, 8*sizeof(int) );
RemoveBits(&p_vpar->bit_stream, i_length);
} }
else else
{ {
i_code = ShowBits(&p_vpar->bit_stream, 10) - 0x3e0; if( b_mpeg2 )
i_dct_dc_size = pl_dct_dc_chrom_init_table_2[i_code].i_value; DecodeMVMPEG2( p_vpar, p_mb, 0, i_structure );
i_length = pl_dct_dc_chrom_init_table_2[i_code].i_length; else
RemoveBits( &p_vpar->bit_stream, i_length); DecodeMVMPEG1( p_vpar, p_mb, 0, i_structure );
RemoveBits( &p_vpar->bit_stream, 1 );
}
if( p_mb->i_mb_type & MB_PATTERN )
{
switch( i_chroma_format )
{
case CHROMA_420:
p_mb->i_coded_block_pattern = CodedPattern420( p_vpar );
break;
case CHROMA_422:
p_mb->i_coded_block_pattern = CodedPattern422( p_vpar );
break;
case CHROMA_444:
p_mb->i_coded_block_pattern = CodedPattern444( p_vpar );
} }
} }
if (i_dct_dc_size==0)
i_dct_dc_diff = 0;
else else
{ {
i_dct_dc_diff = GetBits( &p_vpar->bit_stream, i_dct_dc_size); p_mb->i_coded_block_pattern =
if ((i_dct_dc_diff & (1<<(i_dct_dc_size-1)))==0) (1 << (4 + p_mb->i_chroma_nb_blocks)) - 1;
i_dct_dc_diff-= (1<<i_dct_dc_size) - 1; }
} }
/* Dump the variable length code */ if( p_vpar->picture.b_error )
//RemoveBits( &p_vpar->bit_stream, {
// p_vpar->pppl_dct_dc_size[i_type][i_select][i_pos].i_length ); /* Mark this block as skipped (better than green blocks), and go
* to the next slice. */
(*pi_mb_address)--;
vpar_DestroyMacroblock( &p_vpar->vfifo, p_mb );
return;
}
/* Read the actual code with the good length */ /*
p_vpar->slice.pi_dc_dct_pred[i_cc] += i_dct_dc_diff; * Effectively decode blocks.
*/
p_mb->ppi_blocks[i_b][0] = ( p_vpar->slice.pi_dc_dct_pred[i_cc] << i_mask = 1 << (3 + p_mb->i_chroma_nb_blocks);
( 3 - p_vpar->picture.i_intra_dc_precision ) );
i_nc = ( p_vpar->slice.pi_dc_dct_pred[i_cc] != 0 );
//fprintf( stderr, "coucou\n" ); /* luminance */
/* Decoding of the AC coefficients */ p_data1 = p_mb->p_picture->p_y
+ p_mb->i_l_x + p_vpar->mb.i_l_y*(p_vpar->sequence.i_width);
i_coef = 0; for( i_b = 0 ; i_b < 4 ; i_b++, i_mask >>= 1 )
b_vlc_intra = p_vpar->picture.b_intra_vlc_format;
for( i_parse = 1; /*i_parse < 64*/; i_parse++ )
{
i_code = ShowBits( &p_vpar->bit_stream, 16 );
if( i_code >= 16384 )
{
if( b_vlc_intra )
{ {
i_run = pl_DCT_tab0a[(i_code>>8)-4].i_run; if( p_mb->i_coded_block_pattern & i_mask )
i_level = pl_DCT_tab0a[(i_code>>8)-4].i_level;
i_length = pl_DCT_tab0a[(i_code>>8)-4].i_length;
//fprintf( stderr, "**********> %d, %d, %d *******\n", i_run, i_level, (i_code>>8)-4 );
}
else
{ {
i_run = pl_DCT_tab_ac[(i_code>>12)-4].i_run; memset( p_mb->ppi_blocks[i_b], 0, 64*sizeof(dctelem_t) );
i_level = pl_DCT_tab_ac[(i_code>>12)-4].i_level; (*pppf_decode_block[b_mpeg2]
i_length = pl_DCT_tab_ac[(i_code>>12)-4].i_length; [p_mb->i_mb_type & MB_INTRA])
( p_vpar, p_mb, i_b );
/* 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
if( p_vpar->picture.b_error )
{ {
i_run = ppl_dct_coef[b_vlc_intra][i_code].i_run; /* Mark this block as skipped (better than green blocks), and go
i_length = ppl_dct_coef[b_vlc_intra][i_code].i_length; * to the next slice. */
i_level = ppl_dct_coef[b_vlc_intra][i_code].i_level; (*pi_mb_address)--;
vpar_DestroyMacroblock( &p_vpar->vfifo, p_mb );
return;
} }
#if 0 /* chrominance */
p_data1 = p_mb->p_picture->p_u
+ p_mb->i_c_x
+ p_vpar->mb.i_c_y
* (p_vpar->sequence.i_chroma_width);
p_data2 = p_mb->p_picture->p_v
+ p_mb->i_c_x
+ p_vpar->mb.i_c_y
* (p_vpar->sequence.i_chroma_width);
for( i_b = 4; i_b < 4 + p_mb->i_chroma_nb_blocks;
i_b++, i_mask >>= 1 )
{ {
int code = i_code; yuv_data_t * pp_data[2] = {p_data1, p_data2};
int intra_vlc_format = b_vlc_intra;
dct_lookup_t tab;
if (code>=16384 && !intra_vlc_format) if( p_mb->i_coded_block_pattern & i_mask )
tab = pl_DCT_tab_ac[(code>>12)-4];
else if (code>=1024)
{ {
if (intra_vlc_format) memset( p_mb->ppi_blocks[i_b], 0, 64*sizeof(dctelem_t) );
tab = pl_DCT_tab0a[(code>>8)-4]; (*pppf_decode_block[b_mpeg2]
else [p_mb->i_mb_type & MB_INTRA])
tab = pl_DCT_tab0[(code>>8)-4]; ( p_vpar, p_mb, i_b );
/* 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 if (code>=512) }
if( !p_vpar->picture.b_error )
{ {
if (intra_vlc_format) UpdateContext( p_vpar, i_structure );
tab = pl_DCT_tab1a[(code>>6)-8]; #ifndef VDEC_SMP
else /* Decode the macroblock NOW ! */
tab = pl_DCT_tab1[(code>>6)-8]; vdec_DecodeMacroblock( p_vpar->pp_vdec[0], p_mb );
#endif
} }
else if (code>=256)
tab = pl_DCT_tab2[(code>>4)-16];
else if (code>=128)
tab = pl_DCT_tab3[(code>>3)-16];
else if (code>=64)
tab = pl_DCT_tab4[(code>>2)-16];
else if (code>=32)
tab = pl_DCT_tab5[(code>>1)-16];
else if (code>=16)
tab = pl_DCT_tab6[code-16];
else else
{ {
fprintf( stderr, "invalid Huffman code in Decode_MPEG2_Intra_Block()\n"); /* Mark this block as skipped (better than green blocks), and go
* to the next slice. */
(*pi_mb_address)--;
vpar_DestroyMacroblock( &p_vpar->vfifo, p_mb );
} }
}
if( (i_run != tab.i_run) || (i_length != tab.i_length) || (i_level != tab.i_level) ) /*****************************************************************************
{ * vpar_ParseMacroblockVWXYZ : Parse the next macroblock ; specific functions
fprintf( stderr, "ET M....... !!!\n" ); *****************************************************************************
exit(0); * V = MPEG2 ?
} * W = coding type ?
} * X = chroma format ?
#endif * Y = structure ?
* Z = second field ?
*****************************************************************************/
void vpar_ParseMacroblock2I420F0( vpar_thread_t * 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 )
{
ParseMacroblock( p_vpar, pi_mb_address, i_mb_previous, 0, 1,
I_CODING_TYPE, CHROMA_420, FRAME_STRUCTURE, 0 );
}
void vpar_ParseMacroblock2P420F0( vpar_thread_t * 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 )
{
ParseMacroblock( p_vpar, pi_mb_address, i_mb_previous, 0, 1,
P_CODING_TYPE, CHROMA_420, FRAME_STRUCTURE, 0 );
}
void vpar_ParseMacroblock2B420F0( vpar_thread_t * 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 )
{
ParseMacroblock( p_vpar, pi_mb_address, i_mb_previous, 0, 1,
B_CODING_TYPE, CHROMA_420, FRAME_STRUCTURE, 0 );
}
void vpar_ParseMacroblock2I420T0( vpar_thread_t * 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 )
{
ParseMacroblock( p_vpar, pi_mb_address, i_mb_previous, 0, 1,
I_CODING_TYPE, CHROMA_420, TOP_FIELD, 0 );
}
RemoveBits( &p_vpar->bit_stream, i_length ); void vpar_ParseMacroblock2P420T0( vpar_thread_t * 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 )
{
ParseMacroblock( p_vpar, pi_mb_address, i_mb_previous, 0, 1,
P_CODING_TYPE, CHROMA_420, TOP_FIELD, 0 );
}
switch( i_run ) void vpar_ParseMacroblock2B420T0( vpar_thread_t * p_vpar, int * pi_mb_address,
{ int i_mb_previous, int i_mb_base,
case DCT_ESCAPE: boolean_t b_mpeg2, int i_coding_type,
i_run = GetBits( &p_vpar->bit_stream, 6 ); int i_chroma_format, int i_structure,
i_level = GetBits( &p_vpar->bit_stream, 12 ); boolean_t b_second_field )
/*p_mb->ppi_blocks[i_b][i_parse] = ( b_sign = ( i_level > 2047 ) ) {
? ( -4096 + i_level ) ParseMacroblock( p_vpar, pi_mb_address, i_mb_previous, 0, 1,
: i_level;*/ B_CODING_TYPE, CHROMA_420, TOP_FIELD, 0 );
i_level = (b_sign = ( i_level > 2047 )) ? 4096 - i_level }
: i_level;
break;
case DCT_EOB:
if( i_nc <= 1 )
{
p_mb->pf_idct[i_b] = vdec_SparseIDCT;
p_mb->pi_sparse_pos[i_b] = i_coef;
}
else
{
p_mb->pf_idct[i_b] = vdec_IDCT;
}
return;
break; void vpar_ParseMacroblock2I420B1( vpar_thread_t * p_vpar, int * pi_mb_address,
default: int i_mb_previous, int i_mb_base,
b_sign = GetBits( &p_vpar->bit_stream, 1 ); boolean_t b_mpeg2, int i_coding_type,
//p_mb->ppi_blocks[i_b][i_parse] = b_sign ? -i_level : i_level; int i_chroma_format, int i_structure,
} boolean_t b_second_field )
// fprintf( stderr, "i_code : %d (%d), run : %d, %d, %d (%4x) ", i_code , b_vlc_intra, {
// i_run, i_level, i_parse, ShowBits( &p_vpar->bit_stream, 16 ) ); ParseMacroblock( p_vpar, pi_mb_address, i_mb_previous, i_mb_base, 1,
I_CODING_TYPE, CHROMA_420, BOTTOM_FIELD, 1 );
}
//fprintf( stderr, "- %4x\n",ShowBits( &p_vpar->bit_stream, 16 ) ); void vpar_ParseMacroblock2P420B1( vpar_thread_t * p_vpar, int * pi_mb_address,
if( i_parse >= 64 ) 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 )
{ {
fprintf( stderr, "Beuhh dans l'intra decode (%d)\n", i_b ); ParseMacroblock( p_vpar, pi_mb_address, i_mb_previous, i_mb_base, 1,
break; P_CODING_TYPE, CHROMA_420, BOTTOM_FIELD, 1 );
} }
i_coef = i_parse;
i_parse += i_run;
i_nc ++;
i_pos = pi_scan[p_vpar->picture.b_alternate_scan][i_parse]; void vpar_ParseMacroblock2B420B1( vpar_thread_t * p_vpar, int * pi_mb_address,
i_level = ( i_level * int i_mb_previous, int i_mb_base,
p_vpar->slice.i_quantizer_scale * boolean_t b_mpeg2, int i_coding_type,
ppi_quant[i_quant_type][i_pos] ) >> 4; int i_chroma_format, int i_structure,
p_mb->ppi_blocks[i_b][i_pos] = b_sign ? -i_level : i_level; boolean_t b_second_field )
} {
ParseMacroblock( p_vpar, pi_mb_address, i_mb_previous, i_mb_base, 1,
B_CODING_TYPE, CHROMA_420, BOTTOM_FIELD, 1 );
}
fprintf( stderr, "MPEG2 end (%d)\n", i_b ); void vpar_ParseMacroblockGENERIC( vpar_thread_t * p_vpar, int * pi_mb_address,
p_vpar->picture.b_error = 1; 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 )
{
ParseMacroblock( p_vpar, pi_mb_address, i_mb_previous, i_mb_base, b_mpeg2,
i_coding_type, i_chroma_format, i_structure, b_second_field );
} }
\ No newline at end of file
...@@ -389,9 +389,6 @@ static void SequenceHeader( vpar_thread_t * p_vpar ) ...@@ -389,9 +389,6 @@ static void SequenceHeader( vpar_thread_t * p_vpar )
if( ShowBits( &p_vpar->bit_stream, 32 ) == EXTENSION_START_CODE ) if( ShowBits( &p_vpar->bit_stream, 32 ) == EXTENSION_START_CODE )
{ {
int i_dummy; int i_dummy;
static f_chroma_pattern_t ppf_chroma_pattern[4] =
{NULL, vpar_CodedPattern420,
vpar_CodedPattern422, vpar_CodedPattern444};
/* Turn the MPEG2 flag on */ /* Turn the MPEG2 flag on */
p_vpar->sequence.b_mpeg2 = 1; p_vpar->sequence.b_mpeg2 = 1;
...@@ -402,8 +399,6 @@ static void SequenceHeader( vpar_thread_t * p_vpar ) ...@@ -402,8 +399,6 @@ static void SequenceHeader( vpar_thread_t * p_vpar )
RemoveBits( &p_vpar->bit_stream, 12 ); RemoveBits( &p_vpar->bit_stream, 12 );
p_vpar->sequence.b_progressive = GetBits( &p_vpar->bit_stream, 1 ); 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.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_width |= GetBits( &p_vpar->bit_stream, 2 ) << 12;
p_vpar->sequence.i_height |= 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 */ /* bit_rate_extension, marker_bit, vbv_buffer_size_extension, low_delay */
...@@ -413,8 +408,6 @@ static void SequenceHeader( vpar_thread_t * p_vpar ) ...@@ -413,8 +408,6 @@ static void SequenceHeader( vpar_thread_t * p_vpar )
/* frame_rate_extension_d */ /* frame_rate_extension_d */
p_vpar->sequence.r_frame_rate *= (i_dummy + 1) p_vpar->sequence.r_frame_rate *= (i_dummy + 1)
/ (GetBits( &p_vpar->bit_stream, 5 ) + 1); / (GetBits( &p_vpar->bit_stream, 5 ) + 1);
p_vpar->sequence.pf_decode_mv = vpar_MPEG2MotionVector;
} }
else else
{ {
...@@ -423,9 +416,6 @@ static void SequenceHeader( vpar_thread_t * p_vpar ) ...@@ -423,9 +416,6 @@ static void SequenceHeader( vpar_thread_t * p_vpar )
p_vpar->sequence.b_mpeg2 = 0; p_vpar->sequence.b_mpeg2 = 0;
p_vpar->sequence.b_progressive = 1; p_vpar->sequence.b_progressive = 1;
p_vpar->sequence.i_chroma_format = CHROMA_420; 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 */ /* Update sizes */
...@@ -513,9 +503,33 @@ static void GroupHeader( vpar_thread_t * p_vpar ) ...@@ -513,9 +503,33 @@ static void GroupHeader( vpar_thread_t * p_vpar )
*****************************************************************************/ *****************************************************************************/
static void PictureHeader( vpar_thread_t * p_vpar ) static void PictureHeader( vpar_thread_t * p_vpar )
{ {
static f_macroblock_type_t ppf_macroblock_type[5] = {NULL, static f_parse_mb_t ppf_parse_mb[4][4][2] =
vpar_IMBType, vpar_PMBType, {
vpar_BMBType, vpar_DMBType}; {
{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_structure;
int i_mb_address, i_mb_base; int i_mb_address, i_mb_base;
...@@ -527,11 +541,10 @@ static void PictureHeader( vpar_thread_t * p_vpar ) ...@@ -527,11 +541,10 @@ static void PictureHeader( vpar_thread_t * p_vpar )
RemoveBits( &p_vpar->bit_stream, 10 ); /* temporal_reference */ RemoveBits( &p_vpar->bit_stream, 10 ); /* temporal_reference */
p_vpar->picture.i_coding_type = GetBits( &p_vpar->bit_stream, 3 ); 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 */ 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.pb_full_pel_vector[0] = GetBits( &p_vpar->bit_stream, 1 );
p_vpar->picture.i_forward_f_code = GetBits( &p_vpar->bit_stream, 3 ); 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 ) ...@@ -733,7 +746,7 @@ static void PictureHeader( vpar_thread_t * p_vpar )
p_vpar->picture.i_structure = i_structure; p_vpar->picture.i_structure = i_structure;
/* Initialize picture data for decoding. */ /* 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; i_mb_base = p_vpar->sequence.i_mb_size >> 1;
p_vpar->mb.i_l_y = 1; p_vpar->mb.i_l_y = 1;
...@@ -750,10 +763,25 @@ static void PictureHeader( vpar_thread_t * p_vpar ) ...@@ -750,10 +763,25 @@ static void PictureHeader( vpar_thread_t * p_vpar )
/* Extension and User data. */ /* Extension and User data. */
ExtensionAndUserData( p_vpar ); 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). */ /* Picture data (ISO/IEC 13818-2 6.2.3.7). */
NextStartCode( p_vpar ); NextStartCode( p_vpar );
while( i_mb_address+i_mb_base < p_vpar->sequence.i_mb_size 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 )) if( ((i_dummy = ShowBits( &p_vpar->bit_stream, 32 ))
< SLICE_START_CODE_MIN) || < SLICE_START_CODE_MIN) ||
...@@ -769,6 +797,11 @@ static void PictureHeader( vpar_thread_t * p_vpar ) ...@@ -769,6 +797,11 @@ static void PictureHeader( vpar_thread_t * p_vpar )
p_vpar->sequence.pf_slice_header( p_vpar, &i_mb_address, i_mb_base, i_dummy & 255 ); 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 ) if( p_vpar->picture.b_error )
{ {
/* Trash picture. */ /* Trash picture. */
...@@ -827,6 +860,8 @@ static __inline__ void SliceHeader( vpar_thread_t * p_vpar, ...@@ -827,6 +860,8 @@ static __inline__ void SliceHeader( vpar_thread_t * p_vpar,
int i_mb_address_save = *pi_mb_address; int i_mb_address_save = *pi_mb_address;
p_vpar->picture.b_error = 0;
/* slice_vertical_position_extension and priority_breakpoint already done */ /* slice_vertical_position_extension and priority_breakpoint already done */
LoadQuantizerScale( p_vpar ); LoadQuantizerScale( p_vpar );
...@@ -853,11 +888,18 @@ static __inline__ void SliceHeader( vpar_thread_t * p_vpar, ...@@ -853,11 +888,18 @@ static __inline__ void SliceHeader( vpar_thread_t * p_vpar,
do do
{ {
vpar_ParseMacroblock( p_vpar, pi_mb_address, i_mb_address_save, p_vpar->picture.pf_parse_mb( p_vpar, pi_mb_address,
i_mb_base ); 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; 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 ); NextStartCode( p_vpar );
} }
......
...@@ -126,6 +126,7 @@ void vpar_MotionVector( vpar_thread_t * p_vpar, macroblock_t * p_mb, int i_r, ...@@ -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_motion_code, i_motion_residual;
int i_r_size; int i_r_size;
int pi_dm_vector[2];
i_r_size = p_vpar->picture.ppi_f_code[i_s][0]-1; i_r_size = p_vpar->picture.ppi_f_code[i_s][0]-1;
i_motion_code = vpar_MotionCode( p_vpar ); 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, ...@@ -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) ) 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 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, ...@@ -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) ) 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 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)) >> 1) + pi_dm_vector[1] - 1;
/* vector for prediction of bottom field from top field */
p_mb->ppi_dmv[1][0] = ((3*i_mv_x + (i_mv_x > 0)) >> 1) + pi_dm_vector[0];
p_mb->ppi_dmv[1][1] = ((3*i_mv_y + (i_mv_y > 0)) >> 1) + pi_dm_vector[1] + 1;
}
else
{
/* vector for prediction of top field from bottom field */
p_mb->ppi_dmv[0][0] = ((3*i_mv_x + (i_mv_x > 0)) >> 1) + pi_dm_vector[0];
p_mb->ppi_dmv[0][1] = ((3*i_mv_y + (i_mv_y > 0)) >> 1) + pi_dm_vector[1] - 1;
/* vector for prediction of bottom field from top field */
p_mb->ppi_dmv[1][0] = ((i_mv_x + (i_mv_x > 0)) >> 1) + pi_dm_vector[0];
p_mb->ppi_dmv[1][1] = ((i_mv_y + (i_mv_y > 0)) >> 1) + pi_dm_vector[1] + 1;
}
#undef i_mv_y
}
else
{
#define i_mv_y p_mb->pppi_motion_vectors[0][0][1]
/* vector for prediction from field of opposite 'parity' */
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)) >> 1) + pi_dm_vector[1];
/* correct for vertical field shift */
if( p_vpar->picture.i_structure == TOP_FIELD )
p_mb->ppi_dmv[0][1]--;
else
p_mb->ppi_dmv[0][1]++;
#undef i_mv_y
}
#undef i_mv_x
} }
} }
......
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