📄 mp4decvopb.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) 2001-2008 Intel Corporation. All Rights Reserved.
//
// Description: Decodes B-VOPs
//
*/
#include "umc_defs.h"
#if defined (UMC_ENABLE_MPEG4_VIDEO_DECODER)
#include "mp4.h"
#include "mp4dec.h"
/*
// Purpose: decode MPEG-4 BVOP
*/
mp4_Status mp4_DecodeVOP_B(mp4_Info* pInfo)
{
__ALIGN16(Ipp16s, coeffMB, 64*6);
__ALIGN16(Ipp8u, tmpMB, 64*4);
Ipp32u code;
Ipp8u *pYc, *pCbc, *pCrc, *pYp, *pCbp, *pCrp, *pYn, *pCbn, *pCrn, *pc, *pr, *pn;
Ipp32s stepYp, stepYc, stepYn, stepCbp, stepCbc, stepCbn, stepCrp, stepCrc, stepCrn, mbPerRow, mbPerCol;
Ipp32s dx, dy, TRB, TRD, quant, mbCurr, mbInVideoPacket, colNum, rowNum;
IppiRect limitRectL, limitRectC;
Ipp32s quarter_sample, modb, mb_type, cbpb, dct_type, field_prediction, rvlc = 0, scan;
Ipp32s mb_ftfr, mb_fbfr, mb_btfr, mb_bbfr, fcode_forward, fcode_backward;
mp4_MacroBlock *pMBinfo;
mp4_Status sts;
sts = MP4_STATUS_OK;
stepYc = pInfo->VisualObject.cFrame.stepY;
stepYp = pInfo->VisualObject.rFrame.stepY;
stepYn = pInfo->VisualObject.nFrame.stepY;
stepCbc = pInfo->VisualObject.cFrame.stepCb;
stepCbp = pInfo->VisualObject.rFrame.stepCb;
stepCbn = pInfo->VisualObject.nFrame.stepCb;
stepCrc = pInfo->VisualObject.cFrame.stepCr;
stepCrp = pInfo->VisualObject.rFrame.stepCr;
stepCrn = pInfo->VisualObject.nFrame.stepCr;
pYc = pInfo->VisualObject.cFrame.pY;
pCbc = pInfo->VisualObject.cFrame.pCb;
pCrc = pInfo->VisualObject.cFrame.pCr;
pYp = pInfo->VisualObject.rFrame.pY;
pCbp = pInfo->VisualObject.rFrame.pCb;
pCrp = pInfo->VisualObject.rFrame.pCr;
pYn = pInfo->VisualObject.nFrame.pY;
pCbn = pInfo->VisualObject.nFrame.pCb;
pCrn = pInfo->VisualObject.nFrame.pCr;
quarter_sample = pInfo->VisualObject.VideoObject.quarter_sample;
scan = pInfo->VisualObject.VideoObject.VideoObjectPlane.alternate_vertical_scan_flag ? IPPVC_SCAN_VERTICAL : IPPVC_SCAN_ZIGZAG;
fcode_forward = pInfo->VisualObject.VideoObject.VideoObjectPlane.fcode_forward;
fcode_backward = pInfo->VisualObject.VideoObject.VideoObjectPlane.fcode_backward;
// Bounding rectangles for MV limitation
limitRectL.x = - 16 * MP4_NUM_EXT_MB;
limitRectL.y = - 16 * MP4_NUM_EXT_MB;
limitRectL.width = pInfo->VisualObject.VideoObject.width + 16 * 2 * MP4_NUM_EXT_MB;
limitRectL.height = pInfo->VisualObject.VideoObject.height + 16 * 2 * MP4_NUM_EXT_MB;
limitRectC.x = -8 * MP4_NUM_EXT_MB;
limitRectC.y = -8 * MP4_NUM_EXT_MB;
limitRectC.width = (pInfo->VisualObject.VideoObject.width >> 1) + 8 * 2 * MP4_NUM_EXT_MB;
limitRectC.height = (pInfo->VisualObject.VideoObject.height >> 1) + 8 * 2 * MP4_NUM_EXT_MB;
quant = pInfo->VisualObject.VideoObject.VideoObjectPlane.quant;
mbPerRow = pInfo->VisualObject.VideoObject.MacroBlockPerRow;
mbPerCol = pInfo->VisualObject.VideoObject.MacroBlockPerCol;
mbCurr = colNum = rowNum = 0;
TRD = pInfo->VisualObject.VideoObject.TRD;
TRB = pInfo->VisualObject.VideoObject.TRB;
pMBinfo = pInfo->VisualObject.VideoObject.MBinfo;
// decode interlaced B-VOP
if (pInfo->VisualObject.VideoObject.interlaced) {
IppMotionVector mvCbCrF, mvCbCrB, mvForwT, mvBackT, mvForwB, mvBackB, mvForw[4], mvBack[4], mvCbCrFFT, mvCbCrFFB, mvCbCrBFT, mvCbCrBFB, *mvField = pInfo->VisualObject.VideoObject.FieldMV;
// warning "variable may be used without having been initialized"
mvCbCrF.dx = mvCbCrF.dy = mvCbCrB.dx = mvCbCrB.dy = mvCbCrFFT.dx = mvCbCrFFT.dy = mvCbCrFFB.dx = mvCbCrFFB.dy = mvCbCrBFT.dx = mvCbCrBFT.dy = mvCbCrBFB.dx = mvCbCrBFB.dy = 0;
mb_ftfr = mb_fbfr = mb_btfr = mb_bbfr = 0;
for (;;) {
mbInVideoPacket = 0;
// reset MV predictors at new VideoPacket
mvForwT.dx = mvForwT.dy = mvBackT.dx = mvBackT.dy = mvForwB.dx = mvForwB.dy = mvBackB.dx = mvBackB.dy = 0;
// decode B-VOP macroblocks
for (;;) {
if (pMBinfo->not_coded) {
ippiCopy16x16_8u_C1R(pYp, stepYp, pYc, stepYc);
ippiCopy8x8_8u_C1R(pCbp, stepCbp, pCbc, stepCbc);
ippiCopy8x8_8u_C1R(pCrp, stepCrp, pCrc, stepCrc);
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB_NOTCODED);
} else {
cbpb = 0;
if (mp4_GetBit(pInfo)) {
modb = 2;
mb_type = IPPVC_MBTYPE_DIRECT;
} else {
modb = mp4_GetBit(pInfo);
// decode mb_type
code = mp4_ShowBits9(pInfo, 4);
if (code != 0) {
mb_type = mp4_BVOPmb_type[code].code;
mp4_FlushBits(pInfo, mp4_BVOPmb_type[code].len);
} else {
mp4_Error("Error when decode mb_type of B-VOP macroblock");
goto Err_1;
}
if (modb == 0)
cbpb = mp4_GetBits9(pInfo, 6);
if (mb_type != IPPVC_MBTYPE_DIRECT && cbpb != 0)
mp4_UpdateQuant_B(pInfo, quant);
}
dct_type = 0;
field_prediction = 0;
if (cbpb != 0)
dct_type = mp4_GetBit(pInfo);
if (mb_type != IPPVC_MBTYPE_DIRECT) {
field_prediction = mp4_GetBit(pInfo);
if (field_prediction) {
if (mb_type != IPPVC_MBTYPE_BACKWARD) {
mb_ftfr = mp4_GetBit(pInfo);
mb_fbfr = mp4_GetBit(pInfo);
}
if (mb_type != IPPVC_MBTYPE_FORWARD) {
mb_btfr = mp4_GetBit(pInfo);
mb_bbfr = mp4_GetBit(pInfo);
}
}
}
// coordinates of current MB for limitation
dx = colNum * 16;
dy = rowNum * 16;
if (mb_type == IPPVC_MBTYPE_FORWARD) {
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB_FORWARD);
if (!field_prediction) {
if (mp4_DecodeMV(pInfo, &mvForwT, fcode_forward) != MP4_STATUS_OK)
goto Err_1;
if (quarter_sample) {
mp4_LimitMVQ(&mvForwT, &mvForw[0], &limitRectL, dx, dy, 16);
mp4_ComputeChromaMVQ(&mvForw[0], &mvCbCrF);
mp4_Copy16x16QP_8u(pYp, stepYp, pYc, stepYc, &mvForw[0], 0);
} else {
mp4_LimitMV(&mvForwT, &mvForw[0], &limitRectL, dx, dy, 16);
mp4_ComputeChromaMV(&mvForw[0], &mvCbCrF);
mp4_Copy16x16HP_8u(pYp, stepYp, pYc, stepYc, &mvForw[0], 0);
}
//mvForw[1] = mvForw[2] = mvForw[3] = mvForw[0];
mvForwB = mvForwT;
} else {
mvForwT.dy = (Ipp16s)mp4_Div2(mvForwT.dy);
if (mp4_DecodeMV(pInfo, &mvForwT, fcode_forward) != MP4_STATUS_OK)
goto Err_1;
mvForwB.dy = (Ipp16s)mp4_Div2(mvForwB.dy);
if (mp4_DecodeMV(pInfo, &mvForwB, fcode_forward) != MP4_STATUS_OK)
goto Err_1;
if (quarter_sample) {
mp4_LimitFMVQ(&mvForwT, &mvForw[0], &limitRectL, dx, dy, 16);
mp4_Copy16x8QP_8u(pYp+(mb_ftfr ? stepYp : 0), stepYp*2, pYc, stepYc*2, &mvForw[0], 0);
mvForw[0].dx = (Ipp16s)mp4_Div2(mvForw[0].dx);
mvForw[0].dy = (Ipp16s)(mp4_Div2(mvForw[0].dy*2) >> 1);
mp4_LimitFMVQ(&mvForwB, &mvForw[2], &limitRectL, dx, dy, 16);
mp4_Copy16x8QP_8u(pYp+(mb_fbfr ? stepYp : 0), stepYp*2, pYc+stepYc, stepYc*2, &mvForw[2], 0);
mvForw[2].dx = (Ipp16s)mp4_Div2(mvForw[2].dx);
mvForw[2].dy = (Ipp16s)(mp4_Div2(mvForw[2].dy*2) >> 1);
} else {
mp4_LimitFMV(&mvForwT, &mvForw[0], &limitRectL, dx, dy, 16);
mp4_Copy16x8HP_8u(pYp+(mb_ftfr ? stepYp : 0), stepYp*2, pYc, stepYc*2, &mvForw[0], 0);
mp4_LimitFMV(&mvForwB, &mvForw[2], &limitRectL, dx, dy, 16);
mp4_Copy16x8HP_8u(pYp+(mb_fbfr ? stepYp : 0), stepYp*2, pYc+stepYc, stepYc*2, &mvForw[2], 0);
}
mvForwT.dy <<= 1;
mvForwB.dy <<= 1;
//mvForw[1] = mvForw[0];
//mvForw[3] = mvForw[2];
mp4_ComputeChromaMV(&mvForw[0], &mvCbCrFFT);
mp4_ComputeChromaMV(&mvForw[2], &mvCbCrFFB);
}
if (mp4_DecodeInterMB(pInfo, coeffMB, quant, cbpb, scan) != MP4_STATUS_OK)
goto Err_1;
if (!dct_type) {
mp4_AddResidual(cbpb & 32, pYc, stepYc, coeffMB);
mp4_AddResidual(cbpb & 16, pYc+8, stepYc, coeffMB+64);
mp4_AddResidual(cbpb & 8, pYc+stepYc*8, stepYc, coeffMB+128);
mp4_AddResidual(cbpb & 4, pYc+stepYc*8+8, stepYc, coeffMB+192);
} else {
mp4_AddResidual(cbpb & 32, pYc, stepYc*2, coeffMB);
mp4_AddResidual(cbpb & 16, pYc+8, stepYc*2, coeffMB+64);
mp4_AddResidual(cbpb & 8, pYc+stepYc, stepYc*2, coeffMB+128);
mp4_AddResidual(cbpb & 4, pYc+stepYc+8, stepYc*2, coeffMB+192);
}
if (!field_prediction) {
mp4_MC_HP(cbpb & 2, pCbp, stepCbp, pCbc, stepCbc, coeffMB+256, &mvCbCrF, 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -