📄 mp4dmblk.c
字号:
/******************************************************************************// INTEL CORPORATION PROPRIETARY INFORMATION// This software is supplied under the terms of a license agreement or// nondisclosure agreement with Intel Corporation and may not be copied// or disclosed except in accordance with the terms of that agreement.// Copyright (c) 2003 Intel Corporation. All Rights Reserved.//// Description: Macroblock decoding functions of MPEG-4 video decoder// sample code for Intel(R) Integrated Performance Primitives.// Functions List:// decode_inter_mb_mpeg4()// decode_intra_mb_mpeg4()// decode_mb_pvop_mpeg4()// decode_mb_ivop_mpeg4()******************************************************************************/#include "sampmp4.h"/******************************************************************************// Name: decode_inter_mb_mpeg4// Desicription:// Decode the texture data of an INTER macroblock//// Input Arguments:// stream_buf - Pointer to the source video bitstream // dec_state - Pointer to the general state struct of MPEG-4 decoder// vop_infor - Pointer to the vop information struct of MPEG-4 decoder//// Output Arguments:// stream_buf - Pointer to the updated video bitstream// vop_infor - Pointer to the updated vop information struct of MPEG-4// decoder//// Returns:// SAMPLE_STATUS_NOERR If succeeds// SAMPLE_STATUS_ERR If decoding fails// Note:// ******************************************************************************/sample_status decode_inter_mb_mpeg4(sample_bitstream *stream_buf, const mp4_dec_state *dec_state, mp4_dec_vop_infor *vop_infor, int mbx_indx, int mby_indx){ IppiRect ref_rect_vop; int i, blk_indx, mbx_pos, mby_pos, tmp_step, predict_type; IppMotionVector mv_curmb_buf[8], mv_chr; IppMotionVector* mv_curmb = (IppMotionVector*)SAMPLE_ALIGN4(mv_curmb_buf); Ipp8u transp_curmb_buf[8]; Ipp8u* transp_curmb = (Ipp8u*)SAMPLE_ALIGN4(transp_curmb_buf); sample_status ret_code; /* residual block coefficients of inter MB */ Ipp16s inter_blk_coeff_buf[SAMPLE_VIDEO_BLOCK_SQUARE_SIZE + 8]; Ipp16s* inter_blk_coeff = (Ipp16s*)SAMPLE_ALIGN8(inter_blk_coeff_buf); /* for rectangular shape, 4 blocks in one MacroBlock are always opaque */ for(i=0; i< 4; i++ ) { transp_curmb[i] = IPP_VIDEO_OPAQUE; } /* coded mb */ if (!vop_infor->mb_not_coded) { /* motion vector decoding */ /* vop_infor->mv_buf, mv_curmb, vop_infor->tranp_buf, transp_curmb // must be 4 byte aligned */ if (ippiDecodePadMV_PVOP_MPEG4( &stream_buf->bs_cur_byte, &stream_buf->bs_cur_bitoffset, vop_infor->mv_buf, vop_infor->mv_buf + 4, vop_infor->mv_buf + 8, mv_curmb, vop_infor->tranp_buf, vop_infor->tranp_buf + 4, vop_infor->tranp_buf + 8, transp_curmb, vop_infor->fcode_fwd, vop_infor->mb_type) != ippStsNoErr) { return SAMPLE_STATUS_ERR; } /* update mv_buf to store unlimited motion vectors */ vop_infor->mv_buf += 4; for(i=0;i<4;i++){ vop_infor->mv_buf[i].dx = mv_curmb[i].dx; vop_infor->mv_buf[i].dy = mv_curmb[i].dy; } /* motion vector limitation */ ref_rect_vop.x = - SAMPLE_VIDEO_MB_SIZE; ref_rect_vop.y = - SAMPLE_VIDEO_MB_SIZE; ref_rect_vop.width = dec_state->frame_dimension.width + SAMPLE_VIDEO_MB_SIZE * 2; ref_rect_vop.height = dec_state->frame_dimension.height + SAMPLE_VIDEO_MB_SIZE * 2; if (IPP_VIDEO_INTER4V == vop_infor->mb_type) { for(i=0; i<4; i++){ mbx_pos = mbx_indx * SAMPLE_VIDEO_MB_SIZE + (i & 1) * SAMPLE_VIDEO_BLOCK_SIZE; mby_pos = mby_indx * SAMPLE_VIDEO_MB_SIZE + (i >> 1) * SAMPLE_VIDEO_BLOCK_SIZE; if (ippiLimitMVToRect_MPEG4( &mv_curmb[i], &mv_curmb[i], &ref_rect_vop, mbx_pos, mby_pos, SAMPLE_VIDEO_BLOCK_SIZE) != ippStsNoErr) { return SAMPLE_STATUS_ERR; } } } else { mbx_pos = mbx_indx * SAMPLE_VIDEO_MB_SIZE; mby_pos = mby_indx * SAMPLE_VIDEO_MB_SIZE; if (ippiLimitMVToRect_MPEG4( mv_curmb, mv_curmb, &ref_rect_vop, mbx_pos, mby_pos, SAMPLE_VIDEO_MB_SIZE) != ippStsNoErr) { return SAMPLE_STATUS_ERR; } for(i=1;i<4;i++){ mv_curmb[i].dx = mv_curmb[0].dx; mv_curmb[i].dy = mv_curmb[0].dy; } } /* Decoding the texture data of current Inter MB */ /* luminace blocks */ for (blk_indx = Y_BLOCK1; blk_indx <= Y_BLOCK4; blk_indx++) { /* calculate the current block position in MB */ tmp_step = (blk_indx & 0x1) * SAMPLE_VIDEO_BLOCK_SIZE + (blk_indx >> 1) * dec_state->frame_step_set.y_step * SAMPLE_VIDEO_BLOCK_SIZE; vop_infor->cur_bk.y_ptr = vop_infor->cur_mb.y_ptr + tmp_step; vop_infor->fwd_ref_bk.y_ptr = vop_infor->fwd_ref_mb.y_ptr + tmp_step; /* calculate the predict reference block position in MB */ tmp_step = (mv_curmb[blk_indx].dx >> 1) + (mv_curmb[blk_indx].dy >> 1) * dec_state->frame_step_set.y_step; vop_infor->fwd_ref_bk.y_ptr += tmp_step; /* determine interpolation type for half-pixel precision */ predict_type = ((mv_curmb[blk_indx].dy & 0x1) << 1) | (mv_curmb[blk_indx].dx & 0x1); if (vop_infor->cbpy & (1 << (3 - blk_indx))) { /* inter block decoding */ ret_code = decode_block_inter_mpeg4 (stream_buf, inter_blk_coeff, vop_infor->cur_qp, dec_state->qmatrix_inter); if(SAMPLE_STATUS_NOERR != ret_code) { return ret_code; } /* motion compensation */ /* vop_infor->cur_bk.y_ptr must be 8 byte aligned */ if(ippStsNoErr != (*(vop_infor->recon_block_func_ptr))( vop_infor->fwd_ref_bk.y_ptr, dec_state->frame_step_set.y_step, inter_blk_coeff, vop_infor->cur_bk.y_ptr, dec_state->frame_step_set.y_step, predict_type)) { return SAMPLE_STATUS_ERR; } } else { /* no residual components in the block */ /* block copy */ /* vop_infor->cur_bk.y_ptr must be 8 byte aligned */ if(ippStsNoErr != (*(vop_infor->copy_block_func_ptr))( vop_infor->fwd_ref_bk.y_ptr, dec_state->frame_step_set.y_step, vop_infor->cur_bk.y_ptr, dec_state->frame_step_set.y_step, predict_type)) { return SAMPLE_STATUS_ERR; } } } /* chrominance blocks */ /* look up motion vector for chorminance blocks */ ret_code = lookup_uvmv_mpeg4 (vop_infor->mv_buf, &mv_chr, vop_infor->mb_type); if(SAMPLE_STATUS_NOERR != ret_code) { return ret_code; } /* motion vector limitation */ ref_rect_vop.x = - SAMPLE_VIDEO_BLOCK_SIZE; ref_rect_vop.y = - SAMPLE_VIDEO_BLOCK_SIZE; ref_rect_vop.width = dec_state->frame_dimension.width / 2 + SAMPLE_VIDEO_MB_SIZE; ref_rect_vop.height = dec_state->frame_dimension.height / 2 + SAMPLE_VIDEO_MB_SIZE; mbx_pos = mbx_indx * SAMPLE_VIDEO_BLOCK_SIZE; mby_pos = mby_indx * SAMPLE_VIDEO_BLOCK_SIZE; if (ippiLimitMVToRect_MPEG4( &mv_chr, &mv_chr, &ref_rect_vop, mbx_pos, mby_pos, SAMPLE_VIDEO_BLOCK_SIZE) != ippStsNoErr) { return SAMPLE_STATUS_ERR; } predict_type = ((mv_chr.dy & 0x1) << 1) | (mv_chr.dx & 0x1); /* U block */ /* calculate the current block position */ vop_infor->cur_bk.cb_ptr = vop_infor->cur_mb.cb_ptr; /* calculate the predict reference block position */ tmp_step = (mv_chr.dx >> 1) + (mv_chr.dy >> 1) * dec_state->frame_step_set.cb_step; vop_infor->fwd_ref_bk.cb_ptr = vop_infor->fwd_ref_mb.cb_ptr + tmp_step; if (vop_infor->cbpc & 2) { /* inter block decoding */ ret_code = decode_block_inter_mpeg4 (stream_buf, inter_blk_coeff, vop_infor->cur_qp, dec_state->qmatrix_inter); if(SAMPLE_STATUS_NOERR != ret_code) { return ret_code; } /* motion compensation */ /* vop_infor->cur_bk.cb_ptr must be 8 byte aligned */ if(ippStsNoErr != (*(vop_infor->recon_block_func_ptr))( vop_infor->fwd_ref_bk.cb_ptr, dec_state->frame_step_set.cb_step, inter_blk_coeff, vop_infor->cur_bk.cb_ptr, dec_state->frame_step_set.cb_step, predict_type)) { return SAMPLE_STATUS_ERR; } } else { /* no residual components in the block */ /* block copy */ /* vop_infor->cur_bk.cb_ptr must be 8 byte aligned */ if(ippStsNoErr != (*(vop_infor->copy_block_func_ptr))( vop_infor->fwd_ref_bk.cb_ptr, dec_state->frame_step_set.cb_step, vop_infor->cur_bk.cb_ptr, dec_state->frame_step_set.cb_step, predict_type)) { return SAMPLE_STATUS_ERR; } } /* V block */ /* calculate the current block position */ vop_infor->cur_bk.cr_ptr = vop_infor->cur_mb.cr_ptr; /* calculate the predict reference block position */ tmp_step = (mv_chr.dx >> 1) + (mv_chr.dy >> 1) * dec_state->frame_step_set.cr_step; vop_infor->fwd_ref_bk.cr_ptr = vop_infor->fwd_ref_mb.cr_ptr + tmp_step; if (vop_infor->cbpc & 1) { /* inter block decoding */ ret_code = decode_block_inter_mpeg4 (stream_buf, inter_blk_coeff, vop_infor->cur_qp, dec_state->qmatrix_inter); if(SAMPLE_STATUS_NOERR != ret_code) { return ret_code; } /* motion compensation */ /* vop_infor->cur_bk.cr_ptr must be 8 byte aligned */ if(ippStsNoErr != (*(vop_infor->recon_block_func_ptr))( vop_infor->fwd_ref_bk.cr_ptr, dec_state->frame_step_set.cr_step, inter_blk_coeff, vop_infor->cur_bk.cr_ptr, dec_state->frame_step_set.cr_step, predict_type)) { return SAMPLE_STATUS_ERR; } } else { /* no residual components in the block */ /* block copy */ /* vop_infor->cur_bk.cr_ptr must be 8 byte aligned */ if(ippStsNoErr != (*(vop_infor->copy_block_func_ptr))( vop_infor->fwd_ref_bk.cr_ptr, dec_state->frame_step_set.cr_step, vop_infor->cur_bk.cr_ptr, dec_state->frame_step_set.cr_step, predict_type)) { return SAMPLE_STATUS_ERR; } } } else { /* if not coded */ /* update mv_buf ptr */ vop_infor->mv_buf += 4; for(i=0; i<4; i++) { vop_infor->mv_buf[i].dx = 0; vop_infor->mv_buf[i].dy = 0; } /* copy macroblock from fwd reference frame */ ret_code = copy_mb_from_ref_plane( vop_infor->fwd_ref_mb.y_ptr, dec_state->frame_step_set.y_step, vop_infor->fwd_ref_mb.cb_ptr, dec_state->frame_step_set.cb_step, vop_infor->fwd_ref_mb.cr_ptr, dec_state->frame_step_set.cr_step, vop_infor->cur_mb.y_ptr, dec_state->frame_step_set.y_step, vop_infor->cur_mb.cb_ptr, dec_state->frame_step_set.cb_step, vop_infor->cur_mb.cr_ptr, dec_state->frame_step_set.cr_step); if(SAMPLE_STATUS_NOERR != ret_code) { return SAMPLE_STATUS_ERR; } } return SAMPLE_STATUS_NOERR;}/******************************************************************************// Name: decode_intra_mb_mpeg4// Desicription:// Decode the texture data of an INTRA macroblock
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -