📄 mp4decvop.c
字号:
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);
lnz = 63;
} else {
k = coeff[0] * dcScaler;
mp4_CLIP(k, -2048, 2047);
coeff[0] = (Ipp16s)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;
lastNZ[blockNum] = lnz;
pm >>= 1;
coeff += 64;
}
return MP4_STATUS_OK;
}
mp4_Status mp4_DecodeInterMB(mp4_Info *pInfo, Ipp16s *coeffMB, Ipp32s quant, Ipp32s pat, Ipp32s scan)
{
Ipp32s i, lnz, pm = 32;
Ipp16s *coeff = coeffMB;
for (i = 0; i < 6; i ++) {
if ((pat) & pm) {
if (ippiReconstructCoeffsInter_MPEG4_1u16s(&pInfo->bufptr, &pInfo->bitoff, coeff, &lnz, pInfo->VisualObject.VideoObject.reversible_vlc, scan, pInfo->VisualObject.VideoObject.QuantInvInterSpec, quant) != ippStsNoErr) {
mp4_Error("Error: decoding coefficients of Inter block");
return MP4_STATUS_ERROR;
}
if (pInfo->VisualObject.VideoObject.quant_type == 0 || (coeff[63] == 0)) {
if (lnz != 0) {
if (scan == IPPVC_SCAN_ZIGZAG) {
if ((lnz <= 4) && (coeff[16] == 0))
ippiDCT8x8Inv_2x2_16s_C1I(coeff);
else if ((lnz <= 13) && (coeff[32] == 0))
ippiDCT8x8Inv_4x4_16s_C1I(coeff);
else
ippiDCT8x8Inv_16s_C1I(coeff);
} else { // IPPVC_SCAN_VERTICAL
if ((lnz <= 5) && (coeff[16] == 0) && (coeff[24] == 0))
ippiDCT8x8Inv_2x2_16s_C1I(coeff);
else if (lnz <= 9)
ippiDCT8x8Inv_4x4_16s_C1I(coeff);
else
ippiDCT8x8Inv_16s_C1I(coeff);
}
} else {
mp4_Set64_16s((Ipp16s)((coeff[0] + 4) >> 3), coeff);
}
} else {
ippiDCT8x8Inv_16s_C1I(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;
}
void mp4_DCTInvCoeffsInterMB(mp4_Info *pInfo, Ipp16s *coeffMB, Ipp32s lastNZ[], Ipp32s pat, Ipp32s scan)
{
Ipp32s i, lnz, pm = 32;
Ipp16s *coeff = coeffMB;
for (i = 0; i < 6; i ++) {
if ((pat) & pm) {
if (pInfo->VisualObject.VideoObject.quant_type == 0 || (coeff[63] == 0)) {
lnz = lastNZ[i];
if (lnz != 0) {
if (scan == IPPVC_SCAN_ZIGZAG) {
if ((lnz <= 4) && (coeff[16] == 0))
ippiDCT8x8Inv_2x2_16s_C1I(coeff);
else if ((lnz <= 13) && (coeff[32] == 0))
ippiDCT8x8Inv_4x4_16s_C1I(coeff);
else
ippiDCT8x8Inv_16s_C1I(coeff);
} else { // IPPVC_SCAN_VERTICAL
if ((lnz <= 5) && (coeff[16] == 0) && (coeff[24] == 0))
ippiDCT8x8Inv_2x2_16s_C1I(coeff);
else if (lnz <= 9)
ippiDCT8x8Inv_4x4_16s_C1I(coeff);
else
ippiDCT8x8Inv_16s_C1I(coeff);
}
} else {
mp4_Set64_16s((Ipp16s)((coeff[0] + 4) >> 3), coeff);
}
} else {
ippiDCT8x8Inv_16s_C1I(coeff);
}
}
pm >>= 1;
coeff += 64;
}
}
/*
// decode mcbpc and set MBtype and ChromaPattern
*/
mp4_Status mp4_DecodeMCBPC_P(mp4_Info* pInfo, Ipp32s *mbType, Ipp32s *mbPattern, Ipp32s stat)
{
Ipp32u code;
Ipp32s type, pattern;
code = mp4_ShowBits9(pInfo, 9);
if (code >= 256) {
type = IPPVC_MBTYPE_INTER;
pattern = 0;
mp4_FlushBits(pInfo, 1);
} else {
type = mp4_PVOPmb_type[code];
pattern = mp4_PVOPmb_cbpc[code];
mp4_FlushBits(pInfo, mp4_PVOPmb_bits[code]);
}
if (code == 0) {
mp4_Error("Error: decoding MCBPC");
return MP4_STATUS_ERROR;
}
*mbType = type;
*mbPattern = pattern;
if (stat) {
if (type == IPPVC_MBTYPE_INTER)
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB_INTER);
else if (type == IPPVC_MBTYPE_INTER_Q)
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB_INTER_Q);
else if (type == IPPVC_MBTYPE_INTRA)
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB_INTRA);
else if (type == IPPVC_MBTYPE_INTRA_Q)
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB_INTRA_Q);
else if (type == IPPVC_MBTYPE_INTER4V)
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB_INTER4V);
}
return MP4_STATUS_OK;
}
mp4_Status mp4_PredictDecode1MV(mp4_Info *pInfo, mp4_MacroBlock *MBcurr, Ipp32s y, Ipp32s x)
{
IppMotionVector *mvLeft, *mvTop, *mvRight, *mvCurr;
Ipp32s mbInRow = pInfo->VisualObject.VideoObject.MacroBlockPerRow;
Ipp32s fcode = pInfo->VisualObject.VideoObject.VideoObjectPlane.fcode_forward;
Ipp32s resync_marker_disable = pInfo->VisualObject.VideoObject.resync_marker_disable;
// block 0
mvCurr = MBcurr[0].mv;
mvLeft = MBcurr[-1].mv;
mvTop = MBcurr[-mbInRow].mv;
mvRight = MBcurr[-mbInRow+1].mv;
if (resync_marker_disable) {
if ((y | x) == 0) {
mvCurr[0].dx = mvCurr[0].dy = 0;
} else if (x == 0) {
mvCurr[0].dx = mp4_Median(0, mvTop[2].dx, mvRight[2].dx);
mvCurr[0].dy = mp4_Median(0, mvTop[2].dy, mvRight[2].dy);
} else if (y == 0) {
mvCurr[0] = mvLeft[1];
} else if (x == mbInRow - 1) {
mvCurr[0].dx = mp4_Median(0, mvLeft[1].dx, mvTop[2].dx);
mvCurr[0].dy = mp4_Median(0, mvLeft[1].dy, mvTop[2].dy);
} else {
mvCurr[0].dx = mp4_Median(mvLeft[1].dx, mvTop[2].dx, mvRight[2].dx);
mvCurr[0].dy = mp4_Median(mvLeft[1].dy, mvTop[2].dy, mvRight[2].dy);
}
} else {
Ipp32s validLeft, validTop, validRight;
if (x > 0)
validLeft = MBcurr[-1].validPred;
else
validLeft = 0;
if (y > 0)
validTop = MBcurr[-mbInRow].validPred;
else
validTop = 0;
if ((y > 0) && (x < mbInRow - 1))
validRight = MBcurr[-mbInRow+1].validPred;
else
validRight = 0;
switch ((validLeft << 2) | (validTop << 1) | validRight) {
case 7:
mvCurr[0].dx = mp4_Median(mvLeft[1].dx, mvTop[2].dx, mvRight[2].dx);
mvCurr[0].dy = mp4_Me
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -