📄 mp4decvopi.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 I-VOPs//*/#include "mp4.h"#include "mp4dec.h"/*// decode mcbpc and set MBtype and ChromaPattern*/static mp4_Status mp4_DecodeMCBPC_I(mp4_Info* pInfo, int *mbType, int *mbPattern){ Ipp32u code; int type, pattern, fb; code = mp4_ShowBits9(pInfo, 9); if (code == 1) { type = IPPVC_MB_STUFFING; pattern = 0; fb = 9; } else if (code >= 64) { type = IPPVC_MBTYPE_INTRA; pattern = code >> 6; if (pattern >= 4) { pattern = 0; fb = 1; } else fb = 3; } else { type = IPPVC_MBTYPE_INTRA_Q; pattern = code >> 3; if (pattern >= 4) { pattern = 0; fb = 4; } else if (code >= 8) { fb = 6; } else { mp4_Error("Error when decode mcbpc of I-VOP macroblock"); return MP4_STATUS_ERROR; } } mp4_FlushBits(pInfo, fb); *mbType = type; *mbPattern = pattern; if (type == IPPVC_MBTYPE_INTRA) mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB_INTRA); else if (type == IPPVC_MBTYPE_INTRA_Q) mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB_INTRA_Q); return MP4_STATUS_OK;}/*// decode cbpy for Intra nontransparent MB*/__INLINE mp4_Status mp4_DecodeCBPY_I(mp4_Info* pInfo, int *yPattern){ Ipp32u code; code = mp4_ShowBits9(pInfo, 6); *yPattern = mp4_cbpy4[code].code; if (mp4_cbpy4[code].len == 255) { mp4_Error("Error when decode cbpy of I-VOP macroblock"); return MP4_STATUS_ERROR; } else { mp4_FlushBits(pInfo, mp4_cbpy4[code].len); return MP4_STATUS_OK; }}/*// decode cbpy for Intra Shape MB*/__INLINE mp4_Status mp4_DecodeCBPY_I_Shape(mp4_Info* pInfo, int nNonTransp, int *yPattern){ Ipp32u code, i; i = nNonTransp - 1; code = mp4_ShowBits9(pInfo, mp4_cbpy_b[i]); *yPattern = mp4_cbpy_t[i][code].code; if (mp4_cbpy_t[i][code].len == 255) { mp4_Error("Error when decode cbpy of I-VOP with Shape macroblock"); return MP4_STATUS_ERROR; } else { mp4_FlushBits(pInfo, mp4_cbpy_t[i][code].len); return MP4_STATUS_OK; }}/*// decode MPEG-4 IVOP with Shape*/mp4_Status mp4_DecodeVOP_I_Shape(mp4_Info* pInfo){/* Ipp32u code; int quant, quantPred, i, dcVLC, nmb, mbPerRow, mbPerCol; int stepYc, stepCbc, stepCrc; IppStatus status; Ipp8u *pY, *pCb, *pCr, *pQuantMatIntra, *ppbq, *pB; Ipp16s *ppbrY, *ppbrCb, *ppbrCr, *ppbcY, *ppbcCb, *ppbcCr; mp4_MacroBlock MacroBlock = {0}; int conv_ratio, scan_type, blockSize, nOpaq, cbpy; int mbCurr, mbInVideoPacket, colNum, rowNum, k; mp4_ShapeInfo *curShapeInfo; status = mp4_InitVOPShape(pInfo); if (status != MP4_STATUS_OK) return status; stepYc = pInfo->VisualObject.cFrame.stepY; stepCbc = pInfo->VisualObject.cFrame.stepCb; stepCrc = pInfo->VisualObject.cFrame.stepCr; mbPerRow = pInfo->VisualObject.cFrame.mbPerRow; mbPerCol = pInfo->VisualObject.cFrame.mbPerCol; pQuantMatIntra = pInfo->VisualObject.VideoObject.quant_type ? pInfo->VisualObject.VideoObject.intra_quant_mat : NULL; // for B-VOP ippsZero_8u(pInfo->VisualObject.VideoObject.MacroBlockNotCoded, mbPerCol*mbPerRow); ippsZero_8u((Ipp8u*)pInfo->VisualObject.VideoObject.MVfull, mbPerCol*mbPerRow*4*sizeof(IppMotionVector)); // needed for ippVC predict mechanism ppbcY = pInfo->VisualObject.VideoObject.PredictBuffCol_Y; ppbcCb = pInfo->VisualObject.VideoObject.PredictBuffCol_Cb; ppbcCr = pInfo->VisualObject.VideoObject.PredictBuffCol_Cr; quant = pInfo->VisualObject.VideoObject.VideoObjectPlane.quant; curShapeInfo = pInfo->VisualObject.VideoObject.ShapeInfo; conv_ratio = 1; nmb = pInfo->VisualObject.VideoObject.MacroBlockPerVOP;// decode data_partitioned I-VOP if (pInfo->VisualObject.VideoObject.data_partitioned) { mp4_MacroBlock *pMacroBlock; mbCurr = 0; colNum = rowNum = 0; // avoid warning C4701 pY = pCb = pCr = ppbq = 0; ppbrY = ppbrCb = ppbrCr = 0; for (;;) { // reset ACDC predict buffer on new Video_packet for (i = 0; i <= mbPerRow; i ++) { pInfo->VisualObject.VideoObject.PredictBuffRow_Y[i*16] = -1; pInfo->VisualObject.VideoObject.PredictBuffRow_Y[i*16+8] = -1; pInfo->VisualObject.VideoObject.PredictBuffRow_Cb[i*8] = -1; pInfo->VisualObject.VideoObject.PredictBuffRow_Cr[i*8] = -1; } ppbcY[0] = ppbcY[8] = ppbcCb[0] = ppbcCr[0] = -1; pMacroBlock = &pInfo->VisualObject.VideoObject.MBfull[mbCurr]; mbInVideoPacket = 0; // decode dc part for (;;) { // decode mcbpc if (mp4_DecodeMCBPC_I(pInfo, &pMacroBlock->type, &pMacroBlock->cbpc) != MP4_STATUS_OK) return MP4_STATUS_ERROR; if (pMacroBlock->type != IPPVC_MB_STUFFING) { quantPred = quant; // decode dquant if (pMacroBlock->type == IPPVC_MBTYPE_INTRA_Q) mp4_UpdateQuant(pInfo, quant); pMacroBlock->dquant = quant; if (mbInVideoPacket == 0) quantPred = quant; dcVLC = (quantPred < mp4_DC_vlc_Threshold[pInfo->VisualObject.VideoObject.VideoObjectPlane.intra_dc_vlc_thr]) ? 1 : 0; // decode DCs if (dcVLC) { for (k= 0; k < 6; k ++) { status = ippiDecodeVLC_IntraDCVLC_MPEG4_1u16s(&pInfo->bufptr, &pInfo->bitoff, &pMacroBlock->dct_dc[k], k < 4 ? IPPVC_LUMINANCE : IPPVC_CHROMINANCE); if (status != ippStsNoErr) { mp4_Error("Error when decode coefficients of Intra block"); return MP4_STATUS_ERROR; } } } pMacroBlock ++; mbInVideoPacket ++; } if (mp4_ShowBits(pInfo, 19) == MP4_DC_MARKER) { code = mp4_GetBits(pInfo, 19); break; } } pMacroBlock = &pInfo->VisualObject.VideoObject.MBfull[mbCurr]; for (i = 0; i < mbInVideoPacket; i ++) { // decode ac_pred_flag pMacroBlock->ac_pred_flag = mp4_GetBit(pInfo); // decode cbpy if (mp4_DecodeCBPY_I(pInfo, &pMacroBlock->cbpy) != MP4_STATUS_OK) return MP4_STATUS_ERROR; pMacroBlock ++; } pMacroBlock = &pInfo->VisualObject.VideoObject.MBfull[mbCurr]; for (i = 0; i < mbInVideoPacket; i ++) { if (colNum == 0) { pY = pInfo->VisualObject.cFrame.pY + rowNum * 16 * stepYc; pCb = pInfo->VisualObject.cFrame.pCb + rowNum * 8 * stepCbc; pCr = pInfo->VisualObject.cFrame.pCr + rowNum * 8 * stepCrc; // needed for ippVC predict mechanism if (rowNum) ppbrY[-8] = ppbcY[8]; / * Update DC part of last MB per line * / ppbrY = pInfo->VisualObject.VideoObject.PredictBuffRow_Y + 16; ppbrCb = pInfo->VisualObject.VideoObject.PredictBuffRow_Cb + 8; ppbrCr = pInfo->VisualObject.VideoObject.PredictBuffRow_Cr + 8; ppbcY[0] = ppbcY[8] = ppbcCb[0] = ppbcCr[0] = -1; ppbq = pInfo->VisualObject.VideoObject.PredictBuffQuant; } quant = pMacroBlock->dquant; quantPred = (i == 0) ? quant : pMacroBlock[-1].dquant; dcVLC = (quantPred < mp4_DC_vlc_Threshold[pInfo->VisualObject.VideoObject.VideoObjectPlane.intra_dc_vlc_thr]) ? 1 : 0; // decode ACs and reconstruct blocks if ((status = mp4_ReconBlockIntraDP_MPEG4(pInfo, pMacroBlock, dcVLC, pY, stepYc, ppbrY, ppbcY, ppbq, quant, 0, pInfo->VisualObject.VideoObject.reversible_vlc, pQuantMatIntra, pMacroBlock->cbpy & 8)) != ippStsNoErr) return MP4_STATUS_ERROR; if ((status = mp4_ReconBlockIntraDP_MPEG4(pInfo, pMacroBlock, dcVLC, pY+8, stepYc, ppbrY+8, ppbcY, ppbq, quant, 1, pInfo->VisualObject.VideoObject.reversible_vlc, pQuantMatIntra, pMacroBlock->cbpy & 4)) != ippStsNoErr) return MP4_STATUS_ERROR; if ((status = mp4_ReconBlockIntraDP_MPEG4(pInfo, pMacroBlock, dcVLC, pY+8*stepYc, stepYc, ppbrY, ppbcY+8, ppbq, quant, 2, pInfo->VisualObject.VideoObject.reversible_vlc, pQuantMatIntra, pMacroBlock->cbpy & 2)) != ippStsNoErr) return MP4_STATUS_ERROR; if ((status = mp4_ReconBlockIntraDP_MPEG4(pInfo, pMacroBlock, dcVLC, pY+8*stepYc+8, stepYc, ppbrY+8, ppbcY+8, ppbq, quant, 3, pInfo->VisualObject.VideoObject.reversible_vlc, pQuantMatIntra, pMacroBlock->cbpy & 1)) != ippStsNoErr) return MP4_STATUS_ERROR; if ((status = mp4_ReconBlockIntraDP_MPEG4(pInfo, pMacroBlock, dcVLC, pCb, stepCbc, ppbrCb, ppbcCb, ppbq, quant, 4, pInfo->VisualObject.VideoObject.reversible_vlc, pQuantMatIntra, pMacroBlock->cbpc & 2)) != ippStsNoErr) return MP4_STATUS_ERROR; if ((status = mp4_ReconBlockIntraDP_MPEG4(pInfo, pMacroBlock, dcVLC, pCr, stepCrc, ppbrCr, ppbcCr, ppbq, quant, 5, pInfo->VisualObject.VideoObject.reversible_vlc, pQuantMatIntra, pMacroBlock->cbpc & 1)) != ippStsNoErr) return MP4_STATUS_ERROR; // update predict buffers ppbq ++; ppbq[0] = (Ipp8u)quant; pY += 16; pCr += 8; pCb += 8; ppbrY += 16; ppbrCb += 8; ppbrCr += 8; mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB); pMacroBlock ++; colNum ++; if (colNum == mbPerRow) { colNum = 0; rowNum ++; } } mbCurr += mbInVideoPacket; if (mbCurr == nmb) break; if (!pInfo->VisualObject.VideoObject.resync_marker_disable)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -