📄 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-2005 Intel Corporation. All Rights Reserved.//// Description: Decodes B-VOPs//*/#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; int stepYp, stepYc, stepYn, stepCbp, stepCbc, stepCbn, stepCrp, stepCrc, stepCrn; int dx, dy, TRB, TRD, quant, mbCurr, mbInVideoPacket, colNum, rowNum, nmb; IppiRect limitRectL, limitRectC; int quarter_sample, modb, mb_type, cbpb, dct_type, field_prediction, rvlc = 0, scan; int mb_ftfr, mb_fbfr, mb_btfr, mb_bbfr, fcode_forward, fcode_backward; mp4_MacroBlock *pMBinfo; 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; limitRectL.y = -16; limitRectL.width = pInfo->VisualObject.VideoObject.width + 32; limitRectL.height = pInfo->VisualObject.VideoObject.height + 32; limitRectC.x = -8; limitRectC.y = -8; limitRectC.width = (pInfo->VisualObject.VideoObject.width >> 1) + 16; limitRectC.height = (pInfo->VisualObject.VideoObject.height >> 1) + 16; quant = pInfo->VisualObject.VideoObject.VideoObjectPlane.quant; nmb = pInfo->VisualObject.VideoObject.MacroBlockPerVOP; mbCurr = 0; 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"); return MP4_STATUS_ERROR; } 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) { mp4_Error("Error when decode B-VOP motion vector"); return MP4_STATUS_ERROR; } 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) { mp4_Error("Error when decode B-VOP motion vector"); return MP4_STATUS_ERROR; } mvForwB.dy = (Ipp16s)mp4_Div2(mvForwB.dy); if (mp4_DecodeMV(pInfo, &mvForwB, fcode_forward) != MP4_STATUS_OK) { mp4_Error("Error when decode B-VOP motion vector"); return MP4_STATUS_ERROR; } 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) { mp4_Error("Error when decode coefficients of Inter block"); return MP4_STATUS_ERROR; } 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); mp4_MC_HP(cbpb & 1, pCrp, stepCrp, pCrc, stepCrc, coeffMB+320, &mvCbCrF, 0); } else { mp4_Copy8x4HP_8u(pCbp+(mb_ftfr ? stepCbp : 0), stepCbp*2, pCbc, stepCbc*2, &mvCbCrFFT, 0); mp4_Copy8x4HP_8u(pCrp+(mb_ftfr ? stepCrp : 0), stepCrp*2, pCrc, stepCrc*2, &mvCbCrFFT, 0); mp4_Copy8x4HP_8u(pCbp+(mb_fbfr ? stepCbp : 0), stepCbp*2, pCbc+stepCbc, stepCbc*2, &mvCbCrFFB, 0); mp4_Copy8x4HP_8u(pCrp+(mb_fbfr ? stepCrp : 0), stepCrp*2, pCrc+stepCrc, stepCrc*2, &mvCbCrFFB, 0); mp4_AddResidual(cbpb & 2, pCbc, stepCbc, coeffMB+256);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -