📄 h263_enc_frame.cpp
字号:
bIndx = 2; mCurrPtrY = mPtrY[bIndx]; mCurrPtrU = mPtrU[bIndx]; mCurrPtrV = mPtrV[bIndx]; // set VOP time nt = mSyncTimeB - (mBVOPdist - mNumBVOP) * VOL.fixed_vop_time_increment; mTRD = mBVOPdist + 1; mTRB = mNumBVOP + 1; EncodeVOP(H263_VOP_TYPE_B, nt); } // setup next frame if (isBVOP) { mIndxBVOP ++; if (mIndxBVOP > 2 + mBVOPdist) mIndxBVOP = 2; mNumBVOP ++; if (mNumBVOP == mBVOPdist) { // next frame is not B mNumBVOP = 0; h263_Swap(mForwPtrY, mBackPtrY); h263_Swap(mForwPtrU, mBackPtrU); h263_Swap(mForwPtrV, mBackPtrV); mCurrPtrY = mBackPtrY; mCurrPtrU = mBackPtrU; mCurrPtrV = mBackPtrV; } else { // next frame is B mCurrPtrY = mPtrY[mIndxBVOP]; mCurrPtrU = mPtrU[mIndxBVOP]; mCurrPtrV = mPtrV[mIndxBVOP]; } } else { // next frame is B mCurrPtrY = mPtrY[mIndxBVOP]; mCurrPtrU = mPtrU[mIndxBVOP]; mCurrPtrV = mPtrV[mIndxBVOP]; } mVOPtime += VOL.fixed_vop_time_increment; mFrameCount ++; if (mFrameCount > mBVOPdist + 1) return H263_STS_NOERR; else return isBVOP ? H263_STS_BUFFERED : H263_STS_NOERR;}void ippVideoEncoderH263::PredictMV(h263_MacroBlock *MBcurr, int frGOB, int i, int j, int adv, IppMotionVector *mvPred){ IppMotionVector *mvLeft, *mvTop, *mvRight; int i1, i2; if (adv) { i1 = 1; i2 = 2; } else { i1 = i2 = 0; } mvLeft = MBcurr[-1].mv; mvTop = MBcurr[-mNumMacroBlockPerRow].mv; mvRight = MBcurr[-mNumMacroBlockPerRow+1].mv; if (i == frGOB && j == 0) { mvPred[0].dx = mvPred[0].dy = 0; } else if (j == 0) { mvPred[0].dx = h263_Median(0, mvTop[i2].dx, mvRight[i2].dx); mvPred[0].dy = h263_Median(0, mvTop[i2].dy, mvRight[i2].dy); } else if (i == frGOB) { mvPred[0] = mvLeft[i1]; } else if (j == mNumMacroBlockPerRow - 1) { mvPred[0].dx = h263_Median(0, mvLeft[i1].dx, mvTop[i2].dx); mvPred[0].dy = h263_Median(0, mvLeft[i1].dy, mvTop[i2].dy); } else { mvPred[0].dx = h263_Median(mvLeft[i1].dx, mvTop[i2].dx, mvRight[i2].dx); mvPred[0].dy = h263_Median(mvLeft[i1].dy, mvTop[i2].dy, mvRight[i2].dy); }}void ippVideoEncoderH263::me4MV_Neighbours(h263_MacroBlock *MBcurr, int frGOB, int i, int j, IppMotionVector *mvPred){ IppMotionVector *mvLeft, *mvTop, *mvRight; mvLeft = MBcurr[-1].mv; mvTop = MBcurr[-mNumMacroBlockPerRow].mv; mvRight = MBcurr[-mNumMacroBlockPerRow+1].mv; if (i == frGOB) { mvPred[1].dx = mvPred[1].dy = 32767; // top mvPred[2].dx = mvPred[2].dy = -32767; // top right } else if (j == mNumMacroBlockPerRow - 1) { mvPred[1] = mvTop[3]; // top mvPred[2].dx = mvPred[2].dy = 0; // top right } else { mvPred[1] = mvTop[3]; // top mvPred[2] = mvRight[2]; // top right } if (j == 0) mvPred[3].dx = mvPred[3].dy = 0; // left else mvPred[3] = mvLeft[3];}void ippVideoEncoderH263::Predict3MV(h263_MacroBlock *MBcurr, int frGOB, int i, int j, IppMotionVector *mvPred, IppMotionVector *mvCurr){ IppMotionVector *mvLeft, *mvTop, *mvRight; mvLeft = MBcurr[-1].mv; mvTop = MBcurr[-mNumMacroBlockPerRow].mv; mvRight = MBcurr[-mNumMacroBlockPerRow+1].mv; // block 1 if (i == frGOB) { mvPred[1] = mvCurr[0]; } else if (j == mNumMacroBlockPerRow - 1) { mvPred[1].dx = h263_Median(mvCurr[0].dx, mvTop[3].dx, 0); mvPred[1].dy = h263_Median(mvCurr[0].dy, mvTop[3].dy, 0); } else { mvPred[1].dx = h263_Median(mvCurr[0].dx, mvTop[3].dx, mvRight[2].dx); mvPred[1].dy = h263_Median(mvCurr[0].dy, mvTop[3].dy, mvRight[2].dy); } // block 2 if (j == 0) { mvPred[2].dx = h263_Median(0, mvCurr[0].dx, mvCurr[1].dx); mvPred[2].dy = h263_Median(0, mvCurr[0].dy, mvCurr[1].dy); } else { mvPred[2].dx = h263_Median(mvLeft[3].dx, mvCurr[0].dx, mvCurr[1].dx); mvPred[2].dy = h263_Median(mvLeft[3].dy, mvCurr[0].dy, mvCurr[1].dy); } // block 3 mvPred[3].dx = h263_Median(mvCurr[2].dx, mvCurr[0].dx, mvCurr[1].dx); mvPred[3].dy = h263_Median(mvCurr[2].dy, mvCurr[0].dy, mvCurr[1].dy);}void ippVideoEncoderH263::EncodeMV(IppMotionVector *mv, int mbType){ int i, nMV = (mbType == IPPVC_MBTYPE_INTER4V) ? 4 : 1; for (i = 0; i < nMV; i++) { if (VOP.UMV <= 1) { cBS.PutBits(mVLC_MVD_TB12[mv[i].dx+32].code, mVLC_MVD_TB12[mv[i].dx+32].len); cBS.PutBits(mVLC_MVD_TB12[mv[i].dy+32].code, mVLC_MVD_TB12[mv[i].dy+32].len); } else { int mvabs[2], sign[2], j, val, s; int m, nbits; Ipp32u code; sign[0] = (mv[i].dx >= 0 ? 0 : 1); mvabs[0] = (mv[i].dx >= 0 ? mv[i].dx : -mv[i].dx); sign[1] = (mv[i].dy >= 0 ? 0 : 1); mvabs[1] = (mv[i].dy >= 0 ? mv[i].dy : -mv[i].dy); for (j = 0; j < 2; j++) { val = mvabs[j]; s = sign[j]; if (val == 0) cBS.PutBits(1, 1); else if (val == 1) cBS.PutBits(s << 1, 3); else { if (val < 32) { m = 16; nbits = 11; } else { m = 2048; nbits = 25; } while (1) { if (val & m) break; nbits -= 2; m >>= 1; } val &= m - 1; m >>= 1; code = 0; while (m) { code |= ((val & m) << 1) | m; code <<= 1; m >>= 1; } code <<= 1; code |= s << 1; cBS.PutBits(code, nbits); } } if (mv[i].dx == 1 && mv[i].dy == 1) cBS.PutBits(1, 1); } }}inline void ippVideoEncoderH263::EncodeMCBPC_I(int mbtype, int mcbpc){ if (mbtype == IPPVC_MBTYPE_INTRA) { if (mcbpc == 0) cBS.PutBits(1, 1); else cBS.PutBits(mcbpc, 3); } else { if (mcbpc == 0) cBS.PutBits(1, 4); else cBS.PutBits(mcbpc, 7); }}inline void ippVideoEncoderH263::EncodeAdvIntraPredMode(int scan){ if (scan == IPPVC_SCAN_ZIGZAG) cBS.PutBits(0, 1); else if (scan == IPPVC_SCAN_VERTICAL) cBS.PutBits(3, 2); else cBS.PutBits(2, 2);}inline void ippVideoEncoderH263::EncodeCBPY_I(int pat){ cBS.PutBits(mVLC_CBPY_TB8[pat].code, mVLC_CBPY_TB8[pat].len);}inline void ippVideoEncoderH263::EncodeMCBPC_P(int mbtype, int pat){ cBS.PutBits(mVLC_MCBPC_TB7[mbtype*4+pat].code, mVLC_MCBPC_TB7[mbtype*4+pat].len);}inline void ippVideoEncoderH263::EncodeCBPY_P(int mbtype, int pat){ if (mbtype <= IPPVC_MBTYPE_INTER4V) pat = 15 - pat; cBS.PutBits(mVLC_CBPY_TB8[pat].code, mVLC_CBPY_TB8[pat].len);}void ippVideoEncoderH263::ChooseAdvIntraPred(h263_MacroBlock *MBcurr, Ipp16s *coeffs, int *predDir){ h263_Block *bCurr; Ipp16s *predAcA, *predAcC; Ipp32s sadDC, sadH, sadV, absCoefV, absCoefH, s, dc; Ipp16s *coef; int i, v; sadDC = sadH = sadV = 0; for (i = 0; i < 4; i++) { bCurr = &MBcurr->block[i]; coef = coeffs + i*64; absCoefH = absCoefV = 0; bCurr->dctOr_acA[0] = bCurr->dctOr_acC[0] = coef[0]; for (v = 1; v < 8; v++) { bCurr->dctOr_acA[v] = coef[v*8]; absCoefV += abs(coef[v*8]); bCurr->dctOr_acC[v] = coef[v]; absCoefH += abs(coef[v]); } predAcA = bCurr->predA ? (bCurr->predA->validPredIntra ? bCurr->predA->dctOr_acA : NULL) : NULL; predAcC = bCurr->predC ? (bCurr->predC->validPredIntra ? bCurr->predC->dctOr_acC : NULL) : NULL; if (predAcA) { if (predAcC) dc = abs(coef[0] - ((predAcA[0] + predAcC[0] + 1) >> 1)); else dc = abs(coef[0] - predAcA[0]); } else if (predAcC) dc = abs(coef[0] - predAcC[0]); else dc = abs(coef[0] - 1024); sadDC += dc + ((absCoefV + absCoefH) << 5); // block to the left s = absCoefH; if (predAcA) { dc = abs(coef[0] - predAcA[0]); for (v = 1; v < 8; v++) s += abs(coef[v*8] - predAcA[v]); } else { dc = abs(coef[0] - 1024); s += absCoefV; } sadV += dc + (s << 5); // block above s = absCoefV; if (predAcC) { dc = abs(coef[0] - predAcC[0]); for (v = 1; v < 8; v++) s += abs(coef[v] - predAcC[v]); } else { dc = abs(coef[0] - 1024); s += absCoefH; } sadH += dc + (s << 5); } *predDir = IPPVC_SCAN_ZIGZAG; if (sadV < sadDC) { *predDir = IPPVC_SCAN_VERTICAL; sadDC = sadV; } if (sadH < sadDC) *predDir = IPPVC_SCAN_HORIZONTAL;}int ippVideoEncoderH263::PredictReconstructAdvIntra(Ipp8u *pF[6], h263_MacroBlock *MBcurr, Ipp16s *coeffs, int *nzCount, int quant, int scan){ __ALIGN16(Ipp16s, rcoef, 64); __ALIGN16(Ipp8u, pDec, 64*6); h263_Block *bCurr; Ipp16s *predAcA, *predAcC; Ipp16s *coef; int i, v; Ipp16s pred; int step; int pattern = 0; if (mCalcPSNR) { ippiCopy16x16_8u_C1R(pF[0], mStepLuma, pDec, 16); ippiCopy8x8_8u_C1R(pF[4], mStepChroma, pDec+256, 8); ippiCopy8x8_8u_C1R(pF[5], mStepChroma, pDec+320, 8); } for (i = 0; i < 6; i++) { bCurr = &MBcurr->block[i]; coef = coeffs + i*64; step = (i < 4 ? mStepLuma : mStepChroma); predAcA = bCurr->predA ? (bCurr->predA->validPredIntra ? bCurr->predA->dct_acA : NULL) : NULL; predAcC = bCurr->predC ? (bCurr->predC->validPredIntra ? bCurr->predC->dct_acC : NULL) : NULL; if (scan == IPPVC_SCAN_ZIGZAG) { if (predAcA) if (predAcC) pred = (predAcA[0] + predAcC[0] + 1) >> 1; else pred = predAcA[0]; else pred = predAcC ? predAcC[0] : 1024; coef[0] = coef[0] - pred; } else if (scan == IPPVC_SCAN_VERTICAL) { if (predAcA) { for (v = 0; v < 8; v++) coef[v*8] = coef[v*8] - predAcA[v]; } else coef[0] = coef[0] - 1024; } else { // IPPVC_SCAN_HORIZONTAL if (predAcC) { for (v = 0; v < 8; v++) coef[v] = coef[v] - predAcC[v]; } else coef[0] = coef[0] - 1024; } // No need to clip to [-2048,2047] as Intra AC DCT coeffs are in the range [-1020, 1020], DC - [0, 2040] ippiQuantIntra_H263_16s_C1I(coef, quant, &nzCount[i], 1, VOP.modQuant); if (nzCount[i]) pattern |= 32 >> i; ippsCopy_16s(coef, rcoef, 64); // have only inplace Quant/InvQuant ReconBlockIntra_AdvI_H263(pF[i], step, rcoef, bCurr, quant, nzCount[i], scan); } if (mCalcPSNR) { mPSNR_Y += h263_CalcMSE_16x16(pF[0], mStepLuma, pDec, 16); mPSNR_U += h263_CalcMSE_8x8(pF[4], mStepChroma, pDec+256, 8); mPSNR_V += h263_CalcMSE_8x8(pF[5], mStepChroma, pDec+320, 8); } return pattern;}void ippVideoEncoderH263::DCT8x8MacroBlock_H263(Ipp8u *pY, Ipp8u *pU, Ipp8u *pV, Ipp16s *coeffMB){ ippiDCT8x8Fwd_8u16s_C1R(pY, mStepLuma, coeffMB+0*64); ippiDCT8x8Fwd_8u16s_C1R(pY+8, mStepLuma, coeffMB+1*64); ippiDCT8x8Fwd_8u16s_C1R(pY+8*mStepLuma, mStepLuma, coeffMB+2*64); ippiDCT8x8Fwd_8u16s_C1R(pY+8*mStepLuma+8, mStepLuma, coeffMB+3*64); ippiDCT8x8Fwd_8u16s_C1R(pU, mStepChroma, coeffMB+4*64); ippiDCT8x8Fwd_8u16s_C1R(pV, mStepChroma, coeffMB+5*64);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -