📄 mp4decvop.c
字号:
wC = wL >> 1;
hC = hL >> 1;
#endif
mp4_ExpandFrameReplicate(pInfo->VisualObject.cFrame.apY, wL, hL, 16 * MP4_NUM_EXT_MB, pInfo->VisualObject.cFrame.stepY);
mp4_ExpandFrameReplicate(pInfo->VisualObject.cFrame.apCb, wC, hC, 8 * MP4_NUM_EXT_MB, pInfo->VisualObject.cFrame.stepCb);
mp4_ExpandFrameReplicate(pInfo->VisualObject.cFrame.apCr, wC, hC, 8 * MP4_NUM_EXT_MB, pInfo->VisualObject.cFrame.stepCr);
/*
if (pInfo->VisualObject.VideoObject.interlaced) {
Ipp8u *psb, *pdb, *pst, *pdt;
// pad fields
psb = pInfo->VisualObject.cFrame.pY + pInfo->VisualObject.cFrame.stepY - 16;
pdb = psb - (pInfo->VisualObject.cFrame.stepY << 1);
pst = pInfo->VisualObject.cFrame.pY + pInfo->VisualObject.cFrame.stepY * (pInfo->VisualObject.VideoObject.height - 2) - 16;
pdt = pst + (pInfo->VisualObject.cFrame.stepY << 1);
for (i = 0; i < 8; i ++) {
ippsCopy_8u(psb, pdb, pInfo->VisualObject.cFrame.stepY);
pdb -= (pInfo->VisualObject.cFrame.stepY << 1);
ippsCopy_8u(pst, pdt, pInfo->VisualObject.cFrame.stepY);
pdt += (pInfo->VisualObject.cFrame.stepY << 1);
}
}
*/
}
mp4_Status mp4_DecodeVideoObjectPlane(mp4_Info* pInfo)
{
mp4_Status status = MP4_STATUS_OK;
Ipp64s vop_time;
// set VOP time
if (pInfo->VisualObject.VideoObject.short_video_header) {
vop_time = pInfo->VisualObject.VideoObject.vop_sync_time + pInfo->VisualObject.VideoObject.VideoObjectPlaneH263.temporal_reference * 1001;
if (pInfo->VisualObject.cFrame.time > vop_time) {
pInfo->VisualObject.VideoObject.vop_sync_time += 256 * 1001;
vop_time += 256 * 1001;
}
} else {
if (pInfo->VisualObject.VideoObject.VideoObjectPlane.coding_type == MP4_VOP_TYPE_B) {
vop_time = pInfo->VisualObject.VideoObject.vop_sync_time_b + pInfo->VisualObject.VideoObject.VideoObjectPlane.modulo_time_base * pInfo->VisualObject.VideoObject.vop_time_increment_resolution + pInfo->VisualObject.VideoObject.VideoObjectPlane.time_increment;
} else {
if (pInfo->VisualObject.VideoObject.GroupOfVideoObjectPlane.time_code > pInfo->VisualObject.VideoObject.vop_sync_time)
pInfo->VisualObject.VideoObject.vop_sync_time = pInfo->VisualObject.VideoObject.GroupOfVideoObjectPlane.time_code;
vop_time = pInfo->VisualObject.VideoObject.vop_sync_time + pInfo->VisualObject.VideoObject.VideoObjectPlane.modulo_time_base * pInfo->VisualObject.VideoObject.vop_time_increment_resolution + pInfo->VisualObject.VideoObject.VideoObjectPlane.time_increment;
if (pInfo->VisualObject.VideoObject.vop_sync_time_b < pInfo->VisualObject.VideoObject.vop_sync_time)
pInfo->VisualObject.VideoObject.vop_sync_time_b = pInfo->VisualObject.VideoObject.vop_sync_time;
if (pInfo->VisualObject.VideoObject.VideoObjectPlane.modulo_time_base != 0) {
pInfo->VisualObject.VideoObject.vop_sync_time = vop_time - pInfo->VisualObject.VideoObject.VideoObjectPlane.time_increment;
}
}
}
// if (pInfo->VisualObject.VideoObject.VideoObjectPlane.coded || vop_time != pInfo->VisualObject.rFrame.time) {
if (pInfo->VisualObject.VideoObject.VideoObjectPlane.coded ||
(vop_time != pInfo->VisualObject.cFrame.time &&
vop_time != pInfo->VisualObject.rFrame.time &&
vop_time != pInfo->VisualObject.nFrame.time)) {
switch (pInfo->VisualObject.VideoObject.VideoObjectPlane.coding_type) {
case MP4_VOP_TYPE_I :
// set new video frame
if (pInfo->VisualObject.VideoObject.sprite_enable == MP4_SPRITE_STATIC) {
mp4_SWAP(mp4_Frame, pInfo->VisualObject.sFrame, pInfo->VisualObject.cFrame);
} else {
if (pInfo->noPVOPs) {
pInfo->VisualObject.vFrame = &pInfo->VisualObject.cFrame;
} else if (pInfo->noBVOPs) {
mp4_SWAP(mp4_Frame, pInfo->VisualObject.rFrame, pInfo->VisualObject.cFrame);
pInfo->VisualObject.vFrame = &pInfo->VisualObject.cFrame;
} else {
if (pInfo->VisualObject.VideoObject.VOPindex > 0) {
if (pInfo->VisualObject.VideoObject.prevPlaneIsB) {
mp4_SWAP(mp4_Frame, pInfo->VisualObject.rFrame, pInfo->VisualObject.nFrame);
pInfo->VisualObject.VideoObject.prevPlaneIsB = 0;
} else {
mp4_SWAP(mp4_Frame, pInfo->VisualObject.rFrame, pInfo->VisualObject.cFrame);
}
pInfo->VisualObject.vFrame = &pInfo->VisualObject.rFrame;
}
}
}
if (pInfo->VisualObject.VideoObject.VideoObjectPlane.coded) {
if (pInfo->VisualObject.VideoObject.shape == MP4_SHAPE_TYPE_RECTANGULAR) {
#ifdef _OMP_KARABAS
if (!pInfo->VisualObject.VideoObject.data_partitioned && pInfo->num_threads >= 2)
status = mp4_DecodeVOP_I_MT(pInfo);
else
#endif
status = mp4_DecodeVOP_I(pInfo);
} //f else
//f status = mp4_DecodeVOP_I_Shape(pInfo);
if (pInfo->VisualObject.VideoObject.sprite_enable == MP4_SPRITE_STATIC && pInfo->VisualObject.VideoObject.VOPindex == 0) {
mp4_SWAP(mp4_Frame, pInfo->VisualObject.sFrame, pInfo->VisualObject.cFrame);
mp4_ExpandFrameReplicate(pInfo->VisualObject.sFrame.apY, pInfo->VisualObject.VideoObject.sprite_width, pInfo->VisualObject.VideoObject.sprite_height, 16, pInfo->VisualObject.sFrame.stepY);
mp4_ExpandFrameReplicate(pInfo->VisualObject.sFrame.apCb, pInfo->VisualObject.VideoObject.sprite_width >> 1, pInfo->VisualObject.VideoObject.sprite_height >> 1, 8, pInfo->VisualObject.sFrame.stepCb);
mp4_ExpandFrameReplicate(pInfo->VisualObject.sFrame.apCr, pInfo->VisualObject.VideoObject.sprite_width >> 1, pInfo->VisualObject.VideoObject.sprite_height >> 1, 8, pInfo->VisualObject.sFrame.stepCr);
} else {
mp4_PadFrame(pInfo);
}
// set past and future time for B-VOP
pInfo->VisualObject.VideoObject.rTime = pInfo->VisualObject.VideoObject.nTime;
pInfo->VisualObject.VideoObject.nTime = vop_time;
#ifdef USE_NOTCODED_STATE
// Clear not_coded MB state
if ((pInfo->VisualObject.VideoObject.sprite_enable != MP4_SPRITE_STATIC) && pInfo->VisualObject.VideoObject.obmc_disable && !pInfo->VisualObject.VideoObject.ncStateCleared) {
ippsZero_8u(pInfo->VisualObject.VideoObject.ncState, pInfo->VisualObject.VideoObject.MacroBlockPerVOP);
pInfo->VisualObject.VideoObject.ncStateCleared = 1;
}
#endif
}
mp4_StatisticInc(&pInfo->VisualObject.Statistic.nVOP_I);
break;
case MP4_VOP_TYPE_P :
// set new video frame
if (pInfo->noBVOPs) {
mp4_SWAP(mp4_Frame, pInfo->VisualObject.rFrame, pInfo->VisualObject.cFrame);
pInfo->VisualObject.vFrame = &pInfo->VisualObject.cFrame;
} else {
if (pInfo->VisualObject.VideoObject.VOPindex > 0) {
if (pInfo->VisualObject.VideoObject.prevPlaneIsB) {
mp4_SWAP(mp4_Frame, pInfo->VisualObject.rFrame, pInfo->VisualObject.nFrame);
pInfo->VisualObject.VideoObject.prevPlaneIsB = 0;
} else {
mp4_SWAP(mp4_Frame, pInfo->VisualObject.rFrame, pInfo->VisualObject.cFrame);
}
pInfo->VisualObject.vFrame = &pInfo->VisualObject.rFrame;
}
}
if (pInfo->VisualObject.VideoObject.VideoObjectPlane.coded) {
#ifdef _OMP_KARABAS
if (!pInfo->VisualObject.VideoObject.data_partitioned && pInfo->num_threads >= 2)
status = mp4_DecodeVOP_P_MT(pInfo);
else
#endif
status = mp4_DecodeVOP_P(pInfo);
mp4_PadFrame(pInfo);
// set past and future time for B-VOP
pInfo->VisualObject.VideoObject.rTime = pInfo->VisualObject.VideoObject.nTime;
pInfo->VisualObject.VideoObject.nTime = vop_time;
}
mp4_StatisticInc(&pInfo->VisualObject.Statistic.nVOP_P);
#ifdef USE_NOTCODED_STATE
pInfo->VisualObject.VideoObject.ncStateCleared = 0;
#endif
break;
case MP4_VOP_TYPE_B :
status = MP4_STATUS_OK;
if (!pInfo->VisualObject.VideoObject.prevPlaneIsB) {
mp4_SWAP(mp4_Frame, pInfo->VisualObject.nFrame, pInfo->VisualObject.cFrame);
pInfo->VisualObject.VideoObject.prevPlaneIsB = 1;
}
// after reset it is need to skip first B-frames
pInfo->VisualObject.vFrame = (pInfo->VisualObject.VideoObject.VOPindex < 2) ? NULL : &pInfo->VisualObject.cFrame;
// set Tframe for direct interlaced mode
if (!pInfo->VisualObject.VideoObject.Tframe)
pInfo->VisualObject.VideoObject.Tframe = (Ipp32s)(vop_time - pInfo->VisualObject.rFrame.time);
if (pInfo->VisualObject.VideoObject.VideoObjectPlane.coded) {
pInfo->VisualObject.VideoObject.TRB = (Ipp32s)(vop_time - pInfo->VisualObject.VideoObject.rTime);
pInfo->VisualObject.VideoObject.TRD = (Ipp32s)(pInfo->VisualObject.VideoObject.nTime - pInfo->VisualObject.VideoObject.rTime);
// defense from bad streams when B-VOPs are before Past and/or Future
if (pInfo->VisualObject.VideoObject.TRB <= 0)
pInfo->VisualObject.VideoObject.TRB = 1;
if (pInfo->VisualObject.VideoObject.TRD <= 0)
pInfo->VisualObject.VideoObject.TRD = 2;
if (pInfo->VisualObject.VideoObject.TRD <= pInfo->VisualObject.VideoObject.TRB) {
pInfo->VisualObject.VideoObject.TRB = 1;
pInfo->VisualObject.VideoObject.TRD = 2;
}
if (pInfo->VisualObject.VideoObject.Tframe >= pInfo->VisualObject.VideoObject.TRD)
pInfo->VisualObject.VideoObject.Tframe = pInfo->VisualObject.VideoObject.TRB;
#ifdef _OMP_KARABAS
if (pInfo->num_threads >= 2)
status = mp4_DecodeVOP_B_MT(pInfo);
else
#endif
status = mp4_DecodeVOP_B(pInfo);
}
mp4_StatisticInc(&pInfo->VisualObject.Statistic.nVOP_B);
break;
case MP4_VOP_TYPE_S :
// set new video frame
if (pInfo->VisualObject.VideoObject.sprite_enable == MP4_SPRITE_GMC) {
if (pInfo->VisualObject.VideoObject.VOPindex > 0) {
if (pInfo->VisualObject.VideoObject.prevPlaneIsB) {
mp4_SWAP(mp4_Frame, pInfo->VisualObject.rFrame, pInfo->VisualObject.nFrame);
pInfo->VisualObject.VideoObject.prevPlaneIsB = 0;
} else {
mp4_SWAP(mp4_Frame, pInfo->VisualObject.rFrame, pInfo->VisualObject.cFrame);
}
pInfo->VisualObject.vFrame = &pInfo->VisualObject.rFrame;
}
} else
pInfo->VisualObject.vFrame = &pInfo->VisualObject.cFrame;
if (pInfo->VisualObject.VideoObject.VideoObjectPlane.coded) {
#ifdef _OMP_KARABAS
if (!pInfo->VisualObject.VideoObject.data_partitioned && pInfo->num_threads >= 2)
status = mp4_DecodeVOP_S_MT(pInfo);
else
#endif
status = mp4_DecodeVOP_S(pInfo);
if (pInfo->VisualObject.VideoObject.sprite_enable == MP4_SPRITE_GMC) {
mp4_PadFrame(pInfo);
// set past and future time for B-VOP
pInfo->VisualObject.VideoObject.rTime = pInfo->VisualObject.VideoObject.nTime;
pInfo->VisualObject.VideoObject.nTime = vop_time;
}
#ifdef USE_NOTCODED_STATE
// Clear not_coded MB state
if ((pInfo->VisualObject.VideoObject.sprite_enable != MP4_SPRITE_STATIC) && pInfo->VisualObject.VideoObject.obmc_disable && !pInfo->VisualObject.VideoObject.ncStateCleared) {
ippsZero_8u(pInfo->VisualObject.VideoObject.ncState, pInfo->VisualObject.VideoObject.MacroBlockPerVOP);
pInfo->VisualObject.VideoObject.ncStateCleared = 1;
}
#endif
}
mp4_StatisticInc(&pInfo->VisualObject.Statistic.nVOP_S);
break;
}
if (!pInfo->VisualObject.VideoObject.VideoObjectPlane.coded) {
ippsCopy_8u(pInfo->VisualObject.rFrame.apY, pInfo->VisualObject.cFrame.apY, pInfo->VisualObject.cFrame.stepY * ((pInfo->VisualObject.VideoObject.MacroBlockPerCol + 2) << 4));
ippsCopy_8u(pInfo->VisualObject.rFrame.apCb, pInfo->VisualObject.cFrame.apCb, pInfo->VisualObject.cFrame.stepCb * ((pInfo->VisualObject.VideoObject.MacroBlockPerCol + 2) << 3));
ippsCopy_8u(pInfo->VisualObject.rFrame.apCr, pInfo->VisualObject.cFrame.apCr, pInfo->VisualObject.cFrame.stepCr * ((pInfo->VisualObject.VideoObject.MacroBlockPerCol + 2) << 3));
#ifdef USE_NOTCODED_STATE
ippsSet_8u(1, pInfo->VisualObject.VideoObject.ncState, pInfo->VisualObject.VideoObject.MacroBlockPerVOP);
pInfo->VisualObject.VideoObject.ncStateCleared = 0;
#endif
}
mp4_StatisticInc(&pInfo->VisualObject.Statistic.nVOP);
}
// save current VOP type
pInfo->VisualObject.cFrame.type = pInfo->VisualObject.VideoObject.VideoObjectPlane.coding_type;
// save current VOP time
pInfo->VisualObject.cFrame.time = vop_time;
return status;
}
/*
// Intra DC and AC reconstruction for SVH macroblock
*/
mp4_Status mp4_DecodeIntraMB_SVH(mp4_Info *pInfo, Ipp32s pat, Ipp32s quant, Ipp8u *pR[], Ipp32s stepR[])
{
__ALIGN16(Ipp16s, coeff, 64);
Ipp32s blockNum, pm = 32, lnz;
for (blockNum = 0; blockNum < 6; blockNum ++) {
if (ippiReconstructCoeffsIntra_H263_1u16s(&pInfo->bufptr, &pInfo->bitoff, coeff, &lnz, pat & pm, quant, 0, IPPVC_SCAN_ZIGZAG, 0) != ippStsNoErr) {
mp4_Error("Error: decoding coefficients of Inter block");
return MP4_STATUS_ERROR;
}
if (lnz > 0) {
ippiDCT8x8Inv_16s8u_C1R(coeff, pR[blockNum], stepR[blockNum]);
} else {
mp4_Set8x8_8u(pR[blockNum], stepR[blockNum], (Ipp8u)((coeff[0] + 4) >> 3));
}
if (pat & pm) {
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTRA_AC);
} else {
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTRA_DC);
}
pm >>= 1;
}
return MP4_STATUS_OK;
}
mp4_Status mp4_DecodeInterMB_SVH(mp4_Info *pInfo, Ipp16s *coeffMB, Ipp32s quant, Ipp32s pat)
{
Ipp32s i, lnz, pm = 32;
Ipp16s *coeff = coeffMB;
for (i = 0; i < 6; i ++) {
if ((pat) & pm) {
if (ippiReconstructCoeffsInter_H263_1u16s(&pInfo->bufptr, &pInfo->bitoff, coeff, &lnz, quant, 0) != ippStsNoErr) {
mp4_Error("Error: decoding coefficients of Inter block");
return MP4_STATUS_ERROR;
}
if (lnz != 0) {
if ((lnz <= 4) && (coeff[16] == 0))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -