📄 h263decframe.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) 2005-2007 Intel Corporation. All Rights Reserved.
//
// Description: Decodes H.263+ frame.
//
*/
#include "h263.h"
#include "h263dec.h"
#pragma warning(disable : 188) // enumerated type mixed with another type ICL
static h263_Status h263_SpatialInterpolateFrame(h263_Frame *srcFrame, h263_Frame *dstFrame, Ipp32s scal_type)
{
IppiSize srcRoiSize;
Ipp32s interp_type;
switch (scal_type) {
case H263_SCALABILITY_SPATIAL_X:
interp_type = IPPVC_INTERP_HORIZONTAL;
break;
case H263_SCALABILITY_SPATIAL_Y:
interp_type = IPPVC_INTERP_VERTICAL;
break;
default:
interp_type = IPPVC_INTERP_2D;
}
srcRoiSize.height = srcFrame->mbPerCol * 16;
srcRoiSize.width = srcFrame->mbPerRow * 16;
if (ippiSpatialInterpolation_H263_8u_C1R(srcFrame->pY, srcFrame->stepY, srcRoiSize, dstFrame->pY, dstFrame->stepY, interp_type) != ippStsNoErr)
return H263_STATUS_ERROR;
srcRoiSize.height = srcFrame->mbPerCol * 8;
srcRoiSize.width = srcFrame->mbPerRow * 8;
if (ippiSpatialInterpolation_H263_8u_C1R(srcFrame->pCb, srcFrame->stepCb, srcRoiSize, dstFrame->pCb, dstFrame->stepCb, interp_type) != ippStsNoErr)
return H263_STATUS_ERROR;
if (ippiSpatialInterpolation_H263_8u_C1R(srcFrame->pCr, srcFrame->stepCr, srcRoiSize, dstFrame->pCr, dstFrame->stepCr, interp_type) != ippStsNoErr)
return H263_STATUS_ERROR;
return H263_STATUS_OK;
}
/*
// h263_Info for decoding of Video Sequence
*/
h263_Status h263_InitVSeq(h263_Info* pInfo, Ipp32s mbPerRow, Ipp32s mbPerCol)
{
h263_VideoPicture *VPic = &pInfo->VideoSequence.VideoPicture;
pInfo->VideoSequence.picture_time_increment_resolution = H263_PIC_TIME_INCR_RESOLUTION;
pInfo->VideoSequence.PicIndex = 0;
if (mbPerRow <= 0)
mbPerRow = pInfo->VideoSequence.VideoPicture.MacroBlockPerRow;
if (mbPerCol <= 0)
mbPerCol = pInfo->VideoSequence.VideoPicture.MacroBlockPerCol;
pInfo->VideoSequence.cFrame.mbPerRow = pInfo->VideoSequence.rFrame.mbPerRow = pInfo->VideoSequence.nFrame.mbPerRow = pInfo->VideoSequence.bFrame.mbPerRow = mbPerRow;
pInfo->VideoSequence.cFrame.mbPerCol = pInfo->VideoSequence.rFrame.mbPerCol = pInfo->VideoSequence.nFrame.mbPerCol = pInfo->VideoSequence.bFrame.mbPerCol = mbPerCol;
pInfo->VideoSequence.cFrame.width = pInfo->VideoSequence.rFrame.width = pInfo->VideoSequence.nFrame.width = pInfo->VideoSequence.bFrame.width = VPic->width;
pInfo->VideoSequence.cFrame.height = pInfo->VideoSequence.rFrame.height = pInfo->VideoSequence.nFrame.height = pInfo->VideoSequence.bFrame.height = VPic->height;
pInfo->VideoSequence.num_of_MBs = mbPerRow * mbPerCol;
#ifdef _OMP_KARABAS
if (pInfo->number_threads < 1 || pInfo->number_threads > h263_GetNumOfThreads())
pInfo->number_threads = h263_GetNumOfThreads();
pInfo->pMBinfoMT = (h263_MacroBlockMT*)ippsMalloc_8u(mbPerRow * pInfo->number_threads * sizeof(h263_MacroBlockMT));
if(!pInfo->pMBinfoMT) return H263_STATUS_NO_MEM;
#endif // _OMP_KARABAS
/* motion info */
pInfo->VideoSequence.MBinfo = (h263_MacroBlock*)ippsMalloc_8u(mbPerRow*mbPerCol*sizeof(h263_MacroBlock));
if (!pInfo->VideoSequence.MBinfo) return H263_STATUS_NO_MEM;
/* motion info for B-frames */
pInfo->VideoSequence.Bmv = (IppMotionVector*)ippsMalloc_8u(2*mbPerRow*sizeof(IppMotionVector));
if (!pInfo->VideoSequence.Bmv) return H263_STATUS_NO_MEM;
/* Advanced Intra Prediction info */
pInfo->VideoSequence.IntraPredBuff.block = (h263_IntraPredBlock*)ippsMalloc_8u((mbPerRow + 1)*6*sizeof(h263_IntraPredBlock));
if (!pInfo->VideoSequence.IntraPredBuff.block)
return H263_STATUS_NO_MEM;
{
h263_IntraPredBlock *mbCurr = pInfo->VideoSequence.IntraPredBuff.block;
h263_IntraPredBlock *mbA = mbCurr, *mbC = mbCurr + 6;
Ipp32s j;
for (j = 0; j < mbPerRow; j ++) {
mbCurr[0].predA = &mbA[1]; mbCurr[0].predC = &mbC[2];
mbCurr[1].predA = &mbC[0]; mbCurr[1].predC = &mbC[3];
mbCurr[2].predA = &mbA[3]; mbCurr[2].predC = &mbC[0];
mbCurr[3].predA = &mbC[2]; mbCurr[3].predC = &mbC[1];
mbCurr[4].predA = &mbA[4]; mbCurr[4].predC = &mbC[4];
mbCurr[5].predA = &mbA[5]; mbCurr[5].predC = &mbC[5];
mbCurr += 6; mbA += 6; mbC += 6;
}
}
/*
if (pInfo->VideoSequence.data_partitioned) {
pInfo->VideoSequence.DataPartBuff = (h263_DataPartMacroBlock*)ippsMalloc_8u(mbPerRow*mbPerCol*sizeof(h263_DataPartMacroBlock));
if (!pInfo->VideoSequence.DataPartBuff) return H263_STATUS_NO_MEM;
}
*/
return H263_STATUS_OK;
}
/*
// Free memory allocated for h263_Info
*/
h263_Status h263_FreeVSeq(h263_Info* pInfo)
{
pInfo->VideoSequence.PicIndex = 0;
#ifdef _OMP_KARABAS
ippsFree(pInfo->pMBinfoMT); pInfo->pMBinfoMT = NULL;
#endif
ippsFree(pInfo->VideoSequence.MBinfo); pInfo->VideoSequence.MBinfo = NULL;
ippsFree(pInfo->VideoSequence.IntraPredBuff.block); pInfo->VideoSequence.IntraPredBuff.block = NULL;
ippsFree(pInfo->VideoSequence.Bmv); pInfo->VideoSequence.Bmv = NULL;
/*
if (pInfo->VideoSequence.data_partitioned) {
ippsFree(pInfo->VideoSequence.DataPartBuff); pInfo->VideoSequence.DataPartBuff = NULL;
}
*/
return H263_STATUS_OK;
}
static void h263_ExpandFrameReplicate(Ipp8u *pSrcDstPlane, Ipp32s frameWidth, Ipp32s frameHeight, Ipp32s expandPels, Ipp32s step)
{
Ipp8u *pDst1, *pDst2, *pSrc1, *pSrc2;
Ipp32s i, j;
Ipp32u t1, t2;
pDst1 = pSrcDstPlane + step * expandPels;
pDst2 = pDst1 + frameWidth + expandPels;
if (expandPels == 8) {
for (i = 0; i < frameHeight; i ++) {
t1 = pDst1[8] + (pDst1[8] << 8);
t2 = pDst2[-1] + (pDst2[-1] << 8);
t1 = (t1 << 16) + t1;
t2 = (t2 << 16) + t2;
((Ipp32u*)pDst1)[0] = t1;
((Ipp32u*)pDst1)[1] = t1;
((Ipp32u*)pDst2)[0] = t2;
((Ipp32u*)pDst2)[1] = t2;
pDst1 += step;
pDst2 += step;
}
} else if (expandPels == 16) {
for (i = 0; i < frameHeight; i ++) {
t1 = pDst1[16] + (pDst1[16] << 8);
t2 = pDst2[-1] + (pDst2[-1] << 8);
t1 = (t1 << 16) + t1;
t2 = (t2 << 16) + t2;
((Ipp32u*)pDst1)[0] = t1;
((Ipp32u*)pDst1)[1] = t1;
((Ipp32u*)pDst1)[2] = t1;
((Ipp32u*)pDst1)[3] = t1;
((Ipp32u*)pDst2)[0] = t2;
((Ipp32u*)pDst2)[1] = t2;
((Ipp32u*)pDst2)[2] = t2;
((Ipp32u*)pDst2)[3] = t2;
pDst1 += step;
pDst2 += step;
}
} else {
for (i = 0; i < frameHeight; i ++) {
ippsSet_8u(pDst1[expandPels], pDst1, expandPels);
ippsSet_8u(pDst2[-1], pDst2, expandPels);
pDst1 += step;
pDst2 += step;
}
}
pDst1 = pSrcDstPlane;
pSrc1 = pSrcDstPlane + expandPels * step;
pDst2 = pSrc1 + frameHeight * step;
pSrc2 = pDst2 - step;
j = frameWidth + 2 * expandPels;
for (i = 0; i < expandPels; i ++) {
ippsCopy_8u(pSrc1, pDst1, j);
ippsCopy_8u(pSrc2, pDst2, j);
pDst1 += step;
pDst2 += step;
}
}
/*
// padding Picture: replication
*/
static void h263_PadFrame(h263_Frame *frame)
{
Ipp32s wL, hL, wC, hC;
wL = frame->mbPerRow * 16;
hL = frame->mbPerCol * 16;
wC = frame->mbPerRow * 8;
hC = frame->mbPerCol * 8;
h263_ExpandFrameReplicate(frame->apY, wL, hL, 16, frame->stepY);
h263_ExpandFrameReplicate(frame->apCb, wC, hC, 8, frame->stepCb);
h263_ExpandFrameReplicate(frame->apCr, wC, hC, 8, frame->stepCr);
}
#define H263_COMPARE_RESAMPLE_PARAMS(flag, VSeq, VPic) \
{ \
Ipp32s i; \
flag = 0; \
for (i = 0; i < 4; i++) { \
if ((VSeq)->warpParams[i].dx != (VPic)->warpParams[i].dx || (VSeq)->warpParams[i].dy != (VPic)->warpParams[i].dy) { \
flag = 1; \
break; \
} \
} \
if ((VSeq)->fillMode != (VPic)->fillMode) \
flag = 1; \
if ((VPic)->fillMode == 0) { \
for (i = 0; i < 3; i++) { \
if ((VSeq)->fillColor[i] != (VPic)->fillColor[i]) { \
flag = 1; \
break; \
} \
} \
} \
}
#define H263_UPDATE_RESAMPLE_PARAMS(VPic, VSeq) \
{ \
Ipp32s i; \
for (i = 0; i < 4; i++) { \
(VSeq)->warpParams[i].dx = (VPic)->warpParams[i].dx; \
(VSeq)->warpParams[i].dy = (VPic)->warpParams[i].dy; \
} \
(VSeq)->fillMode = (VPic)->fillMode; \
if ((VPic)->fillMode == 0) { \
for (i = 0; i < 3; i++) { \
(VSeq)->fillColor[i] = (VPic)->fillColor[i]; \
} \
} \
}
static void h263_PadResampledFrame(h263_Frame *frame, Ipp32s fillMode, Ipp32s fillColor[3])
{
Ipp32s i, j;
Ipp8u colorY, colorCb, colorCr;
Ipp8u *p0, *p1;
Ipp32s width, height;
Ipp32u tY;
Ipp16u tCb, tCr;
/* frame width and height are always divisible by 4 */
if (fillMode == 0) {
colorY = (Ipp8u)fillColor[0];
colorCb = (Ipp8u)fillColor[1];
colorCr = (Ipp8u)fillColor[2];
tY = (colorY << 8) | colorY;
tY = (tY << 16) | tY;
tCb = (colorCb << 8) | colorCb;
tCr = (colorCr << 8) | colorCr;
} else if (fillMode == 1) {
tY = 0x10101010; /* 16 */
tCb = tCr = 0x8080; /* 128 */
} else if (fillMode == 2) {
tY = 0x80808080;
tCb = tCr = 0x8080;
}
width = frame->width;
height = frame->height;
if (width & 15) {
for (i = 0; i < height; i++) {
p0 = frame->pY + width;
if (fillMode == 3) {
tY = (p0[-1] << 8) | p0[-1];
tY = (tY << 16) | tY;
}
for (j = 0; j < (16 - (width & 15)) >> 2; j++)
((Ipp32u *)p0)[j] = tY;
}
width >>= 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -