📄 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 + -