📄 h263decfuncs.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-2006 Intel Corporation. All Rights Reserved.
//
// Description: H.263 decoder functions
//
*/
#include "h263.h"
#include "h263dec.h"
h263_Status h263_PredictDecodeMV(h263_Info *pInfo, h263_MacroBlock *MBcurr, Ipp32s frGOB, Ipp32s y, Ipp32s x, Ipp32s adv)
{
IppMotionVector *mvLeft, *mvTop, *mvRight, *mvCurr;
h263_Status status;
h263_VideoPicture *VPic = &pInfo->VideoSequence.VideoPicture;
Ipp32s mbInRow = VPic->MacroBlockPerRow;
Ipp32s i1, i2;
if (adv) {
i1 = 1;
i2 = 2;
} else {
i1 = i2 = 0;
}
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 = h263_Median(0, mvTop[i2].dx, mvRight[i2].dx);
mvCurr->dy = h263_Median(0, mvTop[i2].dy, mvRight[i2].dy);
} else if (y == frGOB) {
MBcurr->mv[0] = mvLeft[i1];
} else if (x == mbInRow - 1) {
mvCurr->dx = h263_Median(0, mvLeft[i1].dx, mvTop[i2].dx);
mvCurr->dy = h263_Median(0, mvLeft[i1].dy, mvTop[i2].dy);
} else {
mvCurr->dx = h263_Median(mvLeft[i1].dx, mvTop[i2].dx, mvRight[i2].dx);
mvCurr->dy = h263_Median(mvLeft[i1].dy, mvTop[i2].dy, mvRight[i2].dy);
}
if (!VPic->oppmodes.UMV && !VPic->modes.UMV) {
status = h263_DecodeMV(pInfo, mvCurr, -32, 31);
} else if (!VPic->oppmodes.UMV) {
status = h263_DecodeMV(pInfo, mvCurr, -63, 63);
} else {
Ipp32s mvdx, mvdy;
status = h263_DecodeMVD_umvplus(pInfo, &mvdx, &mvdy);
mvCurr->dx = mvCurr->dx + (Ipp16s)mvdx;
mvCurr->dy = mvCurr->dy + (Ipp16s)mvdy;
}
return status;
}
h263_Status h263_DecodeMVD(h263_Info *pInfo, Ipp32s *mvdx, Ipp32s *mvdy, Ipp32s fcode)
{
const h263_VLC1 *pTab;
Ipp32s mvd, sign;
Ipp32u code;
Ipp32s factor = fcode - 1;
/* decode MVDx */
code = h263_ShowBits(pInfo, 12);
if (code >= 128)
pTab = h263_MVD_T14_2 + ((code - 128) >> 5);
else if (code >= 2)
pTab = h263_MVD_T14_1 + (code - 2);
else
return H263_STATUS_ERROR;
mvd = pTab->code;
h263_FlushBits(pInfo, pTab->len);
if (mvd) {
sign = h263_GetBit(pInfo);
if (factor) {
code = h263_GetBits9(pInfo, factor);
mvd = ((mvd - 1) << factor) + code + 1;
}
if (sign)
mvd = -mvd;
}
*mvdx = mvd;
/* decode MVDy */
code = h263_ShowBits(pInfo, 12);
if (code >= 128)
pTab = h263_MVD_T14_2 + ((code - 128) >> 5);
else if (code >= 2)
pTab = h263_MVD_T14_1 + (code - 2);
else
return H263_STATUS_ERROR;
mvd = pTab->code;
h263_FlushBits(pInfo, pTab->len);
if (mvd) {
sign = h263_GetBit(pInfo);
if (factor) {
code = h263_GetBits9(pInfo, factor);
mvd = ((mvd - 1) << factor) + code + 1;
}
if (sign)
mvd = -mvd;
}
*mvdy = mvd;
return H263_STATUS_OK;
}
h263_Status h263_DecodeMV(h263_Info *pInfo, IppMotionVector *mv, Ipp32s leftlim, Ipp32s rightlim)
{
Ipp32s mvdx, mvdy, dx, dy;
if (h263_DecodeMVD(pInfo, &mvdx, &mvdy, 1) != H263_STATUS_OK)
return H263_STATUS_ERROR;
dx = mv->dx + mvdx;
if (dx < leftlim)
dx += 64;
else if (dx > rightlim)
dx -= 64;
mv->dx = (Ipp16s)dx;
dy = mv->dy + mvdy;
if (dy < leftlim)
dy += 64;
else if (dy > rightlim)
dy -= 64;
mv->dy = (Ipp16s)dy;
return H263_STATUS_OK;
}
h263_Status h263_DecodeMVD_umvplus(h263_Info *pInfo, Ipp32s *mvdx, Ipp32s *mvdy)
{
Ipp32s mvx, mvy;
Ipp32u code;
code = h263_GetBit(pInfo);
if (code)
mvx = 0;
else {
mvx = 1;
for (;;) {
code = h263_GetBits9(pInfo, 2);
if ((code & 1) == 0)
break;
mvx = (mvx << 1) | (code >> 1);
}
if (code & 2)
mvx = -mvx;
}
code = h263_GetBit(pInfo);
if (code)
mvy = 0;
else {
mvy = 1;
for (;;) {
code = h263_GetBits9(pInfo, 2);
if ((code & 1) == 0)
break;
mvy = (mvy << 1) | (code >> 1);
}
if (code & 2)
mvy = -mvy;
}
if (mvx == 1 && mvy == 1)
code = h263_GetBit(pInfo);
#ifdef H263_METICULOUS
if (!code) {
h263_Error("Error: Zero anti-emulation bit");
return H263_STATUS_PARSE_ERROR;
}
#endif
*mvdx = mvx;
*mvdy = mvy;
return H263_STATUS_OK;
}
/*
// Intra DC and AC reconstruction for macroblock
*/
h263_Status h263_DecodeMacroBlockIntra(h263_Info *pInfo, Ipp32s pat, Ipp32s quant, Ipp32s quant_c, Ipp8u *pR[], Ipp32s stepR[])
{
__ALIGN16(Ipp16s, coeff, 64);
Ipp32s blockNum, pm = 32, lnz;
Ipp32s modQ = pInfo->VideoSequence.VideoPicture.oppmodes.modQuant;
for (blockNum = 0; blockNum < 6; blockNum++) {
if (blockNum > 3)
quant = quant_c;
if (ippiReconstructCoeffsIntra_H263_1u16s(&pInfo->bufptr, &pInfo->bitoff, coeff, &lnz, pat & pm, quant, 0, IPPVC_SCAN_ZIGZAG, modQ) != ippStsNoErr) {
return H263_STATUS_ERROR;
}
if (lnz > 0) {
ippiDCT8x8Inv_16s8u_C1R(coeff, pR[blockNum], stepR[blockNum]);
h263_StatisticInc_(&pInfo->VideoSequence.Statistic.nB_INTRA_AC);
} else {
h263_Set8x8_8u(pR[blockNum], stepR[blockNum], (Ipp8u)((coeff[0] + 4) >> 3));
h263_StatisticInc_(&pInfo->VideoSequence.Statistic.nB_INTRA_DC);
}
pm >>= 1;
}
return H263_STATUS_OK;
}
h263_Status h263_DecodeMacroBlockIntra_AdvI(h263_Info *pInfo, Ipp32s x, Ipp32s pat, Ipp32s quant, Ipp32s quant_c, Ipp32s scan, Ipp8u *pR[], Ipp32s stepR[])
{
__ALIGN16(Ipp16s, coeff, 64);
Ipp32s blockNum, pm = 32, lnz, dc, ac, k, nz;
Ipp16s *predC, *predA;
h263_IntraPredBlock *bCurr;
Ipp32s modQ = pInfo->VideoSequence.VideoPicture.oppmodes.modQuant;
for (blockNum = 0; blockNum < 6; blockNum ++) {
bCurr = &pInfo->VideoSequence.IntraPredBuff.block[6*x+blockNum];
if (blockNum > 3)
quant = quant_c;
if (pat & pm) {
if (ippiReconstructCoeffsIntra_H263_1u16s(&pInfo->bufptr, &pInfo->bitoff, coeff, &lnz, pat & pm, quant, 1, scan, modQ) != ippStsNoErr)
return H263_STATUS_ERROR;
if (lnz) {
h263_StatisticInc_(&pInfo->VideoSequence.Statistic.nB_INTRA_AC);
} else {
h263_StatisticInc_(&pInfo->VideoSequence.Statistic.nB_INTRA_DC);
}
} else {
if (scan != IPPVC_SCAN_ZIGZAG) {
h263_Zero64_16s(coeff);
} else
coeff[0] = 0;
lnz = 0;
}
nz = 0;
if (scan == IPPVC_SCAN_ZIGZAG) {
if (bCurr->predA->dct_dc >= 0) {
dc = bCurr->predA->dct_dc;
dc = bCurr->predC->dct_dc >= 0 ? ((dc + bCurr->predC->dct_dc) >> 1) : dc;
} else
dc = bCurr->predC->dct_dc >= 0 ? bCurr->predC->dct_dc : 1024;
if (lnz && ((quant > 8) || modQ)) { /* ??? */
for (k = 1; k < 64; k ++) {
h263_CLIP(coeff[k], -2048, 2047);
}
}
} else if (scan == IPPVC_SCAN_HORIZONTAL) {
if (bCurr->predC->dct_dc >= 0) {
dc = bCurr->predC->dct_dc;
predC = bCurr->predC->dct_acC;
for (k = 1; k < 8; k ++) {
ac = coeff[k] + predC[k];
h263_CLIP(ac, -2048, 2047); /* ??? */
coeff[k] = (Ipp16s)ac;
if (ac)
nz = 1;
}
if ((lnz > 7) && ((quant > 8) || modQ)) { /* ??? */
for (k = 8; k < 64; k ++) {
h263_CLIP(coeff[k], -2048, 2047);
}
}
} else {
dc = 1024;
if (lnz && ((quant > 8) || modQ)) { /* ??? */
for (k = 1; k < 64; k ++) {
h263_CLIP(coeff[k], -2048, 2047);
}
}
}
} else { /* scan == IPPVC_SCAN_VERTICAL */
if (bCurr->predA->dct_dc >= 0) {
dc = bCurr->predA->dct_dc;
predA = bCurr->predA->dct_acA;
for (k = 1; k < 8; k ++) {
ac = coeff[k*8] + predA[k];
h263_CLIP(ac, -2048, 2047); /* ??? */
coeff[k*8] = (Ipp16s)ac;
if (ac)
nz = 1;
}
} else
dc = 1024;
if (lnz && ((quant > 8) || modQ)) { /* ??? */
for (k = 1; k < 64; k ++) {
h263_CLIP(coeff[k], -2048, 2047);
}
}
}
dc += coeff[0];
dc |= 1; /* oddify */
h263_CLIP(dc, 0, 2047); /* ??? h263_CLIPR(dc, 2047); */
coeff[0] = (Ipp16s)dc;
if (lnz | nz) {
ippiDCT8x8Inv_16s8u_C1R(coeff, pR[blockNum], stepR[blockNum]);
/* copy predicted coeffs for future Prediction */
for (k = 1; k < 8; k ++) {
bCurr[6].dct_acC[k] = coeff[k];
bCurr[6].dct_acA[k] = coeff[k*8];
}
} else {
k = (coeff[0] + 4) >> 3;
h263_CLIPR(k, 255);
h263_Set8x8_8u(pR[blockNum], stepR[blockNum], (Ipp8u)k);
for (k = 1; k < 8; k ++) {
bCurr[6].dct_acC[k] = bCurr[6].dct_acA[k] = 0;
}
}
bCurr[6].dct_dc = coeff[0];
pm >>= 1;
}
return H263_STATUS_OK;
}
h263_Status h263_DecodeMacroBlockInter(h263_Info *pInfo, Ipp16s *coeffMB, Ipp32s quant, Ipp32s quant_c, Ipp32s pat)
{
Ipp32s i, lnz, pm = 32;
Ipp16s *coeff = coeffMB;
Ipp32s modQ = pInfo->VideoSequence.VideoPicture.oppmodes.modQuant;
Ipp32s altInterVLC = pInfo->VideoSequence.VideoPicture.oppmodes.altInterVLC;
for (i = 0; i < 6; i ++) {
if (i > 3)
quant = quant_c;
if ((pat) & pm) {
if (!altInterVLC) {
if (ippiReconstructCoeffsInter_H263_1u16s(&pInfo->bufptr, &pInfo->bitoff, coeff, &lnz, quant, modQ) != ippStsNoErr)
return H263_STATUS_ERROR;
} else {
__ALIGN16(Ipp16s, coeffZ, 64);
if (ippiDecodeCoeffsInter_H263_1u16s(&pInfo->bufptr, &pInfo->bitoff, coeffZ, &lnz, modQ, IPPVC_SCAN_NONE) != ippStsNoErr)
if (ippiDecodeCoeffsIntra_H263_1u16s(&pInfo->bufptr, &pInfo->bitoff, coeffZ, &lnz, 1, modQ, IPPVC_SCAN_NONE) != ippStsNoErr)
return H263_STATUS_ERROR;
ippiQuantInvInter_H263_16s_C1I(coeffZ, lnz, quant, modQ);
ippiScanInv_16s_C1(coeffZ, coeff, lnz, IPPVC_SCAN_ZIGZAG);
}
if (lnz != 0) {
if ((lnz <= 4) && (coeff[16] == 0))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -