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

* Optimisation du parseur ;

* R�activation du motion DMV ;

Pour info, on torche largement le d�codeur de r�f�rence (50 %).
parent e05c74bf
......@@ -23,26 +23,21 @@ typedef void (*f_motion_t)( struct macroblock_s* );
/*****************************************************************************
* Prototypes
*****************************************************************************/
/* Empty function for intra macroblocks motion compensation */
void vdec_MotionDummy( struct macroblock_s * p_mb );
/* Motion compensation */
void vdec_MotionFieldField420( struct macroblock_s * p_mb );
void vdec_MotionField16x8420( struct macroblock_s * p_mb );
void vdec_MotionFieldDMV( struct macroblock_s * p_mb );
void vdec_MotionFieldDMV420( struct macroblock_s * p_mb );
void vdec_MotionFrameFrame420( struct macroblock_s * p_mb );
void vdec_MotionFrameField420( struct macroblock_s * p_mb );
void vdec_MotionFrameDMV( struct macroblock_s * p_mb );
void vdec_MotionFrameDMV420( struct macroblock_s * p_mb );
void vdec_MotionFieldField422( struct macroblock_s * p_mb );
void vdec_MotionField16x8422( struct macroblock_s * p_mb );
void vdec_MotionFieldDMV( struct macroblock_s * p_mb );
void vdec_MotionFieldDMV422( struct macroblock_s * p_mb );
void vdec_MotionFrameFrame422( struct macroblock_s * p_mb );
void vdec_MotionFrameField422( struct macroblock_s * p_mb );
void vdec_MotionFrameDMV( struct macroblock_s * p_mb );
void vdec_MotionFrameDMV422( struct macroblock_s * p_mb );
void vdec_MotionFieldField444( struct macroblock_s * p_mb );
void vdec_MotionField16x8444( struct macroblock_s * p_mb );
void vdec_MotionFieldDMV( struct macroblock_s * p_mb );
void vdec_MotionFieldDMV444( struct macroblock_s * p_mb );
void vdec_MotionFrameFrame444( struct macroblock_s * p_mb );
void vdec_MotionFrameField444( struct macroblock_s * p_mb );
void vdec_MotionFrameDMV( struct macroblock_s * p_mb );
\ No newline at end of file
void vdec_MotionFrameDMV444( struct macroblock_s * p_mb );
\ No newline at end of file
......@@ -74,6 +74,10 @@ static __inline__ macroblock_t * vpar_NewMacroblock( video_fifo_t * p_fifo )
/* No more structures available. This should not happen ! */
intf_DbgMsg("vpar debug: macroblock list is empty, delaying\n");
vlc_mutex_unlock( &P_buffer.lock );
if( p_fifo->p_vpar->b_die )
{
return( NULL );
}
msleep(VPAR_OUTMEM_SLEEP);
vlc_mutex_lock( &P_buffer.lock );
}
......
......@@ -15,6 +15,12 @@
* "video_fifo.h"
*****************************************************************************/
/*****************************************************************************
* Function pointers
*****************************************************************************/
typedef void (*f_parse_mb_t)( struct vpar_thread_s*, int *, int, int,
boolean_t, int, int, int, boolean_t);
/*****************************************************************************
* macroblock_t : information on a macroblock
*****************************************************************************/
......@@ -22,16 +28,8 @@ typedef struct macroblock_s
{
int i_mb_type; /* macroblock type */
int i_coded_block_pattern;
int i_structure;
int i_current_structure;
boolean_t b_P_coding_type; /* Is it P_CODING_TYPE ? */
picture_t * p_picture;
int i_l_x, i_l_y; /* position of macroblock (lum) */
int i_c_x, i_c_y; /* position of macroblock (chroma) */
int i_chroma_nb_blocks; /* nb of bks for a chr comp */
int i_l_stride; /* number of yuv_data_t to ignore
* when changing lines */
int i_c_stride; /* idem, for chroma */
picture_t * p_picture;
/* IDCT information */
dctelem_t ppi_blocks[12][64]; /* blocks */
......@@ -44,16 +42,24 @@ typedef struct macroblock_s
picture_t * p_forward;
int ppi_field_select[2][2];
int pppi_motion_vectors[2][2][2];
int pi_dm_vector[2];
boolean_t b_top_field_first;
int ppi_dmv[2][2];
int i_l_x, i_c_x;
int i_motion_l_y;
int i_motion_c_y;
boolean_t b_motion_field;
int i_l_stride; /* number of yuv_data_t to
* ignore when changing line */
int i_c_stride; /* idem, for chroma */
boolean_t b_P_second; /* Second field of a P picture ?
* (used to determine the predicting
* frame) */
boolean_t b_motion_field; /* Field we are predicting
* (top field or bottom field) */
/* AddBlock information */
yuv_data_t * p_data[12]; /* pointer to the position
* in the final picture */
int i_addb_l_stride, i_addb_c_stride;
/* nb of coeffs to jump when changing lines */
} macroblock_t;
/*****************************************************************************
......@@ -61,12 +67,8 @@ typedef struct macroblock_s
*****************************************************************************/
typedef struct
{
int i_mb_type, i_motion_type, i_mv_count, i_mv_format;
boolean_t b_dmv;
/* Macroblock Type */
int i_coded_block_pattern;
boolean_t b_dct_type;
int i_motion_type, i_mv_count, i_mv_format;
boolean_t b_dmv, b_dct_type;
int i_l_x, i_l_y, i_c_x, i_c_y;
} macroblock_parsing_t;
......@@ -139,12 +141,53 @@ void vpar_InitPMBType( struct vpar_thread_s * p_vpar );
void vpar_InitBMBType( struct vpar_thread_s * p_vpar );
void vpar_InitCodedPattern( struct vpar_thread_s * p_vpar );
void vpar_InitDCTTables( struct vpar_thread_s * p_vpar );
void vpar_ParseMacroblock( struct vpar_thread_s * p_vpar, int * pi_mb_address,
int i_mb_previous, int i_mb_base );
int vpar_CodedPattern420( struct vpar_thread_s* p_vpar );
int vpar_CodedPattern422( struct vpar_thread_s* p_vpar );
int vpar_CodedPattern444( struct vpar_thread_s* p_vpar );
int vpar_IMBType( struct vpar_thread_s* p_vpar );
int vpar_PMBType( struct vpar_thread_s* p_vpar );
int vpar_BMBType( struct vpar_thread_s* p_vpar );
int vpar_DMBType( struct vpar_thread_s* p_vpar );
void vpar_ParseMacroblockGENERIC( struct vpar_thread_s* p_vpar, int * pi_mb_address,
int i_mb_previous, int i_mb_base,
boolean_t b_mpeg2, int i_coding_type,
int i_chroma_format, int i_structure,
boolean_t b_second_field );
void vpar_ParseMacroblock2I420F0( struct vpar_thread_s* p_vpar, int * pi_mb_address,
int i_mb_previous, int i_mb_base,
boolean_t b_mpeg2, int i_coding_type,
int i_chroma_format, int i_structure,
boolean_t b_second_field );
void vpar_ParseMacroblock2P420F0( struct vpar_thread_s* p_vpar, int * pi_mb_address,
int i_mb_previous, int i_mb_base,
boolean_t b_mpeg2, int i_coding_type,
int i_chroma_format, int i_structure,
boolean_t b_second_field );
void vpar_ParseMacroblock2B420F0( struct vpar_thread_s* p_vpar, int * pi_mb_address,
int i_mb_previous, int i_mb_base,
boolean_t b_mpeg2, int i_coding_type,
int i_chroma_format, int i_structure,
boolean_t b_second_field );
void vpar_ParseMacroblock2I420T0( struct vpar_thread_s* p_vpar, int * pi_mb_address,
int i_mb_previous, int i_mb_base,
boolean_t b_mpeg2, int i_coding_type,
int i_chroma_format, int i_structure,
boolean_t b_second_field );
void vpar_ParseMacroblock2P420T0( struct vpar_thread_s* p_vpar, int * pi_mb_address,
int i_mb_previous, int i_mb_base,
boolean_t b_mpeg2, int i_coding_type,
int i_chroma_format, int i_structure,
boolean_t b_second_field );
void vpar_ParseMacroblock2B420T0( struct vpar_thread_s* p_vpar, int * pi_mb_address,
int i_mb_previous, int i_mb_base,
boolean_t b_mpeg2, int i_coding_type,
int i_chroma_format, int i_structure,
boolean_t b_second_field );
void vpar_ParseMacroblock2I420B1( struct vpar_thread_s* p_vpar, int * pi_mb_address,
int i_mb_previous, int i_mb_base,
boolean_t b_mpeg2, int i_coding_type,
int i_chroma_format, int i_structure,
boolean_t b_second_field );
void vpar_ParseMacroblock2P420B1( struct vpar_thread_s* p_vpar, int * pi_mb_address,
int i_mb_previous, int i_mb_base,
boolean_t b_mpeg2, int i_coding_type,
int i_chroma_format, int i_structure,
boolean_t b_second_field );
void vpar_ParseMacroblock2B420B1( struct vpar_thread_s* p_vpar, int * pi_mb_address,
int i_mb_previous, int i_mb_base,
boolean_t b_mpeg2, int i_coding_type,
int i_chroma_format, int i_structure,
boolean_t b_second_field );
......@@ -19,11 +19,8 @@
* Function pointers
*****************************************************************************/
struct vpar_thread_s;
struct macroblock_s;
typedef void (*f_slice_header_t)( struct vpar_thread_s*, int*, int, u32);
typedef int (*f_chroma_pattern_t)( struct vpar_thread_s* );
typedef int (*f_macroblock_type_t)( struct vpar_thread_s* );
/*****************************************************************************
* quant_matrix_t : Quantization Matrix
......@@ -50,8 +47,6 @@ typedef struct sequence_s
f_slice_header_t pf_slice_header;
quant_matrix_t intra_quant, nonintra_quant;
quant_matrix_t chroma_intra_quant, chroma_nonintra_quant;
void (*pf_decode_mv)( struct vpar_thread_s *, struct macroblock_s *, int );
f_chroma_pattern_t pf_decode_pattern;
/* Chromatic information */
unsigned int i_chroma_format;
......@@ -64,12 +59,12 @@ typedef struct sequence_s
picture_t * p_backward;
/* Copyright extension */
boolean_t b_copyright_flag; /* Whether the following
information is significant
or not. */
u8 i_copyright_id;
boolean_t b_original;
u64 i_copyright_nb;
boolean_t b_copyright_flag; /* Whether the following
information is significant
or not. */
u8 i_copyright_id;
boolean_t b_original;
u64 i_copyright_nb;
} sequence_t;
/*****************************************************************************
......@@ -89,6 +84,8 @@ typedef struct picture_parsing_s
boolean_t b_repeat_first_field;
int i_l_stride, i_c_stride;
f_parse_mb_t pf_parse_mb;
/* Used for second field management */
int i_current_structure;
......@@ -100,8 +97,6 @@ typedef struct picture_parsing_s
/* Relative to the current field */
int i_coding_type, i_structure;
boolean_t b_frame_structure;
boolean_t b_motion_field;
f_macroblock_type_t pf_macroblock_type;
boolean_t b_error;
} picture_parsing_t;
......
......@@ -455,59 +455,6 @@ static __inline__ void Motion444(
i_select, b_average );
}
/*****************************************************************************
* DualPrimeArithmetic : Dual Prime Additional arithmetic (7.6.3.6)
*****************************************************************************/
static __inline__ void DualPrimeArithmetic( macroblock_t * p_mb,
int ppi_dmv[2][2],
int i_mv_x, int i_mv_y )
{
if( p_mb->i_structure == FRAME_STRUCTURE )
{
if( p_mb->b_top_field_first )
{
/* vector for prediction of top field from bottom field */
ppi_dmv[0][0] = ((i_mv_x + (i_mv_x > 0)) >> 1) + p_mb->pi_dm_vector[0];
ppi_dmv[0][1] = ((i_mv_y + (i_mv_y > 0)) >> 1) + p_mb->pi_dm_vector[1] - 1;
/* vector for prediction of bottom field from top field */
ppi_dmv[1][0] = ((3*i_mv_x + (i_mv_x > 0)) >> 1) + p_mb->pi_dm_vector[0];
ppi_dmv[1][1] = ((3*i_mv_y + (i_mv_y > 0)) >> 1) + p_mb->pi_dm_vector[1] + 1;
}
else
{
/* vector for prediction of top field from bottom field */
ppi_dmv[0][0] = ((3*i_mv_x + (i_mv_x > 0)) >> 1) + p_mb->pi_dm_vector[0];
ppi_dmv[0][1] = ((3*i_mv_y + (i_mv_y > 0)) >> 1) + p_mb->pi_dm_vector[1] - 1;
/* vector for prediction of bottom field from top field */
ppi_dmv[1][0] = ((i_mv_x + (i_mv_x > 0)) >> 1) + p_mb->pi_dm_vector[0];
ppi_dmv[1][1] = ((i_mv_y + (i_mv_y > 0)) >> 1) + p_mb->pi_dm_vector[1] + 1;
}
}
else
{
/* vector for prediction from field of opposite 'parity' */
ppi_dmv[0][0] = ((i_mv_x + (i_mv_x > 0)) >> 1) + p_mb->pi_dm_vector[0];
ppi_dmv[0][1] = ((i_mv_y + (i_mv_y > 0)) >> 1) + p_mb->pi_dm_vector[1];
/* correct for vertical field shift */
if( p_mb->i_structure == TOP_FIELD )
ppi_dmv[0][1]--;
else
ppi_dmv[0][1]++;
}
}
/*****************************************************************************
* vdec_MotionDummy : motion compensation for an intra macroblock
*****************************************************************************/
void vdec_MotionDummy( macroblock_t * p_mb )
{
/* Nothing to do :) */
}
/*****************************************************************************
* vdec_MotionFieldField : motion compensation for field motion type (field)
*****************************************************************************/
......@@ -516,8 +463,7 @@ void vdec_MotionDummy( macroblock_t * p_mb )
\
if( p_mb->i_mb_type & MB_MOTION_FORWARD ) \
{ \
if( p_mb->b_P_coding_type \
&& (p_mb->i_current_structure == FRAME_STRUCTURE) \
if( p_mb->b_P_second \
&& (p_mb->b_motion_field != p_mb->ppi_field_select[0][0]) )\
p_pred = p_mb->p_picture; \
else \
......@@ -573,8 +519,7 @@ void vdec_MotionFieldField444( macroblock_t * p_mb )
\
if( p_mb->i_mb_type & MB_MOTION_FORWARD ) \
{ \
if( p_mb->b_P_coding_type \
&& (p_mb->i_current_structure == FRAME_STRUCTURE) \
if( p_mb->b_P_second \
&& (p_mb->b_motion_field != p_mb->ppi_field_select[0][0]) )\
p_pred = p_mb->p_picture; \
else \
......@@ -586,8 +531,7 @@ void vdec_MotionFieldField444( macroblock_t * p_mb )
p_mb->pppi_motion_vectors[0][0][1], \
p_mb->i_l_stride, p_mb->i_c_stride, 8, 0, 0 ); \
\
if( p_mb->b_P_coding_type \
&& (p_mb->i_current_structure == FRAME_STRUCTURE) \
if( p_mb->b_P_second \
&& (p_mb->b_motion_field != p_mb->ppi_field_select[1][0]) )\
p_pred = p_mb->p_picture; \
else \
......@@ -649,44 +593,45 @@ void vdec_MotionField16x8444( macroblock_t * p_mb )
}
/*****************************************************************************
* vdec_MotionFieldDMV : motion compensation for dmv motion type (field)
* vdec_MotionFieldDMVXXX : motion compensation for dmv motion type (field)
*****************************************************************************/
void vdec_MotionFieldDMV( macroblock_t * p_mb )
#define FIELDDMV( MOTION ) \
{ \
/* This is necessarily a MOTION_FORWARD only macroblock, in a P \
* picture. */ \
picture_t * p_pred; \
\
/* predict from field of same parity */ \
MOTION( p_mb, p_mb->p_forward, \
p_mb->b_motion_field, p_mb->b_motion_field, \
p_mb->pppi_motion_vectors[0][0][0], \
p_mb->pppi_motion_vectors[0][0][1], \
p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 0 ); \
\
if( p_mb->b_P_second ) \
p_pred = p_mb->p_picture; \
else \
p_pred = p_mb->p_forward; \
\
/* predict from field of opposite parity */ \
MOTION( p_mb, p_pred, !p_mb->b_motion_field, p_mb->b_motion_field, \
p_mb->ppi_dmv[0][0], p_mb->ppi_dmv[0][1], \
p_mb->i_l_stride, p_mb->i_c_stride, 16, 0, 1 ); \
} /* FIELDDMV */
void vdec_MotionFieldDMV420( macroblock_t * p_mb )
{
#if 0
/* This is necessarily a MOTION_FORWARD only macroblock */
motion_arg_t args;
picture_t * p_pred;
int ppi_dmv[2][2];
args.i_height = 16;
args.b_average = 0;
args.b_dest_field = p_mb->b_motion_field;
args.i_offset = 0;
if( p_mb->i_current_structure == FRAME_STRUCTURE )
p_pred = p_mb->p_picture;
else
p_pred = p_mb->p_forward;
DualPrimeArithmetic( p_mb, ppi_dmv, p_mb->pppi_motion_vectors[0][0][0],
p_mb->pppi_motion_vectors[0][0][1] );
/* predict from field of same parity */
args.p_source = p_mb->p_forward;
args.b_source_field = p_mb->b_motion_field;
args.i_mv_x = p_mb->pppi_motion_vectors[0][0][0];
args.i_mv_y = p_mb->pppi_motion_vectors[0][0][1];
p_mb->pf_chroma_motion( p_mb, &args );
/* predict from field of opposite parity */
args.b_average = 1;
args.p_source = p_pred;
args.b_source_field = !p_mb->b_motion_field;
args.i_mv_x = ppi_dmv[0][0];
args.i_mv_y = ppi_dmv[0][1];
p_mb->pf_chroma_motion( p_mb, &args );
#endif
FIELDDMV( Motion420 )
}
void vdec_MotionFieldDMV422( macroblock_t * p_mb )
{
FIELDDMV( Motion422 )
}
void vdec_MotionFieldDMV444( macroblock_t * p_mb )
{
FIELDDMV( Motion444 )
}
/*****************************************************************************
......@@ -800,53 +745,49 @@ void vdec_MotionFrameField444( macroblock_t * p_mb )
}
/*****************************************************************************
* vdec_MotionFrameDMV : motion compensation for dmv motion type (frame)
* vdec_MotionFrameDMVXXX : motion compensation for dmv motion type (frame)
*****************************************************************************/
void vdec_MotionFrameDMV( macroblock_t * p_mb )
#define FRAMEDMV( MOTION ) \
{ \
/* This is necessarily a MOTION_FORWARD only macroblock, in a P \
* picture. */ \
\
/* predict top field from top field */ \
MOTION( p_mb, p_mb->p_forward, 0, 0, \
p_mb->pppi_motion_vectors[0][0][0], \
p_mb->pppi_motion_vectors[0][0][1], \
/* ????? >> 1 ? */ \
p_mb->i_l_stride << 1, p_mb->i_c_stride << 1, 8, 0, 0 ); \
\
/* predict and add to top field from bottom field */ \
MOTION( p_mb, p_mb->p_forward, 1, 0, \
p_mb->ppi_dmv[0][0], p_mb->ppi_dmv[0][1], \
p_mb->i_l_stride << 1, p_mb->i_c_stride << 1, 8, 0, 1 ); \
\
/* predict bottom field from bottom field */ \
MOTION( p_mb, p_mb->p_forward, 1, 1, \
p_mb->pppi_motion_vectors[0][0][0], \
p_mb->pppi_motion_vectors[0][0][1], \
/* ????? >> 1 ? */ \
p_mb->i_l_stride << 1, p_mb->i_c_stride << 1, 8, 0, 0 ); \
\
/* predict and add to bottom field from top field */ \
MOTION( p_mb, p_mb->p_forward, 1, 0, \
p_mb->ppi_dmv[1][0], p_mb->ppi_dmv[1][1], \
p_mb->i_l_stride << 1, p_mb->i_c_stride << 1, 8, 0, 1 ); \
} /* FRAMEDMV */
void vdec_MotionFrameDMV420( macroblock_t * p_mb )
{
#if 0
/* This is necessarily a MOTION_FORWARD only macroblock */
motion_arg_t args;
int ppi_dmv[2][2];
args.i_l_x_step = p_mb->i_l_stride << 1;
args.i_c_x_step = p_mb->i_c_stride << 1;
args.i_height = 8;
args.b_average = 0;
args.b_dest_field = 0;
args.i_offset = 0;
args.p_source = p_mb->p_forward;
DualPrimeArithmetic( p_mb, ppi_dmv, p_mb->pppi_motion_vectors[0][0][0],
p_mb->pppi_motion_vectors[0][0][1] );
/* predict top field from top field */
args.b_source_field = 0;
args.i_mv_x = p_mb->pppi_motion_vectors[0][0][0];
args.i_mv_y = p_mb->pppi_motion_vectors[0][0][1] >> 1;
p_mb->pf_chroma_motion( p_mb, &args );
/* predict and add to top field from bottom field */
args.b_average = 1;
args.b_source_field = 1;
args.i_mv_x = ppi_dmv[0][0];
args.i_mv_y = ppi_dmv[0][1];
p_mb->pf_chroma_motion( p_mb, &args );
/* predict bottom field from bottom field */
args.b_average = 0;
args.b_dest_field = 1;
args.b_source_field = 0;
args.i_mv_x = p_mb->pppi_motion_vectors[0][0][0];
args.i_mv_y = p_mb->pppi_motion_vectors[0][0][1] >> 1;
p_mb->pf_chroma_motion( p_mb, &args );
/* predict and add to bottom field from top field */
args.b_average = 1;
args.b_source_field = 1;
args.i_mv_x = ppi_dmv[1][0];
args.i_mv_y = ppi_dmv[1][1];
p_mb->pf_chroma_motion( p_mb, &args );
#endif
FRAMEDMV( Motion420 )
}
void vdec_MotionFrameDMV422( macroblock_t * p_mb )
{
FRAMEDMV( Motion422 )
}
void vdec_MotionFrameDMV444( macroblock_t * p_mb )
{
FRAMEDMV( Motion444 )
}
......@@ -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 );
/*
* 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 */
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},
......@@ -347,6 +359,8 @@ static dct_lookup_t pl_DCT_tab6[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}
};
/*
* Initialization of lookup tables
*/
......@@ -378,7 +392,7 @@ void vpar_InitCrop( vpar_thread_t * p_vpar )
#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 */
......@@ -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 */
......@@ -500,8 +514,8 @@ void vpar_InitBMBType( vpar_thread_t * p_vpar )
}
/*****************************************************************************
* InitCodedPattern : Initialize the lookup table for decoding
* coded block pattern
* vpar_InitCodedPattern : Initialize the lookup table for decoding
* coded block pattern
*****************************************************************************/
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
* from the vlc code
* vpar_InitDCTTables : Initialize tables giving the length of the dct
* coefficient from the vlc code
*****************************************************************************/
/* First fonction for filling the table */
......@@ -560,441 +574,650 @@ void vpar_InitDCTTables( vpar_thread_t * p_vpar )
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,
macroblock_t * p_mb )
static void vpar_DecodeMPEG1Non( vpar_thread_t * p_vpar, macroblock_t * p_mb, int i_b )
{
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) ||
(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) )
if( p_vpar->picture.i_coding_type == D_CODING_TYPE )
{
p_mb->i_motion_l_y--;
p_mb->i_motion_c_y--;
/* Remove end_of_macroblock (always 1, prevents startcode emulation)
* 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 */
while( i_index == 8 )
if( p_vpar->picture.i_coding_type == D_CODING_TYPE )
{
RemoveBits( &p_vpar->bit_stream, 11 );
i_addr_inc += 33;
i_index = ShowBits( &p_vpar->bit_stream, 11 );
/* Remove end_of_macroblock (always 1, prevents startcode emulation)
* ISO/IEC 11172-2 section 2.4.2.7 and 2.4.3.6 */
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,
macroblock_t * p_mb )
static void vpar_DecodeMPEG2Non( vpar_thread_t * p_vpar, macroblock_t * p_mb, int i_b )
{
static f_motion_t pppf_motion[4][2][4] =
{
{ {NULL, NULL, NULL, NULL},
{NULL, NULL, NULL, NULL}
},
{ {NULL, vdec_MotionFieldField420, vdec_MotionField16x8420, vdec_MotionFieldDMV},
{NULL, vdec_MotionFrameField420, vdec_MotionFrameFrame420, vdec_MotionFrameDMV}
},
{ {NULL, vdec_MotionFieldField422, vdec_MotionField16x8422, vdec_MotionFieldDMV},
{NULL, vdec_MotionFrameField422, vdec_MotionFrameFrame422, vdec_MotionFrameDMV}
},
{ {NULL, vdec_MotionFieldField444, vdec_MotionField16x8444, vdec_MotionFieldDMV},
{NULL, vdec_MotionFrameField444, vdec_MotionFrameFrame444, vdec_MotionFrameDMV}
}
};
static int ppi_mv_count[2][4] = { {0, 1, 2, 1}, {0, 2, 1, 1} };
static int ppi_mv_format[2][4] = { {0, 1, 1, 1}, {0, 1, 2, 1} };
int i_parse;
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 int pi_cc_index[12] = { 0, 0, 0, 0, 1, 2, 1, 2, 1, 2 };
/* Get macroblock_type. */
p_vpar->mb.i_mb_type = (p_vpar->picture.pf_macroblock_type)( p_vpar );
p_mb->i_mb_type = p_vpar->mb.i_mb_type;
i_cc = pi_cc_index[i_b];
/* 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);
/* 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 ); */
/* 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 */
if( !(p_vpar->mb