📄 h263decfuncs.c
字号:
Ipp32u code; int type, pattern; code = h263_ShowBits9(pInfo, 9); if (code >= 256) { type = IPPVC_MBTYPE_INTER; pattern = 0; h263_FlushBits(pInfo, 1); } else if (code) { type = h263_Pmb_type[code]; pattern = h263_Pmb_cbpc[code]; h263_FlushBits(pInfo, h263_Pmb_bits[code]); } else { h263_FlushBits(pInfo, 9); code = h263_ShowBits9(pInfo, 4); if (code < 8) { h263_Error("Error when decoding mcbpc of P-Frame macroblock"); return H263_STATUS_ERROR; } else if (code < 12) { pattern = 0; h263_FlushBits(pInfo, 2); } else { pattern = (code & 3) ? (code & 3) : 1; h263_FlushBits(pInfo, 4); } type = IPPVC_MBTYPE_INTER4V_Q; } *mbType = type; *mbPattern = pattern; if (stat) { if (type == IPPVC_MBTYPE_INTER) h263_StatisticInc_(&pInfo->VideoSequence.Statistic.nMB_INTER); else if (type == IPPVC_MBTYPE_INTER_Q) h263_StatisticInc_(&pInfo->VideoSequence.Statistic.nMB_INTER_Q); else if (type == IPPVC_MBTYPE_INTRA) h263_StatisticInc_(&pInfo->VideoSequence.Statistic.nMB_INTRA); else if (type == IPPVC_MBTYPE_INTRA_Q) h263_StatisticInc_(&pInfo->VideoSequence.Statistic.nMB_INTRA_Q); else if (type == IPPVC_MBTYPE_INTER4V) h263_StatisticInc_(&pInfo->VideoSequence.Statistic.nMB_INTER4V); else if (type == IPPVC_MBTYPE_INTER4V_Q) h263_StatisticInc_(&pInfo->VideoSequence.Statistic.nMB_INTER4V_Q); } return H263_STATUS_OK;}void h263_DecodeMODB_iPB(h263_Info* pInfo, int *bmb_type, int *cbpb, int *mvdb){ Ipp32u code; int fbits; code = h263_ShowBits9(pInfo, 5); if (code < 24) { *bmb_type = IPPVC_MBTYPE_INTERPOLATE; *cbpb = code >> 4; fbits = 1 + *cbpb; h263_StatisticInc_(&pInfo->VideoSequence.Statistic.nMB_INTERPOLATE_iPB); } else if (code < 30) { *bmb_type = IPPVC_MBTYPE_FORWARD; *mvdb = 1; *cbpb = (code >> 2) & 1; fbits = 3 + *cbpb; h263_StatisticInc_(&pInfo->VideoSequence.Statistic.nMB_FORWARD_iPB); } else { *bmb_type = IPPVC_MBTYPE_BACKWARD; *cbpb = code & 1; fbits = 5; h263_StatisticInc_(&pInfo->VideoSequence.Statistic.nMB_BACKWARD_iPB); } h263_FlushBits(pInfo, fbits);}/*// decode mcbpc and set MBtype and ChromaPattern for EI-frames*/h263_Status h263_DecodeMCBPC_EI(h263_Info* pInfo, int *mbType, int *mbPattern){ Ipp32u code; int len; h263_VLC1 vlc; code = h263_ShowBits9(pInfo, 8); if (code >= 32) { code >>= 5; *mbType = IPPVC_MBTYPE_INTER; /* IPPVC_MBTYPE_INTER(_Q) is used for UPWARD prediction */ *mbPattern = (code > 3) ? 0 : (code & 3); len = (code > 3) ? 1 : 3; } else if (code >= 16) { *mbType = IPPVC_MBTYPE_INTER_Q; *mbPattern = 0; len = 4; } else if (code != 0) { vlc = h263_EImb_type[code - 1]; *mbType = vlc.code; len = vlc.len & 15; *mbPattern = vlc.len >> 4; } else { h263_FlushBits(pInfo, 8); if (h263_GetBit(pInfo) == 1) { *mbType = IPPVC_MB_STUFFING; return H263_STATUS_OK; } else { h263_Error("Error when decoding mcbpc of EI-Frame macroblock"); return H263_STATUS_ERROR; } } h263_FlushBits(pInfo, len);#ifdef H263_FULL_STAT if (*mbType == IPPVC_MBTYPE_INTER) h263_StatisticInc_(&pInfo->VideoSequence.Statistic.nMB_UPWARD_EI); else if (*mbType == IPPVC_MBTYPE_INTER_Q) h263_StatisticInc_(&pInfo->VideoSequence.Statistic.nMB_UPWARD_Q_EI); else if (*mbType == IPPVC_MBTYPE_INTRA) h263_StatisticInc_(&pInfo->VideoSequence.Statistic.nMB_INTRA_EI); else if (*mbType == IPPVC_MBTYPE_INTRA_Q) h263_StatisticInc_(&pInfo->VideoSequence.Statistic.nMB_INTRA_Q_EI);#endif return H263_STATUS_OK;}/*// decode MBTYPE for B-frames*/h263_Status h263_DecodeMBTYPE_B(h263_Info* pInfo, int *mbType, int *cbp, int *dquant){ Ipp32u code; int len; h263_VLC1 vlc; code = h263_ShowBits9(pInfo, 7); if (code == 0) { h263_FlushBits(pInfo, 7); if (h263_GetBits9(pInfo, 2) == 1) { *mbType = IPPVC_MB_STUFFING; return H263_STATUS_OK; } else { h263_Error("Error when decoding mcbpc of B-Frame macroblock"); return H263_STATUS_ERROR; } } else if (code <= 3) { *dquant = (2 &~ code); *cbp = 1; *mbType = (code & 2) ? IPPVC_MBTYPE_INTRA : IPPVC_MBTYPE_INTRA_Q; h263_FlushBits(pInfo, 7 - (code >> 1));#ifdef H263_FULL_STAT if (*mbType == IPPVC_MBTYPE_INTRA) h263_StatisticInc_(&pInfo->VideoSequence.Statistic.nMB_INTRA); else h263_StatisticInc_(&pInfo->VideoSequence.Statistic.nMB_INTRA_Q);#endif return H263_STATUS_OK; } vlc = h263_Bmb_type[(code >> 2) - 1]; *mbType = vlc.code; len = vlc.len & 15; *cbp = vlc.len & 0x10; *dquant = vlc.len & 0x20; h263_FlushBits(pInfo, len);#ifdef H263_FULL_STAT if (*mbType == IPPVC_MBTYPE_DIRECT) h263_StatisticInc_(&pInfo->VideoSequence.Statistic.nMB_DIRECT_B); else if (*mbType == IPPVC_MBTYPE_INTERPOLATE) h263_StatisticInc_(&pInfo->VideoSequence.Statistic.nMB_INTERPOLATE_B); else if (*mbType == IPPVC_MBTYPE_BACKWARD) h263_StatisticInc_(&pInfo->VideoSequence.Statistic.nMB_BACKWARD_B); else if (*mbType == IPPVC_MBTYPE_FORWARD) h263_StatisticInc_(&pInfo->VideoSequence.Statistic.nMB_BACKWARD_B);#endif return H263_STATUS_OK;}/*// decode MBTYPE for EP-frames*/h263_Status h263_DecodeMBTYPE_EP(h263_Info* pInfo, int *mbType, int *cbp, int *dquant){ Ipp32u code; int len; h263_VLC1 vlc; code = h263_ShowBits9(pInfo, 8); if (code == 0) { h263_FlushBits(pInfo, 8); if (h263_GetBit(pInfo) == 1) { *mbType = IPPVC_MB_STUFFING; return H263_STATUS_OK; } else { h263_Error("Error when decoding mcbpc of EP-Frame macroblock"); return H263_STATUS_ERROR; } } else if (code <= 3) { *mbType = (code & 2) ? IPPVC_MBTYPE_INTRA : IPPVC_MBTYPE_INTRA_Q; h263_FlushBits(pInfo, 8 - (code >> 1));#ifdef H263_FULL_STAT if (*mbType == IPPVC_MBTYPE_INTRA) h263_StatisticInc_(&pInfo->VideoSequence.Statistic.nMB_INTRA); else h263_StatisticInc_(&pInfo->VideoSequence.Statistic.nMB_INTRA_Q);#endif return H263_STATUS_OK; } code >>= 2; if (code < 8) vlc = h263_EPmb_type_0[code - 1]; else vlc = h263_EPmb_type_1[(code >> 3) - 1]; *mbType = vlc.code; len = vlc.len & 15; *cbp = vlc.len & 0x10; *dquant = vlc.len & 0x20; h263_FlushBits(pInfo, len);#ifdef H263_FULL_STAT if (*mbType == IPPVC_MBTYPE_INTERPOLATE) h263_StatisticInc_(&pInfo->VideoSequence.Statistic.nMB_INTERPOLATE_EP); else if (*mbType == IPPVC_MBTYPE_BACKWARD) h263_StatisticInc_(&pInfo->VideoSequence.Statistic.nMB_UPWARD_EP); else if (*mbType == IPPVC_MBTYPE_FORWARD) h263_StatisticInc_(&pInfo->VideoSequence.Statistic.nMB_FORWARD_EP);#endif return H263_STATUS_OK;}h263_Status h263_PredictDecode4MV(h263_Info *pInfo, h263_MacroBlock *MBcurr, int frGOB, int y, int x){ IppMotionVector *mvLeft, *mvTop, *mvRight, *mvCurr; h263_VideoPicture *VPic = &pInfo->VideoSequence.VideoPicture; int mbInRow = VPic->MacroBlockPerRow; int mvdx, mvdy; h263_Status status; int noUMVplus = !VPic->oppmodes.UMV; int noUMV = noUMVplus && !VPic->modes.UMV; mvCurr = MBcurr[0].mv; mvLeft = MBcurr[-1].mv; mvTop = MBcurr[-mbInRow].mv; mvRight = MBcurr[-mbInRow+1].mv; /* block 0 */ if (y == frGOB && x == 0) { mvCurr[0].dx = mvCurr[0].dy = 0; } else if (x == 0) { mvCurr[0].dx = h263_Median(0, mvTop[2].dx, mvRight[2].dx); mvCurr[0].dy = h263_Median(0, mvTop[2].dy, mvRight[2].dy); } else if (y == frGOB) { mvCurr[0] = mvLeft[1]; } else if (x == mbInRow - 1) { mvCurr[0].dx = h263_Median(0, mvLeft[1].dx, mvTop[2].dx); mvCurr[0].dy = h263_Median(0, mvLeft[1].dy, mvTop[2].dy); } else { mvCurr[0].dx = h263_Median(mvLeft[1].dx, mvTop[2].dx, mvRight[2].dx); mvCurr[0].dy = h263_Median(mvLeft[1].dy, mvTop[2].dy, mvRight[2].dy); } if (noUMV) { status = h263_DecodeMV(pInfo, &mvCurr[0], -32, 31); } else if (noUMVplus) { status = h263_DecodeMV(pInfo, &mvCurr[0], -63, 63); } else { status = h263_DecodeMVD_umvplus(pInfo, &mvdx, &mvdy); mvCurr[0].dx = mvCurr[0].dx + (Ipp16s)mvdx; mvCurr[0].dy = mvCurr[0].dy + (Ipp16s)mvdy; } if (status != H263_STATUS_OK) return status; /* block 1 */ if (y == frGOB) { mvCurr[1] = mvCurr[0]; } else if (x == mbInRow - 1) { mvCurr[1].dx = h263_Median(mvCurr[0].dx, mvTop[3].dx, 0); mvCurr[1].dy = h263_Median(mvCurr[0].dy, mvTop[3].dy, 0); } else { mvCurr[1].dx = h263_Median(mvCurr[0].dx, mvTop[3].dx, mvRight[2].dx); mvCurr[1].dy = h263_Median(mvCurr[0].dy, mvTop[3].dy, mvRight[2].dy); } if (noUMV) { status = h263_DecodeMV(pInfo, &mvCurr[1], -32, 31); } else if (noUMVplus) { status = h263_DecodeMV(pInfo, &mvCurr[1], -63, 63); } else { status = h263_DecodeMVD_umvplus(pInfo, &mvdx, &mvdy); mvCurr[1].dx = mvCurr[1].dx + (Ipp16s)mvdx; mvCurr[1].dy = mvCurr[1].dy + (Ipp16s)mvdy; } if (status != H263_STATUS_OK) return status; /* block 2 */ if (x == 0) { mvCurr[2].dx = h263_Median(0, mvCurr[0].dx, mvCurr[1].dx); mvCurr[2].dy = h263_Median(0, mvCurr[0].dy, mvCurr[1].dy); } else { mvCurr[2].dx = h263_Median(mvLeft[3].dx, mvCurr[0].dx, mvCurr[1].dx); mvCurr[2].dy = h263_Median(mvLeft[3].dy, mvCurr[0].dy, mvCurr[1].dy); } if (noUMV) { status = h263_DecodeMV(pInfo, &mvCurr[2], -32, 31); } else if (noUMVplus) { status = h263_DecodeMV(pInfo, &mvCurr[2], -63, 63); } else { status = h263_DecodeMVD_umvplus(pInfo, &mvdx, &mvdy); mvCurr[2].dx = mvCurr[2].dx + (Ipp16s)mvdx; mvCurr[2].dy = mvCurr[2].dy + (Ipp16s)mvdy; } if (status != H263_STATUS_OK) return status; /* block 3 */ mvCurr[3].dx = h263_Median(mvCurr[2].dx, mvCurr[0].dx, mvCurr[1].dx); mvCurr[3].dy = h263_Median(mvCurr[2].dy, mvCurr[0].dy, mvCurr[1].dy); if (noUMV) { status = h263_DecodeMV(pInfo, &mvCurr[3], -32, 31); } else if (noUMVplus) { status = h263_DecodeMV(pInfo, &mvCurr[3], -63, 63); } else { status = h263_DecodeMVD_umvplus(pInfo, &mvdx, &mvdy); mvCurr[3].dx = mvCurr[3].dx + (Ipp16s)mvdx; mvCurr[3].dy = mvCurr[3].dy + (Ipp16s)mvdy; } if (status != H263_STATUS_OK) return status; return H263_STATUS_OK;}void h263_OBMC(h263_Info *pInfo, h263_MacroBlock *pMBinfo, IppMotionVector *mvCur, int colNum, int rowNum, IppiRect limitRectL, Ipp8u *pYc, int stepYc, Ipp8u *pYr, int stepYr, int cbpy, Ipp16s *coeffMB){ IppMotionVector mvOBMCL, mvOBMCU, mvOBMCR, mvOBMCB, *mvLeft, *mvUpper, *mvRight; h263_VideoPicture *VPic = &pInfo->VideoSequence.VideoPicture; int mbPerRow = VPic->MacroBlockPerRow, dx, dy, rt; /* get Right MV */ if (colNum == mbPerRow - 1) mvRight = &mvCur[1]; else if ((pMBinfo[1].type & 0xC0) == 0x80) /* INTRA(_Q), no vector for B-part */ mvRight = &mvCur[1]; else mvRight = pMBinfo[1].mv; /* get Left MV */ if (colNum == 0) mvLeft = mvCur - 1; else if ((pMBinfo[-1].type & 0xC0) == 0x80) mvLeft = mvCur - 1; else mvLeft = pMBinfo[-1].mv; /* get Upper MV */ if (rowNum == 0) mvUpper = mvCur - 2; else if ((pMBinfo[-mbPerRow].type & 0xC0) == 0x80) mvUpper = mvCur - 2; else mvUpper = pMBinfo[-mbPerRow].mv; dx = colNum * 16; dy = rowNum * 16; rt = VPic->rtype; h263_LimitMV(&mvLeft[1], &mvOBMCL, &limitRectL, dx, dy, 8); h263_LimitMV(&mvUpper[2], &mvOBMCU, &limitRectL, dx, dy, 8); h263_LimitMV(&mvCur[1], &mvOBMCR, &limitRectL, dx, dy, 8); h263_LimitMV(&mvCur[2], &mvOBMCB, &limitRectL, dx, dy, 8); ippiOBMC8x8HP_MPEG4_8u_C1R(pYr, stepYr, pYc, stepYc, &mvCur[0], &mvOBMCL, &mvOBMCR, &mvOBMCU, &mvOBMCB, rt); h263_LimitMV(&mvCur[0], &mvOBMCL, &limitRectL, dx+8, dy, 8); h263_LimitMV(&mvUpper[3], &mvOBMCU, &limitRectL, dx+8, dy, 8); h263_LimitMV(&mvRight[0], &mvOBMCR, &limitRectL, dx+8, dy, 8); h263_LimitMV(&mvCur[3], &mvOBMCB, &limitRectL, dx+8, dy, 8); ippiOBMC8x8HP_MPEG4_8u_C1R(pYr+8, stepYr, pYc+8, stepYc, &mvCur[1], &mvOBMCL, &mvOBMCR, &mvOBMCU, &mvOBMCB, rt); h263_LimitMV(&mvLeft[3], &mvOBMCL, &limitRectL, dx, dy+8, 8); h263_LimitMV(&mvCur[0], &mvOBMCU, &limitRectL, dx, dy+8, 8); h263_LimitMV(&mvCur[3], &mvOBMCR, &limitRectL, dx, dy+8, 8); ippiOBMC8x8HP_MPEG4_8u_C1R(pYr+stepYr*8, stepYr, pYc+stepYc*8, stepYc, &mvCur[2], &mvOBMCL, &mvOBMCR, &mvOBMCU, &mvCur[2], rt); h263_LimitMV(&mvCur[2], &mvOBMCL, &limitRectL, dx+8, dy+8, 8); h263_LimitMV(&mvCur[1], &mvOBMCU, &limitRectL, dx+8, dy+8, 8); h263_LimitMV(&mvRight[2], &mvOBMCR, &limitRectL, dx+8, dy+8, 8); ippiOBMC8x8HP_MPEG4_8u_C1R(pYr+8+stepYr*8, stepYr, pYc+8+stepYc*8, stepYc, &mvCur[3], &mvOBMCL, &mvOBMCR, &mvOBMCU, &mvCur[3], rt); h263_AddResidual(cbpy & 8, pYc, stepYc, coeffMB); h263_AddResidual(cbpy & 4, pYc+8, stepYc, coeffMB+64); h263_AddResidual(cbpy & 2, pYc+stepYc*8, stepYc, coeffMB+128); h263_AddResidual(cbpy & 1, pYc+stepYc*8+8, stepYc, coeffMB+192);}int h263_UpdateQuant_Mod(h263_Info *pInfo){ h263_VideoPicture *VPic = &pInfo->VideoSequence.VideoPicture; int quant = VPic->pic_quant; int dquant, quant_c; Ipp32u code; code = h263_ShowBits9(pInfo, 6); if (code >= 32) { dquant = (code >> 4) & 1; VPic->pic_quant = h263_dquant_Mod[dquant][quant - 1]; h263_FlushBits(pInfo, 2); } else { VPic->pic_quant = code; h263_FlushBits(pInfo, 6); } quant_c = h263_quant_c[VPic->pic_quant]; return quant_c;}/* intra-macroblock horizontal boundaries are processed in h263_DecodeFrame_P() */void h263_DeblockingFilter_P(h263_Info *pInfo, h263_Frame *frame){ Ipp8u *pYc, *pCbc, *pCrc; int stepYc, stepCbc, stepCrc, mbPerRow, mbPerCol; h263_MacroBlock *pMBinfo; int quant, quant_c; int i, j; h263_VideoPicture *VPic = &pInfo->VideoSequence.VideoPicture; stepYc = frame->stepY; stepCbc = frame->stepCb; stepCrc = frame->stepCr; mbPerRow = frame->mbPerRow; mbPerCol = frame->mbPerCol; /* Horizontal */ for (i = 1; i < mbPerCol; i++) { if (pInfo->VideoSequence.GOBboundary[i] > 0) continue; /* no filtering across GOB boundaries */ pYc = frame->pY + (stepYc << 4)*i; pCbc = frame->pCb + (stepCbc << 3)*i; pCrc = frame->pCr + (stepCrc << 3)*i; pMBinfo = pInfo->VideoSequence.MBinfo + mbPerRow*i; for (j = 0; j < mbPerRow; j++) { if (pMBinfo[j].type != IPPVC_MB_STUFFING) { quant = pMBinfo[j].quant; quant_c = VPic->oppmodes.modQuant ? h263_quant_c[quant] : quant; H263_MB_HOR_DEBLOCKING(pYc, stepYc, pCbc, stepCbc, pCrc, stepCrc, quant, quant_c); } else if (pMBinfo[j-mbPerRow].type != IPPVC_MB_STUFFING) { quant = pMBinfo[j-mbPerRow].quant; quant_c = VPic->oppmodes.modQuant ? h263_quant_c[quant] : quant; H263_MB_HOR_DEBLOCKING(pYc, stepYc, pCbc, stepCbc, pCrc, stepCrc, quant, quant_c); } pYc += 16; pCbc += 8; pCrc += 8; } } /* Vertical */ for (i = 0; i < mbPerCol; i++) { if (pInfo->VideoSequence.GOBboundary[i] > 1) continue; /* the row belongs to a skipped GOB */ pYc = frame->pY + (stepYc << 4)*i; pCbc = frame->pCb + (stepCbc << 3)*i;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -