📄 mp4decvopp.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 P-VOPs//*/#include "mp4.h"#include "mp4dec.h"/*// used for short_viseo_header*/static mp4_Status mp4_PredictDecodeMV(mp4_Info *pInfo, mp4_MacroBlock *MBcurr, int frGOB, int y, int x){ IppMotionVector *mvLeft, *mvTop, *mvRight, *mvCurr; int mbInRow = pInfo->VisualObject.VideoObject.MacroBlockPerRow; mvCurr = MBcurr[0].mv; mvLeft = MBcurr[-1].mv; mvTop = MBcurr[-mbInRow].mv; mvRight = MBcurr[-mbInRow+1].mv; if (y == frGOB && x == 0) { mvCurr->dx = mvCurr->dy = 0; } else if (x == 0) { mvCurr->dx = mp4_Median(0, mvTop[0].dx, mvRight[0].dx); mvCurr->dy = mp4_Median(0, mvTop[0].dy, mvRight[0].dy); } else if (y == frGOB) { MBcurr->mv[0] = mvLeft[0]; } else if (x == mbInRow - 1) { mvCurr->dx = mp4_Median(0, mvLeft[0].dx, mvTop[0].dx); mvCurr->dy = mp4_Median(0, mvLeft[0].dy, mvTop[0].dy); } else { mvCurr->dx = mp4_Median(mvLeft[0].dx, mvTop[0].dx, mvRight[0].dx); mvCurr->dy = mp4_Median(mvLeft[0].dy, mvTop[0].dy, mvRight[0].dy); } return mp4_DecodeMV(pInfo, mvCurr, 1);}/*// decode MPEG-4 PVOP*/mp4_Status mp4_DecodeVOP_P(mp4_Info* pInfo){ __ALIGN16(Ipp16s, coeffMB, 64*6); int stepYr, stepYc, stepCbr, stepCbc, stepCrr, stepCrc, stepFc[6]; int i, j, nmb, dx, dy, mbCurr, mbInVideoPacket, colNum, rowNum, mbPerRow, mbPerCol; Ipp8u *pYc, *pCbc, *pCrc, *pYr, *pCbr, *pCrr, *pFc[6]; int mb_not_coded, mb_type, cbpc, cbpy, ac_pred_flag, cbpyPrev; int dcVLC, quant, quantPred, rvlc, scan, obmc_disable, rt, quarter_sample; IppiRect limitRectL, limitRectC; IppMotionVector mvCur[4], mvPrev[4], mvTmp[4], mvCbCr; mp4_MacroBlock *pMBinfo; mbPerRow = pInfo->VisualObject.VideoObject.MacroBlockPerRow; mbPerCol = pInfo->VisualObject.VideoObject.MacroBlockPerCol; stepYc = pInfo->VisualObject.cFrame.stepY; stepYr = pInfo->VisualObject.rFrame.stepY; stepCbc = pInfo->VisualObject.cFrame.stepCb; stepCbr = pInfo->VisualObject.rFrame.stepCb; stepCrc = pInfo->VisualObject.cFrame.stepCr; stepCrr = pInfo->VisualObject.rFrame.stepCr; pYc = pInfo->VisualObject.cFrame.pY; pCbc = pInfo->VisualObject.cFrame.pCb; pCrc = pInfo->VisualObject.cFrame.pCr; pYr = pInfo->VisualObject.rFrame.pY; pCbr = pInfo->VisualObject.rFrame.pCb; pCrr = pInfo->VisualObject.rFrame.pCr; stepFc[0] = stepFc[1] = stepFc[2] = stepFc[3] = stepYc; stepFc[4] = stepCbc; stepFc[5] = stepCrc; // Bounding rectangle for MV limitation limitRectL.x = - 16; limitRectL.y = - 16; limitRectL.width = pInfo->VisualObject.VideoObject.width + 32; limitRectL.height = pInfo->VisualObject.VideoObject.height + 32; pMBinfo = pInfo->VisualObject.VideoObject.MBinfo; // warning "variable may be used without having been initialized" cbpc = cbpy = mb_type = 0;// decode short_video_header P-VOP if (pInfo->VisualObject.VideoObject.short_video_header) { int frGOB; IppMotionVector mvCur; quant = pInfo->VisualObject.VideoObject.VideoObjectPlaneH263.vop_quant; nmb = 0; pInfo->VisualObject.VideoObject.VideoObjectPlaneH263.gob_number = 0; dy = 0; frGOB = 0; for (i = 0; i < mbPerCol; i ++) { dx = 0; for (j = 0; j < mbPerRow; j ++) { do { mb_not_coded = mp4_GetBit(pInfo); if (mb_not_coded) break; if (mp4_DecodeMCBPC_P(pInfo, &mb_type, &cbpc, 1) != MP4_STATUS_OK) return MP4_STATUS_ERROR; } while (mb_type == IPPVC_MB_STUFFING); if (mb_not_coded) { ippiCopy16x16_8u_C1R(pYr, stepYr, pYc, stepYc); ippiCopy8x8_8u_C1R(pCbr, stepCbr, pCbc, stepCbc); ippiCopy8x8_8u_C1R(pCrr, stepCrr, pCrc, stepCrc); pMBinfo->mv[0].dx = pMBinfo->mv[0].dy = 0; mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB_NOTCODED); } else { if (mb_type == IPPVC_MBTYPE_INTER4V || mb_type == IPPVC_MBTYPE_INTER4V_Q) { mp4_Error("Error in MacroblockType. 4MV shall not be used for short_video_header"); return MP4_STATUS_ERROR; } if (mp4_DecodeCBPY_P(pInfo, &cbpy, mb_type) != MP4_STATUS_OK) return MP4_STATUS_ERROR; if (mb_type == IPPVC_MBTYPE_INTER_Q || mb_type == IPPVC_MBTYPE_INTRA_Q) mp4_UpdateQuant(pInfo, quant); if (mb_type >= IPPVC_MBTYPE_INTRA) { pFc[0] = pYc; pFc[1] = pYc + 8; pFc[2] = pYc + 8 * stepYc; pFc[3] = pYc + 8 * stepYc + 8; pFc[4] = pCbc; pFc[5] = pCrc; if (mp4_DecodeIntraMB_SVH(pInfo, (cbpy << 2) + cbpc, quant, pFc, stepFc) != MP4_STATUS_OK) { mp4_Error("Error when decode coefficients of Intra block"); return MP4_STATUS_ERROR; } pMBinfo->mv[0].dx = pMBinfo->mv[0].dy = 0; } else { if (mp4_PredictDecodeMV(pInfo, pMBinfo, frGOB, i, j) != MP4_STATUS_OK) { mp4_Error("Error when decode motion vector"); return MP4_STATUS_ERROR; } mp4_LimitMV(&pMBinfo->mv[0], &mvCur, &limitRectL, dx, dy, 16); mp4_ComputeChromaMV(&mvCur, &mvCbCr);/* if ((cbpy << 2) + cbpc) if (mp4_DecodeInterMB_SVH(pInfo, coeffMB, quant, (cbpy << 2) + cbpc) != MP4_STATUS_OK) { mp4_Error("Error when decode coefficients of Inter block"); return MP4_STATUS_ERROR; } mp4_Copy16x16HP_8u(pYr, stepYr, pYc, stepYc, &mvCur, 0); mp4_AddResidual(cbpy & 8, pYc, stepYc, coeffMB); mp4_AddResidual(cbpy & 4, pYc+8, stepYc, coeffMB+64); mp4_AddResidual(cbpy & 2, pYc+stepYc*8, stepYc, coeffMB+128); mp4_AddResidual(cbpy & 1, pYc+stepYc*8+8, stepYc, coeffMB+192); mp4_MC_HP(cbpc & 2, pCbr, stepCbr, pCbc, stepCbc, coeffMB+256, &mvCbCr, 0); mp4_MC_HP(cbpc & 1, pCrr, stepCrr, pCrc, stepCrc, coeffMB+320, &mvCbCr, 0);*/ // decode and MC blocks if (cbpy) { mp4_DecodeMCInterBlock_SVH(pInfo, quant, cbpy & 8, pYr, pYc, stepYr, coeffMB, &mvCur); mp4_DecodeMCInterBlock_SVH(pInfo, quant, cbpy & 4, pYr+8, pYc+8, stepYr, coeffMB, &mvCur); mp4_DecodeMCInterBlock_SVH(pInfo, quant, cbpy & 2, pYr+stepYr*8, pYc+stepYc*8, stepYr, coeffMB, &mvCur); mp4_DecodeMCInterBlock_SVH(pInfo, quant, cbpy & 1, pYr+8+stepYr*8, pYc+8+stepYc*8, stepYr, coeffMB, &mvCur); } else { mp4_Copy16x16HP_8u(pYr, stepYr, pYc, stepYc, &mvCur, 0); mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTER_NC); mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTER_NC); mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTER_NC); mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTER_NC); } mp4_DecodeMCInterBlock_SVH(pInfo, quant, cbpc & 2, pCbr, pCbc, stepCbr, coeffMB, &mvCbCr); mp4_DecodeMCInterBlock_SVH(pInfo, quant, cbpc & 1, pCrr, pCrc, stepCrr, coeffMB, &mvCbCr); } } mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB); pYc += 16; pCrc += 8; pCbc += 8; pYr += 16; pCrr += 8; pCbr += 8; dx += 16; pMBinfo ++; mp4_CheckDecodeGOB_SVH(pInfo, nmb, frGOB, i, quant); } dy += 16; pYc += 2 * MP4_NUM_EXT_MB * 16 + (stepYc << 4) - stepYc; pCbc += 2 * MP4_NUM_EXT_MB * 8 + (stepCbc << 3) - stepCbc; pCrc += 2 * MP4_NUM_EXT_MB * 8 + (stepCrc << 3) - stepCrc; pYr += 2 * MP4_NUM_EXT_MB * 16 + (stepYr << 4) - stepYr; pCbr += 2 * MP4_NUM_EXT_MB * 8 + (stepCbr << 3) - stepCbr; pCrr += 2 * MP4_NUM_EXT_MB * 8 + (stepCrr << 3) - stepCrr; } mp4_AlignBits(pInfo); return MP4_STATUS_OK; } rt = pInfo->VisualObject.VideoObject.VideoObjectPlane.rounding_type; quarter_sample = pInfo->VisualObject.VideoObject.quarter_sample; obmc_disable = pInfo->VisualObject.VideoObject.obmc_disable; rvlc = pInfo->VisualObject.VideoObject.reversible_vlc; scan = pInfo->VisualObject.VideoObject.VideoObjectPlane.alternate_vertical_scan_flag ? IPPVC_SCAN_VERTICAL : IPPVC_SCAN_ZIGZAG; // Bounding rectangles for MV limitation limitRectC.x = -8; limitRectC.y = -8; limitRectC.width = (pInfo->VisualObject.VideoObject.width >> 1) + 16; limitRectC.height = (pInfo->VisualObject.VideoObject.height >> 1) + 16; nmb = pInfo->VisualObject.VideoObject.MacroBlockPerVOP; quant = quantPred = pInfo->VisualObject.VideoObject.VideoObjectPlane.quant; mbCurr = 0; colNum = rowNum = 0; // warning "variable may be used without having been initialized" ac_pred_flag = cbpyPrev = 0; mvCbCr.dx = mvCbCr.dy = 0;// decode data_partitioned P-VOP if (pInfo->VisualObject.VideoObject.data_partitioned) { for (;;) { mp4_DataPartMacroBlock *pMBdp; int x = colNum, y = rowNum; // reset Intra prediction buffer on new Video_packet mp4_ResetIntraPredBuffer(pInfo); pMBdp = &pInfo->VisualObject.VideoObject.DataPartBuff[mbCurr]; pMBinfo = &pInfo->VisualObject.VideoObject.MBinfo[mbCurr]; mbInVideoPacket = 0; // decode not_coded/mb_type/cbpc/MV part for (;;) { mb_not_coded = mp4_GetBit(pInfo); if (mb_not_coded) { mb_type = IPPVC_MBTYPE_INTER; mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB_NOTCODED); } else { if (mp4_DecodeMCBPC_P(pInfo, &mb_type, &cbpc, 1) != MP4_STATUS_OK) return MP4_STATUS_ERROR; } if (mb_type != IPPVC_MB_STUFFING) { pMBinfo->validPred = 1; if (!mb_not_coded && (mb_type <= IPPVC_MBTYPE_INTER4V)) { if (mb_type != IPPVC_MBTYPE_INTER4V) { if (mp4_PredictDecode1MV(pInfo, pMBinfo, y, x) != MP4_STATUS_OK) { mp4_Error("Error when decode motion vector");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -