📄 mp4decvop.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 MPEG-4 bitstream.
//
*/
#include "umc_defs.h"
#if defined (UMC_ENABLE_MPEG4_VIDEO_DECODER)
#include "mp4.h"
#include "mp4dec.h"
#pragma warning(disable : 188) // enumerated type mixed with another type ICL
void mp4_ResetVOL(mp4_Info *pInfo)
{
pInfo->VisualObject.VideoObject.VOPindex = 0;
pInfo->VisualObject.VideoObject.prevPlaneIsB = 0;
pInfo->VisualObject.VideoObject.GroupOfVideoObjectPlane.time_code = 0;
pInfo->VisualObject.vFrame = NULL;
}
static mp4_Status mp4_AllocInitFrame(mp4_Frame* pFrame, Ipp32s mbPerRow, Ipp32s mbPerCol)
{
Ipp32s w, h;
w = (mbPerRow + 2 * MP4_NUM_EXT_MB) << 4;
h = (mbPerCol + 2 * MP4_NUM_EXT_MB) << 4;
pFrame->stepY = w;
pFrame->apY = ippsMalloc_8u(w * h);
if (!pFrame->apY)
return MP4_STATUS_NO_MEM;
ippsSet_8u(0, pFrame->apY, w * h);
pFrame->pY = pFrame->apY + w * 16 + 16;
w >>= 1;
h >>= 1;
pFrame->stepCb = w;
pFrame->apCb = ippsMalloc_8u(w * h);
if (!pFrame->apCb)
return MP4_STATUS_NO_MEM;
ippsSet_8u(128, pFrame->apCb, w * h);
pFrame->pCb = pFrame->apCb + w * 8 + 8;
pFrame->stepCr = w;
pFrame->apCr = ippsMalloc_8u(w * h);
if (!pFrame->apCr)
return MP4_STATUS_NO_MEM;
pFrame->pCr = pFrame->apCr + w * 8 + 8;
ippsSet_8u(128, pFrame->apCr, w * h);
return MP4_STATUS_OK;
}
/*
// mp4_Info for decoding of Video Object Layer
*/
mp4_Status mp4_InitVOL(mp4_Info* pInfo)
{
Ipp32s mbPerRow, mbPerCol, specSize;
if (pInfo->VisualObject.VideoObject.short_video_header) {
pInfo->noBVOPs = 1;
} else {
if (pInfo->strictSyntaxCheck) {
if (pInfo->VisualObject.VideoObject.random_accessible_vol)
pInfo->noPVOPs = pInfo->noBVOPs = 1;
if (pInfo->VisualObject.VideoObject.type_indication == MP4_VIDEO_OBJECT_TYPE_SIMPLE ||
pInfo->VisualObject.VideoObject.type_indication == MP4_VIDEO_OBJECT_TYPE_ADVANCED_REAL_TIME_SIMPLE ||
pInfo->VisualObject.VideoObject.VOLControlParameters.low_delay) {
pInfo->noBVOPs = 1;
}
}
}
if (pInfo->VisualObject.VideoObject.shape == MP4_SHAPE_TYPE_RECTANGULAR) {
mbPerRow = (pInfo->VisualObject.VideoObject.width + 15) >> 4;
mbPerCol = (pInfo->VisualObject.VideoObject.height + 15) >> 4;
// current frame
// if (mp4_AllocInitFrame(&pInfo->VisualObject.cFrame, mbPerRow, mbPerCol) != MP4_STATUS_OK)
// return MP4_STATUS_NO_MEM;
if (pInfo->VisualObject.VideoObject.sprite_enable != MP4_SPRITE_STATIC) {
// ref in past frame
// if (mp4_AllocInitFrame(&pInfo->VisualObject.rFrame, mbPerRow, mbPerCol) != MP4_STATUS_OK)
// return MP4_STATUS_NO_MEM;
// ref in future frame
// if (mp4_AllocInitFrame(&pInfo->VisualObject.nFrame, mbPerRow, mbPerCol) != MP4_STATUS_OK)
// return MP4_STATUS_NO_MEM;
// motion info (not needed for Sprites)
pInfo->VisualObject.VideoObject.MBinfo = (mp4_MacroBlock*)ippsMalloc_8u(mbPerRow*mbPerCol*sizeof(mp4_MacroBlock));
if (!pInfo->VisualObject.VideoObject.MBinfo) return MP4_STATUS_NO_MEM;
#ifdef USE_NOTCODED_STATE
// not_coded MB state
pInfo->VisualObject.VideoObject.ncState = ippsMalloc_8u(mbPerCol * mbPerRow);
if (!pInfo->VisualObject.VideoObject.ncState) return MP4_STATUS_NO_MEM;
pInfo->VisualObject.VideoObject.ncStateCleared = 0;
#endif
} else { // data for static sprite
mbPerRow = pInfo->VisualObject.sFrame.mbPerRow = (pInfo->VisualObject.VideoObject.sprite_width + 15) >> 4;
mbPerCol = pInfo->VisualObject.sFrame.mbPerCol = (pInfo->VisualObject.VideoObject.sprite_height + 15) >> 4;
// if (mp4_AllocInitFrame(&pInfo->VisualObject.sFrame, mbPerRow, mbPerCol) != MP4_STATUS_OK)
// return MP4_STATUS_NO_MEM;
}
pInfo->VisualObject.VideoObject.MacroBlockPerRow = mbPerRow;
pInfo->VisualObject.VideoObject.MacroBlockPerCol = mbPerCol;
pInfo->VisualObject.VideoObject.MacroBlockPerVOP = mbPerRow * mbPerCol;
pInfo->VisualObject.VideoObject.mbns = mp4_GetMacroBlockNumberSize(pInfo->VisualObject.VideoObject.MacroBlockPerVOP);
#ifdef _OMP_KARABAS
if (pInfo->num_threads < 1 || pInfo->num_threads > mp4_GetNumOfThreads())
pInfo->num_threads = mp4_GetNumOfThreads();
pInfo->pMBinfoMT = (mp4_MacroBlockMT*)ippsMalloc_8u(mbPerRow * pInfo->num_threads * sizeof(mp4_MacroBlockMT));
if(!pInfo->pMBinfoMT) return MP4_STATUS_NO_MEM;
#endif // _OMP_KARABAS
if (!pInfo->VisualObject.VideoObject.short_video_header) {
// Intra Prediction info (not needed for SVH)
pInfo->VisualObject.VideoObject.IntraPredBuff.quant = ippsMalloc_8u(mbPerRow + 1);
if (!pInfo->VisualObject.VideoObject.IntraPredBuff.quant) return MP4_STATUS_NO_MEM;
pInfo->VisualObject.VideoObject.IntraPredBuff.block = (mp4_IntraPredBlock*)ippsMalloc_8u((mbPerRow + 1)*6*sizeof(mp4_IntraPredBlock));
if (!pInfo->VisualObject.VideoObject.IntraPredBuff.block) return MP4_STATUS_NO_MEM;
{
mp4_IntraPredBlock *mbCurr = pInfo->VisualObject.VideoObject.IntraPredBuff.block;
mp4_IntraPredBlock *mbA = mbCurr, *mbB = pInfo->VisualObject.VideoObject.IntraPredBuff.dcB, *mbC = mbCurr + 6;
Ipp32s j;
for (j = 0; j < mbPerRow; j ++) {
mbCurr[0].predA = &mbA[1]; mbCurr[0].predB = &mbB[3]; mbCurr[0].predC = &mbC[2];
mbCurr[1].predA = &mbC[0]; mbCurr[1].predB = &mbC[2]; mbCurr[1].predC = &mbC[3];
mbCurr[2].predA = &mbA[3]; mbCurr[2].predB = &mbA[1]; mbCurr[2].predC = &mbC[0];
mbCurr[3].predA = &mbC[2]; mbCurr[3].predB = &mbC[0]; mbCurr[3].predC = &mbC[1];
mbCurr[4].predA = &mbA[4]; mbCurr[4].predB = &mbB[4]; mbCurr[4].predC = &mbC[4];
mbCurr[5].predA = &mbA[5]; mbCurr[5].predB = &mbB[5]; mbCurr[5].predC = &mbC[5];
mbCurr += 6; mbA += 6; mbC += 6;
}
}
if (pInfo->VisualObject.VideoObject.data_partitioned) {
// DataPart info
pInfo->VisualObject.VideoObject.DataPartBuff = (mp4_DataPartMacroBlock*)ippsMalloc_8u(mbPerRow*mbPerCol*sizeof(mp4_DataPartMacroBlock));
if (!pInfo->VisualObject.VideoObject.DataPartBuff) return MP4_STATUS_NO_MEM;
}
if (pInfo->VisualObject.VideoObject.interlaced) {
// Field MV for B-VOP
pInfo->VisualObject.VideoObject.FieldMV = (IppMotionVector*)ippsMalloc_8u(mbPerRow*mbPerCol*sizeof(IppMotionVector)*2);
if (!pInfo->VisualObject.VideoObject.FieldMV) return MP4_STATUS_NO_MEM;
}
ippiQuantInvIntraGetSize_MPEG4(&specSize);
pInfo->VisualObject.VideoObject.QuantInvIntraSpec = (IppiQuantInvIntraSpec_MPEG4*)ippsMalloc_8u(specSize);
ippiQuantInvIntraInit_MPEG4(pInfo->VisualObject.VideoObject.quant_type ? pInfo->VisualObject.VideoObject.intra_quant_mat : NULL, pInfo->VisualObject.VideoObject.QuantInvIntraSpec, 8);
ippiQuantInvInterGetSize_MPEG4(&specSize);
pInfo->VisualObject.VideoObject.QuantInvInterSpec = (IppiQuantInvInterSpec_MPEG4*)ippsMalloc_8u(specSize);
ippiQuantInvInterInit_MPEG4(pInfo->VisualObject.VideoObject.quant_type ? pInfo->VisualObject.VideoObject.nonintra_quant_mat : NULL, pInfo->VisualObject.VideoObject.QuantInvInterSpec, 8);
ippiWarpGetSize_MPEG4(&specSize);
pInfo->VisualObject.VideoObject.WarpSpec = (IppiWarpSpec_MPEG4*)ippsMalloc_8u(specSize);
}
}
return MP4_STATUS_OK;
}
/*
// Free memory allocated for mp4_Info
*/
mp4_Status mp4_FreeVOL(mp4_Info* pInfo)
{
if (pInfo->VisualObject.VideoObject.shape == MP4_SHAPE_TYPE_RECTANGULAR) {
// ippsFree(pInfo->VisualObject.cFrame.apY); pInfo->VisualObject.cFrame.apY = pInfo->VisualObject.cFrame.pY = NULL;
// ippsFree(pInfo->VisualObject.cFrame.apCb); pInfo->VisualObject.cFrame.apCb = pInfo->VisualObject.cFrame.pCb = NULL;
// ippsFree(pInfo->VisualObject.cFrame.apCr); pInfo->VisualObject.cFrame.apCr = pInfo->VisualObject.cFrame.pCr = NULL;
if (pInfo->VisualObject.VideoObject.sprite_enable != MP4_SPRITE_STATIC) {
// if (!pInfo->noPVOPs) {
// ippsFree(pInfo->VisualObject.rFrame.apY); pInfo->VisualObject.rFrame.apY = pInfo->VisualObject.rFrame.pY = NULL;
// ippsFree(pInfo->VisualObject.rFrame.apCb); pInfo->VisualObject.rFrame.apCb = pInfo->VisualObject.rFrame.pCb = NULL;
// ippsFree(pInfo->VisualObject.rFrame.apCr); pInfo->VisualObject.rFrame.apCr = pInfo->VisualObject.rFrame.pCr = NULL;
// }
// if (!pInfo->noBVOPs) {
// ippsFree(pInfo->VisualObject.nFrame.apY); pInfo->VisualObject.nFrame.apY = pInfo->VisualObject.nFrame.pY = NULL;
// ippsFree(pInfo->VisualObject.nFrame.apCb); pInfo->VisualObject.nFrame.apCb = pInfo->VisualObject.nFrame.pCb = NULL;
// ippsFree(pInfo->VisualObject.nFrame.apCr); pInfo->VisualObject.nFrame.apCr = pInfo->VisualObject.nFrame.pCr = NULL;
// }
ippsFree(pInfo->VisualObject.VideoObject.MBinfo); pInfo->VisualObject.VideoObject.MBinfo = NULL;
#ifdef USE_NOTCODED_STATE
ippsFree(pInfo->VisualObject.VideoObject.ncState);
#endif
} else {
// ippsFree(pInfo->VisualObject.sFrame.apY); pInfo->VisualObject.sFrame.apY = pInfo->VisualObject.sFrame.pY = NULL;
// ippsFree(pInfo->VisualObject.sFrame.apCb); pInfo->VisualObject.sFrame.apCb = pInfo->VisualObject.sFrame.pCb = NULL;
// ippsFree(pInfo->VisualObject.sFrame.apCr); pInfo->VisualObject.sFrame.apCr = pInfo->VisualObject.sFrame.pCr = NULL;
}
if (!pInfo->VisualObject.VideoObject.short_video_header) {
ippsFree(pInfo->VisualObject.VideoObject.IntraPredBuff.quant); pInfo->VisualObject.VideoObject.IntraPredBuff.quant = NULL;
ippsFree(pInfo->VisualObject.VideoObject.IntraPredBuff.block); pInfo->VisualObject.VideoObject.IntraPredBuff.block = NULL;
if (pInfo->VisualObject.VideoObject.data_partitioned) {
ippsFree(pInfo->VisualObject.VideoObject.DataPartBuff); pInfo->VisualObject.VideoObject.DataPartBuff = NULL;
}
if (pInfo->VisualObject.VideoObject.interlaced) {
ippsFree(pInfo->VisualObject.VideoObject.FieldMV); pInfo->VisualObject.VideoObject.FieldMV = NULL;
}
ippsFree(pInfo->VisualObject.VideoObject.QuantInvIntraSpec); pInfo->VisualObject.VideoObject.QuantInvIntraSpec = NULL;
ippsFree(pInfo->VisualObject.VideoObject.QuantInvInterSpec); pInfo->VisualObject.VideoObject.QuantInvInterSpec = NULL;
ippsFree(pInfo->VisualObject.VideoObject.WarpSpec); pInfo->VisualObject.VideoObject.WarpSpec = NULL;
}
#ifdef _OMP_KARABAS
ippsFree(pInfo->pMBinfoMT); pInfo->pMBinfoMT = NULL;
#endif // _OMP_KARABAS
} /* //f else {
// free current
mp4_FreeVOPShape(pInfo);
mp4_SWAP(mp4_Frame, pInfo->VisualObject.rFrame, pInfo->VisualObject.cFrame);
// free ref
mp4_FreeVOPShape(pInfo);
mp4_SWAP(mp4_Frame, pInfo->VisualObject.nFrame, pInfo->VisualObject.cFrame);
// free future
mp4_FreeVOPShape(pInfo);
if (pInfo->VisualObject.VideoObject.sprite_enable == MP4_SPRITE_STATIC) {
// free sprite
mp4_SWAP(mp4_Frame, pInfo->VisualObject.sFrame, pInfo->VisualObject.cFrame);
mp4_FreeVOPShape(pInfo);
}
} */
return MP4_STATUS_OK;
}
mp4_Status mp4_DecodeMVD(mp4_Info *pInfo, Ipp32s *mvdx, Ipp32s *mvdy, Ipp32s fcode)
{
const mp4_VLC1 *pTab;
Ipp32s mvd, sign;
Ipp32u code;
Ipp32s factor = fcode - 1;
/* decode MVDx */
code = mp4_ShowBits(pInfo, 12);
if (code >= 128)
pTab = mp4_MVD_B12_2 + ((code - 128) >> 5);
else if (code >= 2)
pTab = mp4_MVD_B12_1 + (code - 2);
else {
mp4_Error("Error: decoding MVD");
return MP4_STATUS_ERROR;
}
mvd = pTab->code;
mp4_FlushBits(pInfo, pTab->len);
if (mvd) {
sign = mp4_GetBit(pInfo);
if (factor) {
code = mp4_GetBits9(pInfo, factor);
mvd = ((mvd - 1) << factor) + code + 1;
}
if (sign)
mvd = -mvd;
}
*mvdx = mvd;
/* decode MVDy */
code = mp4_ShowBits(pInfo, 12);
if (code >= 128)
pTab = mp4_MVD_B12_2 + ((code - 128) >> 5);
else if (code >= 2)
pTab = mp4_MVD_B12_1 + (code - 2);
else {
mp4_Error("Error: decoding MVD");
return MP4_STATUS_ERROR;
}
mvd = pTab->code;
mp4_FlushBits(pInfo, pTab->len);
if (mvd) {
sign = mp4_GetBit(pInfo);
if (factor) {
code = mp4_GetBits9(pInfo, factor);
mvd = ((mvd - 1) << factor) + code + 1;
}
if (sign)
mvd = -mvd;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -