Commit 3861944d authored by Christophe Massiot's avatar Christophe Massiot
Browse files

* Chroma 4:2:2 and 4:4:4 support in the decoder.

* Fixed bugs in the C YUV transform with 4:2:2 format.
parent bfd9535d
......@@ -2,7 +2,7 @@
* vdec_ext-plugins.h : structures from the video decoder exported to plug-ins
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: vdec_ext-plugins.h,v 1.5 2001/09/25 11:46:13 massiot Exp $
* $Id: vdec_ext-plugins.h,v 1.6 2001/10/11 13:19:27 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -34,8 +34,6 @@ typedef struct idct_inner_s
/* sparse IDCT or not, add or copy ? */
int i_sparse_pos; /* position of the
* non-NULL coeff */
yuv_data_t * p_dct_data; /* pointer to the position
* in the final picture */
} idct_inner_t;
typedef struct motion_inner_s
......@@ -53,11 +51,14 @@ typedef struct macroblock_s
int i_mb_modes;
/* IDCT information */
idct_inner_t p_idcts[6];
idct_inner_t p_idcts[12];
int i_coded_block_pattern;
/* which blocks are coded ? */
int i_lum_dct_stride, i_chrom_dct_stride;
/* nb of coeffs to jump when changing lines */
yuv_data_t * p_y_data;
yuv_data_t * p_u_data;
yuv_data_t * p_v_data;
/* pointers to the position
* in the final picture */
/* Motion compensation information */
motion_inner_t p_motions[8];
......
......@@ -2,7 +2,7 @@
* transforms_common.h: YUV transformation macros for truecolor
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: transforms_common.h,v 1.2 2001/03/21 13:42:34 sam Exp $
* $Id: transforms_common.h,v 1.3 2001/10/11 13:19:27 massiot Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
*
......@@ -95,7 +95,7 @@
*****************************************************************************/
#define SCALE_HEIGHT( CHROMA, BPP ) \
/* If line is odd, rewind 4:2:0 U and V samples */ \
if( ((CHROMA == 420) || (CHROMA == 422)) && !(i_y & 0x1) ) \
if( (CHROMA == 420) && !(i_y & 0x1) ) \
{ \
p_u -= i_chroma_width; \
p_v -= i_chroma_width; \
......@@ -113,7 +113,7 @@
/* Height reduction: skip next source line */ \
p_y += i_width; \
i_y++; \
if( (CHROMA == 420) || (CHROMA == 422) ) \
if( CHROMA == 420 ) \
{ \
if( i_y & 0x1 ) \
{ \
......@@ -121,7 +121,7 @@
p_v += i_chroma_width; \
} \
} \
else if( CHROMA == 444 ) \
else if( (CHROMA == 422) || (CHROMA == 444) ) \
{ \
p_u += i_width; \
p_v += i_width; \
......
......@@ -2,7 +2,7 @@
* transforms_yuv.h: C specific YUV transformation macros
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: transforms_yuv.h,v 1.2 2001/03/21 13:42:34 sam Exp $
* $Id: transforms_yuv.h,v 1.3 2001/10/11 13:19:27 massiot Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
*
......@@ -123,7 +123,7 @@
#define SCALE_HEIGHT_DITHER( CHROMA ) \
\
/* If line is odd, rewind 4:2:0 U and V samples */ \
if( ((CHROMA == 420) || (CHROMA == 422)) && !(i_y & 0x1) ) \
if( (CHROMA == 420) && !(i_y & 0x1) ) \
{ \
p_u -= i_chroma_width; \
p_v -= i_chroma_width; \
......@@ -142,7 +142,7 @@
/* Height reduction: skip next source line */ \
p_y += i_width; \
i_y++; \
if( (CHROMA == 420) || (CHROMA == 422) ) \
if( CHROMA == 420 ) \
{ \
if( i_y & 0x1 ) \
{ \
......@@ -150,7 +150,7 @@
p_v += i_chroma_width; \
} \
} \
else if( CHROMA == 444 ) \
else if( (CHROMA == 422) || (CHROMA == 444) ) \
{ \
p_u += i_width; \
p_v += i_width; \
......
......@@ -2,7 +2,7 @@
* video_decoder.c : video decoder thread
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: video_decoder.c,v 1.58 2001/09/05 16:07:50 massiot Exp $
* $Id: video_decoder.c,v 1.59 2001/10/11 13:19:27 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Michel Lespinasse <walken@zoy.org>
......@@ -183,7 +183,8 @@ static __inline__ void MotionBlock( vdec_pool_t * p_pool,
yuv_data_t * pp_dest[3], int i_dest_offset,
yuv_data_t * pp_src[3], int i_src_offset,
int i_stride, int i_height,
boolean_t b_second_half, boolean_t b_color )
boolean_t b_second_half,
int i_chroma_format )
{
int i_xy_half;
yuv_data_t * p_src1;
......@@ -199,28 +200,37 @@ static __inline__ void MotionBlock( vdec_pool_t * p_pool,
( pp_dest[0] + i_dest_offset + b_second_half * (i_stride << 3),
p_src1, i_stride, i_height );
if( b_color )
if( i_chroma_format != CHROMA_NONE )
{
/* Expanded at compile-time. */
i_x_pred /= 2;
i_y_pred /= 2;
if( i_chroma_format != CHROMA_444 )
{
i_x_pred /= 2;
i_stride >>= 1;
i_src_offset >>= 1;
i_dest_offset >>= 1;
}
if( i_chroma_format == CHROMA_420 )
{
i_y_pred /= 2;
i_height >>= 1;
}
i_xy_half = ((i_y_pred & 1) << 1) | (i_x_pred & 1);
i_stride >>= 1;
i_height >>= 1;
i_src_offset >>= 1;
i_src_offset += b_second_half * (i_stride << 2);
i_dest_offset >>= 1;
i_dest_offset += b_second_half * (i_stride << 2);
i_src_offset += b_second_half * (i_stride << 3);
i_dest_offset += b_second_half * (i_stride << 3);
p_src1 = pp_src[1] + i_src_offset
+ (i_x_pred >> 1) + (i_y_pred >> 1) * i_stride;
p_src2 = pp_src[2] + i_src_offset
+ (i_x_pred >> 1) + (i_y_pred >> 1) * i_stride;
p_pool->ppppf_motion[b_average][1][i_xy_half]
p_pool->ppppf_motion[b_average][(i_chroma_format != CHROMA_444)]
[i_xy_half]
( pp_dest[1] + i_dest_offset, p_src1, i_stride, i_height );
p_pool->ppppf_motion[b_average][1][i_xy_half]
p_pool->ppppf_motion[b_average][(i_chroma_format != CHROMA_444)]
[i_xy_half]
( pp_dest[2] + i_dest_offset, p_src2, i_stride, i_height );
}
}
......@@ -229,12 +239,62 @@ static __inline__ void MotionBlock( vdec_pool_t * p_pool,
/*****************************************************************************
* DecodeMacroblock: decode a macroblock
*****************************************************************************/
#define DECLARE_DECODEMB( PSZ_NAME, B_COLOR ) \
#define DECODE_INTRA_BLOCK( i_b, p_dest, I_CHROMA ) \
p_idct = &p_mb->p_idcts[i_b]; \
p_idct->pf_idct( p_idct->pi_block, p_dest, \
i_b < 4 ? i_lum_dct_stride : \
I_CHROMA == CHROMA_420 ? \
p_vpar->picture.i_field_width >> 1 : \
i_chrom_dct_stride, \
p_vdec->p_idct_data, p_idct->i_sparse_pos );
#define DECODE_NONINTRA_BLOCK( i_b, p_dest, I_CHROMA ) \
if( p_mb->i_coded_block_pattern & (1 << (3 + p_vpar->sequence.i_chroma_nb_blocks - i_b)) ) \
{ \
DECODE_INTRA_BLOCK( i_b, p_dest, I_CHROMA ); \
}
#define DECLARE_DECODEMB( PSZ_NAME, I_CHROMA ) \
void PSZ_NAME ( vdec_thread_t *p_vdec, macroblock_t * p_mb ) \
{ \
int i; \
int i, i_lum_dct_offset, i_lum_dct_stride; \
/* This is to keep the compiler happy with CHROMA_420 and CHROMA_NONE */\
int i_chrom_dct_offset __attribute__((unused)); \
int i_chrom_dct_stride __attribute__((unused)); \
idct_inner_t * p_idct; \
vdec_pool_t * p_pool = p_vdec->p_pool; \
vpar_thread_t * p_vpar = p_pool->p_vpar; \
\
if( p_mb->i_mb_modes & DCT_TYPE_INTERLACED ) \
{ \
i_lum_dct_offset = p_vpar->picture.i_field_width; \
i_lum_dct_stride = p_vpar->picture.i_field_width * 2; \
if( I_CHROMA == CHROMA_422 ) \
{ \
i_chrom_dct_offset = p_vpar->picture.i_field_width >> 1; \
i_chrom_dct_stride = p_vpar->picture.i_field_width; \
} \
else if( I_CHROMA == CHROMA_444 ) \
{ \
i_chrom_dct_offset = p_vpar->picture.i_field_width; \
i_chrom_dct_stride = p_vpar->picture.i_field_width * 2; \
} \
} \
else \
{ \
i_lum_dct_offset = p_vpar->picture.i_field_width * 8; \
i_lum_dct_stride = p_vpar->picture.i_field_width; \
if( I_CHROMA == CHROMA_422 ) \
{ \
i_chrom_dct_offset = p_vpar->picture.i_field_width * 4; \
i_chrom_dct_stride = p_vpar->picture.i_field_width >> 1; \
} \
else if( I_CHROMA == CHROMA_444 ) \
{ \
i_chrom_dct_offset = p_vpar->picture.i_field_width * 8; \
i_chrom_dct_stride = p_vpar->picture.i_field_width; \
} \
} \
\
if( !(p_mb->i_mb_modes & MB_INTRA) ) \
{ \
......@@ -249,44 +309,81 @@ void PSZ_NAME ( vdec_thread_t *p_vdec, macroblock_t * p_mb ) \
p_mb->pp_dest, p_motion->i_dest_offset, \
p_motion->pp_source, p_motion->i_src_offset, \
p_motion->i_stride, p_motion->i_height, \
p_motion->b_second_half, B_COLOR ); \
p_motion->b_second_half, I_CHROMA ); \
} \
\
for( i = 0, p_idct = p_mb->p_idcts; i < 4 + 2 * B_COLOR; \
i++, p_idct++ ) \
/* \
* Inverse DCT (ISO/IEC 13818-2 section Annex A) and \
* adding prediction and coefficient data (ISO/IEC \
* 13818-2 section 7.6.8) \
*/ \
DECODE_NONINTRA_BLOCK( 0, p_mb->p_y_data, I_CHROMA ); \
DECODE_NONINTRA_BLOCK( 1, p_mb->p_y_data + 8, I_CHROMA ); \
DECODE_NONINTRA_BLOCK( 2, p_mb->p_y_data + i_lum_dct_offset, \
I_CHROMA ); \
DECODE_NONINTRA_BLOCK( 3, p_mb->p_y_data + i_lum_dct_offset + 8, \
I_CHROMA ); \
if( I_CHROMA != CHROMA_NONE ) \
{ \
if( p_mb->i_coded_block_pattern & (1 << (5 - i)) ) \
DECODE_NONINTRA_BLOCK( 4, p_mb->p_u_data, I_CHROMA ); \
DECODE_NONINTRA_BLOCK( 5, p_mb->p_v_data, I_CHROMA ); \
if( I_CHROMA != CHROMA_420 ) \
{ \
/* \
* Inverse DCT (ISO/IEC 13818-2 section Annex A) and \
* adding prediction and coefficient data (ISO/IEC \
* 13818-2 section 7.6.8) \
*/ \
p_idct->pf_idct( p_idct->pi_block, p_idct->p_dct_data, \
i < 4 ? p_mb->i_lum_dct_stride : \
p_mb->i_chrom_dct_stride, \
p_vdec->p_idct_data, \
p_idct->i_sparse_pos ); \
DECODE_NONINTRA_BLOCK( 6, p_mb->p_u_data \
+ i_chrom_dct_offset, I_CHROMA );\
DECODE_NONINTRA_BLOCK( 7, p_mb->p_v_data \
+ i_chrom_dct_offset, I_CHROMA );\
if( I_CHROMA == CHROMA_444 ) \
{ \
DECODE_NONINTRA_BLOCK( 8, p_mb->p_u_data + 8, \
I_CHROMA ); \
DECODE_NONINTRA_BLOCK( 9, p_mb->p_v_data + 8, \
I_CHROMA ); \
DECODE_NONINTRA_BLOCK( 10, p_mb->p_u_data + 8 \
+ i_chrom_dct_offset, I_CHROMA );\
DECODE_NONINTRA_BLOCK( 11, p_mb->p_v_data + 8 \
+ i_chrom_dct_offset, I_CHROMA );\
} \
} \
} \
} \
else \
{ \
/* Intra macroblock */ \
for( i = 0, p_idct = p_mb->p_idcts; i < 4 + 2 * B_COLOR; \
i++, p_idct++ ) \
DECODE_INTRA_BLOCK( 0, p_mb->p_y_data, I_CHROMA ); \
DECODE_INTRA_BLOCK( 1, p_mb->p_y_data + 8, I_CHROMA ); \
DECODE_INTRA_BLOCK( 2, p_mb->p_y_data + i_lum_dct_offset, \
I_CHROMA ); \
DECODE_INTRA_BLOCK( 3, p_mb->p_y_data + i_lum_dct_offset + 8, \
I_CHROMA ); \
if( I_CHROMA != CHROMA_NONE ) \
{ \
p_idct->pf_idct( p_idct->pi_block, p_idct->p_dct_data, \
i < 4 ? p_mb->i_lum_dct_stride : \
p_mb->i_chrom_dct_stride, \
p_vdec->p_idct_data, \
p_idct->i_sparse_pos ); \
DECODE_INTRA_BLOCK( 4, p_mb->p_u_data, I_CHROMA ); \
DECODE_INTRA_BLOCK( 5, p_mb->p_v_data, I_CHROMA ); \
if( I_CHROMA != CHROMA_420 ) \
{ \
DECODE_INTRA_BLOCK( 6, p_mb->p_u_data \
+ i_chrom_dct_offset, I_CHROMA ); \
DECODE_INTRA_BLOCK( 7, p_mb->p_v_data \
+ i_chrom_dct_offset, I_CHROMA ); \
if( I_CHROMA == CHROMA_444 ) \
{ \
DECODE_INTRA_BLOCK( 8, p_mb->p_u_data + 8, I_CHROMA ); \
DECODE_INTRA_BLOCK( 9, p_mb->p_v_data + 8, I_CHROMA ); \
DECODE_INTRA_BLOCK( 10, p_mb->p_u_data + 8 \
+ i_chrom_dct_offset, I_CHROMA );\
DECODE_INTRA_BLOCK( 11, p_mb->p_v_data + 8 \
+ i_chrom_dct_offset, I_CHROMA );\
} \
} \
} \
} \
}
DECLARE_DECODEMB( vdec_DecodeMacroblockC, 1 );
DECLARE_DECODEMB( vdec_DecodeMacroblockBW, 0 );
DECLARE_DECODEMB( vdec_DecodeMacroblockBW, CHROMA_NONE );
DECLARE_DECODEMB( vdec_DecodeMacroblock420, CHROMA_420 );
DECLARE_DECODEMB( vdec_DecodeMacroblock422, CHROMA_422 );
DECLARE_DECODEMB( vdec_DecodeMacroblock444, CHROMA_444 );
#undef DECLARE_DECODEMB
......
......@@ -2,7 +2,7 @@
* video_decoder.h : video decoder thread
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: video_decoder.h,v 1.5 2001/08/22 17:21:45 massiot Exp $
* $Id: video_decoder.h,v 1.6 2001/10/11 13:19:27 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -26,10 +26,14 @@
*****************************************************************************/
void vdec_InitThread ( struct vdec_thread_s * );
void vdec_EndThread ( struct vdec_thread_s * );
void vdec_DecodeMacroblockC ( struct vdec_thread_s *,
struct macroblock_s * );
void vdec_DecodeMacroblockBW ( struct vdec_thread_s *,
struct macroblock_s * );
void vdec_DecodeMacroblock420( struct vdec_thread_s *,
struct macroblock_s * );
void vdec_DecodeMacroblock422( struct vdec_thread_s *,
struct macroblock_s * );
void vdec_DecodeMacroblock444( struct vdec_thread_s *,
struct macroblock_s * );
struct vdec_thread_s * vdec_CreateThread( struct vdec_pool_s * );
void vdec_DestroyThread ( struct vdec_thread_s * );
......@@ -2,7 +2,7 @@
* video_parser.h : video parser thread
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: video_parser.h,v 1.15 2001/10/01 16:44:07 massiot Exp $
* $Id: video_parser.h,v 1.16 2001/10/11 13:19:27 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
* Jean-Marc Dressler <polux@via.ecp.fr>
......@@ -116,6 +116,8 @@ typedef struct sequence_s
unsigned int i_aspect_ratio; /* height/width display ratio */
unsigned int i_matrix_coefficients;/* coeffs of the YUV transform */
int i_chroma_format, i_scalable_mode;
int i_chroma_nb_blocks;
boolean_t b_chroma_h_subsampled, b_chroma_v_subsampled;
int i_frame_rate; /* theoritical frame rate in fps*1001 */
boolean_t b_mpeg2; /* guess */
boolean_t b_progressive; /* progressive (ie.
......@@ -202,6 +204,7 @@ typedef struct picture_parsing_s
#define SC_TEMP 4
/* Chroma types */
#define CHROMA_NONE 0
#define CHROMA_420 1
#define CHROMA_422 2
#define CHROMA_444 3
......
......@@ -2,7 +2,7 @@
* vpar_blocks.c : blocks parsing
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: vpar_blocks.c,v 1.12 2001/10/01 16:44:07 massiot Exp $
* $Id: vpar_blocks.c,v 1.13 2001/10/11 13:19:27 massiot Exp $
*
* Authors: Michel Lespinasse <walken@zoy.org>
* Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
......@@ -179,14 +179,14 @@ static __inline__ int GetChromaDCDiff( vpar_thread_t * p_vpar )
/*****************************************************************************
* MPEG2IntraB14 : Decode an intra block according to ISO/IEC 13818-2 table B14
*****************************************************************************/
static void MPEG2IntraB14( vpar_thread_t * p_vpar, idct_inner_t * p_idct )
static void MPEG2IntraB14( vpar_thread_t * p_vpar, idct_inner_t * p_idct,
u8 * pi_quant )
{
int i_coeff, i_mismatch, i_code, i_pos, i_value, i_nc;
s32 i_sign;
dct_lookup_t * p_tab;
int i_q_scale = p_vpar->mb.i_quantizer_scale;
u8 * pi_quant = p_vpar->sequence.intra_quant.pi_matrix;
dctelem_t * p_dest = p_idct->pi_block;
u8 * p_scan = p_vpar->picture.pi_scan;
......@@ -327,14 +327,14 @@ store_coeff:
/*****************************************************************************
* MPEG2IntraB15 : Decode an intra block according to ISO/IEC 13818-2 table B15
*****************************************************************************/
static void MPEG2IntraB15( vpar_thread_t * p_vpar, idct_inner_t * p_idct )
static void MPEG2IntraB15( vpar_thread_t * p_vpar, idct_inner_t * p_idct,
u8 * pi_quant )
{
int i_coeff, i_mismatch, i_code, i_pos, i_value, i_nc;
s32 i_sign;
dct_lookup_t * p_tab;
int i_q_scale = p_vpar->mb.i_quantizer_scale;
u8 * pi_quant = p_vpar->sequence.intra_quant.pi_matrix;
dctelem_t * p_dest = p_idct->pi_block;
u8 * p_scan = p_vpar->picture.pi_scan;
......@@ -471,20 +471,16 @@ store_coeff:
/*****************************************************************************
* MPEG2NonIntra : Decode a non-intra MPEG-2 block
*****************************************************************************/
static void MPEG2NonIntra( vpar_thread_t * p_vpar, idct_inner_t * p_idct )
static void MPEG2NonIntra( vpar_thread_t * p_vpar, idct_inner_t * p_idct,
u8 * pi_quant )
{
int i_coeff, i_mismatch, i_code, i_pos, i_value, i_nc;
s32 i_sign;
dct_lookup_t * p_tab;
int i_q_scale = p_vpar->mb.i_quantizer_scale;
u8 * pi_quant = p_vpar->sequence.nonintra_quant.pi_matrix;
dctelem_t * p_dest = p_idct->pi_block;
u8 * p_scan = p_vpar->picture.pi_scan;
static int meuh = 0;
meuh++;
if( meuh == 3745 )
i_coeff = 0;
i_coeff = -1;
i_mismatch = 1;
......@@ -644,14 +640,14 @@ coeff_2:
/*****************************************************************************
* MPEG1Intra : Decode an MPEG-1 intra block
*****************************************************************************/
static void MPEG1Intra( vpar_thread_t * p_vpar, idct_inner_t * p_idct )
static void MPEG1Intra( vpar_thread_t * p_vpar, idct_inner_t * p_idct,
u8 * pi_quant )
{
int i_coeff, i_code, i_pos, i_value, i_nc;
s32 i_sign;
dct_lookup_t * p_tab;
int i_q_scale = p_vpar->mb.i_quantizer_scale;
u8 * pi_quant = p_vpar->sequence.intra_quant.pi_matrix;
dctelem_t * p_dest = p_idct->pi_block;
u8 * p_scan = p_vpar->picture.pi_scan;
......@@ -787,14 +783,14 @@ store_coeff:
/*****************************************************************************
* MPEG1NonIntra : Decode a non-intra MPEG-1 block
*****************************************************************************/
static void MPEG1NonIntra( vpar_thread_t * p_vpar, idct_inner_t * p_idct )
static void MPEG1NonIntra( vpar_thread_t * p_vpar, idct_inner_t * p_idct,
u8 * pi_quant )
{
int i_coeff, i_code, i_pos, i_value, i_nc;
s32 i_sign;
dct_lookup_t * p_tab;
int i_q_scale = p_vpar->mb.i_quantizer_scale;
u8 * pi_quant = p_vpar->sequence.nonintra_quant.pi_matrix;
dctelem_t * p_dest = p_idct->pi_block;
u8 * p_scan = p_vpar->picture.pi_scan;
......@@ -951,57 +947,48 @@ coeff_2:
/*****************************************************************************
* *MB : decode all blocks of the macroblock
*****************************************************************************/
#define DECODE_LUMABLOCK( i_b, p_dest, PF_MBFUNC ) \
p_idct = &p_mb->p_idcts[i_b]; \
#define DECODE_LUMABLOCK( I_B, PF_MBFUNC ) \
p_idct = &p_mb->p_idcts[I_B]; \
memset( p_idct->pi_block, 0, 64*sizeof(dctelem_t) ); \
p_idct->p_dct_data = p_dest; \
p_vpar->mb.pi_dc_dct_pred[0] += GetLumaDCDiff( p_vpar ); \
p_idct->pi_block[0] = p_vpar->mb.pi_dc_dct_pred[0] \
<< (3 - p_vpar->picture.i_intra_dc_precision ); \
PF_MBFUNC( p_vpar, p_idct );
PF_MBFUNC( p_vpar, p_idct, p_vpar->sequence.intra_quant.pi_matrix );
#define DECODE_CHROMABLOCK( I_B, PF_MBFUNC, I_CC ) \
p_idct = &p_mb->p_idcts[I_B]; \
memset( p_idct->pi_block, 0, 64*sizeof(dctelem_t) ); \
p_vpar->mb.pi_dc_dct_pred[I_CC] += GetChromaDCDiff( p_vpar ); \
p_idct->pi_block[0] = p_vpar->mb.pi_dc_dct_pred[I_CC] \
<< (3 - p_vpar->picture.i_intra_dc_precision ); \
PF_MBFUNC( p_vpar, p_idct, \
p_vpar->sequence.chroma_intra_quant.pi_matrix );
#define DECLARE_INTRAMB( PSZ_NAME, PF_MBFUNC ) \
static __inline__ void PSZ_NAME( vpar_thread_t * p_vpar, \
macroblock_t * p_mb ) \
{ \
int i_dct_offset; \
yuv_data_t * p_lum_dest; \
idct_inner_t * p_idct; \
int i_b = 4; \
\
p_lum_dest = p_mb->pp_dest[0] + p_vpar->mb.i_offset; \
p_mb->p_y_data = p_mb->pp_dest[0] + p_vpar->mb.i_offset; \
p_mb->p_u_data = p_mb->pp_dest[1] + (p_vpar->mb.i_offset \
>> p_vpar->sequence.b_chroma_h_subsampled); \
p_mb->p_v_data = p_mb->pp_dest[2] + (p_vpar->mb.i_offset \
>> p_vpar->sequence.b_chroma_h_subsampled); \
\
if( p_mb->i_mb_modes & DCT_TYPE_INTERLACED ) \
{ \
i_dct_offset = p_vpar->picture.i_field_width; \
p_mb->i_lum_dct_stride = p_vpar->picture.i_field_width * 2; \
} \
else \
DECODE_LUMABLOCK( 0, PF_MBFUNC ); \
DECODE_LUMABLOCK( 1, PF_MBFUNC ); \
DECODE_LUMABLOCK( 2, PF_MBFUNC ); \
DECODE_LUMABLOCK( 3, PF_MBFUNC ); \
\
do \
{ \
i_dct_offset = p_vpar->picture.i_field_width * 8; \
p_mb->i_lum_dct_stride = p_vpar->picture.i_field_width; \
DECODE_CHROMABLOCK( i_b, PF_MBFUNC, 1 ); \
DECODE_CHROMABLOCK( i_b + 1, PF_MBFUNC, 2 ); \
i_b += 2; \
} \
p_mb->i_chrom_dct_stride = p_vpar->picture.i_field_width >> 1; \
\
DECODE_LUMABLOCK( 0, p_lum_dest, PF_MBFUNC ); \
DECODE_LUMABLOCK( 1, p_lum_dest + 8, PF_MBFUNC ); \
DECODE_LUMABLOCK( 2, p_lum_dest + i_dct_offset, PF_MBFUNC ); \
DECODE_LUMABLOCK( 3, p_lum_dest + i_dct_offset + 8, PF_MBFUNC ); \
\
p_idct = &p_mb->p_idcts[4]; \
memset( p_idct->pi_block, 0, 64*sizeof(dctelem_t) ); \
p_idct->p_dct_data = p_mb->pp_dest[1] + (p_vpar->mb.i_offset >> 1); \
p_vpar->mb.pi_dc_dct_pred[1] += GetChromaDCDiff( p_vpar ); \
p_idct->pi_block[0] = p_vpar->mb.pi_dc_dct_pred[1] \
<< (3 - p_vpar->picture.i_intra_dc_precision ); \
PF_MBFUNC( p_vpar, p_idct ); \
\
p_idct = &p_mb->p_idcts[5]; \
memset( p_idct->pi_block, 0, 64*sizeof(dctelem_t) ); \
p_idct->p_dct_data = p_mb->pp_dest[2] + (p_vpar->mb.i_offset >> 1); \
p_vpar->mb.pi_dc_dct_pred[2] += GetChromaDCDiff( p_vpar ); \
p_idct->pi_block[0] = p_vpar->mb.pi_dc_dct_pred[2] \
<< (3 - p_vpar->picture.i_intra_dc_precision ); \
PF_MBFUNC( p_vpar, p_idct ); \
while( i_b < 4 + p_vpar->sequence.i_chroma_nb_blocks ); \
}
DECLARE_INTRAMB( MPEG1IntraMB, MPEG1Intra );
......@@ -1010,53 +997,59 @@ DECLARE_INTRAMB( MPEG2IntraB15MB, MPEG2IntraB15 );
#undef DECLARE_INTRAMB
#undef DECODE_LUMABLOCK
#undef DECODE_CHROMABLOCK
#define DECODE_BLOCK( i_b, p_dest, PF_MBFUNC ) \
if( p_mb->i_coded_block_pattern & (1 << (5 - i_b)) ) \
#define DECODE_LUMABLOCK( I_B, PF_MBFUNC ) \
if( p_mb->i_coded_block_pattern & (1 << (3 + p_vpar->sequence.i_chroma_nb_blocks - (I_B))) ) \
{ \
p_idct = &p_mb->p_idcts[i_b]; \
p_idct = &p_mb->p_idcts[I_B]; \
memset( p_idct->pi_block, 0, 64*sizeof(dctelem_t) ); \
p_idct->p_dct_data = p_dest; \
PF_MBFUNC( p_vpar, p_idct ); \
PF_MBFUNC( p_vpar, p_idct, \
p_vpar->sequence.nonintra_quant.pi_matrix ); \
}
#define DECODE_CHROMABLOCK( I_B, PF_MBFUNC ) \
if( p_mb->i_coded_block_pattern & (1 << (3 + p_vpar->sequence.i_chroma_nb_blocks - (I_B))) ) \
{ \
p_idct = &p_mb->p_idcts[I_B]; \
memset( p_idct->pi_block, 0, 64*sizeof(dctelem_t) ); \
PF_MBFUNC( p_vpar, p_idct, \
p_vpar->sequence.chroma_nonintra_quant.pi_matrix ); \
}
#define DECLARE_NONINTRAMB( PSZ_NAME, PF_MBFUNC ) \
static __inline__ void PSZ_NAME( vpar_thread_t * p_vpar, \
macroblock_t * p_mb ) \
{ \
int i_dct_offset; \
yuv_data_t * p_lum_dest; \
idct_inner_t * p_idct; \
int i_b = 4; \
\
p_lum_dest = p_mb->pp_dest[0] + p_vpar->mb.i_offset; \
p_mb->p_y_data = p_mb->pp_dest[0] + p_vpar->mb.i_offset; \
p_mb->p_u_data = p_mb->pp_dest[1] + (p_vpar->mb.i_offset \
>> p_vpar->sequence.b_chroma_h_subsampled); \
p_mb->p_v_data = p_mb->pp_dest[2] + (p_vpar->mb.i_offset \
>> p_vpar->sequence.b_chroma_h_subsampled); \
\