Commit 7b3ed3ad authored by Christophe Massiot's avatar Christophe Massiot

* Various miscellaneous minor optimizations of the video parser.

parent 95ef185a
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* input_ext-dec.h: structures exported to the VideoLAN decoders * input_ext-dec.h: structures exported to the VideoLAN decoders
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN * Copyright (C) 1999, 2000 VideoLAN
* $Id: input_ext-dec.h,v 1.17 2001/01/20 13:08:33 sam Exp $ * $Id: input_ext-dec.h,v 1.18 2001/01/21 01:36:25 massiot Exp $
* *
* Authors: * Authors:
* *
...@@ -135,6 +135,11 @@ typedef struct bit_fifo_s ...@@ -135,6 +135,11 @@ typedef struct bit_fifo_s
*****************************************************************************/ *****************************************************************************/
typedef struct bit_stream_s typedef struct bit_stream_s
{ {
/*
* Bit structures
*/
bit_fifo_t fifo;
/* /*
* Input structures * Input structures
*/ */
...@@ -160,11 +165,6 @@ typedef struct bit_stream_s ...@@ -160,11 +165,6 @@ typedef struct bit_stream_s
byte_t * p_byte; byte_t * p_byte;
/* Pointer to the last byte that is to be read (in the current TS packet */ /* Pointer to the last byte that is to be read (in the current TS packet */
byte_t * p_end; byte_t * p_end;
/*
* Bit structures
*/
bit_fifo_t fifo;
} bit_stream_t; } bit_stream_t;
/***************************************************************************** /*****************************************************************************
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* vpar_blocks.h : video parser blocks management * vpar_blocks.h : video parser blocks management
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN * Copyright (C) 1999, 2000 VideoLAN
* $Id: vpar_blocks.h,v 1.32 2001/01/18 05:13:22 sam Exp $ * $Id: vpar_blocks.h,v 1.33 2001/01/21 01:36:25 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>
...@@ -172,4 +172,28 @@ void vpar_InitBMBType( struct vpar_thread_s * p_vpar ); ...@@ -172,4 +172,28 @@ void vpar_InitBMBType( struct vpar_thread_s * p_vpar );
void vpar_InitCodedPattern( struct vpar_thread_s * p_vpar ); void vpar_InitCodedPattern( struct vpar_thread_s * p_vpar );
void vpar_InitDCTTables( struct vpar_thread_s * p_vpar ); void vpar_InitDCTTables( struct vpar_thread_s * p_vpar );
void vpar_InitScanTable( struct vpar_thread_s * p_vpar ); void vpar_InitScanTable( struct vpar_thread_s * p_vpar );
void vpar_PictureData( struct vpar_thread_s * p_vpar, int i_mb_base );
typedef void (*f_picture_data_t)( struct vpar_thread_s * p_vpar,
int i_mb_base );
#define PROTO_PICD( FUNCNAME ) \
void FUNCNAME( struct vpar_thread_s * p_vpar, int i_mb_base );
PROTO_PICD( vpar_PictureDataGENERIC )
#if (VPAR_OPTIM_LEVEL > 0)
PROTO_PICD( vpar_PictureData1I )
PROTO_PICD( vpar_PictureData1P )
PROTO_PICD( vpar_PictureData1B )
PROTO_PICD( vpar_PictureData1D )
PROTO_PICD( vpar_PictureData2IF )
PROTO_PICD( vpar_PictureData2PF )
PROTO_PICD( vpar_PictureData2BF )
#endif
#if (VPAR_OPTIM_LEVEL > 1)
PROTO_PICD( vpar_PictureData2IT )
PROTO_PICD( vpar_PictureData2PT )
PROTO_PICD( vpar_PictureData2BT )
PROTO_PICD( vpar_PictureData2IB )
PROTO_PICD( vpar_PictureData2PB )
PROTO_PICD( vpar_PictureData2BB )
#endif
...@@ -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.6 2001/01/18 05:13:23 sam Exp $ * $Id: video_parser.h,v 1.7 2001/01/21 01:36:25 massiot Exp $
* *
* Authors: Christophe Massiot <massiot@via.ecp.fr> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -83,6 +83,8 @@ typedef struct video_buffer_s ...@@ -83,6 +83,8 @@ typedef struct video_buffer_s
*****************************************************************************/ *****************************************************************************/
typedef struct vpar_thread_s typedef struct vpar_thread_s
{ {
bit_stream_t bit_stream;
/* Thread properties and locks */ /* Thread properties and locks */
vlc_thread_t thread_id; /* id for thread functions */ vlc_thread_t thread_id; /* id for thread functions */
...@@ -93,7 +95,6 @@ typedef struct vpar_thread_s ...@@ -93,7 +95,6 @@ typedef struct vpar_thread_s
/* Input properties */ /* Input properties */
decoder_fifo_t * p_fifo; /* PES input fifo */ decoder_fifo_t * p_fifo; /* PES input fifo */
bit_stream_t bit_stream;
vdec_config_t * p_config; vdec_config_t * p_config;
/* Output properties */ /* Output properties */
......
...@@ -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.72 2001/01/18 05:13:23 sam Exp $ * $Id: vpar_blocks.c,v 1.73 2001/01/21 01:36:25 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>
...@@ -398,40 +398,10 @@ static dct_lookup_t * ppl_dct_tab1[2] = { pl_DCT_tab_ac, pl_DCT_tab0a }; ...@@ -398,40 +398,10 @@ static dct_lookup_t * ppl_dct_tab1[2] = { pl_DCT_tab_ac, pl_DCT_tab0a };
static dct_lookup_t * ppl_dct_tab2[2] = { pl_DCT_tab_ac, pl_DCT_tab_dc }; static dct_lookup_t * ppl_dct_tab2[2] = { pl_DCT_tab_ac, pl_DCT_tab_dc };
/* Lookup Table for the chromatic component */
static int pi_cc_index[12] = { 0, 0, 0, 0, 1, 2, 1, 2, 1, 2 };
/* /*
* Initialization of lookup tables * Initialization of lookup tables
*/ */
/*****************************************************************************
* vpar_InitCrop : Initialize the crop table for saturation
* (ISO/IEC 13818-2 section 7.4.3)
*****************************************************************************/
#if defined(MPEG2_COMPLIANT) && !defined(VDEC_DFT)
void vpar_InitCrop( vpar_thread_t * p_vpar )
{
int i_dummy;
p_vpar->pi_crop = p_vpar->pi_crop_buf + 4096;
for( i_dummy = -4096; i_dummy < -2048; i_dummy++ )
{
p_vpar->pi_crop[i_dummy] = -2048;
}
for( ; i_dummy < 2047; i_dummy++ )
{
p_vpar->pi_crop[i_dummy] = i_dummy;
}
for( ; i_dummy < 4095; i_dummy++ )
{
p_vpar->pi_crop[i_dummy] = 2047;
}
}
#endif
/***************************************************************************** /*****************************************************************************
* vpar_InitMbAddrInc : Initialize the lookup table for mb_addr_inc * vpar_InitMbAddrInc : Initialize the lookup table for mb_addr_inc
*****************************************************************************/ *****************************************************************************/
...@@ -634,31 +604,29 @@ void vpar_InitScanTable( vpar_thread_t * p_vpar ) ...@@ -634,31 +604,29 @@ void vpar_InitScanTable( vpar_thread_t * p_vpar )
* Block parsing * Block parsing
*/ */
#define SATURATE(val) \
if( val > 2047 ) \
val = 2047; \
else if( val < -2048 ) \
val = -2048;
/***************************************************************************** /*****************************************************************************
* DecodeMPEG1NonIntra : decode MPEG-1 non-intra blocks * DecodeMPEG1NonIntra : decode MPEG-1 non-intra blocks
*****************************************************************************/ *****************************************************************************/
static __inline__ void DecodeMPEG1NonIntra( vpar_thread_t * p_vpar, static __inline__ void DecodeMPEG1NonIntra( vpar_thread_t * p_vpar,
macroblock_t * p_mb, int i_b, macroblock_t * p_mb, int i_b,
int i_chroma_format ) boolean_t b_chroma, int i_cc )
{ {
int i_parse; int i_parse;
int i_nc; int i_nc;
int i_cc;
int i_coef; int i_coef;
int i_code; int i_code;
int i_length; int i_length;
int i_pos; int i_pos;
int i_run; int i_run;
int i_level; int i_level;
boolean_t b_dc;
boolean_t b_sign; boolean_t b_sign;
boolean_t b_chroma; dct_lookup_t * p_tab;
/* Give the chromatic component (0, 1, 2) */
i_cc = pi_cc_index[i_b];
/* Determine whether it is luminance or not (chrominance) */
b_chroma = ( i_cc + 1 ) >> 1;
/* There should be no D picture in non-intra blocks */ /* There should be no D picture in non-intra blocks */
if( p_vpar->picture.i_coding_type == D_CODING_TYPE ) if( p_vpar->picture.i_coding_type == D_CODING_TYPE )
...@@ -675,17 +643,15 @@ static __inline__ void DecodeMPEG1NonIntra( vpar_thread_t * p_vpar, ...@@ -675,17 +643,15 @@ static __inline__ void DecodeMPEG1NonIntra( vpar_thread_t * p_vpar,
i_code = ShowBits( &p_vpar->bit_stream, 16 ); i_code = ShowBits( &p_vpar->bit_stream, 16 );
if( i_code >= 16384 ) if( i_code >= 16384 )
{ {
b_dc = (i_parse == 0); p_tab = &ppl_dct_tab2[(i_parse == 0)][(i_code>>12)-4];
i_run = ppl_dct_tab2[b_dc][(i_code>>12)-4].i_run;
i_level = ppl_dct_tab2[b_dc][(i_code>>12)-4].i_level;
i_length = ppl_dct_tab2[b_dc][(i_code>>12)-4].i_length;
} }
else else
{ {
i_run = p_vpar->ppl_dct_coef[0][i_code].i_run; p_tab = &p_vpar->ppl_dct_coef[0][i_code];
i_length = p_vpar->ppl_dct_coef[0][i_code].i_length;
i_level = p_vpar->ppl_dct_coef[0][i_code].i_level;
} }
i_run = p_tab->i_run;
i_level = p_tab->i_level;
i_length = p_tab->i_length;
RemoveBits( &p_vpar->bit_stream, i_length ); RemoveBits( &p_vpar->bit_stream, i_length );
...@@ -735,13 +701,14 @@ static __inline__ void DecodeMPEG1NonIntra( vpar_thread_t * p_vpar, ...@@ -735,13 +701,14 @@ static __inline__ void DecodeMPEG1NonIntra( vpar_thread_t * p_vpar,
* p_vpar->sequence.nonintra_quant.pi_matrix[i_pos] ) >> 4; * p_vpar->sequence.nonintra_quant.pi_matrix[i_pos] ) >> 4;
/* Mismatch control */ /* Mismatch control */
if( i_level ) /* Should always be true */
{
/* Equivalent to : if( (val & 1) == 0 ) val = val - 1; */ /* Equivalent to : if( (val & 1) == 0 ) val = val - 1; */
i_level = (i_level - 1) | 1; i_level = (i_level - 1) | 1;
}
p_mb->ppi_blocks[i_b][i_pos] = b_sign ? -i_level : i_level; i_level = b_sign ? -i_level : i_level;
SATURATE( i_level );
p_mb->ppi_blocks[i_b][i_pos] = i_level;
} }
intf_ErrMsg("vpar error: DCT coeff (non-intra) is out of bounds"); intf_ErrMsg("vpar error: DCT coeff (non-intra) is out of bounds");
...@@ -752,12 +719,11 @@ static __inline__ void DecodeMPEG1NonIntra( vpar_thread_t * p_vpar, ...@@ -752,12 +719,11 @@ static __inline__ void DecodeMPEG1NonIntra( vpar_thread_t * p_vpar,
* DecodeMPEG1Intra : decode MPEG-1 intra blocks * DecodeMPEG1Intra : decode MPEG-1 intra blocks
*****************************************************************************/ *****************************************************************************/
static __inline__ void DecodeMPEG1Intra( vpar_thread_t * p_vpar, static __inline__ void DecodeMPEG1Intra( vpar_thread_t * p_vpar,
macroblock_t * p_mb, int i_b , macroblock_t * p_mb, int i_b,
int i_chroma_format ) boolean_t b_chroma, int i_cc )
{ {
int i_parse; int i_parse;
int i_nc; int i_nc;
int i_cc;
int i_coef; int i_coef;
int i_code; int i_code;
int i_length; int i_length;
...@@ -767,30 +733,25 @@ static __inline__ void DecodeMPEG1Intra( vpar_thread_t * p_vpar, ...@@ -767,30 +733,25 @@ static __inline__ void DecodeMPEG1Intra( vpar_thread_t * p_vpar,
int i_run; int i_run;
int i_level; int i_level;
boolean_t b_sign; boolean_t b_sign;
boolean_t b_chroma; dct_lookup_t * p_tab;
lookup_t * p_lookup;
/* Give the chromatic component (0, 1, 2) */ u8 * pi_quant = p_vpar->sequence.intra_quant.pi_matrix;
i_cc = pi_cc_index[i_b];
/* Determine whether it is luminance or not (chrominance) */
b_chroma = ( i_cc + 1 ) >> 1;
/* decode length */ /* decode length */
i_code = ShowBits(&p_vpar->bit_stream, 5); i_code = ShowBits(&p_vpar->bit_stream, 5);
if (i_code<31) if (i_code<31)
{ {
i_dct_dc_size = ppl_dct_dc_init_table_1[b_chroma][i_code].i_value; p_lookup = &ppl_dct_dc_init_table_1[b_chroma][i_code];
i_length = ppl_dct_dc_init_table_1[b_chroma][i_code].i_length;
RemoveBits( &p_vpar->bit_stream, i_length);
} }
else else
{ {
i_code = ShowBits(&p_vpar->bit_stream, (9+b_chroma)) - (0x1f0 * (b_chroma + 1)); i_code = ShowBits(&p_vpar->bit_stream, (9+b_chroma)) - (0x1f0 * (b_chroma + 1));
i_dct_dc_size = ppl_dct_dc_init_table_2[b_chroma][i_code].i_value; p_lookup = &ppl_dct_dc_init_table_2[b_chroma][i_code];
i_length = ppl_dct_dc_init_table_2[b_chroma][i_code].i_length;
RemoveBits( &p_vpar->bit_stream, i_length);
} }
i_dct_dc_size = p_lookup->i_value;
i_length = p_lookup->i_length;
RemoveBits( &p_vpar->bit_stream, i_length );
if (i_dct_dc_size == 0) if (i_dct_dc_size == 0)
i_dct_dc_diff = 0; i_dct_dc_diff = 0;
...@@ -808,7 +769,6 @@ static __inline__ void DecodeMPEG1Intra( vpar_thread_t * p_vpar, ...@@ -808,7 +769,6 @@ static __inline__ void DecodeMPEG1Intra( vpar_thread_t * p_vpar,
i_nc = ( p_vpar->mb.pi_dc_dct_pred[i_cc] != 0 ); i_nc = ( p_vpar->mb.pi_dc_dct_pred[i_cc] != 0 );
if( p_vpar->picture.i_coding_type == D_CODING_TYPE ) if( p_vpar->picture.i_coding_type == D_CODING_TYPE )
{ {
/* Remove end_of_macroblock (always 1, prevents startcode emulation) /* Remove end_of_macroblock (always 1, prevents startcode emulation)
...@@ -823,22 +783,21 @@ static __inline__ void DecodeMPEG1Intra( vpar_thread_t * p_vpar, ...@@ -823,22 +783,21 @@ static __inline__ void DecodeMPEG1Intra( vpar_thread_t * p_vpar,
i_coef = 0; i_coef = 0;
b_sign = 0; b_sign = 0;
for( i_parse = 1; !p_vpar->p_fifo->b_die/*i_parse < 64*/; i_parse++ ) for( i_parse = 1; !p_vpar->p_fifo->b_die; i_parse++ )
{ {
i_code = ShowBits( &p_vpar->bit_stream, 16 ); i_code = ShowBits( &p_vpar->bit_stream, 16 );
/* We use 2 main tables for the coefficients */ /* We use 2 main tables for the coefficients */
if( i_code >= 16384 ) if( i_code >= 16384 )
{ {
i_run = ppl_dct_tab1[0][(i_code>>12)-4].i_run; p_tab = &ppl_dct_tab1[0][(i_code>>12)-4];
i_level = ppl_dct_tab1[0][(i_code>>12)-4].i_level;
i_length = ppl_dct_tab1[0][(i_code>>12)-4].i_length;
} }
else else
{ {
i_run = p_vpar->ppl_dct_coef[0][i_code].i_run; p_tab = &p_vpar->ppl_dct_coef[0][i_code];
i_length = p_vpar->ppl_dct_coef[0][i_code].i_length;
i_level = p_vpar->ppl_dct_coef[0][i_code].i_level;
} }
i_run = p_tab->i_run;
i_length = p_tab->i_length;
i_level = p_tab->i_level;
RemoveBits( &p_vpar->bit_stream, i_length ); RemoveBits( &p_vpar->bit_stream, i_length );
...@@ -887,17 +846,17 @@ static __inline__ void DecodeMPEG1Intra( vpar_thread_t * p_vpar, ...@@ -887,17 +846,17 @@ static __inline__ void DecodeMPEG1Intra( vpar_thread_t * p_vpar,
/* Determine the position of the block in the frame */ /* Determine the position of the block in the frame */
i_pos = p_vpar->ppi_scan[p_vpar->picture.b_alternate_scan][i_parse]; i_pos = p_vpar->ppi_scan[p_vpar->picture.b_alternate_scan][i_parse];
i_level = ( i_level * i_level = ( i_level *
p_vpar->mb.i_quantizer_scale * p_vpar->mb.i_quantizer_scale * pi_quant[i_pos] ) >> 3;
p_vpar->sequence.intra_quant.pi_matrix[i_pos] ) >> 3;
/* Mismatch control */ /* Mismatch control */
if( i_level ) /* Should always be true */
{
/* Equivalent to : if( (val & 1) == 0 ) val = val - 1; */ /* Equivalent to : if( (val & 1) == 0 ) val = val - 1; */
i_level = (i_level - 1) | 1; i_level = (i_level - 1) | 1;
}
p_mb->ppi_blocks[i_b][i_pos] = b_sign ? -i_level : i_level; i_level = b_sign ? -i_level : i_level;
SATURATE( i_level );
p_mb->ppi_blocks[i_b][i_pos] = i_level;
} }
intf_ErrMsg("vpar error: DCT coeff (intra) is out of bounds"); intf_ErrMsg("vpar error: DCT coeff (intra) is out of bounds");
...@@ -909,27 +868,23 @@ static __inline__ void DecodeMPEG1Intra( vpar_thread_t * p_vpar, ...@@ -909,27 +868,23 @@ static __inline__ void DecodeMPEG1Intra( vpar_thread_t * p_vpar,
*****************************************************************************/ *****************************************************************************/
static __inline__ void DecodeMPEG2NonIntra( vpar_thread_t * p_vpar, static __inline__ void DecodeMPEG2NonIntra( vpar_thread_t * p_vpar,
macroblock_t * p_mb, int i_b, macroblock_t * p_mb, int i_b,
int i_chroma_format ) boolean_t b_chroma, int i_cc )
{ {
int i_parse; int i_parse;
int i_nc; int i_nc;
int i_cc;
int i_coef; int i_coef;
int i_code; int i_code;
int i_length; int i_length;
int i_pos; int i_pos;
int i_run; int i_run;
int i_level; int i_level;
boolean_t b_dc; int i_mismatch = 1;
boolean_t b_sign; boolean_t b_sign;
boolean_t b_chroma;
u8 * pi_quant; u8 * pi_quant;
dct_lookup_t * p_tab;
/* Give the chromatic component (0, 1, 2) */ /* FIXME : if you want to enable other types of chroma, replace this
i_cc = pi_cc_index[i_b]; * by p_vpar->sequence.i_chroma_format. */
int i_chroma_format = CHROMA_420;
/* Determine whether it is luminance or not (chrominance) */
b_chroma = ( i_cc + 1 ) >> 1;
/* Give a pointer to the quantization matrices for intra blocks */ /* Give a pointer to the quantization matrices for intra blocks */
if( (i_chroma_format == CHROMA_420) || (!b_chroma) ) if( (i_chroma_format == CHROMA_420) || (!b_chroma) )
...@@ -950,18 +905,15 @@ static __inline__ void DecodeMPEG2NonIntra( vpar_thread_t * p_vpar, ...@@ -950,18 +905,15 @@ static __inline__ void DecodeMPEG2NonIntra( vpar_thread_t * p_vpar,
i_code = ShowBits( &p_vpar->bit_stream, 16 ); i_code = ShowBits( &p_vpar->bit_stream, 16 );
if( i_code >= 16384 ) if( i_code >= 16384 )
{ {
b_dc = (i_parse == 0); p_tab = &ppl_dct_tab2[(i_parse == 0)][(i_code>>12)-4];
i_run = ppl_dct_tab2[b_dc][(i_code>>12)-4].i_run;
i_level = ppl_dct_tab2[b_dc][(i_code>>12)-4].i_level;
i_length = ppl_dct_tab2[b_dc][(i_code>>12)-4].i_length;
} }
else else
{ {
i_run = p_vpar->ppl_dct_coef[0][i_code].i_run; p_tab = &p_vpar->ppl_dct_coef[0][i_code];
i_length = p_vpar->ppl_dct_coef[0][i_code].i_length;
i_level = p_vpar->ppl_dct_coef[0][i_code].i_level;
} }
i_run = p_tab->i_run;
i_level = p_tab->i_level;
i_length = p_tab->i_length;
RemoveBits( &p_vpar->bit_stream, i_length ); RemoveBits( &p_vpar->bit_stream, i_length );
...@@ -974,11 +926,6 @@ static __inline__ void DecodeMPEG2NonIntra( vpar_thread_t * p_vpar, ...@@ -974,11 +926,6 @@ static __inline__ void DecodeMPEG2NonIntra( vpar_thread_t * p_vpar,
: i_level; : i_level;
break; break;
case DCT_EOB: case DCT_EOB:
#ifdef HAVE_MMX
/* The MMX IDCT has a precision problem with non-intra
* blocks. */
p_mb->ppi_blocks[i_b][0] += 4;
#endif
if( i_nc <= 1 ) if( i_nc <= 1 )
{ {
p_mb->pf_idct[i_b] = p_vpar->pf_sparse_idct; p_mb->pf_idct[i_b] = p_vpar->pf_sparse_idct;
...@@ -988,6 +935,9 @@ static __inline__ void DecodeMPEG2NonIntra( vpar_thread_t * p_vpar, ...@@ -988,6 +935,9 @@ static __inline__ void DecodeMPEG2NonIntra( vpar_thread_t * p_vpar,
{ {
p_mb->pf_idct[i_b] = p_vpar->pf_idct; p_mb->pf_idct[i_b] = p_vpar->pf_idct;
} }
/* Mismatch control */
p_mb->ppi_blocks[i_b][63] ^= i_mismatch & 1;
return; return;
break; break;
...@@ -1006,7 +956,16 @@ static __inline__ void DecodeMPEG2NonIntra( vpar_thread_t * p_vpar, ...@@ -1006,7 +956,16 @@ static __inline__ void DecodeMPEG2NonIntra( vpar_thread_t * p_vpar,
i_pos = p_vpar->ppi_scan[p_vpar->picture.b_alternate_scan][i_parse]; i_pos = p_vpar->ppi_scan[p_vpar->picture.b_alternate_scan][i_parse];
i_level = ( ((i_level << 1) + 1) * p_vpar->mb.i_quantizer_scale i_level = ( ((i_level << 1) + 1) * p_vpar->mb.i_quantizer_scale
* pi_quant[i_pos] ) >> 5; * pi_quant[i_pos] ) >> 5;
p_mb->ppi_blocks[i_b][i_pos] = b_sign ? -i_level : i_level;
/* Could be replaced by (i_level ^ sign) - sign */
i_level = b_sign ? -i_level : i_level;
SATURATE( i_level );
p_mb->ppi_blocks[i_b][i_pos] = i_level;
/* Mismatch control */
i_mismatch ^= i_level;
} }
intf_ErrMsg("vpar error: DCT coeff (non-intra) is out of bounds"); intf_ErrMsg("vpar error: DCT coeff (non-intra) is out of bounds");
...@@ -1018,11 +977,10 @@ static __inline__ void DecodeMPEG2NonIntra( vpar_thread_t * p_vpar, ...@@ -1018,11 +977,10 @@ static __inline__ void DecodeMPEG2NonIntra( vpar_thread_t * p_vpar,
*****************************************************************************/ *****************************************************************************/
static __inline__ void DecodeMPEG2Intra( vpar_thread_t * p_vpar, static __inline__ void DecodeMPEG2Intra( vpar_thread_t * p_vpar,
macroblock_t * p_mb, int i_b, macroblock_t * p_mb, int i_b,
int i_chroma_format ) boolean_t b_chroma, int i_cc )
{ {
int i_parse; int i_parse;
int i_nc; int i_nc;
int i_cc;
int i_coef; int i_coef;
int i_code; int i_code;
int i_length; int i_length;
...@@ -1031,16 +989,15 @@ static __inline__ void DecodeMPEG2Intra( vpar_thread_t * p_vpar, ...@@ -1031,16 +989,15 @@ static __inline__ void DecodeMPEG2Intra( vpar_thread_t * p_vpar,
int i_dct_dc_diff; int i_dct_dc_diff;
int i_run; int i_run;
int i_level; int i_level;
int i_mismatch = 1;
boolean_t b_vlc_intra; boolean_t b_vlc_intra;
boolean_t b_sign; boolean_t b_sign;
boolean_t b_chroma;
u8 * pi_quant; u8 * pi_quant;
dct_lookup_t * p_tab;
/* Give the chromatic component (0, 1, 2) */ lookup_t * p_lookup;
i_cc = pi_cc_index[i_b]; /* FIXME : if you want to enable other types of chroma, replace this
* by p_vpar->sequence.i_chroma_format. */
/* Determine whether it is luminance or not (chrominance) */ int i_chroma_format = CHROMA_420;
b_chroma = ( i_cc + 1 ) >> 1;
/* Give a pointer to the quantization matrices for intra blocks */ /* Give a pointer to the quantization matrices for intra blocks */
if( (i_chroma_format == CHROMA_420) || (!b_chroma) ) if( (i_chroma_format == CHROMA_420) || (!b_chroma) )
...@@ -1053,21 +1010,20 @@ static __inline__ void DecodeMPEG2Intra( vpar_thread_t * p_vpar, ...@@ -1053,21 +1010,20 @@ static __inline__ void DecodeMPEG2Intra( vpar_thread_t * p_vpar,
} }
/* decode length */ /* decode length */
i_code = ShowBits(&p_vpar->bit_stream, 5); i_code = ShowBits( &p_vpar->bit_stream, 5 );
if (i_code<31) if (i_code < 31)
{ {
i_dct_dc_size = ppl_dct_dc_init_table_1[b_chroma][i_code].i_value; p_lookup = &ppl_dct_dc_init_table_1[b_chroma][i_code];
i_length = ppl_dct_dc_init_table_1[b_chroma][i_code].i_length;
RemoveBits( &p_vpar->bit_stream, i_length);
} }
else else
{ {
i_code = ShowBits(&p_vpar->bit_stream, (9+b_chroma)) - (0x1f0 * (b_chroma + 1)); i_code = ShowBits(&p_vpar->bit_stream, (9+b_chroma)) - (0x1f0 * (b_chroma + 1));
i_dct_dc_size = ppl_dct_dc_init_table_2[b_chroma][i_code].i_value; p_lookup = &ppl_dct_dc_init_table_2[b_chroma][i_code];
i_length = ppl_dct_dc_init_table_2[b_chroma][i_code].i_length;
RemoveBits( &p_vpar->bit_stream, i_length);
} }
i_dct_dc_size = p_lookup->i_value;
i_length = p_lookup->i_length;
RemoveBits( &p_vpar->bit_stream, i_length );
if (i_dct_dc_size == 0) if (i_dct_dc_size == 0)
i_dct_dc_diff = 0; i_dct_dc_diff = 0;
...@@ -1086,27 +1042,25 @@ static __inline__ void DecodeMPEG2Intra( vpar_thread_t * p_vpar, ...@@ -1086,27 +1042,25 @@ static __inline__ void DecodeMPEG2Intra( vpar_thread_t * p_vpar,
i_nc = ( p_vpar->mb.pi_dc_dct_pred[i_cc] != 0 ); i_nc = ( p_vpar->mb.pi_dc_dct_pred[i_cc] != 0 );
/* Decoding of the AC coefficients */ /* Decoding of the AC coefficients */
i_coef = 0; i_coef = 0;
b_vlc_intra = p_vpar->picture.b_intra_vlc_format; b_vlc_intra = p_vpar->picture.b_intra_vlc_format;
for( i_parse = 1; !p_vpar->p_fifo->b_die/*i_parse < 64*/; i_parse++ ) for( i_parse = 1; !p_vpar->p_fifo->b_die; i_parse++ )
{ {
i_code = ShowBits( &p_vpar->bit_stream, 16 ); i_code = ShowBits( &p_vpar->bit_stream, 16 );
/* We use 2 main tables for the coefficients */ /* We use 2 main tables for the coefficients */
if( i_code >= 16384 ) if( i_code >= 16384 )
{ {
i_run = ppl_dct_tab1[b_vlc_intra][(i_code>>(12-(4*b_vlc_intra)))-4].i_run; p_tab = &ppl_dct_tab1[b_vlc_intra][(i_code>>(12-(4*b_vlc_intra)))-4];
i_level = ppl_dct_tab1[b_vlc_intra][(i_code>>(12-(4*b_vlc_intra)))-4].i_level;
i_length = ppl_dct_tab1[b_vlc_intra][(i_code>>(12-(4*b_vlc_intra)))-4].i_length;
} }
else else
{ {
i_run = p_vpar->ppl_dct_coef[b_vlc_intra][i_code].i_run; p_tab = &p_vpar->ppl_dct_coef[b_vlc_intra][i_code];
i_length = p_vpar->ppl_dct_coef[b_vlc_intra][i_code].i_length;
i_level = p_vpar->ppl_dct_coef[b_vlc_intra][i_code].i_level;
} }
i_run = p_tab->i_run;
i_level = p_tab->i_level;
i_length = p_tab->i_length;
RemoveBits( &p_vpar->bit_stream, i_length ); RemoveBits( &p_vpar->bit_stream, i_length );
...@@ -1128,6 +1082,9 @@ static __inline__ void DecodeMPEG2Intra( vpar_thread_t * p_vpar, ...@@ -1128,6 +1082,9 @@ static __inline__ void DecodeMPEG2Intra( vpar_thread_t * p_vpar,
{ {
p_mb->pf_idct[i_b] = p_vpar->pf_idct; p_mb->pf_idct[i_b] = p_vpar->pf_idct;
} }
/* Mismatch control */
p_mb->ppi_blocks[i_b][63] ^= i_mismatch & 1;
return; return;
break; break;
...@@ -1151,13 +1108,104 @@ static __inline__ void DecodeMPEG2Intra( vpar_thread_t * p_vpar, ...@@ -1151,13 +1108,104 @@ static __inline__ void DecodeMPEG2Intra( vpar_thread_t * p_vpar,
i_level = ( i_level * i_level = ( i_level *
p_vpar->mb.i_quantizer_scale * p_vpar->mb.i_quantizer_scale *
pi_quant[i_pos] ) >> 4; pi_quant[i_pos] ) >> 4;
p_mb->ppi_blocks[i_b][i_pos] = b_sign ? -i_level : i_level;
i_level = b_sign ? -i_level : i_level;
SATURATE( i_level );
p_mb->ppi_blocks[i_b][i_pos] = i_level;
/* Mismatch control */
i_mismatch ^= i_level;
} }
intf_ErrMsg("vpar error: DCT coeff (intra) is out of bounds"); intf_ErrMsg("vpar error: DCT coeff (intra) is out of bounds");
p_vpar->picture.b_error = 1; p_vpar->picture.b_error = 1;
} }
/*****************************************************************************
* Decode*Blocks : decode blocks
*****************************************************************************/
static int pi_x[12] = {0,8,0,8,0,0,0,0,8,8,8,8};
static int pi_y[2][12] = { {0,0,8,8,0,0,8,8,0,0,8,8},
{0,0,1,1,0,0,1,1,0,0,1,1} };
#define PARSEERROR \
if( p_vpar->picture.b_error ) \
{ \
return; \
}
#define DECODEBLOCKS( MBFUNC, BLOCKFUNC ) \
static void MBFUNC( vpar_thread_t * p_vpar, macroblock_t * p_mb ) \
{ \
/* FIXME : if you want to enable other types of chroma, replace this\
* by p_vpar->sequence.i_chroma_format. */ \
int i_chroma_format = CHROMA_420; \
int i_mask, i_b; \
yuv_data_t * p_data1; \
yuv_data_t * p_data2; \
\
i_mask = 1 << (3 + (1 << i_chroma_format)); \
\
/* luminance */ \
p_data1 = p_mb->p_picture->p_y \
+ p_mb->i_l_x + p_vpar->mb.i_l_y * (p_vpar->sequence.i_width); \
\
for( i_b = 0 ; i_b < 4 ; i_b++, i_mask >>= 1 ) \
{ \
if( p_mb->i_coded_block_pattern & i_mask ) \
{ \
memset( p_mb->ppi_blocks[i_b], 0, 64*sizeof(dctelem_t) ); \
BLOCKFUNC( p_vpar, p_mb, i_b, 0, 0 ); \
\
/* Calculate block coordinates. */ \
p_mb->p_data[i_b] = p_data1 \
+ pi_y[p_vpar->mb.b_dct_type][i_b] \
* p_vpar->picture.i_l_stride \
+ pi_x[i_b]; \
\
PARSEERROR \
} \
} \
\
/* chrominance */ \
p_data1 = p_mb->p_picture->p_u \
+ p_mb->i_c_x \
+ p_vpar->mb.i_c_y \
* (p_vpar->sequence.i_chroma_width); \
p_data2 = p_mb->p_picture->p_v \
+ p_mb->i_c_x \
+ p_vpar->mb.i_c_y \
* (p_vpar->sequence.i_chroma_width); \
\
for( i_b = 4; i_b < 4 + (1 << i_chroma_format); \
i_b++, i_mask >>= 1 ) \
{ \
yuv_data_t * pp_data[2] = {p_data1, p_data2}; \
\
if( p_mb->i_coded_block_pattern & i_mask ) \
{ \
memset( p_mb->ppi_blocks[i_b], 0, 64*sizeof(dctelem_t) ); \
BLOCKFUNC( p_vpar, p_mb, i_b, 1, 1 + ((i_b - 4) & 1) ); \
\
/* Calculate block coordinates. */ \
p_mb->p_data[i_b] = pp_data[i_b & 1] \
+ pi_y[p_vpar->mb.b_dct_type][i_b] \
* p_vpar->picture.i_c_stride \
+ pi_x[i_b]; \
\
PARSEERROR \
} \
} \
}
DECODEBLOCKS( DecodeMPEG1NonIntraMB, DecodeMPEG1NonIntra );
DECODEBLOCKS( DecodeMPEG1IntraMB, DecodeMPEG1Intra );
DECODEBLOCKS( DecodeMPEG2NonIntraMB, DecodeMPEG2NonIntra );
DECODEBLOCKS( DecodeMPEG2IntraMB, DecodeMPEG2Intra );
#undef PARSEERROR
/* /*
* Motion vectors * Motion vectors
...@@ -1203,7 +1251,7 @@ static __inline__ int MotionCode( vpar_thread_t * p_vpar ) ...@@ -1203,7 +1251,7 @@ static __inline__ int MotionCode( vpar_thread_t * p_vpar )
if( (i_code -= 12) < 0 ) if( (i_code -= 12) < 0 )
{ {
p_vpar->picture.b_error = 1; p_vpar->picture.b_error = 1;
intf_DbgMsg( "vpar debug: Invalid motion_vector code" ); intf_ErrMsg( "vpar error: Invalid motion_vector code" );
return 0; return 0;
} }
...@@ -1336,7 +1384,7 @@ static __inline__ void MotionVector( vpar_thread_t * p_vpar, ...@@ -1336,7 +1384,7 @@ static __inline__ void MotionVector( vpar_thread_t * p_vpar,
p_mb->ppi_dmv[0][1] = ((i_mv_y + (i_mv_y > 0)) >> 1) + pi_dm_vector[1]; p_mb->ppi_dmv[0][1] = ((i_mv_y + (i_mv_y > 0)) >> 1) + pi_dm_vector[1];
/* correct for vertical field shift */ /* correct for vertical field shift */
if( p_vpar->picture.i_structure == TOP_FIELD ) if( i_structure == TOP_FIELD )
p_mb->ppi_dmv[0][1]--; p_mb->ppi_dmv[0][1]--;
else else
p_mb->ppi_dmv[0][1]++; p_mb->ppi_dmv[0][1]++;
...@@ -1401,7 +1449,7 @@ static void DecodeMVMPEG2( vpar_thread_t * p_vpar, ...@@ -1401,7 +1449,7 @@ static void DecodeMVMPEG2( vpar_thread_t * p_vpar,
/***************************************************************************** /*****************************************************************************
* MacroblockAddressIncrement : Get the macroblock_address_increment field * MacroblockAddressIncrement : Get the macroblock_address_increment field
*****************************************************************************/ *****************************************************************************/
static int MacroblockAddressIncrement( vpar_thread_t * p_vpar ) static __inline__ int MacroblockAddressIncrement( vpar_thread_t * p_vpar )
{ {
int i_addr_inc = 0; int i_addr_inc = 0;
/* Index in the lookup table mb_addr_inc */ /* Index in the lookup table mb_addr_inc */
...@@ -1526,10 +1574,10 @@ static __inline__ int CodedPattern444( vpar_thread_t * p_vpar ) ...@@ -1526,10 +1574,10 @@ static __inline__ int CodedPattern444( vpar_thread_t * p_vpar )
*****************************************************************************/ *****************************************************************************/
static __inline__ void InitMacroblock( vpar_thread_t * p_vpar, static __inline__ void InitMacroblock( vpar_thread_t * p_vpar,
macroblock_t * p_mb, int i_coding_type, macroblock_t * p_mb, int i_coding_type,
int i_chroma_format, int i_structure )
int i_structure,
boolean_t b_second_field )
{ {
int i_chroma_format = CHROMA_420; /* FIXME : MP@ML */
p_mb->i_chroma_nb_blocks = 1 << i_chroma_format; p_mb->i_chroma_nb_blocks = 1 << i_chroma_format;
p_mb->p_picture = p_vpar->picture.p_picture; p_mb->p_picture = p_vpar->picture.p_picture;
...@@ -1553,7 +1601,8 @@ static __inline__ void InitMacroblock( vpar_thread_t * p_vpar, ...@@ -1553,7 +1601,8 @@ static __inline__ void InitMacroblock( vpar_thread_t * p_vpar,
} }
p_mb->i_addb_l_stride = (p_mb->i_l_stride = p_vpar->picture.i_l_stride) - 8; p_mb->i_addb_l_stride = (p_mb->i_l_stride = p_vpar->picture.i_l_stride) - 8;
p_mb->i_addb_c_stride = (p_mb->i_c_stride = p_vpar->picture.i_c_stride) - 8; p_mb->i_addb_c_stride = (p_mb->i_c_stride = p_vpar->picture.i_c_stride) - 8;
p_mb->b_P_second = ( b_second_field && i_coding_type == P_CODING_TYPE ); p_mb->b_P_second = ( (i_structure == p_vpar->picture.i_current_structure)
&& i_coding_type == P_CODING_TYPE );
} }
/***************************************************************************** /*****************************************************************************
...@@ -1579,15 +1628,14 @@ static __inline__ void UpdateContext( vpar_thread_t * p_vpar, int i_structure ) ...@@ -1579,15 +1628,14 @@ static __inline__ void UpdateContext( vpar_thread_t * p_vpar, int i_structure )
*****************************************************************************/ *****************************************************************************/
static __inline__ void SkippedMacroblock( vpar_thread_t * p_vpar, int i_mb, static __inline__ void SkippedMacroblock( vpar_thread_t * p_vpar, int i_mb,
int i_mb_base, int i_coding_type, int i_mb_base, int i_coding_type,
int i_chroma_format, int i_structure )
int i_structure,
boolean_t b_second_field )
{ {
macroblock_t * p_mb; macroblock_t * p_mb;
int i_chroma_format = CHROMA_420; /* FIXME : MP@ML */
if( i_coding_type == I_CODING_TYPE ) if( i_coding_type == I_CODING_TYPE )
{ {
intf_DbgMsg("vpar error: skipped macroblock in I-picture"); intf_ErrMsg("vpar error: skipped macroblock in I-picture");
p_vpar->picture.b_error = 1; p_vpar->picture.b_error = 1;
return; return;
} }
...@@ -1601,8 +1649,7 @@ static __inline__ void SkippedMacroblock( vpar_thread_t * p_vpar, int i_mb, ...@@ -1601,8 +1649,7 @@ static __inline__ void SkippedMacroblock( vpar_thread_t * p_vpar, int i_mb,
p_vpar->picture.pp_mb[i_mb_base + i_mb] = p_mb; p_vpar->picture.pp_mb[i_mb_base + i_mb] = p_mb;
#endif #endif
InitMacroblock( p_vpar, p_mb, i_coding_type, i_chroma_format, InitMacroblock( p_vpar, p_mb, i_coding_type, i_structure );
i_structure, b_second_field );
/* Motion type is picture structure. */ /* Motion type is picture structure. */
p_mb->pf_motion = p_vpar->ppf_motion_skipped[i_chroma_format] p_mb->pf_motion = p_vpar->ppf_motion_skipped[i_chroma_format]
...@@ -1612,14 +1659,11 @@ static __inline__ void SkippedMacroblock( vpar_thread_t * p_vpar, int i_mb, ...@@ -1612,14 +1659,11 @@ static __inline__ void SkippedMacroblock( vpar_thread_t * p_vpar, int i_mb,
/* Motion direction and motion vectors depend on the coding type. */ /* Motion direction and motion vectors depend on the coding type. */
if( i_coding_type == B_CODING_TYPE ) if( i_coding_type == B_CODING_TYPE )
{ {
int i, j, k;
p_mb->i_mb_type = p_vpar->mb.i_motion_dir; p_mb->i_mb_type = p_vpar->mb.i_motion_dir;
for( i = 0; i < 2; i++ ) memcpy( p_mb->pppi_motion_vectors, p_vpar->mb.pppi_pmv,
for( j = 0; j < 2; j++ ) sizeof( p_vpar->mb.pppi_pmv ) );
for( k = 0; k < 2; k++ )
p_mb->pppi_motion_vectors[i][j][k] = p_vpar->mb.pppi_pmv[i][j][k];
} }
else if( i_coding_type == P_CODING_TYPE ) else
{ {
p_mb->i_mb_type = MB_MOTION_FORWARD; p_mb->i_mb_type = MB_MOTION_FORWARD;
memset( p_mb->pppi_motion_vectors, 0, 8*sizeof(int) ); memset( p_mb->pppi_motion_vectors, 0, 8*sizeof(int) );
...@@ -1642,7 +1686,6 @@ static __inline__ void SkippedMacroblock( vpar_thread_t * p_vpar, int i_mb, ...@@ -1642,7 +1686,6 @@ static __inline__ void SkippedMacroblock( vpar_thread_t * p_vpar, int i_mb,
*****************************************************************************/ *****************************************************************************/
static __inline__ void MacroblockModes( vpar_thread_t * p_vpar, static __inline__ void MacroblockModes( vpar_thread_t * p_vpar,
macroblock_t * p_mb, macroblock_t * p_mb,
int i_chroma_format,
int i_coding_type, int i_coding_type,
int i_structure ) int i_structure )
{ {
...@@ -1709,12 +1752,15 @@ static __inline__ void MacroblockModes( vpar_thread_t * p_vpar, ...@@ -1709,12 +1752,15 @@ static __inline__ void MacroblockModes( vpar_thread_t * p_vpar,
* sample. */ * sample. */
p_mb->i_addb_l_stride <<= 1; p_mb->i_addb_l_stride <<= 1;
p_mb->i_addb_l_stride += 8; p_mb->i_addb_l_stride += 8;
#if 0
/* FIXME: MP@ML */
/* With CHROMA_420, the DCT is necessarily frame-coded. */ /* With CHROMA_420, the DCT is necessarily frame-coded. */
if( i_chroma_format != CHROMA_420 ) if( i_chroma_format != CHROMA_420 )
{ {
p_mb->i_addb_c_stride <<= 1; p_mb->i_addb_c_stride <<= 1;
p_mb->i_addb_c_stride += 8; p_mb->i_addb_c_stride += 8;
} }
#endif
} }
} }
} }
...@@ -1732,68 +1778,6 @@ if( p_vpar->picture.b_error ) \ ...@@ -1732,68 +1778,6 @@ if( p_vpar->picture.b_error ) \
return; \ return; \
} }
#define PARSEBLOCKS( MPEG1FUNC, MPEG2FUNC ) \
{ \
i_mask = 1 << (3 + (1 << i_chroma_format)); \
\
/* luminance */ \
p_data1 = p_mb->p_picture->p_y \
+ p_mb->i_l_x + p_vpar->mb.i_l_y*(p_vpar->sequence.i_width); \
\
for( i_b = 0 ; i_b < 4 ; i_b++, i_mask >>= 1 ) \
{ \
if( p_mb->i_coded_block_pattern & i_mask ) \
{ \
memset( p_mb->ppi_blocks[i_b], 0, 64*sizeof(dctelem_t) ); \
if( b_mpeg2 ) \
MPEG2FUNC( p_vpar, p_mb, i_b, i_chroma_format ); \
else \
MPEG1FUNC( p_vpar, p_mb, i_b, i_chroma_format ); \
\
/* Calculate block coordinates. */ \
p_mb->p_data[i_b] = p_data1 \
+ pi_y[p_vpar->mb.b_dct_type][i_b] \
* p_vpar->picture.i_l_stride \
+ pi_x[i_b]; \
\
PARSEERROR \
} \
} \
\
/* chrominance */ \
p_data1 = p_mb->p_picture->p_u \
+ p_mb->i_c_x \
+ p_vpar->mb.i_c_y \
* (p_vpar->sequence.i_chroma_width); \
p_data2 = p_mb->p_picture->p_v \
+ p_mb->i_c_x \
+ p_vpar->mb.i_c_y \
* (p_vpar->sequence.i_chroma_width); \
\
for( i_b = 4; i_b < 4 + (1 << i_chroma_format); \
i_b++, i_mask >>= 1 ) \
{ \
yuv_data_t * pp_data[2] = {p_data1, p_data2}; \
\
if( p_mb->i_coded_block_pattern & i_mask ) \
{ \
memset( p_mb->ppi_blocks[i_b], 0, 64*sizeof(dctelem_t) ); \
if( b_mpeg2 ) \
MPEG2FUNC( p_vpar, p_mb, i_b, i_chroma_format ); \
else \
MPEG1FUNC( p_vpar, p_mb, i_b, i_chroma_format ); \
\
/* Calculate block coordinates. */ \
p_mb->p_data[i_b] = pp_data[i_b & 1] \
+ pi_y[p_vpar->mb.b_dct_type][i_b] \
* p_vpar->picture.i_c_stride \
+ pi_x[i_b]; \
\
PARSEERROR \
} \
} \
}
static __inline__ void ParseMacroblock( static __inline__ void ParseMacroblock(
vpar_thread_t * p_vpar, vpar_thread_t * p_vpar,
int * pi_mb_address, /* previous address to be int * pi_mb_address, /* previous address to be
...@@ -1804,19 +1788,12 @@ static __inline__ void ParseMacroblock( ...@@ -1804,19 +1788,12 @@ static __inline__ void ParseMacroblock(
* optimized routines : */ * optimized routines : */
boolean_t b_mpeg2, /* you know what ? */ boolean_t b_mpeg2, /* you know what ? */
int i_coding_type, /* I, P, B or D */ int i_coding_type, /* I, P, B or D */
int i_chroma_format, /* 4:2:0, 4:2:2 or 4:4:4 */ int i_structure ) /* T(OP), B(OTTOM) or F(RAME) */
int i_structure, /* T(OP), B(OTTOM) or F(RAME) */
boolean_t b_second_field ) /* second field of a
* field picture */
{ {
static int pi_x[12] = {0,8,0,8,0,0,0,0,8,8,8,8}; int i_mb;
static int pi_y[2][12] = { {0,0,8,8,0,0,8,8,0,0,8,8},
{0,0,1,1,0,0,1,1,0,0,1,1} };
int i_mb, i_b, i_mask;
int i_inc; int i_inc;
int i_chroma_format = CHROMA_420; /* FIXME : MP@ML */
macroblock_t * p_mb; macroblock_t * p_mb;
yuv_data_t * p_data1;
yuv_data_t * p_data2;
i_inc = MacroblockAddressIncrement( p_vpar ); i_inc = MacroblockAddressIncrement( p_vpar );
*pi_mb_address += i_inc; *pi_mb_address += i_inc;
...@@ -1846,7 +1823,7 @@ static __inline__ void ParseMacroblock( ...@@ -1846,7 +1823,7 @@ static __inline__ void ParseMacroblock(
for( i_mb = i_mb_previous + 1; i_mb < *pi_mb_address; i_mb++ ) for( i_mb = i_mb_previous + 1; i_mb < *pi_mb_address; i_mb++ )
{ {
SkippedMacroblock( p_vpar, i_mb, i_mb_base, i_coding_type, SkippedMacroblock( p_vpar, i_mb, i_mb_base, i_coding_type,
i_chroma_format, i_structure, b_second_field ); i_structure );
} }
} }
...@@ -1860,12 +1837,10 @@ static __inline__ void ParseMacroblock( ...@@ -1860,12 +1837,10 @@ static __inline__ void ParseMacroblock(
p_vpar->picture.pp_mb[i_mb_base + *pi_mb_address] = p_mb; p_vpar->picture.pp_mb[i_mb_base + *pi_mb_address] = p_mb;
#endif #endif
InitMacroblock( p_vpar, p_mb, i_coding_type, i_chroma_format, InitMacroblock( p_vpar, p_mb, i_coding_type, i_structure );
i_structure, b_second_field );
/* Parse off macroblock_modes structure. */ /* Parse off macroblock_modes structure. */
MacroblockModes( p_vpar, p_mb, i_chroma_format, i_coding_type, MacroblockModes( p_vpar, p_mb, i_coding_type, i_structure );
i_structure );
if( p_mb->i_mb_type & MB_QUANT ) if( p_mb->i_mb_type & MB_QUANT )
{ {
...@@ -1937,7 +1912,11 @@ static __inline__ void ParseMacroblock( ...@@ -1937,7 +1912,11 @@ static __inline__ void ParseMacroblock(
/* /*
* Effectively decode blocks. * Effectively decode blocks.
*/ */
PARSEBLOCKS( DecodeMPEG1NonIntra, DecodeMPEG2NonIntra ) if( b_mpeg2 )
DecodeMPEG2NonIntraMB( p_vpar, p_mb );
else
DecodeMPEG1NonIntraMB( p_vpar, p_mb );
PARSEERROR
} }
else else
{ {
...@@ -1978,7 +1957,11 @@ static __inline__ void ParseMacroblock( ...@@ -1978,7 +1957,11 @@ static __inline__ void ParseMacroblock(
/* /*
* Effectively decode blocks. * Effectively decode blocks.
*/ */
PARSEBLOCKS( DecodeMPEG1Intra, DecodeMPEG2Intra ) if( b_mpeg2 )
DecodeMPEG2IntraMB( p_vpar, p_mb );
else
DecodeMPEG1IntraMB( p_vpar, p_mb );
PARSEERROR
} }
if( !p_vpar->picture.b_error ) if( !p_vpar->picture.b_error )
...@@ -1998,189 +1981,27 @@ static __inline__ void ParseMacroblock( ...@@ -1998,189 +1981,27 @@ static __inline__ void ParseMacroblock(
} }
} }
#undef PARSEERROR
/* /*
* Picture data parsing management * Picture data parsing management
*/ */
/*****************************************************************************
* ParseMacroblockVWXYZ : Parse the next macroblock ; specific functions
*****************************************************************************
* V = MPEG2 ?
* W = coding type ?
* X = chroma format ?
* Y = structure ?
* Z = second field ?
*****************************************************************************/
void ParseMacroblockGENERIC( vpar_thread_t * p_vpar, int * pi_mb_address,
int i_mb_previous, int i_mb_base,
boolean_t b_mpeg2, int i_coding_type,
int i_chroma_format, int i_structure,
boolean_t b_second_field )
{
ParseMacroblock( p_vpar, pi_mb_address, i_mb_previous, i_mb_base,
b_mpeg2, i_coding_type, i_chroma_format,
i_structure, b_second_field );
}
#if (VPAR_OPTIM_LEVEL > 0)
/* Optimizations for frame pictures */
void ParseMacroblock2I420F0( vpar_thread_t * p_vpar, int * pi_mb_address, int i_mb_previous, int i_mb_base,
boolean_t b_mpeg2, int i_coding_type,
int i_chroma_format, int i_structure,
boolean_t b_second_field )
{
ParseMacroblock( p_vpar, pi_mb_address, i_mb_previous, i_mb_base,
1, I_CODING_TYPE, CHROMA_420,
FRAME_STRUCTURE, 0 );
}
void ParseMacroblock2P420F0( vpar_thread_t * p_vpar, int * pi_mb_address, int i_mb_previous, int i_mb_base,
boolean_t b_mpeg2, int i_coding_type,
int i_chroma_format, int i_structure,
boolean_t b_second_field )
{
ParseMacroblock( p_vpar, pi_mb_address, i_mb_previous, i_mb_base,
1, P_CODING_TYPE, CHROMA_420,
FRAME_STRUCTURE, 0 );
}
void ParseMacroblock2B420F0( vpar_thread_t * p_vpar, int * pi_mb_address, int i_mb_previous, int i_mb_base,
boolean_t b_mpeg2, int i_coding_type,
int i_chroma_format, int i_structure,
boolean_t b_second_field )
{
ParseMacroblock( p_vpar, pi_mb_address, i_mb_previous, i_mb_base,
1, B_CODING_TYPE, CHROMA_420,
FRAME_STRUCTURE, 0 );
}
#endif
#if (VPAR_OPTIM_LEVEL > 1)
/* Optimizations for field pictures */
void ParseMacroblock2I420TZ( vpar_thread_t * p_vpar, int * pi_mb_address, int i_mb_previous, int i_mb_base,
boolean_t b_mpeg2, int i_coding_type,
int i_chroma_format, int i_structure,
boolean_t b_second_field )
{
ParseMacroblock( p_vpar, pi_mb_address, i_mb_previous, i_mb_base,
1, I_CODING_TYPE, CHROMA_420,
TOP_FIELD, (p_vpar->picture.i_structure !=
p_vpar->picture.i_current_structure) );
}
void ParseMacroblock2P420TZ( vpar_thread_t * p_vpar, int * pi_mb_address, int i_mb_previous, int i_mb_base,
boolean_t b_mpeg2, int i_coding_type,
int i_chroma_format, int i_structure,
boolean_t b_second_field )
{
ParseMacroblock( p_vpar, pi_mb_address, i_mb_previous, i_mb_base,
1, P_CODING_TYPE, CHROMA_420,
TOP_FIELD, (p_vpar->picture.i_structure !=
p_vpar->picture.i_current_structure) );
}
void ParseMacroblock2B420TZ( vpar_thread_t * p_vpar, int * pi_mb_address, int i_mb_previous, int i_mb_base,
boolean_t b_mpeg2, int i_coding_type,
int i_chroma_format, int i_structure,
boolean_t b_second_field )
{
ParseMacroblock( p_vpar, pi_mb_address, i_mb_previous, i_mb_base,
1, B_CODING_TYPE, CHROMA_420,
TOP_FIELD, (p_vpar->picture.i_structure !=
p_vpar->picture.i_current_structure) );
}
void ParseMacroblock2I420BZ( vpar_thread_t * p_vpar, int * pi_mb_address, int i_mb_previous, int i_mb_base,
boolean_t b_mpeg2, int i_coding_type,
int i_chroma_format, int i_structure,
boolean_t b_second_field )
{
ParseMacroblock( p_vpar, pi_mb_address, i_mb_previous, i_mb_base,
1, I_CODING_TYPE, CHROMA_420,
BOTTOM_FIELD, (p_vpar->picture.i_structure !=
p_vpar->picture.i_current_structure) );
}
void ParseMacroblock2P420BZ( vpar_thread_t * p_vpar, int * pi_mb_address, int i_mb_previous, int i_mb_base,
boolean_t b_mpeg2, int i_coding_type,
int i_chroma_format, int i_structure,
boolean_t b_second_field )
{
ParseMacroblock( p_vpar, pi_mb_address, i_mb_previous, i_mb_base,
1, P_CODING_TYPE, CHROMA_420,
BOTTOM_FIELD, (p_vpar->picture.i_structure !=
p_vpar->picture.i_current_structure) );
}
void ParseMacroblock2B420BZ( vpar_thread_t * p_vpar, int * pi_mb_address, int i_mb_previous, int i_mb_base,
boolean_t b_mpeg2, int i_coding_type,
int i_chroma_format, int i_structure,
boolean_t b_second_field )
{
ParseMacroblock( p_vpar, pi_mb_address, i_mb_previous, i_mb_base,
1, B_CODING_TYPE, CHROMA_420,
BOTTOM_FIELD, (p_vpar->picture.i_structure !=
p_vpar->picture.i_current_structure) );
}
#endif
/***************************************************************************** /*****************************************************************************
* SliceHeader : Parse the next slice structure * SliceHeader : Parse the next slice structure
*****************************************************************************/ *****************************************************************************/
typedef void (*f_parse_mb_t)( vpar_thread_t * p_vpar, int * pi_mb_address, int i_mb_previous, int i_mb_base,
boolean_t b_mpeg2, int i_coding_type,
int i_chroma_format, int i_structure,
boolean_t b_second_field );
static __inline__ void SliceHeader( vpar_thread_t * p_vpar, static __inline__ void SliceHeader( vpar_thread_t * p_vpar,
int * pi_mb_address, int i_mb_base, int * pi_mb_address, int i_mb_base,
u32 i_vert_code, boolean_t b_high, u32 i_vert_code, boolean_t b_mpeg2,
boolean_t b_dp_scalable, int i_coding_type, int i_structure )
boolean_t b_mpeg2, int i_coding_type,
int i_chroma_format, int i_structure,
boolean_t b_second_field )
{ {
static f_parse_mb_t ppf_parse_mb[4][4] =
{
{
NULL, NULL, NULL, NULL
},
{
/* TOP_FIELD */
#if (VPAR_OPTIM_LEVEL > 1)
NULL, ParseMacroblock2I420TZ, ParseMacroblock2P420TZ,
ParseMacroblock2B420TZ
#else
NULL, ParseMacroblockGENERIC, ParseMacroblockGENERIC,
ParseMacroblockGENERIC
#endif
},
{
/* BOTTOM_FIELD */
#if (VPAR_OPTIM_LEVEL > 1)
NULL, ParseMacroblock2I420BZ, ParseMacroblock2P420BZ,
ParseMacroblock2B420BZ
#else
NULL, ParseMacroblockGENERIC, ParseMacroblockGENERIC,
ParseMacroblockGENERIC
#endif
},
{
/* FRAME_PICTURE */
#if (VPAR_OPTIM_LEVEL > 0)
NULL, ParseMacroblock2I420F0, ParseMacroblock2P420F0,
ParseMacroblock2B420F0
#else
NULL, ParseMacroblockGENERIC, ParseMacroblockGENERIC,
ParseMacroblockGENERIC
#endif
}
};
int i_mb_address_save = *pi_mb_address; int i_mb_address_save = *pi_mb_address;
p_vpar->picture.b_error = 0; p_vpar->picture.b_error = 0;
#if 0
/* FIXME : MP@ML doesn't support this. */
if( b_high ) if( b_high )
{ {
/* Picture with more than 2800 lines. */ /* Picture with more than 2800 lines. */
...@@ -2191,6 +2012,7 @@ static __inline__ void SliceHeader( vpar_thread_t * p_vpar, ...@@ -2191,6 +2012,7 @@ static __inline__ void SliceHeader( vpar_thread_t * p_vpar,
/* DATA_PARTITIONING scalability. */ /* DATA_PARTITIONING scalability. */
RemoveBits( &p_vpar->bit_stream, 7 ); /* priority_breakpoint */ RemoveBits( &p_vpar->bit_stream, 7 ); /* priority_breakpoint */
} }
#endif
LoadQuantizerScale( p_vpar ); LoadQuantizerScale( p_vpar );
...@@ -2204,7 +2026,7 @@ static __inline__ void SliceHeader( vpar_thread_t * p_vpar, ...@@ -2204,7 +2026,7 @@ static __inline__ void SliceHeader( vpar_thread_t * p_vpar,
RemoveBits( &p_vpar->bit_stream, 8 ); RemoveBits( &p_vpar->bit_stream, 8 );
} }
} }
*pi_mb_address = (i_vert_code - 1)*p_vpar->sequence.i_mb_width; *pi_mb_address = (i_vert_code - 1) * p_vpar->sequence.i_mb_width;
if( *pi_mb_address < i_mb_address_save ) if( *pi_mb_address < i_mb_address_save )
{ {
...@@ -2223,40 +2045,8 @@ static __inline__ void SliceHeader( vpar_thread_t * p_vpar, ...@@ -2223,40 +2045,8 @@ static __inline__ void SliceHeader( vpar_thread_t * p_vpar,
do do
{ {
if( i_mb_address_save >= p_vpar->sequence.i_mb_size ) ParseMacroblock( p_vpar, pi_mb_address, i_mb_address_save,
{ i_mb_base, b_mpeg2, i_coding_type, i_structure );
p_vpar->picture.b_error = 1;
return;
}
if( p_vpar->sequence.i_chroma_format != CHROMA_420
|| !p_vpar->sequence.b_mpeg2 || p_vpar->sequence.i_height > 2800
|| p_vpar->sequence.i_scalable_mode == SC_DP )
{
/* Weird stream. Use the slower generic function. */
ParseMacroblockGENERIC( p_vpar, pi_mb_address, i_mb_address_save,
i_mb_base, b_mpeg2, i_coding_type,
i_chroma_format, i_structure,
b_second_field );
}
else
{
/* Try to find an optimized function. */
if( ppf_parse_mb[i_structure]
[p_vpar->picture.i_coding_type] == NULL )
{
intf_ErrMsg( "vpar error: bad ppf_parse_mb function pointer (struct:%d, coding type:%d)",
i_structure, i_coding_type );
}
else
{
ppf_parse_mb[i_structure][i_coding_type]
( p_vpar, pi_mb_address, i_mb_address_save,
i_mb_base, b_mpeg2, i_coding_type,
i_chroma_format, i_structure,
b_second_field );
}
}
i_mb_address_save = *pi_mb_address; i_mb_address_save = *pi_mb_address;
if( p_vpar->picture.b_error ) if( p_vpar->picture.b_error )
...@@ -2264,32 +2054,32 @@ static __inline__ void SliceHeader( vpar_thread_t * p_vpar, ...@@ -2264,32 +2054,32 @@ static __inline__ void SliceHeader( vpar_thread_t * p_vpar,
return; return;
} }
} }
while( ShowBits( &p_vpar->bit_stream, 23 ) while( ShowBits( &p_vpar->bit_stream, 23 ) && !p_vpar->p_fifo->b_die );
&& !p_vpar->p_fifo->b_die );
NextStartCode( &p_vpar->bit_stream ); NextStartCode( &p_vpar->bit_stream );
} }
/***************************************************************************** /*****************************************************************************
* PictureData : Parse off all macroblocks (ISO/IEC 13818-2 6.2.3.7) * PictureData : Parse off all macroblocks (ISO/IEC 13818-2 6.2.3.7)
*****************************************************************************/ *****************************************************************************/
void vpar_PictureData( vpar_thread_t * p_vpar, int i_mb_base ) static __inline__ void vpar_PictureData( vpar_thread_t * p_vpar,
int i_mb_base, boolean_t b_mpeg2,
int i_coding_type, int i_structure )
{ {
int i_mb_address = 0; int i_mb_address = 0;
u32 i_dummy; u32 i_dummy;
NextStartCode( &p_vpar->bit_stream ); NextStartCode( &p_vpar->bit_stream );
while( ((p_vpar->picture.i_coding_type != I_CODING_TYPE while( ((i_coding_type != I_CODING_TYPE && i_coding_type != D_CODING_TYPE)
&& p_vpar->picture.i_coding_type != D_CODING_TYPE)
|| !p_vpar->picture.b_error) || !p_vpar->picture.b_error)
&& i_mb_address < (p_vpar->sequence.i_mb_size && i_mb_address < (p_vpar->sequence.i_mb_size
>> (p_vpar->picture.i_structure != FRAME_STRUCTURE)) >> (i_structure != FRAME_STRUCTURE))
&& !p_vpar->p_fifo->b_die ) && !p_vpar->p_fifo->b_die )
{ {
if( ((i_dummy = ShowBits( &p_vpar->bit_stream, 32 )) if( ((i_dummy = ShowBits( &p_vpar->bit_stream, 32 ))
< SLICE_START_CODE_MIN) || < SLICE_START_CODE_MIN) ||
(i_dummy > SLICE_START_CODE_MAX) ) (i_dummy > SLICE_START_CODE_MAX) )
{ {
intf_DbgMsg("vpar debug: premature end of picture"); intf_ErrMsg("vpar error: premature end of picture");
p_vpar->picture.b_error = 1; p_vpar->picture.b_error = 1;
break; break;
} }
...@@ -2297,40 +2087,57 @@ void vpar_PictureData( vpar_thread_t * p_vpar, int i_mb_base ) ...@@ -2297,40 +2087,57 @@ void vpar_PictureData( vpar_thread_t * p_vpar, int i_mb_base )
/* Decode slice data. */ /* Decode slice data. */
SliceHeader( p_vpar, &i_mb_address, i_mb_base, i_dummy & 255, SliceHeader( p_vpar, &i_mb_address, i_mb_base, i_dummy & 255,
(p_vpar->sequence.i_height > 2800), b_mpeg2, i_coding_type, i_structure );
(p_vpar->sequence.i_scalable_mode == SC_DP),
p_vpar->sequence.b_mpeg2, p_vpar->picture.i_coding_type,
p_vpar->sequence.i_chroma_format,
p_vpar->picture.i_structure,
(p_vpar->picture.i_structure !=
p_vpar->picture.i_current_structure) );
} }
/* Try to recover from error. If we missed less than half the /* Try to recover from error. If we missed less than half the
* number of macroblocks of the picture, mark the missed ones * number of macroblocks of the picture, mark the missed ones
* as skipped. */ * as skipped. */
if( (p_vpar->picture.i_coding_type == P_CODING_TYPE if( (i_coding_type == P_CODING_TYPE || i_coding_type == B_CODING_TYPE)
|| p_vpar->picture.i_coding_type == B_CODING_TYPE)
&& p_vpar->picture.b_error && && p_vpar->picture.b_error &&
( (i_mb_address-i_mb_base) > (p_vpar->sequence.i_mb_size >> 1) ( (i_mb_address-i_mb_base) > (p_vpar->sequence.i_mb_size >> 1)
|| (p_vpar->picture.i_structure != FRAME_STRUCTURE || (i_structure != FRAME_STRUCTURE
&& (i_mb_address-i_mb_base) > (p_vpar->sequence.i_mb_size >> 2) ) ) ) && (i_mb_address-i_mb_base) >
(p_vpar->sequence.i_mb_size >> 2) ) ) )
{ {
int i_mb; int i_mb;
p_vpar->picture.b_error = 0; p_vpar->picture.b_error = 0;
for( i_mb = i_mb_address + 1; for( i_mb = i_mb_address + 1;
i_mb < (p_vpar->sequence.i_mb_size i_mb < (p_vpar->sequence.i_mb_size
<< (p_vpar->picture.i_structure != FRAME_STRUCTURE)); << (i_structure != FRAME_STRUCTURE));
i_mb++ ) i_mb++ )
{ {
SkippedMacroblock( p_vpar, i_mb, i_mb_base, SkippedMacroblock( p_vpar, i_mb, i_mb_base,
p_vpar->picture.i_coding_type, i_coding_type,
p_vpar->sequence.i_chroma_format, i_structure );
p_vpar->picture.i_structure,
(p_vpar->picture.i_structure !=
p_vpar->picture.i_current_structure) );
} }
} }
} }
#define DECLARE_PICD( FUNCNAME, B_MPEG2, I_CODING_TYPE, I_STRUCTURE ) \
void FUNCNAME( vpar_thread_t * p_vpar, int i_mb_base ) \
{ \
vpar_PictureData( p_vpar, i_mb_base, B_MPEG2, I_CODING_TYPE, \
I_STRUCTURE ); \
}
DECLARE_PICD( vpar_PictureDataGENERIC, p_vpar->sequence.b_mpeg2,
p_vpar->picture.i_coding_type, p_vpar->picture.i_structure );
#if (VPAR_OPTIM_LEVEL > 0)
DECLARE_PICD( vpar_PictureData1I, 0, I_CODING_TYPE, FRAME_STRUCTURE );
DECLARE_PICD( vpar_PictureData1P, 0, P_CODING_TYPE, FRAME_STRUCTURE );
DECLARE_PICD( vpar_PictureData1B, 0, B_CODING_TYPE, FRAME_STRUCTURE );
DECLARE_PICD( vpar_PictureData1D, 0, D_CODING_TYPE, FRAME_STRUCTURE );
DECLARE_PICD( vpar_PictureData2IF, 1, I_CODING_TYPE, FRAME_STRUCTURE );
DECLARE_PICD( vpar_PictureData2PF, 1, P_CODING_TYPE, FRAME_STRUCTURE );
DECLARE_PICD( vpar_PictureData2BF, 1, B_CODING_TYPE, FRAME_STRUCTURE );
#endif
#if (VPAR_OPTIM_LEVEL > 1)
DECLARE_PICD( vpar_PictureData2IT, 1, I_CODING_TYPE, TOP_FIELD );
DECLARE_PICD( vpar_PictureData2PT, 1, P_CODING_TYPE, TOP_FIELD );
DECLARE_PICD( vpar_PictureData2BT, 1, B_CODING_TYPE, TOP_FIELD );
DECLARE_PICD( vpar_PictureData2IB, 1, I_CODING_TYPE, BOTTOM_FIELD );
DECLARE_PICD( vpar_PictureData2PB, 1, P_CODING_TYPE, BOTTOM_FIELD );
DECLARE_PICD( vpar_PictureData2BB, 1, B_CODING_TYPE, BOTTOM_FIELD );
#endif
...@@ -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.74 2001/01/18 05:13:23 sam Exp $ * $Id: vpar_headers.c,v 1.75 2001/01/21 01:36:26 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>
...@@ -572,7 +572,7 @@ static void PictureHeader( vpar_thread_t * p_vpar ) ...@@ -572,7 +572,7 @@ static void PictureHeader( vpar_thread_t * p_vpar )
p_vpar->picture.i_current_structure = 0; p_vpar->picture.i_current_structure = 0;
intf_DbgMsg("vpar debug: odd number of field picture."); intf_ErrMsg("vpar error: odd number of field pictures.");
} }
/* Do we have the reference pictures ? */ /* Do we have the reference pictures ? */
...@@ -737,7 +737,68 @@ static void PictureHeader( vpar_thread_t * p_vpar ) ...@@ -737,7 +737,68 @@ static void PictureHeader( vpar_thread_t * p_vpar )
/* Extension and User data. */ /* Extension and User data. */
ExtensionAndUserData( p_vpar ); ExtensionAndUserData( p_vpar );
vpar_PictureData( p_vpar, i_mb_base ); /* This is an MP@ML decoder, please note that neither of the following
* assertions can be true :
* p_vpar->sequence.i_chroma_format != CHROMA_420
* p_vpar->sequence.i_height > 2800
* p_vpar->sequence.i_scalable_mode == SC_DP
* Be cautious if you try to use the decoder for other profiles and
* levels.
*/
if( p_vpar->sequence.b_mpeg2 )
{
static f_picture_data_t ppf_picture_data[4][4] =
{
{
NULL, NULL, NULL, NULL
},
{
/* TOP_FIELD */
#if (VPAR_OPTIM_LEVEL > 1)
NULL, vpar_PictureData2IT, vpar_PictureData2PT,
vpar_PictureData2BT
#else
NULL, vpar_PictureDataGENERIC, vpar_PictureDataGENERIC,
vpar_PictureDataGENERIC
#endif
},
{
/* BOTTOM_FIELD */
#if (VPAR_OPTIM_LEVEL > 1)
NULL, vpar_PictureData2IB, vpar_PictureData2PB,
vpar_PictureData2BB
#else
NULL, vpar_PictureDataGENERIC, vpar_PictureDataGENERIC,
vpar_PictureDataGENERIC
#endif
},
{
/* FRAME_PICTURE */
#if (VPAR_OPTIM_LEVEL > 0)
NULL, vpar_PictureData2IF, vpar_PictureData2PF,
vpar_PictureData2BF
#else
NULL, vpar_PictureDataGENERIC, vpar_PictureDataGENERIC,
vpar_PictureDataGENERIC
#endif
}
};
ppf_picture_data[p_vpar->picture.i_structure]
[p_vpar->picture.i_coding_type]( p_vpar, i_mb_base );
}
else
{
#if (VPAR_OPTIM_LEVEL > 0)
static f_picture_data_t pf_picture_data[5] =
{ NULL, vpar_PictureData1I, vpar_PictureData1P, vpar_PictureData1B,
vpar_PictureData1D };
pf_picture_data[p_vpar->picture.i_coding_type]( p_vpar, i_mb_base );
#else
vpar_PictureDataGENERIC( p_vpar, i_mb_base );
#endif
}
if( p_vpar->p_fifo->b_die || p_vpar->p_fifo->b_error ) if( p_vpar->p_fifo->b_die || p_vpar->p_fifo->b_error )
{ {
......
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