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

* 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 @@ ...@@ -2,7 +2,7 @@
* vdec_ext-plugins.h : structures from the video decoder exported to plug-ins * vdec_ext-plugins.h : structures from the video decoder exported to plug-ins
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN * 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> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -34,8 +34,6 @@ typedef struct idct_inner_s ...@@ -34,8 +34,6 @@ typedef struct idct_inner_s
/* sparse IDCT or not, add or copy ? */ /* sparse IDCT or not, add or copy ? */
int i_sparse_pos; /* position of the int i_sparse_pos; /* position of the
* non-NULL coeff */ * non-NULL coeff */
yuv_data_t * p_dct_data; /* pointer to the position
* in the final picture */
} idct_inner_t; } idct_inner_t;
typedef struct motion_inner_s typedef struct motion_inner_s
...@@ -53,11 +51,14 @@ typedef struct macroblock_s ...@@ -53,11 +51,14 @@ typedef struct macroblock_s
int i_mb_modes; int i_mb_modes;
/* IDCT information */ /* IDCT information */
idct_inner_t p_idcts[6]; idct_inner_t p_idcts[12];
int i_coded_block_pattern; int i_coded_block_pattern;
/* which blocks are coded ? */ /* which blocks are coded ? */
int i_lum_dct_stride, i_chrom_dct_stride; yuv_data_t * p_y_data;
/* nb of coeffs to jump when changing lines */ yuv_data_t * p_u_data;
yuv_data_t * p_v_data;
/* pointers to the position
* in the final picture */
/* Motion compensation information */ /* Motion compensation information */
motion_inner_t p_motions[8]; motion_inner_t p_motions[8];
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* transforms_common.h: YUV transformation macros for truecolor * transforms_common.h: YUV transformation macros for truecolor
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN * 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> * Authors: Vincent Seguin <seguin@via.ecp.fr>
* *
...@@ -95,7 +95,7 @@ ...@@ -95,7 +95,7 @@
*****************************************************************************/ *****************************************************************************/
#define SCALE_HEIGHT( CHROMA, BPP ) \ #define SCALE_HEIGHT( CHROMA, BPP ) \
/* If line is odd, rewind 4:2:0 U and V samples */ \ /* 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_u -= i_chroma_width; \
p_v -= i_chroma_width; \ p_v -= i_chroma_width; \
...@@ -113,7 +113,7 @@ ...@@ -113,7 +113,7 @@
/* Height reduction: skip next source line */ \ /* Height reduction: skip next source line */ \
p_y += i_width; \ p_y += i_width; \
i_y++; \ i_y++; \
if( (CHROMA == 420) || (CHROMA == 422) ) \ if( CHROMA == 420 ) \
{ \ { \
if( i_y & 0x1 ) \ if( i_y & 0x1 ) \
{ \ { \
...@@ -121,7 +121,7 @@ ...@@ -121,7 +121,7 @@
p_v += i_chroma_width; \ p_v += i_chroma_width; \
} \ } \
} \ } \
else if( CHROMA == 444 ) \ else if( (CHROMA == 422) || (CHROMA == 444) ) \
{ \ { \
p_u += i_width; \ p_u += i_width; \
p_v += i_width; \ p_v += i_width; \
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* transforms_yuv.h: C specific YUV transformation macros * transforms_yuv.h: C specific YUV transformation macros
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN * 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> * Authors: Samuel Hocevar <sam@zoy.org>
* *
...@@ -123,7 +123,7 @@ ...@@ -123,7 +123,7 @@
#define SCALE_HEIGHT_DITHER( CHROMA ) \ #define SCALE_HEIGHT_DITHER( CHROMA ) \
\ \
/* If line is odd, rewind 4:2:0 U and V samples */ \ /* 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_u -= i_chroma_width; \
p_v -= i_chroma_width; \ p_v -= i_chroma_width; \
...@@ -142,7 +142,7 @@ ...@@ -142,7 +142,7 @@
/* Height reduction: skip next source line */ \ /* Height reduction: skip next source line */ \
p_y += i_width; \ p_y += i_width; \
i_y++; \ i_y++; \
if( (CHROMA == 420) || (CHROMA == 422) ) \ if( CHROMA == 420 ) \
{ \ { \
if( i_y & 0x1 ) \ if( i_y & 0x1 ) \
{ \ { \
...@@ -150,7 +150,7 @@ ...@@ -150,7 +150,7 @@
p_v += i_chroma_width; \ p_v += i_chroma_width; \
} \ } \
} \ } \
else if( CHROMA == 444 ) \ else if( (CHROMA == 422) || (CHROMA == 444) ) \
{ \ { \
p_u += i_width; \ p_u += i_width; \
p_v += i_width; \ p_v += i_width; \
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* video_decoder.c : video decoder thread * video_decoder.c : video decoder thread
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN * 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> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* Michel Lespinasse <walken@zoy.org> * Michel Lespinasse <walken@zoy.org>
...@@ -183,7 +183,8 @@ static __inline__ void MotionBlock( vdec_pool_t * p_pool, ...@@ -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_dest[3], int i_dest_offset,
yuv_data_t * pp_src[3], int i_src_offset, yuv_data_t * pp_src[3], int i_src_offset,
int i_stride, int i_height, 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; int i_xy_half;
yuv_data_t * p_src1; yuv_data_t * p_src1;
...@@ -199,28 +200,37 @@ static __inline__ void MotionBlock( vdec_pool_t * p_pool, ...@@ -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), ( pp_dest[0] + i_dest_offset + b_second_half * (i_stride << 3),
p_src1, i_stride, i_height ); p_src1, i_stride, i_height );
if( b_color ) if( i_chroma_format != CHROMA_NONE )
{ {
/* Expanded at compile-time. */ /* Expanded at compile-time. */
i_x_pred /= 2; if( i_chroma_format != CHROMA_444 )
i_y_pred /= 2; {
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_xy_half = ((i_y_pred & 1) << 1) | (i_x_pred & 1);
i_stride >>= 1;
i_height >>= 1; i_src_offset += b_second_half * (i_stride << 3);
i_src_offset >>= 1; i_dest_offset += b_second_half * (i_stride << 3);
i_src_offset += b_second_half * (i_stride << 2);
i_dest_offset >>= 1;
i_dest_offset += b_second_half * (i_stride << 2);
p_src1 = pp_src[1] + i_src_offset p_src1 = pp_src[1] + i_src_offset
+ (i_x_pred >> 1) + (i_y_pred >> 1) * i_stride; + (i_x_pred >> 1) + (i_y_pred >> 1) * i_stride;
p_src2 = pp_src[2] + i_src_offset p_src2 = pp_src[2] + i_src_offset
+ (i_x_pred >> 1) + (i_y_pred >> 1) * i_stride; + (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 ); ( 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 ); ( 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, ...@@ -229,12 +239,62 @@ static __inline__ void MotionBlock( vdec_pool_t * p_pool,
/***************************************************************************** /*****************************************************************************
* DecodeMacroblock: decode a macroblock * 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 ) \ 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; \ idct_inner_t * p_idct; \
vdec_pool_t * p_pool = p_vdec->p_pool; \ 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) ) \ if( !(p_mb->i_mb_modes & MB_INTRA) ) \
{ \ { \
...@@ -249,44 +309,81 @@ void PSZ_NAME ( vdec_thread_t *p_vdec, macroblock_t * p_mb ) \ ...@@ -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_mb->pp_dest, p_motion->i_dest_offset, \
p_motion->pp_source, p_motion->i_src_offset, \ p_motion->pp_source, p_motion->i_src_offset, \
p_motion->i_stride, p_motion->i_height, \ 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 ) \
{ \ { \
/* \ DECODE_NONINTRA_BLOCK( 6, p_mb->p_u_data \
* Inverse DCT (ISO/IEC 13818-2 section Annex A) and \ + i_chrom_dct_offset, I_CHROMA );\
* adding prediction and coefficient data (ISO/IEC \ DECODE_NONINTRA_BLOCK( 7, p_mb->p_v_data \
* 13818-2 section 7.6.8) \ + i_chrom_dct_offset, I_CHROMA );\
*/ \ if( I_CHROMA == CHROMA_444 ) \
p_idct->pf_idct( p_idct->pi_block, p_idct->p_dct_data, \ { \
i < 4 ? p_mb->i_lum_dct_stride : \ DECODE_NONINTRA_BLOCK( 8, p_mb->p_u_data + 8, \
p_mb->i_chrom_dct_stride, \ I_CHROMA ); \
p_vdec->p_idct_data, \ DECODE_NONINTRA_BLOCK( 9, p_mb->p_v_data + 8, \
p_idct->i_sparse_pos ); \ 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 \ else \
{ \ { \
/* Intra macroblock */ \ /* Intra macroblock */ \
for( i = 0, p_idct = p_mb->p_idcts; i < 4 + 2 * B_COLOR; \ DECODE_INTRA_BLOCK( 0, p_mb->p_y_data, I_CHROMA ); \
i++, p_idct++ ) \ 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, \ DECODE_INTRA_BLOCK( 4, p_mb->p_u_data, I_CHROMA ); \
i < 4 ? p_mb->i_lum_dct_stride : \ DECODE_INTRA_BLOCK( 5, p_mb->p_v_data, I_CHROMA ); \
p_mb->i_chrom_dct_stride, \ if( I_CHROMA != CHROMA_420 ) \
p_vdec->p_idct_data, \ { \
p_idct->i_sparse_pos ); \ 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, CHROMA_NONE );
DECLARE_DECODEMB( vdec_DecodeMacroblockBW, 0 ); DECLARE_DECODEMB( vdec_DecodeMacroblock420, CHROMA_420 );
DECLARE_DECODEMB( vdec_DecodeMacroblock422, CHROMA_422 );
DECLARE_DECODEMB( vdec_DecodeMacroblock444, CHROMA_444 );
#undef DECLARE_DECODEMB #undef DECLARE_DECODEMB
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* video_decoder.h : video decoder thread * video_decoder.h : video decoder thread
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN * 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> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -26,10 +26,14 @@ ...@@ -26,10 +26,14 @@
*****************************************************************************/ *****************************************************************************/
void vdec_InitThread ( struct vdec_thread_s * ); void vdec_InitThread ( struct vdec_thread_s * );
void vdec_EndThread ( 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 *, void vdec_DecodeMacroblockBW ( struct vdec_thread_s *,
struct macroblock_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 * ); struct vdec_thread_s * vdec_CreateThread( struct vdec_pool_s * );
void vdec_DestroyThread ( struct vdec_thread_s * ); void vdec_DestroyThread ( struct vdec_thread_s * );
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* video_parser.h : video parser thread * video_parser.h : video parser thread
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN * 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> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* Jean-Marc Dressler <polux@via.ecp.fr> * Jean-Marc Dressler <polux@via.ecp.fr>
...@@ -116,6 +116,8 @@ typedef struct sequence_s ...@@ -116,6 +116,8 @@ typedef struct sequence_s
unsigned int i_aspect_ratio; /* height/width display ratio */ unsigned int i_aspect_ratio; /* height/width display ratio */
unsigned int i_matrix_coefficients;/* coeffs of the YUV transform */ unsigned int i_matrix_coefficients;/* coeffs of the YUV transform */
int i_chroma_format, i_scalable_mode; 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 */ int i_frame_rate; /* theoritical frame rate in fps*1001 */
boolean_t b_mpeg2; /* guess */ boolean_t b_mpeg2; /* guess */
boolean_t b_progressive; /* progressive (ie. boolean_t b_progressive; /* progressive (ie.
...@@ -202,6 +204,7 @@ typedef struct picture_parsing_s ...@@ -202,6 +204,7 @@ typedef struct picture_parsing_s
#define SC_TEMP 4 #define SC_TEMP 4
/* Chroma types */ /* Chroma types */
#define CHROMA_NONE 0
#define CHROMA_420 1 #define CHROMA_420 1
#define CHROMA_422 2 #define CHROMA_422 2
#define CHROMA_444 3 #define CHROMA_444 3
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* vpar_blocks.c : blocks parsing * vpar_blocks.c : blocks parsing
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN * 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> * Authors: Michel Lespinasse <walken@zoy.org>
* Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
...@@ -179,14 +179,14 @@ static __inline__ int GetChromaDCDiff( vpar_thread_t * p_vpar ) ...@@ -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 * 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; int i_coeff, i_mismatch, i_code, i_pos, i_value, i_nc;
s32 i_sign; s32 i_sign;
dct_lookup_t * p_tab; dct_lookup_t * p_tab;
int i_q_scale = p_vpar->mb.i_quantizer_scale; 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; dctelem_t * p_dest = p_idct->pi_block;
u8 * p_scan = p_vpar->picture.pi_scan; u8 * p_scan = p_vpar->picture.pi_scan;
...@@ -327,14 +327,14 @@ store_coeff: ...@@ -327,14 +327,14 @@ store_coeff:
/***************************************************************************** /*****************************************************************************
* MPEG2IntraB15 : Decode an intra block according to ISO/IEC 13818-2 table B15 * 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; int i_coeff, i_mismatch, i_code, i_pos, i_value, i_nc;
s32 i_sign; s32 i_sign;
dct_lookup_t * p_tab; dct_lookup_t * p_tab;
int i_q_scale = p_vpar->mb.i_quantizer_scale; 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; dctelem_t * p_dest = p_idct->pi_block;
u8 * p_scan = p_vpar->picture.pi_scan; u8 * p_scan = p_vpar->picture.pi_scan;
...@@ -471,20 +471,16 @@ store_coeff: ...@@ -471,20 +471,16 @@ store_coeff:
/***************************************************************************** /*****************************************************************************
* MPEG2NonIntra : Decode a non-intra MPEG-2 block * 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; int i_coeff, i_mismatch, i_code, i_pos, i_value, i_nc;
s32 i_sign; s32 i_sign;
dct_lookup_t * p_tab; dct_lookup_t * p_tab;
int i_q_scale = p_vpar->mb.i_quantizer_scale; 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; dctelem_t * p_dest = p_idct->pi_block;
u8 * p_scan = p_vpar->picture.pi_scan; u8 * p_scan = p_vpar->picture.pi_scan;
static int meuh = 0;
meuh++;
if( meuh == 3745 )
i_coeff = 0;
i_coeff = -1; i_coeff = -1;
i_mismatch = 1; i_mismatch = 1;
...@@ -644,14 +640,14 @@ coeff_2: ...@@ -644,14 +640,14 @@ coeff_2:
/***************************************************************************** /*****************************************************************************
* MPEG1Intra : Decode an MPEG-1 intra block * 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; int i_coeff, i_code, i_pos, i_value, i_nc;
s32 i_sign; s32 i_sign;
dct_lookup_t * p_tab; dct_lookup_t * p_tab;
int i_q_scale = p_vpar->mb.i_quantizer_scale; 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; dctelem_t * p_dest = p_idct->pi_block;
u8 * p_scan = p_vpar->picture.pi_scan; u8 * p_scan = p_vpar->picture.pi_scan;
...@@ -787,14 +783,14 @@ store_coeff: ...@@ -787,14 +783,14 @@ store_coeff:
/***************************************************************************** /*****************************************************************************
* MPEG1NonIntra : Decode a non-intra MPEG-1 block * 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; int i_coeff, i_code, i_pos, i_value, i_nc;
s32 i_sign; s32 i_sign;
dct_lookup_t * p_tab; dct_lookup_t * p_tab;
int i_q_scale = p_vpar->mb.i_quantizer_scale; 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; dctelem_t * p_dest = p_idct->pi_block;
u8 * p_scan = p_vpar->picture.pi_scan; u8 * p_scan = p_vpar->picture.pi_scan;
...@@ -951,57 +947,48 @@ coeff_2: ...@@ -951,57 +947,48 @@ coeff_2:
/***************************************************************************** /*****************************************************************************
* *MB : decode all blocks of the macroblock * *MB : decode all blocks of the macroblock
*****************************************************************************/ *****************************************************************************/
#define DECODE_LUMABLOCK( i_b, p_dest, PF_MBFUNC ) \ #define DECODE_LUMABLOCK( I_B, PF_MBFUNC ) \
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) ); \ 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_vpar->mb.pi_dc_dct_pred[0] += GetLumaDCDiff( p_vpar ); \
p_idct->pi_block[0] = p_vpar->mb.pi_dc_dct_pred[0] \ p_idct->pi_block[0] = p_vpar->mb.pi_dc_dct_pred[0] \
<< (3 - p_vpar->picture.i_intra_dc_precision ); \ << (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 ) \ #define DECLARE_INTRAMB( PSZ_NAME, PF_MBFUNC ) \
static __inline__ void PSZ_NAME( vpar_thread_t * p_vpar, \ static __inline__ void PSZ_NAME( vpar_thread_t * p_vpar, \
macroblock_t * p_mb ) \ macroblock_t * p_mb ) \
{ \ { \
int i_dct_offset; \
yuv_data_t * p_lum_dest; \
idct_inner_t * p_idct; \ 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 ) \ DECODE_LUMABLOCK( 0, PF_MBFUNC ); \
{ \ DECODE_LUMABLOCK( 1, PF_MBFUNC ); \
i_dct_offset = p_vpar->picture.i_field_width; \ DECODE_LUMABLOCK( 2, PF_MBFUNC ); \
p_mb->i_lum_dct_stride = p_vpar->picture.i_field_width * 2; \ DECODE_LUMABLOCK( 3, PF_MBFUNC ); \
} \ \
else \ do \
{ \ { \
i_dct_offset = p_vpar->picture.i_field_width * 8; \ DECODE_CHROMABLOCK( i_b, PF_MBFUNC, 1 ); \
p_mb->i_lum_dct_stride = p_vpar->picture.i_field_width; \ DECODE_CHROMABLOCK( i_b + 1, PF_MBFUNC, 2 ); \
i_b += 2; \
} \ } \
p_mb->i_chrom_dct_stride = p_vpar->picture.i_field_width >> 1; \ while( i_b < 4 + p_vpar->sequence.i_chroma_nb_blocks ); \
\
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 ); \
} }
DECLARE_INTRAMB( MPEG1IntraMB, MPEG1Intra ); DECLARE_INTRAMB( MPEG1IntraMB, MPEG1Intra );
...@@ -1010,53 +997,59 @@ DECLARE_INTRAMB( MPEG2IntraB15MB, MPEG2IntraB15 ); ...@@ -1010,53 +997,59 @@ DECLARE_INTRAMB( MPEG2IntraB15MB, MPEG2IntraB15 );
#undef DECLARE_INTRAMB #undef DECLARE_INTRAMB
#undef DECODE_LUMABLOCK #undef DECODE_LUMABLOCK
#undef DECODE_CHROMABLOCK
#define DECODE_BLOCK( i_b, p_dest, PF_MBFUNC ) \ #define DECODE_LUMABLOCK( I_B, PF_MBFUNC ) \
if( p_mb->i_coded_block_pattern & (1 << (5 - i_b)) ) \ 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) ); \ 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 ) \ #define DECLARE_NONINTRAMB( PSZ_NAME, PF_MBFUNC ) \
static __inline__ void PSZ_NAME( vpar_thread_t * p_vpar, \ static __inline__ void PSZ_NAME( vpar_thread_t * p_vpar, \
macroblock_t * p_mb ) \ macroblock_t * p_mb ) \
{ \ { \
int i_dct_offset; \
yuv_data_t * p_lum_dest; \
idct_inner_t * p_idct; \ 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 ) \ DECODE_LUMABLOCK( 0, PF_MBFUNC ); \
{ \ DECODE_LUMABLOCK( 1, PF_MBFUNC ); \
i_dct_offset = p_vpar->picture.i_field_width; \ DECODE_LUMABLOCK( 2, PF_MBFUNC ); \
p_mb->i_lum_dct_stride = p_vpar->picture.i_field_width * 2; \ DECODE_LUMABLOCK( 3, PF_MBFUNC ); \
} \ \
else \ do \
{ \ { \
i_dct_offset = p_vpar->picture.i_field_width * 8; \ DECODE_CHROMABLOCK( i_b, PF_MBFUNC ); \
p_mb->i_lum_dct_stride = p_vpar->picture.i_field_width; \ DECODE_CHROMABLOCK( i_b + 1, PF_MBFUNC ); \
i_b += 2; \
} \ } \
p_mb->i_chrom_dct_stride = p_vpar->picture.i_field_width >> 1; \ while( i_b < 4 + p_vpar->sequence.i_chroma_nb_blocks ); \
\
DECODE_BLOCK( 0, p_lum_dest, PF_MBFUNC ); \
DECODE_BLOCK( 1, p_lum_dest + 8, PF_MBFUNC ); \
DECODE_BLOCK( 2, p_lum_dest + i_dct_offset, PF_MBFUNC ); \
DECODE_BLOCK( 3, p_lum_dest + i_dct_offset + 8, PF_MBFUNC ); \
DECODE_BLOCK( 4, p_mb->pp_dest[1] + (p_vpar->mb.i_offset >> 1), \
PF_MBFUNC ); \
DECODE_BLOCK( 5, p_mb->pp_dest[2] + (p_vpar->mb.i_offset >> 1), \
PF_MBFUNC ); \
} }
DECLARE_NONINTRAMB( MPEG1NonIntraMB, MPEG1NonIntra ); DECLARE_NONINTRAMB( MPEG1NonIntraMB, MPEG1NonIntra );
DECLARE_NONINTRAMB( MPEG2NonIntraMB, MPEG2NonIntra ); DECLARE_NONINTRAMB( MPEG2NonIntraMB, MPEG2NonIntra );
#undef DECLARE_NONINTRAMB #undef DECLARE_NONINTRAMB
#undef DECODE_BLOCK #undef DECODE_LUMABLOCK
#undef DECODE_CHROMABLOCK
/* /*
...@@ -1592,16 +1585,48 @@ static __inline__ int CodedPattern( vpar_thread_t * p_vpar ) ...@@ -1592,16 +1585,48 @@ static __inline__ int CodedPattern( vpar_thread_t * p_vpar )
lookup_t * p_tab; lookup_t * p_tab;
int i_code; int i_code;
if( (i_code = ShowBits( &p_vpar->bit_stream, 7 )) >= 0x10 ) /* ? */ if( (i_code = ShowBits( &p_vpar->bit_stream, 7 )) >= 0x10 )
{ {
p_tab = CBP_7 - 16 + i_code; p_tab = CBP_7 - 16 + i_code;
RemoveBits( &p_vpar->bit_stream, p_tab->i_length ); RemoveBits( &p_vpar->bit_stream, p_tab->i_length );
if( p_vpar->sequence.i_chroma_format != CHROMA_420 )
{
int i_value = p_tab->i_value;
if( p_vpar->sequence.i_chroma_format != CHROMA_444 )
{
i_value <<= 2;
i_value |= GetBits( &p_vpar->bit_stream, 2 );
}
else
{
i_value <<= 6;
i_value |= GetBits( &p_vpar->bit_stream, 6 );
}
return( i_value );
}
return( p_tab->i_value ); return( p_tab->i_value );
} }
else else
{ {
p_tab = CBP_9 + ShowBits( &p_vpar->bit_stream, 9 ); p_tab = CBP_9 + ShowBits( &p_vpar->bit_stream, 9 );
RemoveBits( &p_vpar->bit_stream, p_tab->i_length ); RemoveBits( &p_vpar->bit_stream, p_tab->i_length );
if( p_vpar->sequence.i_chroma_format != CHROMA_420 )
{
int i_value = p_tab->i_value;
if( p_vpar->sequence.i_chroma_format != CHROMA_444 )
{
i_value <<= 2;
i_value |= GetBits( &p_vpar->bit_stream, 2 );
}
else
{
i_value <<= 6;
i_value |= GetBits( &p_vpar->bit_stream, 6 );
}
return( i_value );
}
return( p_tab->i_value ); return( p_tab->i_value );
} }
} }
...@@ -1746,18 +1771,18 @@ mb_intra: ...@@ -1746,18 +1771,18 @@ mb_intra:
p_vpar->picture.b_concealment_mv ) \ p_vpar->picture.b_concealment_mv ) \
{ \ { \
p_f_motion->pppi_ref[0][0] += 16 * i_offset; \ p_f_motion->pppi_ref[0][0] += 16 * i_offset; \
p_f_motion->pppi_ref[0][1] += 4 * i_offset; \ p_f_motion->pppi_ref[0][1] += i_chroma_tmp; \
p_f_motion->pppi_ref[0][2] += 4 * i_offset; \ p_f_motion->pppi_ref[0][2] += i_chroma_tmp; \
} \ } \
if( i_coding_type == B_CODING_TYPE ) \ if( i_coding_type == B_CODING_TYPE ) \
{ \ { \
p_b_motion->pppi_ref[0][0] += 16 * i_offset; \ p_b_motion->pppi_ref[0][0] += 16 * i_offset; \
p_b_motion->pppi_ref[0][1] += 4 * i_offset; \ p_b_motion->pppi_ref[0][1] += i_chroma_tmp; \
p_b_motion->pppi_ref[0][2] += 4 * i_offset; \ p_b_motion->pppi_ref[0][2] += i_chroma_tmp; \
} \ } \
p_dest[0] += 16 * i_offset; \ p_dest[0] += 16 * i_offset; \
p_dest[1] += 4 * i_offset; \ p_dest[1] += 4 * i_offset; \
p_dest[2] += 4 * i_offset; \ p_dest[2] += 4 * i_offset; \
i_offset = 0; \ i_offset = 0; \
} \ } \
p_vpar->mb.i_offset = i_offset; p_vpar->mb.i_offset = i_offset;
...@@ -1774,7 +1799,7 @@ static __inline__ void ParseSlice( vpar_thread_t * p_vpar, ...@@ -1774,7 +1799,7 @@ static __inline__ void ParseSlice( vpar_thread_t * p_vpar,
u32 i_vert_code, boolean_t b_mpeg2, u32 i_vert_code, boolean_t b_mpeg2,
int i_coding_type, int i_structure ) int i_coding_type, int i_structure )
{ {
int i_offset, i_width; int i_offset, i_width, i_chroma_tmp;
picture_t * pp_forward_ref[2]; picture_t * pp_forward_ref[2];
yuv_data_t * p_dest[3]; yuv_data_t * p_dest[3];
...@@ -1805,6 +1830,10 @@ static __inline__ void ParseSlice( vpar_thread_t * p_vpar, ...@@ -1805,6 +1830,10 @@ static __inline__ void ParseSlice( vpar_thread_t * p_vpar,
if( i_structure != FRAME_STRUCTURE ) if( i_structure != FRAME_STRUCTURE )
{ {
i_offset <<= 1; i_offset <<= 1;
i_chroma_tmp =
i_offset * (2 - p_vpar->sequence.b_chroma_v_subsampled)
* (2 - p_vpar->sequence.b_chroma_h_subsampled)
+ (i_width >> p_vpar->sequence.b_chroma_h_subsampled);
pp_forward_ref[1] = p_vpar->sequence.p_forward; pp_forward_ref[1] = p_vpar->sequence.p_forward;
if( i_coding_type != B_CODING_TYPE && p_vpar->picture.b_second_field ) if( i_coding_type != B_CODING_TYPE && p_vpar->picture.b_second_field )
...@@ -1815,28 +1844,31 @@ static __inline__ void ParseSlice( vpar_thread_t * p_vpar, ...@@ -1815,28 +1844,31 @@ static __inline__ void ParseSlice( vpar_thread_t * p_vpar,
if( i_coding_type != I_CODING_TYPE || p_vpar->picture.b_concealment_mv ) if( i_coding_type != I_CODING_TYPE || p_vpar->picture.b_concealment_mv )
{ {
p_f_motion->pppi_ref[1][0] = p_f_motion->pppi_ref[1][0] =
pp_forward_ref[1]->p_y + i_offset * 4 + i_width; pp_forward_ref[1]->p_y + i_offset * 4 + i_width;
p_f_motion->pppi_ref[1][1] = p_f_motion->pppi_ref[1][1] =
pp_forward_ref[1]->p_u + i_offset + (i_width >> 1); pp_forward_ref[1]->p_u + i_chroma_tmp;
p_f_motion->pppi_ref[1][2] = p_f_motion->pppi_ref[1][2] =
pp_forward_ref[1]->p_v + i_offset + (i_width >> 1); pp_forward_ref[1]->p_v + i_chroma_tmp;
} }
if( i_coding_type == B_CODING_TYPE ) if( i_coding_type == B_CODING_TYPE )
{ {
p_b_motion->pppi_ref[1][0] = p_b_motion->pppi_ref[1][0] =
p_vpar->sequence.p_backward->p_y + i_offset * 4 + i_width; p_vpar->sequence.p_backward->p_y + i_offset * 4 + i_width;
p_b_motion->pppi_ref[1][1] = p_b_motion->pppi_ref[1][1] =
p_vpar->sequence.p_backward->p_u + i_offset + (i_width >> 1); p_vpar->sequence.p_backward->p_u + i_chroma_tmp;
p_b_motion->pppi_ref[1][2] = p_b_motion->pppi_ref[1][2] =
p_vpar->sequence.p_backward->p_v + i_offset + (i_width >> 1); p_vpar->sequence.p_backward->p_v + i_chroma_tmp;
} }
} }
i_chroma_tmp = i_offset
* (2 - p_vpar->sequence.b_chroma_v_subsampled)
* (2 - p_vpar->sequence.b_chroma_h_subsampled);
if( i_coding_type != I_CODING_TYPE || p_vpar->picture.b_concealment_mv ) if( i_coding_type != I_CODING_TYPE || p_vpar->picture.b_concealment_mv )
{ {
p_f_motion->pppi_ref[0][0] = pp_forward_ref[0]->p_y + i_offset * 4; p_f_motion->pppi_ref[0][0] = pp_forward_ref[0]->p_y + i_offset * 4;
p_f_motion->pppi_ref[0][1] = pp_forward_ref[0]->p_u + i_offset; p_f_motion->pppi_ref[0][1] = pp_forward_ref[0]->p_u + i_chroma_tmp;
p_f_motion->pppi_ref[0][2] = pp_forward_ref[0]->p_v + i_offset; p_f_motion->pppi_ref[0][2] = pp_forward_ref[0]->p_v + i_chroma_tmp;
p_f_motion->pi_f_code[0] = p_vpar->picture.ppi_f_code[0][0]; p_f_motion->pi_f_code[0] = p_vpar->picture.ppi_f_code[0][0];
p_f_motion->pi_f_code[1] = p_vpar->picture.ppi_f_code[0][1]; p_f_motion->pi_f_code[1] = p_vpar->picture.ppi_f_code[0][1];
p_f_motion->ppi_pmv[0][0] = p_f_motion->ppi_pmv[0][1] = 0; p_f_motion->ppi_pmv[0][0] = p_f_motion->ppi_pmv[0][1] = 0;
...@@ -1848,9 +1880,9 @@ static __inline__ void ParseSlice( vpar_thread_t * p_vpar, ...@@ -1848,9 +1880,9 @@ static __inline__ void ParseSlice( vpar_thread_t * p_vpar,
p_b_motion->pppi_ref[0][0] = p_vpar->sequence.p_backward->p_y p_b_motion->pppi_ref[0][0] = p_vpar->sequence.p_backward->p_y
+ i_offset * 4; + i_offset * 4;
p_b_motion->pppi_ref[0][1] = p_vpar->sequence.p_backward->p_u p_b_motion->pppi_ref[0][1] = p_vpar->sequence.p_backward->p_u
+ i_offset; + i_chroma_tmp;
p_b_motion->pppi_ref[0][2] = p_vpar->sequence.p_backward->p_v p_b_motion->pppi_ref[0][2] = p_vpar->sequence.p_backward->p_v
+ i_offset; + i_chroma_tmp;
p_b_motion->pi_f_code[0] = p_vpar->picture.ppi_f_code[1][0]; p_b_motion->pi_f_code[0] = p_vpar->picture.ppi_f_code[1][0];
p_b_motion->pi_f_code[1] = p_vpar->picture.ppi_f_code[1][1]; p_b_motion->pi_f_code[1] = p_vpar->picture.ppi_f_code[1][1];
p_b_motion->ppi_pmv[0][0] = p_b_motion->ppi_pmv[0][1] = 0; p_b_motion->ppi_pmv[0][0] = p_b_motion->ppi_pmv[0][1] = 0;
...@@ -1859,14 +1891,14 @@ static __inline__ void ParseSlice( vpar_thread_t * p_vpar, ...@@ -1859,14 +1891,14 @@ static __inline__ void ParseSlice( vpar_thread_t * p_vpar,
/* Initialize destination pointers. */ /* Initialize destination pointers. */
p_dest[0] = p_vpar->picture.p_picture->p_y + i_offset * 4; p_dest[0] = p_vpar->picture.p_picture->p_y + i_offset * 4;
p_dest[1] = p_vpar->picture.p_picture->p_u + i_offset; p_dest[1] = p_vpar->picture.p_picture->p_u + i_chroma_tmp;
p_dest[2] = p_vpar->picture.p_picture->p_v + i_offset; p_dest[2] = p_vpar->picture.p_picture->p_v + i_chroma_tmp;
if( i_structure == BOTTOM_FIELD ) if( i_structure == BOTTOM_FIELD )
{ {
p_dest[0] += i_width; p_dest[0] += i_width;
p_dest[1] += i_width >> 1; p_dest[1] += i_width >> p_vpar->sequence.b_chroma_h_subsampled;
p_dest[2] += i_width >> 1; p_dest[2] += i_width >> p_vpar->sequence.b_chroma_h_subsampled;
} }
i_width = p_vpar->picture.i_field_width; i_width = p_vpar->picture.i_field_width;
...@@ -1877,19 +1909,22 @@ static __inline__ void ParseSlice( vpar_thread_t * p_vpar, ...@@ -1877,19 +1909,22 @@ static __inline__ void ParseSlice( vpar_thread_t * p_vpar,
p_vpar->mb.i_offset = MacroblockAddressIncrement( p_vpar ) << 4; p_vpar->mb.i_offset = MacroblockAddressIncrement( p_vpar ) << 4;
i_chroma_tmp = i_width * 4
* (2 - p_vpar->sequence.b_chroma_v_subsampled)
* (2 - p_vpar->sequence.b_chroma_h_subsampled);
while( (int)(p_vpar->mb.i_offset - p_vpar->sequence.i_width) >= 0 ) while( (int)(p_vpar->mb.i_offset - p_vpar->sequence.i_width) >= 0 )
{ {
/* Unusual construct at the start of some slices. Jump one line. */ /* Unusual construct at the start of some slices. Jump one line. */
p_vpar->mb.i_offset -= p_vpar->sequence.i_width; p_vpar->mb.i_offset -= p_vpar->sequence.i_width;
p_dest[0] += i_width * 16; p_dest[0] += i_width * 16;
p_dest[1] += i_width * 4; p_dest[1] += i_chroma_tmp;
p_dest[2] += i_width * 4; p_dest[2] += i_chroma_tmp;
p_f_motion->pppi_ref[0][0] += i_width * 16; p_f_motion->pppi_ref[0][0] += i_width * 16;
p_f_motion->pppi_ref[0][1] += i_width * 4; p_f_motion->pppi_ref[0][1] += i_chroma_tmp;
p_f_motion->pppi_ref[0][2] += i_width * 4; p_f_motion->pppi_ref[0][2] += i_chroma_tmp;
p_f_motion->pppi_ref[1][0] += i_width * 16; p_f_motion->pppi_ref[1][0] += i_width * 16;
p_f_motion->pppi_ref[1][1] += i_width * 4; p_f_motion->pppi_ref[1][1] += i_chroma_tmp;
p_f_motion->pppi_ref[1][2] += i_width * 4; p_f_motion->pppi_ref[1][2] += i_chroma_tmp;
} }
for( ; ; ) for( ; ; )
...@@ -1937,7 +1972,6 @@ static __inline__ void ParseSlice( vpar_thread_t * p_vpar, ...@@ -1937,7 +1972,6 @@ static __inline__ void ParseSlice( vpar_thread_t * p_vpar,
} }
/* Decode blocks */ /* Decode blocks */
p_mb->i_coded_block_pattern = (1 << 6) - 1;
if( b_mpeg2 ) if( b_mpeg2 )
{ {
if( p_vpar->picture.b_intra_vlc_format ) if( p_vpar->picture.b_intra_vlc_format )
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* vpar_headers.c : headers parsing * vpar_headers.c : headers parsing
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN * Copyright (C) 1999, 2000 VideoLAN
* $Id: vpar_headers.c,v 1.11 2001/10/01 16:44:07 massiot Exp $ * $Id: vpar_headers.c,v 1.12 2001/10/11 13:19:27 massiot Exp $
* *
* Authors: Christophe Massiot <massiot@via.ecp.fr> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* Stphane Borel <stef@via.ecp.fr> * Stphane Borel <stef@via.ecp.fr>
...@@ -46,6 +46,7 @@ ...@@ -46,6 +46,7 @@
#include "vdec_ext-plugins.h" #include "vdec_ext-plugins.h"
#include "vpar_pool.h" #include "vpar_pool.h"
#include "video_parser.h" #include "video_parser.h"
#include "video_decoder.h"
/* /*
* Local prototypes * Local prototypes
...@@ -397,6 +398,24 @@ static void SequenceHeader( vpar_thread_t * p_vpar ) ...@@ -397,6 +398,24 @@ static void SequenceHeader( vpar_thread_t * p_vpar )
p_vpar->sequence.i_height = (p_vpar->sequence.i_mb_height * 16); p_vpar->sequence.i_height = (p_vpar->sequence.i_mb_height * 16);
p_vpar->sequence.i_size = p_vpar->sequence.i_width p_vpar->sequence.i_size = p_vpar->sequence.i_width
* p_vpar->sequence.i_height; * p_vpar->sequence.i_height;
switch( p_vpar->sequence.i_chroma_format )
{
case CHROMA_420:
p_vpar->sequence.i_chroma_nb_blocks = 2;
p_vpar->sequence.b_chroma_h_subsampled = 1;
p_vpar->sequence.b_chroma_v_subsampled = 1;
break;
case CHROMA_422:
p_vpar->sequence.i_chroma_nb_blocks = 4;
p_vpar->sequence.b_chroma_h_subsampled = 1;
p_vpar->sequence.b_chroma_v_subsampled = 0;
break;
case CHROMA_444:
p_vpar->sequence.i_chroma_nb_blocks = 6;
p_vpar->sequence.b_chroma_h_subsampled = 0;
p_vpar->sequence.b_chroma_v_subsampled = 0;
break;
}
#if 0 #if 0
if( p_vpar->sequence.i_width != i_width_save if( p_vpar->sequence.i_width != i_width_save
...@@ -750,6 +769,28 @@ static void PictureHeader( vpar_thread_t * p_vpar ) ...@@ -750,6 +769,28 @@ static void PictureHeader( vpar_thread_t * p_vpar )
p_vpar->picture.b_current_field = p_vpar->picture.b_current_field =
(i_structure == BOTTOM_FIELD ); (i_structure == BOTTOM_FIELD );
if( !p_vpar->p_config->decoder_config.p_stream_ctrl->b_grayscale )
{
switch( p_vpar->sequence.i_chroma_format )
{
case CHROMA_422:
p_vpar->pool.pf_vdec_decode = vdec_DecodeMacroblock422;
break;
case CHROMA_444:
p_vpar->pool.pf_vdec_decode = vdec_DecodeMacroblock444;
break;
case CHROMA_420:
default:
p_vpar->pool.pf_vdec_decode = vdec_DecodeMacroblock420;
break;
}
}
else
{
p_vpar->pool.pf_vdec_decode = vdec_DecodeMacroblockBW;
}
if( p_vpar->sequence.b_mpeg2 ) if( p_vpar->sequence.b_mpeg2 )
{ {
static f_picture_data_t ppf_picture_data[4][4] = static f_picture_data_t ppf_picture_data[4][4] =
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* vpar_pool.c : management of the pool of decoder threads * vpar_pool.c : management of the pool of decoder threads
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN * Copyright (C) 1999, 2000, 2001 VideoLAN
* $Id: vpar_pool.c,v 1.3 2001/09/25 11:46:14 massiot Exp $ * $Id: vpar_pool.c,v 1.4 2001/10/11 13:19:27 massiot Exp $
* *
* Authors: Christophe Massiot <massiot@via.ecp.fr> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -77,6 +77,7 @@ void vpar_InitPool( vpar_thread_t * p_vpar ) ...@@ -77,6 +77,7 @@ void vpar_InitPool( vpar_thread_t * p_vpar )
p_vpar->pool.p_macroblocks = NULL; p_vpar->pool.p_macroblocks = NULL;
p_vpar->pool.pp_empty_macroblocks = NULL; p_vpar->pool.pp_empty_macroblocks = NULL;
p_vpar->pool.pp_new_macroblocks = NULL; p_vpar->pool.pp_new_macroblocks = NULL;
p_vpar->pool.p_vpar = p_vpar;
vpar_SpawnPool( p_vpar ); vpar_SpawnPool( p_vpar );
/* Initialize fake video decoder structure (used when /* Initialize fake video decoder structure (used when
...@@ -92,7 +93,7 @@ void vpar_InitPool( vpar_thread_t * p_vpar ) ...@@ -92,7 +93,7 @@ void vpar_InitPool( vpar_thread_t * p_vpar )
p_vpar->pool.p_vdec->p_pool = &p_vpar->pool; p_vpar->pool.p_vdec->p_pool = &p_vpar->pool;
vdec_InitThread( p_vpar->pool.p_vdec ); vdec_InitThread( p_vpar->pool.p_vdec );
for( j = 0; j < 6; j++ ) for( j = 0; j < 12; j++ )
{ {
p_vpar->pool.mb.p_idcts[j].pi_block = p_vpar->pool.mb.p_idcts[j].pi_block =
memalign( 16, 64 * sizeof(dctelem_t) ); memalign( 16, 64 * sizeof(dctelem_t) );
...@@ -110,13 +111,11 @@ void vpar_InitPool( vpar_thread_t * p_vpar ) ...@@ -110,13 +111,11 @@ void vpar_InitPool( vpar_thread_t * p_vpar )
void vpar_SpawnPool( vpar_thread_t * p_vpar ) void vpar_SpawnPool( vpar_thread_t * p_vpar )
{ {
int i_new_smp; int i_new_smp;
boolean_t b_grayscale;
stream_ctrl_t * p_control; stream_ctrl_t * p_control;
p_control = p_vpar->p_config->decoder_config.p_stream_ctrl; p_control = p_vpar->p_config->decoder_config.p_stream_ctrl;
vlc_mutex_lock( &p_control->control_lock ); vlc_mutex_lock( &p_control->control_lock );
i_new_smp = p_control->i_smp; i_new_smp = p_control->i_smp;
b_grayscale = p_control->b_grayscale;
vlc_mutex_unlock( &p_control->control_lock ); vlc_mutex_unlock( &p_control->control_lock );
/* FIXME: No error check because I'm tired. Come back later... */ /* FIXME: No error check because I'm tired. Come back later... */
...@@ -136,7 +135,7 @@ void vpar_SpawnPool( vpar_thread_t * p_vpar ) ...@@ -136,7 +135,7 @@ void vpar_SpawnPool( vpar_thread_t * p_vpar )
vdec_DestroyThread( p_vpar->pool.pp_vdec[i] ); vdec_DestroyThread( p_vpar->pool.pp_vdec[i] );
for( j = 0; j < 6; j++ ) for( j = 0; j < 12; j++ )
{ {
free( p_vpar->pool.p_macroblocks[i].p_idcts[j].pi_block ); free( p_vpar->pool.p_macroblocks[i].p_idcts[j].pi_block );
} }
...@@ -172,7 +171,7 @@ void vpar_SpawnPool( vpar_thread_t * p_vpar ) ...@@ -172,7 +171,7 @@ void vpar_SpawnPool( vpar_thread_t * p_vpar )
{ {
int j; int j;
for( j = 0; j < 6; j++ ) for( j = 0; j < 12; j++ )
{ {
p_vpar->pool.p_macroblocks[i].p_idcts[j].pi_block = p_vpar->pool.p_macroblocks[i].p_idcts[j].pi_block =
memalign( 16, 64 * sizeof(dctelem_t) ); memalign( 16, 64 * sizeof(dctelem_t) );
...@@ -206,15 +205,6 @@ void vpar_SpawnPool( vpar_thread_t * p_vpar ) ...@@ -206,15 +205,6 @@ void vpar_SpawnPool( vpar_thread_t * p_vpar )
p_vpar->pool.pf_free_mb = FreeMacroblockDummy; p_vpar->pool.pf_free_mb = FreeMacroblockDummy;
p_vpar->pool.pf_decode_mb = DecodeMacroblockDummy; p_vpar->pool.pf_decode_mb = DecodeMacroblockDummy;
} }
if( !b_grayscale )
{
p_vpar->pool.pf_vdec_decode = vdec_DecodeMacroblockC;
}
else
{
p_vpar->pool.pf_vdec_decode = vdec_DecodeMacroblockBW;
}
} }
/***************************************************************************** /*****************************************************************************
...@@ -230,7 +220,7 @@ void vpar_EndPool( vpar_thread_t * p_vpar ) ...@@ -230,7 +220,7 @@ void vpar_EndPool( vpar_thread_t * p_vpar )
vdec_DestroyThread( p_vpar->pool.pp_vdec[i] ); vdec_DestroyThread( p_vpar->pool.pp_vdec[i] );
for( j = 0; j < 6; j++ ) for( j = 0; j < 12; j++ )
{ {
free( p_vpar->pool.p_macroblocks[i].p_idcts[j].pi_block ); free( p_vpar->pool.p_macroblocks[i].p_idcts[j].pi_block );
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* vpar_pool.h : video parser/video decoders communication * vpar_pool.h : video parser/video decoders communication
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN * Copyright (C) 1999, 2000 VideoLAN
* $Id: vpar_pool.h,v 1.3 2001/09/05 16:07:50 massiot Exp $ * $Id: vpar_pool.h,v 1.4 2001/10/11 13:19:27 massiot Exp $
* *
* Authors: Christophe Massiot <massiot@via.ecp.fr> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -76,6 +76,8 @@ typedef struct vdec_pool_s ...@@ -76,6 +76,8 @@ typedef struct vdec_pool_s
void ( * pf_idct_init ) ( void ** ); void ( * pf_idct_init ) ( void ** );
void ( * ppppf_motion[2][2][4] ) ( yuv_data_t *, yuv_data_t *, void ( * ppppf_motion[2][2][4] ) ( yuv_data_t *, yuv_data_t *,
int, int ); int, int );
struct vpar_thread_s * p_vpar;
} vdec_pool_t; } vdec_pool_t;
/***************************************************************************** /*****************************************************************************
......
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