📄 h263_enc_frame.cpp
字号:
mIndxBPic = 2;
mNumBPic++;
if (mNumBPic == mBPicdist) {
// next frame is not B
mNumBPic = 0;
h263e_Swap(mFrameF, mFrameB);
mFrameC = mFrameB;
} else {
// next frame is B
mFrameC = &mFrame[mIndxBPic];
}
} else {
// next frame is B
mFrameC = &mFrame[mIndxBPic];
}
mPictime += mVideoSequence.fixed_pic_time_increment;
mFrameCount ++;
if (mFrameCount > mBPicdist + 1)
return H263_STS_NOERR;
else
return isBPic ? H263_STS_BUFFERED : H263_STS_NOERR;
}
void ippVideoEncoderH263::PredictMV(h263e_MacroBlock *MBcurr, Ipp32s frGOB, Ipp32s i, Ipp32s j, Ipp32s adv, IppMotionVector *mvPred)
{
IppMotionVector *mvLeft, *mvTop, *mvRight;
Ipp32s 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 = h263e_Median(0, mvTop[i2].dx, mvRight[i2].dx);
mvPred[0].dy = h263e_Median(0, mvTop[i2].dy, mvRight[i2].dy);
} else if (i == frGOB) {
mvPred[0] = mvLeft[i1];
} else if (j == mNumMacroBlockPerRow - 1) {
mvPred[0].dx = h263e_Median(0, mvLeft[i1].dx, mvTop[i2].dx);
mvPred[0].dy = h263e_Median(0, mvLeft[i1].dy, mvTop[i2].dy);
} else {
mvPred[0].dx = h263e_Median(mvLeft[i1].dx, mvTop[i2].dx, mvRight[i2].dx);
mvPred[0].dy = h263e_Median(mvLeft[i1].dy, mvTop[i2].dy, mvRight[i2].dy);
}
}
void ippVideoEncoderH263::me4MV_Neighbours(h263e_MacroBlock *MBcurr, Ipp32s frGOB, Ipp32s i, Ipp32s 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(h263e_MacroBlock *MBcurr, Ipp32s frGOB, Ipp32s i, Ipp32s 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 = h263e_Median(mvCurr[0].dx, mvTop[3].dx, 0);
mvPred[1].dy = h263e_Median(mvCurr[0].dy, mvTop[3].dy, 0);
} else {
mvPred[1].dx = h263e_Median(mvCurr[0].dx, mvTop[3].dx, mvRight[2].dx);
mvPred[1].dy = h263e_Median(mvCurr[0].dy, mvTop[3].dy, mvRight[2].dy);
}
// block 2
if (j == 0) {
mvPred[2].dx = h263e_Median(0, mvCurr[0].dx, mvCurr[1].dx);
mvPred[2].dy = h263e_Median(0, mvCurr[0].dy, mvCurr[1].dy);
} else {
mvPred[2].dx = h263e_Median(mvLeft[3].dx, mvCurr[0].dx, mvCurr[1].dx);
mvPred[2].dy = h263e_Median(mvLeft[3].dy, mvCurr[0].dy, mvCurr[1].dy);
}
// block 3
mvPred[3].dx = h263e_Median(mvCurr[2].dx, mvCurr[0].dx, mvCurr[1].dx);
mvPred[3].dy = h263e_Median(mvCurr[2].dy, mvCurr[0].dy, mvCurr[1].dy);
}
void ippVideoEncoderH263::EncodeMV(IppMotionVector *mv, Ipp32s mbType)
{
Ipp32s i, nMV = (mbType == IPPVC_MBTYPE_INTER4V) ? 4 : 1;
for (i = 0; i < nMV; i++) {
if (mVideoPicture.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 {
Ipp32s mvabs[2], sign[2], j, val, s;
Ipp32s 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(Ipp32s mbtype, Ipp32s 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(Ipp32s 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(Ipp32s pat)
{
cBS.PutBits(mVLC_CBPY_TB8[pat].code, mVLC_CBPY_TB8[pat].len);
}
inline void ippVideoEncoderH263::EncodeMCBPC_P(Ipp32s mbtype, Ipp32s pat)
{
cBS.PutBits(mVLC_MCBPC_TB7[mbtype*4+pat].code, mVLC_MCBPC_TB7[mbtype*4+pat].len);
}
inline void ippVideoEncoderH263::EncodeCBPY_P(Ipp32s mbtype, Ipp32s pat)
{
if (mbtype <= IPPVC_MBTYPE_INTER4V)
pat = 15 - pat;
cBS.PutBits(mVLC_CBPY_TB8[pat].code, mVLC_CBPY_TB8[pat].len);
}
void ippVideoEncoderH263::ChooseAdvIntraPred(h263e_MacroBlock *MBcurr, Ipp16s *coeffs, Ipp32s *predDir)
{
h263e_Block *bCurr;
Ipp16s *predAcA, *predAcC;
Ipp32s sadDC, sadH, sadV, absCoefV, absCoefH, s, dc;
Ipp16s *coef;
Ipp32s 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 += h263e_Abs(coef[v*8]);
bCurr->dctOr_acC[v] = coef[v];
absCoefH += h263e_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 = h263e_Abs(coef[0] - ((predAcA[0] + predAcC[0] + 1) >> 1));
else
dc = h263e_Abs(coef[0] - predAcA[0]);
} else if (predAcC)
dc = h263e_Abs(coef[0] - predAcC[0]);
else
dc = h263e_Abs(coef[0] - 1024);
sadDC += dc + ((absCoefV + absCoefH) << 5);
// block to the left
s = absCoefH;
if (predAcA) {
dc = h263e_Abs(coef[0] - predAcA[0]);
for (v = 1; v < 8; v++)
s += h263e_Abs(coef[v*8] - predAcA[v]);
} else {
dc = h263e_Abs(coef[0] - 1024);
s += absCoefV;
}
sadV += dc + (s << 5);
// block above
s = absCoefV;
if (predAcC) {
dc = h263e_Abs(coef[0] - predAcC[0]);
for (v = 1; v < 8; v++)
s += h263e_Abs(coef[v] - predAcC[v]);
} else {
dc = h263e_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;
}
Ipp32s ippVideoEncoderH263::PredictReconstructAdvIntra(Ipp8u *pF[6], h263e_MacroBlock *MBcurr, Ipp16s *coeffs,
Ipp32s *nzCount, Ipp32s quant, Ipp32s scan)
{
__ALIGN16(Ipp16s, rcoef, 64);
__ALIGN16(Ipp8u, pDec, 64*6);
h263e_Block *bCurr;
Ipp16s *predAcA, *predAcC;
Ipp16s *coef;
Ipp32s i, v;
Ipp16s pred;
Ipp32s step;
Ipp32s 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, mVideoPicture.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 += h263e_CalcMSE_16x16(pF[0], mStepLuma, pDec, 16);
mPSNR_U += h263e_CalcMSE_8x8(pF[4], mStepChroma, pDec+256, 8);
mPSNR_V += h263e_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);
}
// called only if (!mVideoPicture.advIntra)
Ipp32s ippVideoEncoderH263::QuantMacroBlockIntra_H263(Ipp16s *coeffMB, Ipp32s *nzCount, Ipp32s quant)
{
Ipp32s pattern;
ippiQuantIntra_H263_16s_C1I(coeffMB+0*64, quant, &nzCount[0], 0, mVideoPicture.modQuant);
ippiQuantIntra_H263_16s_C1I(coeffMB+1*64, quant, &nzCount[1], 0, mVideoPicture.modQuant);
ippiQuantIntra_H263_16s_C1I(coeffMB+2*64, quant, &nzCount[2], 0, mVideoPicture.modQuant);
ippiQuantIntra_H263_16s_C1I(coeffMB+3*64, quant, &nzCount[3], 0, mVideoPicture.modQuant);
ippiQuantIntra_H263_16s_C1I(coeffMB+4*64, quant, &nzCount[4], 0, mVideoPicture.modQuant);
ippiQuantIntra_H263_16s_C1I(coeffMB+5*64, quant, &nzCount[5], 0, mVideoPicture.modQuant);
h263e_SetPatternIntra(pattern, nzCount, 1);
return pattern;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -