📄 mp4decvop.c
字号:
ippiDCT8x8Inv_2x2_16s_C1I(coeff);
else if ((lnz <= 13) && (coeff[32] == 0))
ippiDCT8x8Inv_4x4_16s_C1I(coeff);
else
ippiDCT8x8Inv_16s_C1I(coeff);
} else {
mp4_Set64_16s((Ipp16s)((coeff[0] + 4) >> 3), coeff);
}
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTER_C);
} else {
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTER_NC);
}
pm >>= 1;
coeff += 64;
}
return MP4_STATUS_OK;
}
/*
// Intra DC and AC reconstruction for macroblock
*/
mp4_Status mp4_DecodeIntraMB(mp4_Info *pInfo, Ipp32s x, Ipp32s pat, Ipp32s quant, Ipp32s dcVLC, Ipp32s ac_pred_flag, Ipp8u *pR[], Ipp32s stepR[])
{
__ALIGN16(Ipp16s, coeff, 64);
Ipp32s blockNum, lnz, predDir, scan, dc, dcA, dcB, dcC, dcP, k, nz, predQuantA, predQuantC, dcScaler, pm = 32;
Ipp16s *predAcA, *predAcC, sDC = 0;
mp4_IntraPredBlock *bCurr;
for (blockNum = 0; blockNum < 6; blockNum ++) {
// find prediction direction
bCurr = &pInfo->VisualObject.VideoObject.IntraPredBuff.block[6*x+blockNum];
dcA = bCurr->predA->dct_dc >= 0 ? bCurr->predA->dct_dc : 1024;
dcB = bCurr->predB->dct_dc >= 0 ? bCurr->predB->dct_dc : 1024;
dcC = bCurr->predC->dct_dc >= 0 ? bCurr->predC->dct_dc : 1024;
if (mp4_ABS(dcA - dcB) < mp4_ABS(dcB - dcC)) {
predDir = IPPVC_SCAN_HORIZONTAL;
dcP = dcC;
} else {
predDir = IPPVC_SCAN_VERTICAL;
dcP = dcA;
}
scan = IPPVC_SCAN_ZIGZAG;
if (pInfo->VisualObject.VideoObject.VideoObjectPlane.alternate_vertical_scan_flag)
scan = IPPVC_SCAN_VERTICAL;
else if (ac_pred_flag)
scan = predDir;
// decode coeffs
if (dcVLC) {
if (ippiDecodeDCIntra_MPEG4_1u16s(&pInfo->bufptr, &pInfo->bitoff, coeff, (blockNum < 4) ? IPPVC_BLOCK_LUMA : IPPVC_BLOCK_CHROMA) != ippStsNoErr) {
mp4_Error("Error: decoding DC coefficient of Intra block");
return MP4_STATUS_ERROR;
}
}
if (pat & pm) {
if (ippiDecodeCoeffsIntra_MPEG4_1u16s(&pInfo->bufptr, &pInfo->bitoff, coeff, &lnz, 0, dcVLC, scan) != ippStsNoErr) {
mp4_Error("Error: decoding coefficients of Intra block");
return MP4_STATUS_ERROR;
}
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTRA_AC);
} else {
if (dcVLC)
sDC = coeff[0];
mp4_Zero64_16s(coeff);
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTRA_DC);
lnz = 0;
if (dcVLC)
coeff[0] = sDC;
}
// predict DC
dcScaler = (blockNum < 4) ? mp4_DCScalerLuma[quant] : mp4_DCScalerChroma[quant];
dc = coeff[0] + mp4_DivIntraDC(dcP, dcScaler);
mp4_CLIP(dc, -2048, 2047);
coeff[0] = (Ipp16s)dc;
// predict AC
nz = 0;
if (ac_pred_flag) {
if (predDir == IPPVC_SCAN_HORIZONTAL && (bCurr->predC->dct_dc >= 0)) {
predAcC = bCurr->predC->dct_acC;
predQuantC = (blockNum == 2 || blockNum == 3) ? quant : pInfo->VisualObject.VideoObject.IntraPredBuff.quant[x+1];
if (predQuantC == quant)
for (k = 1; k < 8; k ++) {
coeff[k] = (Ipp16s)(coeff[k] + predAcC[k]);
if (coeff[k]) {
mp4_CLIP(coeff[k], -2048, 2047);
nz = 1;
}
}
else
for (k = 1; k < 8; k ++) {
coeff[k] = (Ipp16s)(coeff[k] + mp4_DivIntraAC(predAcC[k] * predQuantC, quant));
if (coeff[k]) {
mp4_CLIP(coeff[k], -2048, 2047);
nz = 1;
}
}
} else if (predDir == IPPVC_SCAN_VERTICAL && (bCurr->predA->dct_dc >= 0)) {
predAcA = bCurr->predA->dct_acA;
predQuantA = (blockNum == 1 || blockNum == 3) ? quant : pInfo->VisualObject.VideoObject.IntraPredBuff.quant[x];
if (predQuantA == quant)
for (k = 1; k < 8; k ++) {
coeff[k*8] = (Ipp16s)(coeff[k*8] + predAcA[k]);
if (coeff[k*8]) {
mp4_CLIP(coeff[k*8], -2048, 2047);
nz = 1;
}
}
else
for (k = 1; k < 8; k ++) {
coeff[k*8] = (Ipp16s)(coeff[k*8] + mp4_DivIntraAC(predAcA[k] * predQuantA, quant));
if (coeff[k*8]) {
mp4_CLIP(coeff[k*8], -2048, 2047);
nz = 1;
}
}
}
}
// copy predicted AC for future Prediction
for (k = 1; k < 8; k ++) {
bCurr[6].dct_acC[k] = coeff[k];
bCurr[6].dct_acA[k] = coeff[k*8];
}
if ((nz | lnz) || (pInfo->VisualObject.VideoObject.quant_type == 1)) {
ippiQuantInvIntra_MPEG4_16s_C1I(coeff, 63, pInfo->VisualObject.VideoObject.QuantInvIntraSpec, quant, (blockNum < 4) ? IPPVC_BLOCK_LUMA : IPPVC_BLOCK_CHROMA);
ippiDCT8x8Inv_16s8u_C1R(coeff, pR[blockNum], stepR[blockNum]);
} else {
k = coeff[0] * dcScaler;
mp4_CLIP(k, -2048, 2047);
coeff[0] = (Ipp16s)k;
k = (k + 4) >> 3;
mp4_CLIP(k, 0, 255);
mp4_Set8x8_8u(pR[blockNum], stepR[blockNum], (Ipp8u)k);
}
// copy DC for future Prediction
if (blockNum >= 3)
pInfo->VisualObject.VideoObject.IntraPredBuff.dcB[blockNum].dct_dc = bCurr[6].dct_dc;
bCurr[6].dct_dc = coeff[0];
// copy quant
if (blockNum == 5)
pInfo->VisualObject.VideoObject.IntraPredBuff.quant[x+1] = (Ipp8u)quant;
pm >>= 1;
}
return MP4_STATUS_OK;
}
/*
// Intra DC and AC reconstruction for DP macroblock
*/
mp4_Status mp4_DecodeIntraMB_DP(mp4_Info *pInfo, Ipp16s dct_dc[], Ipp32s x, Ipp32s pat, Ipp32s quant, Ipp32s dcVLC, Ipp32s ac_pred_flag, Ipp8u *pR[], Ipp32s stepR[])
{
__ALIGN16(Ipp16s, coeff, 64);
Ipp32s blockNum, lnz, predDir, scan, dc, dcA, dcB, dcC, dcP, k, nz, predQuantA, predQuantC, dcScaler, pm = 32;
Ipp16s *predAcA, *predAcC;
mp4_IntraPredBlock *bCurr;
for (blockNum = 0; blockNum < 6; blockNum ++) {
// find prediction direction
bCurr = &pInfo->VisualObject.VideoObject.IntraPredBuff.block[6*x+blockNum];
dcA = bCurr->predA->dct_dc >= 0 ? bCurr->predA->dct_dc : 1024;
dcB = bCurr->predB->dct_dc >= 0 ? bCurr->predB->dct_dc : 1024;
dcC = bCurr->predC->dct_dc >= 0 ? bCurr->predC->dct_dc : 1024;
if (mp4_ABS(dcA - dcB) < mp4_ABS(dcB - dcC)) {
predDir = IPPVC_SCAN_HORIZONTAL;
dcP = dcC;
} else {
predDir = IPPVC_SCAN_VERTICAL;
dcP = dcA;
}
scan = (ac_pred_flag) ? predDir : IPPVC_SCAN_ZIGZAG;
// decode coeffs
if (pat & pm) {
if (ippiDecodeCoeffsIntra_MPEG4_1u16s(&pInfo->bufptr, &pInfo->bitoff, coeff, &lnz, pInfo->VisualObject.VideoObject.reversible_vlc, dcVLC, scan) != ippStsNoErr) {
mp4_Error("Error: decoding coefficients of Intra block");
return MP4_STATUS_ERROR;
}
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTRA_AC);
} else {
mp4_Zero64_16s(coeff);
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTRA_DC);
lnz = 0;
}
if (dcVLC)
coeff[0] = dct_dc[blockNum];
// predict DC
dcScaler = (blockNum < 4) ? mp4_DCScalerLuma[quant] : mp4_DCScalerChroma[quant];
dc = coeff[0] + mp4_DivIntraDC(dcP, dcScaler);
mp4_CLIP(dc, -2048, 2047);
coeff[0] = (Ipp16s)dc;
// predict AC
nz = 0;
if (ac_pred_flag) {
if (predDir == IPPVC_SCAN_HORIZONTAL && (bCurr->predC->dct_dc >= 0)) {
predAcC = bCurr->predC->dct_acC;
predQuantC = (blockNum == 2 || blockNum == 3) ? quant : pInfo->VisualObject.VideoObject.IntraPredBuff.quant[x+1];
if (predQuantC == quant)
for (k = 1; k < 8; k ++) {
coeff[k] = (Ipp16s)(coeff[k] + predAcC[k]); // clip ??
if (coeff[k]) {
mp4_CLIP(coeff[k], -2048, 2047);
nz = 1;
}
}
else
for (k = 1; k < 8; k ++) {
coeff[k] = (Ipp16s)(coeff[k] + mp4_DivIntraAC(predAcC[k] * predQuantC, quant));
if (coeff[k]) {
mp4_CLIP(coeff[k], -2048, 2047);
nz = 1;
}
}
} else if (predDir == IPPVC_SCAN_VERTICAL && (bCurr->predA->dct_dc >= 0)) {
predAcA = bCurr->predA->dct_acA;
predQuantA = (blockNum == 1 || blockNum == 3) ? quant : pInfo->VisualObject.VideoObject.IntraPredBuff.quant[x];
if (predQuantA == quant)
for (k = 1; k < 8; k ++) {
coeff[k*8] = (Ipp16s)(coeff[k*8] + predAcA[k]);
if (coeff[k*8]) {
mp4_CLIP(coeff[k*8], -2048, 2047);
nz = 1;
}
}
else
for (k = 1; k < 8; k ++) {
coeff[k*8] = (Ipp16s)(coeff[k*8] + mp4_DivIntraAC(predAcA[k] * predQuantA, quant));
if (coeff[k*8]) {
mp4_CLIP(coeff[k*8], -2048, 2047);
nz = 1;
}
}
}
}
// copy predicted AC for future Prediction
for (k = 1; k < 8; k ++) {
bCurr[6].dct_acC[k] = coeff[k];
bCurr[6].dct_acA[k] = coeff[k*8];
}
if ((nz | lnz) || (pInfo->VisualObject.VideoObject.quant_type == 1)) {
ippiQuantInvIntra_MPEG4_16s_C1I(coeff, 63, pInfo->VisualObject.VideoObject.QuantInvIntraSpec, quant, (blockNum < 4) ? IPPVC_BLOCK_LUMA : IPPVC_BLOCK_CHROMA);
ippiDCT8x8Inv_16s8u_C1R(coeff, pR[blockNum], stepR[blockNum]);
} else {
k = coeff[0] * dcScaler;
mp4_CLIP(k, -2048, 2047);
coeff[0] = (Ipp16s)k;
k = (k + 4) >> 3;
mp4_CLIP(k, 0, 255);
mp4_Set8x8_8u(pR[blockNum], stepR[blockNum], (Ipp8u)k);
}
// copy DC for future Prediction
if (blockNum >= 3)
pInfo->VisualObject.VideoObject.IntraPredBuff.dcB[blockNum].dct_dc = bCurr[6].dct_dc;
bCurr[6].dct_dc = coeff[0];
// copy quant
if (blockNum == 5)
pInfo->VisualObject.VideoObject.IntraPredBuff.quant[x+1] = (Ipp8u)quant;
pm >>= 1;
}
return MP4_STATUS_OK;
}
/*
// Intra DC and AC reconstruction for macroblock (w/o iDCT)
*/
mp4_Status mp4_ReconstructCoeffsIntraMB(mp4_Info *pInfo, Ipp32s x, Ipp32s pat, Ipp32s quant, Ipp32s dcVLC, Ipp32s ac_pred_flag, Ipp16s *coeffMB, Ipp32s lastNZ[])
{
Ipp32s blockNum, lnz, predDir, scan, dc, dcA, dcB, dcC, dcP, k, nz, predQuantA, predQuantC, dcScaler, pm = 32;
Ipp16s *predAcA, *predAcC, sDC = 0, *coeff = coeffMB;
mp4_IntraPredBlock *bCurr;
for (blockNum = 0; blockNum < 6; blockNum ++) {
// find prediction direction
bCurr = &pInfo->VisualObject.VideoObject.IntraPredBuff.block[6*x+blockNum];
dcA = bCurr->predA->dct_dc >= 0 ? bCurr->predA->dct_dc : 1024;
dcB = bCurr->predB->dct_dc >= 0 ? bCurr->predB->dct_dc : 1024;
dcC = bCurr->predC->dct_dc >= 0 ? bCurr->predC->dct_dc : 1024;
if (mp4_ABS(dcA - dcB) < mp4_ABS(dcB - dcC)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -