📄 h263mb.c
字号:
// [SAMPLE_STATUS_NOERR]: Succeeds
// [SAMPLE_STATUS_BITSTREAM_ERR]: Stream parsing error occurs
// [SAMPLE_STATUS_ERR]: Error occurs during decoding
//
// Notes: None
******************************************************************************/
sample_status decode_mb_ppic_h263(sample_bitstream *stream,
h263_dec_state *state)
{
sample_status ret;
short idct_buf[72], *a_idct_buf;
IppMotionVector chroma_mv;
int cbp, predict_type, i;
int ref_y_step = state->ref_picture->pic_plane_step[0];
int ref_cb_step= state->ref_picture->pic_plane_step[1];
int ref_cr_step= state->ref_picture->pic_plane_step[2];
int cur_y_step = state->cur_picture->pic_plane_step[0];
int cur_cb_step= state->cur_picture->pic_plane_step[1];
int cur_cr_step= state->cur_picture->pic_plane_step[2];
/***********************************************************
// Parse MB header
***********************************************************/
ret = parse_mb_header_h263(stream, state);
if(SAMPLE_STATUS_NOERR != ret) {
return ret;
}
/***********************************************************
// If MB type is INTER_Q,
// update quantization param according to GQUANT and DQUANT
***********************************************************/
if(H263_INTER_Q == state->mb_type || H263_INTRA_Q == state->mb_type) {
state->quant = QUANT_CLIP(state->quant+state->dquant);
}
/***********************************************************
// Initialize block pointers
***********************************************************/
state->cur_block.y_ptr = state->cur_mb.y_ptr;
state->cur_block.cb_ptr = state->cur_mb.cb_ptr;
state->cur_block.cr_ptr = state->cur_mb.cr_ptr;
state->ref_block.y_ptr = state->ref_mb.y_ptr;
state->ref_block.cb_ptr = state->ref_mb.cb_ptr;
state->ref_block.cr_ptr = state->ref_mb.cr_ptr;
a_idct_buf = (short*)SAMPLE_ALIGN8(idct_buf);
/***********************************************************
// Decode blocks
***********************************************************/
if(state->cod) {
/* Not Coded, copy from reference blocks */
ippiCopyMB_H263_8u(state->ref_block.y_ptr, state->cur_block.y_ptr, cur_y_step);
ippiCopyBlock_H263_8u(state->ref_block.cb_ptr, state->cur_block.cb_ptr, cur_cb_step);
ippiCopyBlock_H263_8u(state->ref_block.cr_ptr, state->cur_block.cr_ptr, cur_cr_step);
/* Zero motion vector */
state->cur_mv[1].dx = 0;
state->cur_mv[1].dy = 0;
return SAMPLE_STATUS_NOERR;
}
/* Coded */
if(H263_INTRA == state->mb_type || H263_INTRA_Q == state->mb_type) {
/* INTRA block */
state->cur_mv[1].dx = 0;
state->cur_mv[1].dy = 0;
return decode_intra_mb_h263(stream, state);
} else {
/* INTER */
/* Decode MV */
/* First line of GOB or when GOB header is present,
// ippiDecodeMV_TopBorder_H263 is used to decode MV,
// the rest uses ippiDecodeMV_H263.
*/
if(state->mb_index < state->mb_per_row || 1 == state->gob_has_header) {
if(ippStsNoErr != ippiDecodeMV_TopBorder_H263(
&stream->bs_cur_byte,
&stream->bs_cur_bitoffset,
state->cur_mv)) {
return SAMPLE_STATUS_ERR;
}
} else {
if(ippStsNoErr != ippiDecodeMV_H263(
&stream->bs_cur_byte,
&stream->bs_cur_bitoffset,
state->cur_mv)) {
return SAMPLE_STATUS_ERR;
}
}
/* MV for Chominance Blocks */
chroma_mv.dx = (Ipp16s)(((state->cur_mv[1].dx) >> 1)
+ mv_quarter_round_h263[(state->cur_mv[1].dx)&3]);
chroma_mv.dy = (Ipp16s)(((state->cur_mv[1].dy) >> 1)
+ mv_quarter_round_h263[(state->cur_mv[1].dy)&3]);
/* Prediction */
state->ref_block.y_ptr += ((state->cur_mv[1].dx) >> 1);
state->ref_block.cb_ptr += ((chroma_mv.dx) >> 1);
state->ref_block.cr_ptr += ((chroma_mv.dx) >> 1);
if(state->cur_mv[1].dy) {
state->ref_block.y_ptr += ((state->cur_mv[1].dy) >> 1) * ref_y_step;
state->ref_block.cb_ptr+= ((chroma_mv.dy) >> 1) * ref_cb_step;
state->ref_block.cr_ptr+= ((chroma_mv.dy) >> 1) * ref_cr_step;
}
/* Decode MB */
/***********************************
// Luminance Block
***********************************/
predict_type = (state->cur_mv[1].dx & 0x1) |
((state->cur_mv[1].dy & 0x1) << 1);
cbp = state->cbpy;
/* 4 Y blocks */
for(i=0;i<4;i++) {
if(cbp & 0x8) {
if(ippStsNoErr != ippiDecodeBlockCoef_Inter_H263_1u16s(
&stream->bs_cur_byte,
&stream->bs_cur_bitoffset,
a_idct_buf,
state->quant) ) {
return SAMPLE_STATUS_ERR;
}
if(1 == state->rounding_type) {
ippiMCReconBlock_RoundOn (state->ref_block.y_ptr,
ref_y_step,
a_idct_buf,
state->cur_block.y_ptr,
cur_y_step,
predict_type);
} else {
ippiMCReconBlock_RoundOff(state->ref_block.y_ptr,
ref_y_step,
a_idct_buf,
state->cur_block.y_ptr,
cur_y_step,
predict_type);
}
} else {
if(1 == state->rounding_type) {
ippiMCBlock_RoundOn_8u (state->ref_block.y_ptr,
ref_y_step,
state->cur_block.y_ptr,
cur_y_step,
predict_type);
} else {
ippiMCBlock_RoundOff_8u(state->ref_block.y_ptr,
ref_y_step,
state->cur_block.y_ptr,
cur_y_step,
predict_type);
}
}
state->cur_block.y_ptr += SAMPLE_VIDEO_BLOCK_SIZE;
state->ref_block.y_ptr += SAMPLE_VIDEO_BLOCK_SIZE;
if(i&1) {
state->cur_block.y_ptr += SAMPLE_VIDEO_BLOCK_SIZE * cur_y_step
- 2*SAMPLE_VIDEO_BLOCK_SIZE;
state->ref_block.y_ptr += SAMPLE_VIDEO_BLOCK_SIZE * ref_y_step
- 2*SAMPLE_VIDEO_BLOCK_SIZE;
}
cbp <<= 1;
}
/***********************************
// Chrominance Block
***********************************/
predict_type = (chroma_mv.dx & 0x1) |((chroma_mv.dy & 0x1) << 1);
cbp = state->cbpc;
/* Cb block */
if(cbp & 0x2) { /* Non-DC coeff exists */
if(ippStsNoErr != ippiDecodeBlockCoef_Inter_H263_1u16s(
&stream->bs_cur_byte,
&stream->bs_cur_bitoffset,
a_idct_buf,
state->quant)) {
return SAMPLE_STATUS_ERR;
}
if(1 == state->rounding_type) {
ippiMCReconBlock_RoundOn (state->ref_block.cb_ptr,
ref_cb_step,
a_idct_buf,
state->cur_block.cb_ptr,
cur_cb_step,
predict_type);
} else {
ippiMCReconBlock_RoundOff(state->ref_block.cb_ptr,
ref_cb_step,
a_idct_buf,
state->cur_block.cb_ptr,
cur_cb_step,
predict_type);
}
} else { /* Only DC exists */
if(1 == state->rounding_type) {
ippiMCBlock_RoundOn_8u (state->ref_block.cb_ptr,
ref_cb_step,
state->cur_block.cb_ptr,
cur_cb_step,
predict_type);
} else {
ippiMCBlock_RoundOff_8u(state->ref_block.cb_ptr,
ref_cb_step,
state->cur_block.cb_ptr,
cur_cb_step,
predict_type);
}
} /* Cb Block end */
/* Cr Block */
if(cbp & 0x1) { /* Non-DC coeff exists */
if(ippStsNoErr != ippiDecodeBlockCoef_Inter_H263_1u16s(
&stream->bs_cur_byte,
&stream->bs_cur_bitoffset,
a_idct_buf,
state->quant)) {
return SAMPLE_STATUS_ERR;
}
if(1 == state->rounding_type) {
ippiMCReconBlock_RoundOn (state->ref_block.cr_ptr,
ref_cr_step,
a_idct_buf,
state->cur_block.cr_ptr,
cur_cr_step,
predict_type);
} else {
ippiMCReconBlock_RoundOff(state->ref_block.cr_ptr,
ref_cr_step,
a_idct_buf,
state->cur_block.cr_ptr,
cur_cr_step,
predict_type);
}
} else { /* Only DC exists */
if(1 == state->rounding_type) {
ippiMCBlock_RoundOn_8u (state->ref_block.cr_ptr,
ref_cr_step,
state->cur_block.cr_ptr,
cur_cr_step,
predict_type);
} else {
ippiMCBlock_RoundOff_8u(state->ref_block.cr_ptr,
ref_cr_step,
state->cur_block.cr_ptr,
cur_cr_step,
predict_type);
}
} /* Cr block end */
} /* INTER */
return SAMPLE_STATUS_NOERR;
}
/* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -