+/*****************************************************************************
+ * InitMacroblock : Initialize macroblock values
+ *****************************************************************************/
+static __inline__ void InitMacroblock( vpar_thread_t * p_vpar,
+ macroblock_t * p_mb )
+{
+ static f_chroma_motion_t pf_chroma_motion[4] =
+ { NULL, vdec_Motion420, vdec_Motion422, vdec_Motion444 };
+
+ p_mb->p_picture = p_vpar->picture.p_picture;
+ p_mb->i_structure = p_vpar->picture.i_structure;
+ p_mb->i_current_structure = p_vpar->picture.i_current_structure;
+ p_mb->i_l_x = p_vpar->mb.i_l_x;
+ 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_c_y = p_vpar->mb.i_c_y;
+ p_mb->i_chroma_nb_blocks = p_vpar->sequence.i_chroma_nb_blocks;
+ p_mb->pf_chroma_motion = pf_chroma_motion[p_vpar->sequence.i_chroma_format];
+ p_mb->b_P_coding_type = ( p_vpar->picture.i_coding_type == P_CODING_TYPE );
+
+ if( (p_vpar->picture.i_coding_type == P_CODING_TYPE) ||
+ (p_vpar->picture.i_coding_type == B_CODING_TYPE) )
+ p_mb->p_forward = p_vpar->sequence.p_forward;
+ if( p_vpar->picture.i_coding_type == B_CODING_TYPE )
+ p_mb->p_backward = p_vpar->sequence.p_backward;
+
+ 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;
+}
+
+/*****************************************************************************
+ * MacroblockAddressIncrement : Get the macroblock_address_increment field
+ *****************************************************************************/
+static __inline__ int MacroblockAddressIncrement( vpar_thread_t * p_vpar )
+{
+ 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 )
+ {
+ RemoveBits( &p_vpar->bit_stream, 11 );
+ i_addr_inc += 33;
+ 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;
+}
+
+/*****************************************************************************
+ * MacroblockModes : Get the macroblock_modes structure
+ *****************************************************************************/
+static __inline__ void MacroblockModes( vpar_thread_t * p_vpar,
+ macroblock_t * p_mb )
+{
+ static f_motion_t pf_motion[2][4] =
+ { {NULL, vdec_MotionFieldField, vdec_MotionField16x8, vdec_MotionFieldDMV},
+ {NULL, vdec_MotionFrameField, vdec_MotionFrameFrame, vdec_MotionFrameDMV} };
+ static 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. */
+ 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;
+
+ /* 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_vpar->mb.i_mb_type & (MB_MOTION_FORWARD | MB_MOTION_BACKWARD)) )
+ {
+ /* If mb_type has neither MOTION_FORWARD nor MOTION_BACKWARD, this
+ * is useless, but also harmless. */
+ p_vpar->mb.i_motion_type = MOTION_FRAME;
+ }
+ else
+ {
+ if( p_vpar->picture.i_structure == FRAME_STRUCTURE
+ && p_vpar->picture.b_frame_pred_frame_dct )
+ {
+ p_vpar->mb.i_motion_type = MOTION_FRAME;
+ }
+ else
+ {
+ p_vpar->mb.i_motion_type = GetBits( &p_vpar->bit_stream, 2 );
+ }
+ }
+
+ 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 );
+ }
+
+ if( p_vpar->mb.i_mb_type & MB_INTRA )
+ {
+ /* For the intra macroblocks, we use an empty motion
+ * compensation function */
+ p_mb->pf_motion = vdec_MotionDummy;
+ }
+ else
+ {
+ p_mb->pf_motion = pf_motion[p_vpar->picture.b_frame_structure]
+ [p_vpar->mb.i_motion_type];
+ }
+ 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];
+
+ p_vpar->mb.b_dct_type = 0;
+ 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 )) )
+ {
+ /* 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( p_vpar->sequence.i_chroma_format != CHROMA_420 )
+ {
+ p_mb->i_addb_c_stride <<= 1;
+ p_mb->i_addb_c_stride += 8;
+ }
+ }
+ }
+ p_vpar->mb.b_dmv = p_vpar->mb.i_motion_type == MOTION_DMV;
+}
+