📄 mp4_enc_vop.cpp
字号:
mvPred[2].dx = mp4_Median(0, mvCurr[0].dx, mvCurr[1].dx);
mvPred[2].dy = mp4_Median(0, mvCurr[0].dy, mvCurr[1].dy);
} else {
mvPred[2].dx = mp4_Median(mvLeft[3].dx, mvCurr[0].dx, mvCurr[1].dx);
mvPred[2].dy = mp4_Median(mvLeft[3].dy, mvCurr[0].dy, mvCurr[1].dy);
}
// block 3
mvPred[3].dx = mp4_Median(mvCurr[2].dx, mvCurr[0].dx, mvCurr[1].dx);
mvPred[3].dy = mp4_Median(mvCurr[2].dy, mvCurr[0].dy, mvCurr[1].dy);
} else {
Ipp32s validLeft, validTop, validRight;
if (j > 0)
validLeft = MBcurr[-1].validPredInter;
else
validLeft = 0;
if (i > 0)
validTop = MBcurr[-mNumMacroBlockPerRow].validPredInter;
else
validTop = 0;
if ((i > 0) && (j < mNumMacroBlockPerRow - 1))
validRight = MBcurr[-mNumMacroBlockPerRow+1].validPredInter;
else
validRight = 0;
// block 1
switch ((validTop << 1) | validRight) {
case 3:
mvPred[1].dx = mp4_Median(mvCurr[0].dx, mvTop[3].dx, mvRight[2].dx);
mvPred[1].dy = mp4_Median(mvCurr[0].dy, mvTop[3].dy, mvRight[2].dy);
break;
case 2:
mvPred[1].dx = mp4_Median(mvCurr[0].dx, mvTop[3].dx, 0);
mvPred[1].dy = mp4_Median(mvCurr[0].dy, mvTop[3].dy, 0);
break;
case 1:
mvPred[1].dx = mp4_Median(mvCurr[0].dx, 0, mvRight[2].dx);
mvPred[1].dy = mp4_Median(mvCurr[0].dy, 0, mvRight[2].dy);
break;
default:
mvPred[1] = mvCurr[0];
break;
}
// block 2
if (validLeft) {
mvPred[2].dx = mp4_Median(mvLeft[3].dx, mvCurr[0].dx, mvCurr[1].dx);
mvPred[2].dy = mp4_Median(mvLeft[3].dy, mvCurr[0].dy, mvCurr[1].dy);
} else {
mvPred[2].dx = mp4_Median(0, mvCurr[0].dx, mvCurr[1].dx);
mvPred[2].dy = mp4_Median(0, mvCurr[0].dy, mvCurr[1].dy);
}
// block 3
mvPred[3].dx = mp4_Median(mvCurr[2].dx, mvCurr[0].dx, mvCurr[1].dx);
mvPred[3].dy = mp4_Median(mvCurr[2].dy, mvCurr[0].dy, mvCurr[1].dy);
}
}
void ippVideoEncoderMPEG4::Predict3MV(mp4_MacroBlock *MBcurr, Ipp32s i, Ipp32s j, IppMotionVector *mvPred, Ipp32s nB)
{
IppMotionVector *mvLeft, *mvTop, *mvRight, *mvCurr;
mvCurr = MBcurr->mv;
mvLeft = MBcurr[-1].mv;
mvTop = MBcurr[-mNumMacroBlockPerRow].mv;
mvRight = MBcurr[-mNumMacroBlockPerRow+1].mv;
if (!mInsertResync) {
if (nB == 1) {
if (i == 0) {
mvPred[1] = mvCurr[0];
} else if (j == mNumMacroBlockPerRow - 1) {
mvPred[1].dx = mp4_Median(mvCurr[0].dx, mvTop[3].dx, 0);
mvPred[1].dy = mp4_Median(mvCurr[0].dy, mvTop[3].dy, 0);
} else {
mvPred[1].dx = mp4_Median(mvCurr[0].dx, mvTop[3].dx, mvRight[2].dx);
mvPred[1].dy = mp4_Median(mvCurr[0].dy, mvTop[3].dy, mvRight[2].dy);
}
} else if (nB == 2) {
if (j == 0) {
mvPred[2].dx = mp4_Median(0, mvCurr[0].dx, mvCurr[1].dx);
mvPred[2].dy = mp4_Median(0, mvCurr[0].dy, mvCurr[1].dy);
} else {
mvPred[2].dx = mp4_Median(mvLeft[3].dx, mvCurr[0].dx, mvCurr[1].dx);
mvPred[2].dy = mp4_Median(mvLeft[3].dy, mvCurr[0].dy, mvCurr[1].dy);
}
} else {
mvPred[3].dx = mp4_Median(mvCurr[2].dx, mvCurr[0].dx, mvCurr[1].dx);
mvPred[3].dy = mp4_Median(mvCurr[2].dy, mvCurr[0].dy, mvCurr[1].dy);
}
} else {
Ipp32s validLeft, validTop, validRight;
if (j > 0)
validLeft = MBcurr[-1].validPredInter;
else
validLeft = 0;
if (i > 0)
validTop = MBcurr[-mNumMacroBlockPerRow].validPredInter;
else
validTop = 0;
if ((i > 0) && (j < mNumMacroBlockPerRow - 1))
validRight = MBcurr[-mNumMacroBlockPerRow+1].validPredInter;
else
validRight = 0;
if (nB == 1) {
switch ((validTop << 1) | validRight) {
case 3:
mvPred[1].dx = mp4_Median(mvCurr[0].dx, mvTop[3].dx, mvRight[2].dx);
mvPred[1].dy = mp4_Median(mvCurr[0].dy, mvTop[3].dy, mvRight[2].dy);
break;
case 2:
mvPred[1].dx = mp4_Median(mvCurr[0].dx, mvTop[3].dx, 0);
mvPred[1].dy = mp4_Median(mvCurr[0].dy, mvTop[3].dy, 0);
break;
case 1:
mvPred[1].dx = mp4_Median(mvCurr[0].dx, 0, mvRight[2].dx);
mvPred[1].dy = mp4_Median(mvCurr[0].dy, 0, mvRight[2].dy);
break;
default:
mvPred[1] = mvCurr[0];
break;
}
} else if (nB == 2) {
if (validLeft) {
mvPred[2].dx = mp4_Median(mvLeft[3].dx, mvCurr[0].dx, mvCurr[1].dx);
mvPred[2].dy = mp4_Median(mvLeft[3].dy, mvCurr[0].dy, mvCurr[1].dy);
} else {
mvPred[2].dx = mp4_Median(0, mvCurr[0].dx, mvCurr[1].dx);
mvPred[2].dy = mp4_Median(0, mvCurr[0].dy, mvCurr[1].dy);
}
} else {
mvPred[3].dx = mp4_Median(mvCurr[2].dx, mvCurr[0].dx, mvCurr[1].dx);
mvPred[3].dy = mp4_Median(mvCurr[2].dy, mvCurr[0].dy, mvCurr[1].dy);
}
}
}
void ippVideoEncoderMPEG4::PredictIntraDCAC(mp4_MacroBlock *MBcurr, Ipp16s *dcCurr, Ipp32s quant, Ipp32s *predictDir, Ipp32s predAC, Ipp32s *pSum0, Ipp32s *pSum1, Ipp32s *nzCount, Ipp32s nRow)
{
Ipp32s predDir, dc, k, zC, zA, predQuantA, predQuantC, dcScaler, sum0 = 0, sum1 = 0, i;
Ipp16s dcA, dcB, dcC, dcP;
Ipp16s *predAcA, *predAcC;
mp4_Block *bCurr;
for (i = 0; i < 6; i ++) {
bCurr = &MBcurr->block[i];
dcScaler = i < 4 ? mp4_DCScalerLuma[quant] : mp4_DCScalerChroma[quant];
dcA = bCurr->predA ? (bCurr->predA->validPredIntra ? bCurr->predA->dct_dc : mDefDC) : mDefDC;
// next if is needed only for slice coding
if ((nRow == 0) && (i != 2) && (i != 3)) {
dcB = mDefDC;
dcC = mDefDC;
} else {
dcB = bCurr->predB ? (bCurr->predB->validPredIntra ? bCurr->predB->dct_dc : mDefDC) : mDefDC;
dcC = bCurr->predC ? (bCurr->predC->validPredIntra ? bCurr->predC->dct_dc : mDefDC) : mDefDC;
}
if (mp4_Abs(dcA - dcB) < mp4_Abs(dcB - dcC)) {
predDir = IPPVC_SCAN_HORIZONTAL;
dcP = dcC;
} else {
predDir = IPPVC_SCAN_VERTICAL;
dcP = dcA;
}
dc = bCurr->dct_dcq = *dcCurr;
*dcCurr = (Ipp16s)(dc - mp4_DivIntraDC(dcP, dcScaler));
// correct nzCount
if (dc == 0 && *dcCurr != 0)
nzCount[i] ++;
else if (dc != 0 && *dcCurr == 0)
nzCount[i] --;
bCurr->dct_dc = (Ipp16s)(dc * dcScaler);
zC = zA = 0;
for (k = 1; k < 8; k ++) {
bCurr->dct_acC[k] = dcCurr[k];
if (dcCurr[k])
zC = 1;
bCurr->dct_acA[k] = dcCurr[k*8];
if (dcCurr[k*8])
zA = 1;
}
bCurr->dct_acC[0] = (Ipp16s)zC;
bCurr->dct_acA[0] = (Ipp16s)zA;
if (predAC) {
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 (predDir == IPPVC_SCAN_HORIZONTAL && predAcC) {
if (predAcC[0]) {
predQuantC = bCurr->predC->quant;
if (predQuantC == bCurr->quant)
for (k = 1; k < 8; k ++) {
sum0 += mp4_Abs(dcCurr[k]);
dcCurr[k] = (Ipp16s)(dcCurr[k] - predAcC[k]);
sum1 += mp4_Abs(dcCurr[k]);
}
else
for (k = 1; k < 8; k ++) {
sum0 += mp4_Abs(dcCurr[k]);
dcCurr[k] = (Ipp16s)(dcCurr[k] - mp4_DivIntraAC(predAcC[k] * predQuantC, bCurr->quant));
sum1 += mp4_Abs(dcCurr[k]);
}
}
} else if (predDir == IPPVC_SCAN_VERTICAL && predAcA) {
if (predAcA[0]) {
predQuantA = bCurr->predA->quant;
if (predQuantA == bCurr->quant)
for (k = 1; k < 8; k ++) {
sum0 += mp4_Abs(dcCurr[k*8]);
dcCurr[k*8] = (Ipp16s)(dcCurr[k*8] - predAcA[k]);
sum1 += mp4_Abs(dcCurr[k*8]);
}
else
for (k = 1; k < 8; k ++) {
sum0 += mp4_Abs(dcCurr[k*8]);
dcCurr[k*8] = (Ipp16s)(dcCurr[k*8] - mp4_DivIntraAC(predAcA[k] * predQuantA, bCurr->quant));
sum1 += mp4_Abs(dcCurr[k*8]);
}
}
}
} else
predDir = IPPVC_SCAN_ZIGZAG;
predictDir[i] = predDir;
dcCurr += 64;
}
*pSum0 = sum0;
*pSum1 = sum1;
}
static void mp4_RestoreIntraAC(mp4_MacroBlock *MBcurr, Ipp16s *dcCurr, Ipp32s *predDir)
{
Ipp32s i, k;
Ipp16s *predAcA, *predAcC;
mp4_Block *bCurr;
for (i = 0; i < 6; i ++) {
bCurr = &MBcurr->block[i];
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 (predDir[i] == IPPVC_SCAN_HORIZONTAL && predAcC) {
if (predAcC[0] != 0) {
for (k = 1; k < 8; k ++)
dcCurr[k] = bCurr->dct_acC[k];
}
} else if (predDir[i] == IPPVC_SCAN_VERTICAL && predAcA) {
if (predAcA[0] != 0) {
for (k = 1; k < 8; k ++)
dcCurr[k*8] = bCurr->dct_acA[k];
}
}
dcCurr += 64;
}
}
Ipp32s ippVideoEncoderMPEG4::TransMacroBlockIntra_H263(Ipp8u *pY, Ipp8u *pU, Ipp8u *pV, Ipp16s *coeffMB, Ipp32s *nzCount, Ipp32s quant)
{
Ipp32s pattern;
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);
ippiQuantIntra_H263_16s_C1I(coeffMB+0*64, quant, &nzCount[0], 0, 0);
ippiQuantIntra_H263_16s_C1I(coeffMB+1*64, quant, &nzCount[1], 0, 0);
ippiQuantIntra_H263_16s_C1I(coeffMB+2*64, quant, &nzCount[2], 0, 0);
ippiQuantIntra_H263_16s_C1I(coeffMB+3*64, quant, &nzCount[3], 0, 0);
ippiQuantIntra_H263_16s_C1I(coeffMB+4*64, quant, &nzCount[4], 0, 0);
ippiQuantIntra_H263_16s_C1I(coeffMB+5*64, quant, &nzCount[5], 0, 0);
mp4_SetPatternIntra(pattern, nzCount, coeffMB, 1);
return pattern;
}
Ipp32s ippVideoEncoderMPEG4::TransMacroBlockInter_H263(Ipp8u *pYc, Ipp8u *pUc, Ipp8u *pVc, Ipp16s *coeffMB, Ipp32s *nzCount, Ipp32s quant, Ipp8u *mcPred, Ipp32s lumaErr)
{
Ipp32s pattern, sU, sV, sL0, sL1, sL2, sL3, lim;
lim = quant * 16;
if (lumaErr < quant * 20) {
nzCount[0] = nzCount[1] = nzCount[2] = nzCount[3] = 0;
coeffMB[0*64] = coeffMB[1*64] = coeffMB[2*64] = coeffMB[3*64] = 0;
} else {
ippiSubSAD8x8_8u16s_C1R(pYc, mStepLuma, mcPred, 16, coeffMB+0*64, 16, &sL0);
ippiSubSAD8x8_8u16s_C1R(pYc+8, mStepLuma, mcPred+8, 16, coeffMB+1*64, 16, &sL1);
ippiSubSAD8x8_8u16s_C1R(pYc+8*mStepLuma, mStepLuma, mcPred+128, 16, coeffMB+2*64, 16, &sL2);
ippiSubSAD8x8_8u16s_C1R(pYc+8*mStepLuma+8, mStepLuma, mcPred+136, 16, coeffMB+3*64, 16, &sL3);
if (sL0 < lim) {
nzCount[0] = 0;
coeffMB[0*64] = 0;
} else {
ippiDCT8x8Fwd_16s_C1I(coeffMB+0*64);
ippiQuantInter_H263_16s_C1I(coeffMB+0*64, quant, &nzCount[0], 0);
}
if (sL1 < lim) {
nzCount[1] = 0;
coeffMB[1*64] = 0;
} else {
ippiDCT8x8Fwd_16s_C1I(coeffMB+1*64);
ippiQuantInter_H263_16s_C1I(coeffMB+1*64, quant, &nzCount[1], 0);
}
if (sL2 < lim) {
nzCount[2] = 0;
coeffMB[2*64] = 0;
} else {
ippiDCT8x8Fwd_16s_C1I(coeffMB+2*64);
ippiQuantInter_H263_16s_C1I(coeffMB+2*64, quant, &nzCount[2], 0);
}
if (sL3 < lim) {
nzCount[3] = 0;
coeffMB[3*64] = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -