📄 mp4decvop.c
字号:
}
*mvdy = mvd;
return MP4_STATUS_OK;
}
mp4_Status mp4_DecodeMV(mp4_Info *pInfo, IppMotionVector *mv, Ipp32s fcode)
{
Ipp32s mvdx, mvdy, range, range2, dx, dy;
if (mp4_DecodeMVD(pInfo, &mvdx, &mvdy, fcode) != MP4_STATUS_OK)
return MP4_STATUS_ERROR;
range = 16 << fcode;
range2 = range + range;
dx = mv->dx + mvdx;
if (dx < -range)
dx += range2;
else if (dx >= range)
dx -= range2;
mv->dx = (Ipp16s)dx;
dy = mv->dy + mvdy;
if (dy < -range)
dy += range2;
else if (dy >= range)
dy -= range2;
mv->dy = (Ipp16s)dy;
return MP4_STATUS_OK;
}
mp4_Status mp4_Decode4MV(mp4_Info *pInfo, IppMotionVector *mv, Ipp32s fcode)
{
Ipp32s i, mvdx, mvdy, range, range2, dx, dy;
range = 16 << fcode;
range2 = range + range;
for (i = 0; i < 4; i ++) {
if (mp4_DecodeMVD(pInfo, &mvdx, &mvdy, fcode) != MP4_STATUS_OK)
return MP4_STATUS_ERROR;
dx = mv[i].dx + mvdx;
if (dx < -range)
dx += range2;
else if (dx >= range)
dx -= range2;
mv[i].dx = (Ipp16s)dx;
dy = mv[i].dy + mvdy;
if (dy < -range)
dy += range2;
else if (dy >= range)
dy -= range2;
mv[i].dy = (Ipp16s)dy;
}
return MP4_STATUS_OK;
}
mp4_Status mp4_DecodeMV_Direct(mp4_Info *pInfo, IppMotionVector mvC[4], IppMotionVector mvForw[4], IppMotionVector mvBack[4], Ipp32s TRB, Ipp32s TRD, Ipp32s modb, Ipp32s comb_type)
{
Ipp32s mvdx, mvdy, i;
if (modb == 2) {
if (comb_type != IPPVC_MBTYPE_INTER4V) {
mvForw[0].dx = mvForw[1].dx = mvForw[2].dx = mvForw[3].dx = (Ipp16s)((TRB * mvC[0].dx) / TRD);
mvForw[0].dy = mvForw[1].dy = mvForw[2].dy = mvForw[3].dy = (Ipp16s)((TRB * mvC[0].dy) / TRD);
mvBack[0].dx = mvBack[1].dx = mvBack[2].dx = mvBack[3].dx = (Ipp16s)(((TRB - TRD) * mvC[0].dx) / TRD);
mvBack[0].dy = mvBack[1].dy = mvBack[2].dy = mvBack[3].dy = (Ipp16s)(((TRB - TRD) * mvC[0].dy) / TRD);
} else
for (i = 0; i < 4; i ++) {
mvForw[i].dx = (Ipp16s)((TRB * mvC[i].dx) / TRD);
mvForw[i].dy = (Ipp16s)((TRB * mvC[i].dy) / TRD);
mvBack[i].dx = (Ipp16s)(((TRB - TRD) * mvC[i].dx) / TRD);
mvBack[i].dy = (Ipp16s)(((TRB - TRD) * mvC[i].dy) / TRD);
}
} else {
if (mp4_DecodeMVD(pInfo, &mvdx, &mvdy, 1) != MP4_STATUS_OK)
return MP4_STATUS_ERROR;
if (comb_type != IPPVC_MBTYPE_INTER4V) {
mvForw[0].dx = mvForw[1].dx = mvForw[2].dx = mvForw[3].dx = (Ipp16s)((TRB * mvC[0].dx) / TRD + mvdx);
mvForw[0].dy = mvForw[1].dy = mvForw[2].dy = mvForw[3].dy = (Ipp16s)((TRB * mvC[0].dy) / TRD + mvdy);
if (mvdx == 0)
mvBack[0].dx = mvBack[1].dx = mvBack[2].dx = mvBack[3].dx = (Ipp16s)(((TRB - TRD) * mvC[0].dx) / TRD);
else
mvBack[0].dx = mvBack[1].dx = mvBack[2].dx = mvBack[3].dx = (Ipp16s)(mvForw[0].dx - mvC[0].dx);
if (mvdy == 0)
mvBack[0].dy = mvBack[1].dy = mvBack[2].dy = mvBack[3].dy = (Ipp16s)(((TRB - TRD) * mvC[0].dy) / TRD);
else
mvBack[0].dy = mvBack[1].dy = mvBack[2].dy = mvBack[3].dy = (Ipp16s)(mvForw[0].dy - mvC[0].dy);
} else
for (i = 0; i < 4; i++) {
mvForw[i].dx = (Ipp16s)((TRB * mvC[i].dx) / TRD + mvdx);
mvForw[i].dy = (Ipp16s)((TRB * mvC[i].dy) / TRD + mvdy);
if (mvdx == 0)
mvBack[i].dx = (Ipp16s)(((TRB - TRD) * mvC[i].dx) / TRD);
else
mvBack[i].dx = (Ipp16s)(mvForw[i].dx - mvC[i].dx);
if (mvdy == 0)
mvBack[i].dy = (Ipp16s)(((TRB - TRD) * mvC[i].dy) / TRD);
else
mvBack[i].dy = (Ipp16s)(mvForw[i].dy - mvC[i].dy);
}
}
return MP4_STATUS_OK;
}
mp4_Status mp4_DecodeMV_DirectField(mp4_Info *pInfo, Ipp32s mb_ftfr, Ipp32s mb_fbfr, IppMotionVector *mvTop, IppMotionVector *mvBottom, IppMotionVector *mvForwTop, IppMotionVector *mvForwBottom, IppMotionVector *mvBackTop, IppMotionVector *mvBackBottom, Ipp32s TRB, Ipp32s TRD, Ipp32s modb)
{
// field direct mode
Ipp32s TRDt, TRDb, TRBt, TRBb, deltaTop, deltaBottom, mvdx, mvdy;
deltaTop = mb_ftfr;
deltaBottom = mb_fbfr - 1;
if (pInfo->VisualObject.VideoObject.VideoObjectPlane.top_field_first) {
deltaTop = -deltaTop;
deltaBottom = -deltaBottom;
}
TRDt = mp4_DivRoundInf(TRD, pInfo->VisualObject.VideoObject.Tframe) * 2 + deltaTop;
TRDb = mp4_DivRoundInf(TRD, pInfo->VisualObject.VideoObject.Tframe) * 2 + deltaBottom;
TRBt = mp4_DivRoundInf(TRB, pInfo->VisualObject.VideoObject.Tframe) * 2 + deltaTop;
TRBb = mp4_DivRoundInf(TRB, pInfo->VisualObject.VideoObject.Tframe) * 2 + deltaBottom;
if (modb == 2) {
// delta == 0
mvdx = mvdy = 0;
} else {
if (mp4_DecodeMVD(pInfo, &mvdx, &mvdy, 1) != MP4_STATUS_OK)
return MP4_STATUS_ERROR;
}
mvForwTop->dx = (Ipp16s)((TRBt * mvTop->dx) / TRDt + mvdx);
if (mvdx == 0)
mvBackTop->dx = (Ipp16s)(((TRBt - TRDt) * mvTop->dx) / TRDt);
else
mvBackTop->dx = (Ipp16s)(mvForwTop->dx - mvTop->dx);
mvForwTop->dy = (Ipp16s)((TRBt * mvTop->dy * 2) / TRDt + mvdy);
if (mvdy == 0)
mvBackTop->dy = (Ipp16s)(((TRBt - TRDt) * mvTop->dy * 2) / TRDt);
else
mvBackTop->dy = (Ipp16s)(mvForwTop->dy - mvTop->dy * 2);
mvForwBottom->dx = (Ipp16s)((TRBb * mvBottom->dx) / TRDb + mvdx);
if (mvdx == 0)
mvBackBottom->dx = (Ipp16s)(((TRBb - TRDb) * mvBottom->dx) / TRDb);
else
mvBackBottom->dx = (Ipp16s)(mvForwBottom->dx - mvBottom->dx);
mvForwBottom->dy = (Ipp16s)((TRBb * mvBottom->dy * 2) / TRDb + mvdy);
if (mvdy == 0)
mvBackBottom->dy = (Ipp16s)(((TRBb - TRDb) * mvBottom->dy * 2) / TRDb);
else
mvBackBottom->dy = (Ipp16s)(mvForwBottom->dy - mvBottom->dy * 2);
mvForwTop->dy >>= 1;
mvBackTop->dy >>= 1;
mvForwBottom->dy >>= 1;
mvBackBottom->dy >>= 1;
return MP4_STATUS_OK;
}
/*static*/ void mp4_ExpandFrameReplicate(Ipp8u *pSrcDstPlane, Ipp32s frameWidth, Ipp32s frameHeight, Ipp32s expandPels, Ipp32s step)
{
Ipp8u *pDst1, *pDst2, *pSrc1, *pSrc2;
Ipp32s i, j;
Ipp32u t1, t2;
pDst1 = pSrcDstPlane + step * expandPels;
pDst2 = pDst1 + frameWidth + expandPels;
if (expandPels == 8) {
for (i = 0; i < frameHeight; i ++) {
t1 = pDst1[8] + (pDst1[8] << 8);
t2 = pDst2[-1] + (pDst2[-1] << 8);
t1 = (t1 << 16) + t1;
t2 = (t2 << 16) + t2;
((Ipp32u*)pDst1)[0] = t1;
((Ipp32u*)pDst1)[1] = t1;
((Ipp32u*)pDst2)[0] = t2;
((Ipp32u*)pDst2)[1] = t2;
pDst1 += step;
pDst2 += step;
}
} else if (expandPels == 16) {
for (i = 0; i < frameHeight; i ++) {
t1 = pDst1[16] + (pDst1[16] << 8);
t2 = pDst2[-1] + (pDst2[-1] << 8);
t1 = (t1 << 16) + t1;
t2 = (t2 << 16) + t2;
((Ipp32u*)pDst1)[0] = t1;
((Ipp32u*)pDst1)[1] = t1;
((Ipp32u*)pDst1)[2] = t1;
((Ipp32u*)pDst1)[3] = t1;
((Ipp32u*)pDst2)[0] = t2;
((Ipp32u*)pDst2)[1] = t2;
((Ipp32u*)pDst2)[2] = t2;
((Ipp32u*)pDst2)[3] = t2;
pDst1 += step;
pDst2 += step;
}
} else {
for (i = 0; i < frameHeight; i ++) {
ippsSet_8u(pDst1[expandPels], pDst1, expandPels);
ippsSet_8u(pDst2[-1], pDst2, expandPels);
pDst1 += step;
pDst2 += step;
}
}
pDst1 = pSrcDstPlane;
pSrc1 = pSrcDstPlane + expandPels * step;
pDst2 = pSrc1 + frameHeight * step;
pSrc2 = pDst2 - step;
j = frameWidth + 2 * expandPels;
for (i = 0; i < expandPels; i ++) {
ippsCopy_8u(pSrc1, pDst1, j);
ippsCopy_8u(pSrc2, pDst2, j);
pDst1 += step;
pDst2 += step;
}
}
void mp4_PadFrame(mp4_Info* pInfo)
{
#if 0
/*
// padding VOP (for not complete blocks padd by
// 0 for DivX(tm) 5.0 AVI streams
// 128 for QuickTime(tm) MP4 streams
// replication for other
*/
Ipp32s wL, hL, wC, hC, i;
//if (pInfo->VisualObject.VideoObject.short_video_header)
// return;
wL = pInfo->VisualObject.VideoObject.width;
hL = pInfo->VisualObject.VideoObject.height;
wC = pInfo->VisualObject.VideoObject.width >> 1;
hC = pInfo->VisualObject.VideoObject.height >> 1;
if ((pInfo->VisualObject.VideoObject.width & 15 || pInfo->VisualObject.VideoObject.height & 15) &&
((pInfo->ftype == 1 && pInfo->ftype_f == 0) || (pInfo->ftype == 2 && pInfo->ftype_f == 1))) {
Ipp8u pad = (Ipp8u)(pInfo->ftype == 1 ? 128 : 0);
if (pInfo->VisualObject.VideoObject.width & 15) {
Ipp8u *p;
// pad one col
p = pInfo->VisualObject.cFrame.pY + pInfo->VisualObject.VideoObject.width;
for (i = 0; i < pInfo->VisualObject.VideoObject.height; i ++) {
*p = pad;
p += pInfo->VisualObject.cFrame.stepY;
}
p = pInfo->VisualObject.cFrame.pCb + (pInfo->VisualObject.VideoObject.width >> 1);
for (i = 0; i < pInfo->VisualObject.VideoObject.height >> 1; i ++) {
*p = pad;
p += pInfo->VisualObject.cFrame.stepCb;
}
p = pInfo->VisualObject.cFrame.pCr + (pInfo->VisualObject.VideoObject.width >> 1);
for (i = 0; i < pInfo->VisualObject.VideoObject.height >> 1; i ++) {
*p = pad;
p += pInfo->VisualObject.cFrame.stepCr;
}
wL ++;
wC ++;
}
if (pInfo->VisualObject.VideoObject.height & 15) {
// pad one row
ippsSet_8u(pad, pInfo->VisualObject.cFrame.pY + pInfo->VisualObject.cFrame.stepY * pInfo->VisualObject.VideoObject.height, pInfo->VisualObject.VideoObject.width);
ippsSet_8u(pad, pInfo->VisualObject.cFrame.pCb + pInfo->VisualObject.cFrame.stepCb * (pInfo->VisualObject.VideoObject.height >> 1), pInfo->VisualObject.VideoObject.width >> 1);
ippsSet_8u(pad, pInfo->VisualObject.cFrame.pCr + pInfo->VisualObject.cFrame.stepCr * (pInfo->VisualObject.VideoObject.height >> 1), pInfo->VisualObject.VideoObject.width >> 1);
hL ++;
hC ++;
}
}
#else
/*
// padding VOP for not complete blocks
// replication from macroblock boundary for DIVX and MP4 and from frame boundary for other
*/
Ipp32s wL, hL, wC, hC;
if ((pInfo->ftype == 1 && pInfo->ftype_f == 0) || (pInfo->ftype == 2 && pInfo->ftype_f == 1)) {
wL = pInfo->VisualObject.VideoObject.MacroBlockPerRow * 16;
hL = pInfo->VisualObject.VideoObject.MacroBlockPerCol * 16;
} else {
wL = pInfo->VisualObject.VideoObject.width;
hL = pInfo->VisualObject.VideoObject.height;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -