📄 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 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, int frGOB, int y, int x, int adv){ IppMotionVector *mvLeft, *mvTop, *mvRight, *mvCurr; h263_Status status; h263_VideoPicture *VPic = &pInfo->VideoSequence.VideoPicture; int mbInRow = VPic->MacroBlockPerRow; int 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 { int 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, int *mvdx, int *mvdy, int fcode){ const h263_VLC1 *pTab; int mvd, sign; Ipp32u code; int 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, int leftlim, int rightlim){ int 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, int *mvdx, int *mvdy){ int 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, int pat, int quant, int quant_c, Ipp8u *pR[], int stepR[]){ __ALIGN16(Ipp16s, coeff, 64); int blockNum, pm = 32, lnz; int 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, int x, int pat, int quant, int quant_c, int scan, Ipp8u *pR[], int stepR[]){ __ALIGN16(Ipp16s, coeff, 64); int blockNum, pm = 32, lnz, dc, ac, k, nz; Ipp16s *predC, *predA; h263_IntraPredBlock *bCurr; int 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, int quant, int quant_c, int pat){ int i, lnz, pm = 32; Ipp16s *coeff = coeffMB; int modQ = pInfo->VideoSequence.VideoPicture.oppmodes.modQuant; int 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)) ippiDCT8x8Inv_2x2_16s_C1I(coeff); else if ((lnz <= 13) && (coeff[32] == 0)) ippiDCT8x8Inv_4x4_16s_C1I(coeff); else ippiDCT8x8Inv_16s_C1I(coeff); } else { h263_Set64_16s((Ipp16s)((coeff[0] + 4) >> 3), coeff); } h263_StatisticInc_(&pInfo->VideoSequence.Statistic.nB_INTER_C); } else { h263_StatisticInc_(&pInfo->VideoSequence.Statistic.nB_INTER_NC); } pm >>= 1; coeff += 64; } return H263_STATUS_OK;}h263_Status h263_BidirPredMacroblock(Ipp8u *pYr, int stepYr, Ipp8u *pCbr, Ipp8u* pCrr, int stepCr, Ipp8u *pYc, int stepYc, Ipp8u *pCbc, Ipp8u* pCrc, int stepCc, Ipp8u *predMB, IppMotionVector *mvForw, IppMotionVector *mvFCbCr, IppMotionVector *mvBack, IppMotionVector *mvBCbCr, int fourMVmode){ int mvx0, mvx1, mvy0, mvy1, xL0, w0, xL, xR, yT, yB; IppiSize roiSize; Ipp8u *pCur; if (!fourMVmode) h263_Copy16x16HP_8u(pYr, stepYr, predMB, 16, &mvForw[0], 0); else { h263_Copy8x8HP_8u(pYr, stepYr, predMB, 16, &mvForw[0], 0); h263_Copy8x8HP_8u(pYr + 8, stepYr, predMB + 8, 16, &mvForw[1], 0); h263_Copy8x8HP_8u(pYr + 8*stepYr, stepYr, predMB + 8*16, 16, &mvForw[2], 0); h263_Copy8x8HP_8u(pYr + 8 + 8*stepYr, stepYr, predMB + 8 + 8*16, 16, &mvForw[3], 0); } h263_Copy8x8HP_8u(pCbr, stepCr, predMB + 4*64, 8, mvFCbCr, 0); h263_Copy8x8HP_8u(pCrr, stepCr, predMB + 5*64, 8, mvFCbCr, 0); pCur = pYc + H263_MV_OFF_HP(mvBack[0].dx, mvBack[0].dy, stepYc); pCbc += H263_MV_OFF_HP(mvBCbCr->dx, mvBCbCr->dy, stepCc); pCrc += H263_MV_OFF_HP(mvBCbCr->dx, mvBCbCr->dy, stepCc); mvx0 = (-mvBack[0].dx + 1) >> 1; mvx1 = 16 - ((mvBack[0].dx + 1) >> 1); mvy0 = (-mvBack[0].dy + 1) >> 1; mvy1 = 16 - ((mvBack[0].dy + 1) >> 1); xL = H263_MAX(mvx0, 0); xR = H263_MIN(mvx1, 8); roiSize.width = xR - xL; yT = H263_MAX(mvy0, 0); yB = H263_MIN(mvy1, 8); roiSize.height = yB - yT; h263_AddBackPredPB_8u(pCur + xL + yT*stepYc, stepYc, roiSize, predMB + xL + yT*16, 16, &mvBack[0]); if (!fourMVmode) { xL0 = xL; w0 = roiSize.width; xL = H263_MAX(mvx0 - 8, 0); xR = H263_MIN(mvx1 - 8, 8); roiSize.width = xR - xL; h263_AddBackPredPB_8u(pCur + 8 + xL + yT*stepYc, stepYc, roiSize, predMB + 8 + xL + yT*16, 16, &mvBack[0]); roiSize.width = w0; yT = H263_MAX(mvy0 - 8, 0); yB = H263_MIN(mvy1 - 8, 8); roiSize.height = yB - yT; h263_AddBackPredPB_8u(pCur + 8*stepYc + xL0 + yT*stepYc, stepYc, roiSize, predMB + 8*16 + xL0 + yT*16, 16, &mvBack[0]); roiSize.width = xR - xL; h263_AddBackPredPB_8u(pCur + 8*stepYc + 8 + xL + yT*stepYc, stepYc, roiSize, predMB + 8 + 8*16 + xL + yT*16, 16, &mvBack[0]); } else { int i; for (i = 1; i < 4; i++) { mvx0 = ((-mvBack[i].dx + 1) >> 1) - (i & 1)*8; mvx1 = 16 - ((mvBack[i].dx + 1) >> 1) - (i & 1)*8; mvy0 = ((-mvBack[i].dy + 1) >> 1) - (i & 2)*4; mvy1 = 16 - ((mvBack[i].dy + 1) >> 1) - (i & 2)*4; xL = H263_MAX(mvx0, 0); xR = H263_MIN(mvx1, 8); roiSize.width = xR - xL; yT = H263_MAX(mvy0, 0); yB = H263_MIN(mvy1, 8); roiSize.height = yB - yT; pCur = pYc + H263_MV_OFF_HP(mvBack[i].dx, mvBack[i].dy, stepYc) + (i & 1)*8 + (i & 2)*4*stepYc + xL + yT*stepYc; h263_AddBackPredPB_8u(pCur, stepYc, roiSize, predMB + (i & 1)*8 + (i & 2)*4*16 + xL + yT*16, 16, &mvBack[i]); } } mvx0 = (-mvBCbCr->dx + 1) >> 1; mvx1 = 8 - ((mvBCbCr->dx + 1) >> 1); mvy0 = (-mvBCbCr->dy + 1) >> 1; mvy1 = 8 - ((mvBCbCr->dy + 1) >> 1); xL = H263_MAX(mvx0, 0); xR = H263_MIN(mvx1, 8); yT = H263_MAX(mvy0, 0); yB = H263_MIN(mvy1, 8); roiSize.width = xR - xL; roiSize.height = yB - yT; h263_AddBackPredPB_8u(pCbc + xL + yT*stepCc, stepCc, roiSize, predMB + 4*64 + xL + yT*8, 8, mvBCbCr); h263_AddBackPredPB_8u(pCrc + xL + yT*stepCc, stepCc, roiSize, predMB + 5*64 + xL + yT*8, 8, mvBCbCr); return H263_STATUS_OK;}/*// decode mcbpc and set MBtype and ChromaPattern*/h263_Status h263_DecodeMCBPC_P(h263_Info* pInfo, int *mbType, int *mbPattern, int stat){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -