📄 h263decfuncs.c
字号:
h263_Status h263_PredictDecode4MV(h263_Info *pInfo, h263_MacroBlock *MBcurr, Ipp32s frGOB, Ipp32s y, Ipp32s x)
{
IppMotionVector *mvLeft, *mvTop, *mvRight, *mvCurr;
h263_VideoPicture *VPic = &pInfo->VideoSequence.VideoPicture;
Ipp32s mbInRow = VPic->MacroBlockPerRow;
Ipp32s mvdx, mvdy;
h263_Status status;
Ipp32s noUMVplus = !VPic->oppmodes.UMV;
Ipp32s noUMV = noUMVplus && !VPic->modes.UMV;
mvCurr = MBcurr[0].mv;
mvLeft = MBcurr[-1].mv;
mvTop = MBcurr[-mbInRow].mv;
mvRight = MBcurr[-mbInRow+1].mv;
/* block 0 */
if (y == frGOB && x == 0) {
mvCurr[0].dx = mvCurr[0].dy = 0;
} else if (x == 0) {
mvCurr[0].dx = h263_Median(0, mvTop[2].dx, mvRight[2].dx);
mvCurr[0].dy = h263_Median(0, mvTop[2].dy, mvRight[2].dy);
} else if (y == frGOB) {
mvCurr[0] = mvLeft[1];
} else if (x == mbInRow - 1) {
mvCurr[0].dx = h263_Median(0, mvLeft[1].dx, mvTop[2].dx);
mvCurr[0].dy = h263_Median(0, mvLeft[1].dy, mvTop[2].dy);
} else {
mvCurr[0].dx = h263_Median(mvLeft[1].dx, mvTop[2].dx, mvRight[2].dx);
mvCurr[0].dy = h263_Median(mvLeft[1].dy, mvTop[2].dy, mvRight[2].dy);
}
if (noUMV) {
status = h263_DecodeMV(pInfo, &mvCurr[0], -32, 31);
} else if (noUMVplus) {
status = h263_DecodeMV(pInfo, &mvCurr[0], -63, 63);
} else {
status = h263_DecodeMVD_umvplus(pInfo, &mvdx, &mvdy);
mvCurr[0].dx = mvCurr[0].dx + (Ipp16s)mvdx;
mvCurr[0].dy = mvCurr[0].dy + (Ipp16s)mvdy;
}
if (status != H263_STATUS_OK)
return status;
/* block 1 */
if (y == frGOB) {
mvCurr[1] = mvCurr[0];
} else if (x == mbInRow - 1) {
mvCurr[1].dx = h263_Median(mvCurr[0].dx, mvTop[3].dx, 0);
mvCurr[1].dy = h263_Median(mvCurr[0].dy, mvTop[3].dy, 0);
} else {
mvCurr[1].dx = h263_Median(mvCurr[0].dx, mvTop[3].dx, mvRight[2].dx);
mvCurr[1].dy = h263_Median(mvCurr[0].dy, mvTop[3].dy, mvRight[2].dy);
}
if (noUMV) {
status = h263_DecodeMV(pInfo, &mvCurr[1], -32, 31);
} else if (noUMVplus) {
status = h263_DecodeMV(pInfo, &mvCurr[1], -63, 63);
} else {
status = h263_DecodeMVD_umvplus(pInfo, &mvdx, &mvdy);
mvCurr[1].dx = mvCurr[1].dx + (Ipp16s)mvdx;
mvCurr[1].dy = mvCurr[1].dy + (Ipp16s)mvdy;
}
if (status != H263_STATUS_OK)
return status;
/* block 2 */
if (x == 0) {
mvCurr[2].dx = h263_Median(0, mvCurr[0].dx, mvCurr[1].dx);
mvCurr[2].dy = h263_Median(0, mvCurr[0].dy, mvCurr[1].dy);
} else {
mvCurr[2].dx = h263_Median(mvLeft[3].dx, mvCurr[0].dx, mvCurr[1].dx);
mvCurr[2].dy = h263_Median(mvLeft[3].dy, mvCurr[0].dy, mvCurr[1].dy);
}
if (noUMV) {
status = h263_DecodeMV(pInfo, &mvCurr[2], -32, 31);
} else if (noUMVplus) {
status = h263_DecodeMV(pInfo, &mvCurr[2], -63, 63);
} else {
status = h263_DecodeMVD_umvplus(pInfo, &mvdx, &mvdy);
mvCurr[2].dx = mvCurr[2].dx + (Ipp16s)mvdx;
mvCurr[2].dy = mvCurr[2].dy + (Ipp16s)mvdy;
}
if (status != H263_STATUS_OK)
return status;
/* block 3 */
mvCurr[3].dx = h263_Median(mvCurr[2].dx, mvCurr[0].dx, mvCurr[1].dx);
mvCurr[3].dy = h263_Median(mvCurr[2].dy, mvCurr[0].dy, mvCurr[1].dy);
if (noUMV) {
status = h263_DecodeMV(pInfo, &mvCurr[3], -32, 31);
} else if (noUMVplus) {
status = h263_DecodeMV(pInfo, &mvCurr[3], -63, 63);
} else {
status = h263_DecodeMVD_umvplus(pInfo, &mvdx, &mvdy);
mvCurr[3].dx = mvCurr[3].dx + (Ipp16s)mvdx;
mvCurr[3].dy = mvCurr[3].dy + (Ipp16s)mvdy;
}
if (status != H263_STATUS_OK)
return status;
return H263_STATUS_OK;
}
void h263_OBMC(h263_Info *pInfo, h263_MacroBlock *pMBinfo, IppMotionVector *mvCur, Ipp32s colNum, Ipp32s rowNum, IppiRect limitRectL, Ipp8u *pYc, Ipp32s stepYc, Ipp8u *pYr, Ipp32s stepYr, Ipp32s cbpy, Ipp16s *coeffMB)
{
IppMotionVector mvOBMCL, mvOBMCU, mvOBMCR, mvOBMCB, *mvLeft, *mvUpper, *mvRight;
h263_VideoPicture *VPic = &pInfo->VideoSequence.VideoPicture;
Ipp32s mbPerRow = VPic->MacroBlockPerRow, dx, dy, rt;
/* get Right MV */
if (colNum == mbPerRow - 1)
mvRight = &mvCur[1];
else if ((pMBinfo[1].type & 0xC0) == 0x80) /* INTRA(_Q), no vector for B-part */
mvRight = &mvCur[1];
else
mvRight = pMBinfo[1].mv;
/* get Left MV */
if (colNum == 0)
mvLeft = mvCur - 1;
else if ((pMBinfo[-1].type & 0xC0) == 0x80)
mvLeft = mvCur - 1;
else
mvLeft = pMBinfo[-1].mv;
/* get Upper MV */
if (rowNum == 0)
mvUpper = mvCur - 2;
else if ((pMBinfo[-mbPerRow].type & 0xC0) == 0x80)
mvUpper = mvCur - 2;
else
mvUpper = pMBinfo[-mbPerRow].mv;
dx = colNum * 16;
dy = rowNum * 16;
rt = VPic->rtype;
h263_LimitMV(&mvLeft[1], &mvOBMCL, &limitRectL, dx, dy, 8);
h263_LimitMV(&mvUpper[2], &mvOBMCU, &limitRectL, dx, dy, 8);
h263_LimitMV(&mvCur[1], &mvOBMCR, &limitRectL, dx, dy, 8);
h263_LimitMV(&mvCur[2], &mvOBMCB, &limitRectL, dx, dy, 8);
ippiOBMC8x8HP_MPEG4_8u_C1R(pYr, stepYr, pYc, stepYc, &mvCur[0], &mvOBMCL, &mvOBMCR, &mvOBMCU, &mvOBMCB, rt);
h263_LimitMV(&mvCur[0], &mvOBMCL, &limitRectL, dx+8, dy, 8);
h263_LimitMV(&mvUpper[3], &mvOBMCU, &limitRectL, dx+8, dy, 8);
h263_LimitMV(&mvRight[0], &mvOBMCR, &limitRectL, dx+8, dy, 8);
h263_LimitMV(&mvCur[3], &mvOBMCB, &limitRectL, dx+8, dy, 8);
ippiOBMC8x8HP_MPEG4_8u_C1R(pYr+8, stepYr, pYc+8, stepYc, &mvCur[1], &mvOBMCL, &mvOBMCR, &mvOBMCU, &mvOBMCB, rt);
h263_LimitMV(&mvLeft[3], &mvOBMCL, &limitRectL, dx, dy+8, 8);
h263_LimitMV(&mvCur[0], &mvOBMCU, &limitRectL, dx, dy+8, 8);
h263_LimitMV(&mvCur[3], &mvOBMCR, &limitRectL, dx, dy+8, 8);
ippiOBMC8x8HP_MPEG4_8u_C1R(pYr+stepYr*8, stepYr, pYc+stepYc*8, stepYc, &mvCur[2], &mvOBMCL, &mvOBMCR, &mvOBMCU, &mvCur[2], rt);
h263_LimitMV(&mvCur[2], &mvOBMCL, &limitRectL, dx+8, dy+8, 8);
h263_LimitMV(&mvCur[1], &mvOBMCU, &limitRectL, dx+8, dy+8, 8);
h263_LimitMV(&mvRight[2], &mvOBMCR, &limitRectL, dx+8, dy+8, 8);
ippiOBMC8x8HP_MPEG4_8u_C1R(pYr+8+stepYr*8, stepYr, pYc+8+stepYc*8, stepYc, &mvCur[3], &mvOBMCL, &mvOBMCR, &mvOBMCU, &mvCur[3], rt);
h263_AddResidual(cbpy & 8, pYc, stepYc, coeffMB);
h263_AddResidual(cbpy & 4, pYc+8, stepYc, coeffMB+64);
h263_AddResidual(cbpy & 2, pYc+stepYc*8, stepYc, coeffMB+128);
h263_AddResidual(cbpy & 1, pYc+stepYc*8+8, stepYc, coeffMB+192);
}
Ipp32s h263_UpdateQuant_Mod(h263_Info *pInfo)
{
h263_VideoPicture *VPic = &pInfo->VideoSequence.VideoPicture;
Ipp32s quant = VPic->pic_quant;
Ipp32s dquant, quant_c;
Ipp32u code;
code = h263_ShowBits9(pInfo, 6);
if (code >= 32) {
dquant = (code >> 4) & 1;
VPic->pic_quant = h263_dquant_Mod[dquant][quant - 1];
h263_FlushBits(pInfo, 2);
} else {
VPic->pic_quant = code;
h263_FlushBits(pInfo, 6);
}
quant_c = h263_quant_c[VPic->pic_quant];
return quant_c;
}
/* intra-macroblock horizontal boundaries are processed in h263_DecodeFrame_P() */
void h263_DeblockingFilter_P(h263_Info *pInfo, h263_Frame *frame)
{
Ipp8u *pYc, *pCbc, *pCrc;
Ipp32s stepYc, stepCbc, stepCrc, mbPerRow, mbPerCol;
h263_MacroBlock *pMBinfo;
Ipp32s quant, quant_c;
Ipp32s i, j;
h263_VideoPicture *VPic = &pInfo->VideoSequence.VideoPicture;
stepYc = frame->stepY;
stepCbc = frame->stepCb;
stepCrc = frame->stepCr;
mbPerRow = frame->mbPerRow;
mbPerCol = frame->mbPerCol;
/* Horizontal */
for (i = 1; i < mbPerCol; i++) {
if (pInfo->VideoSequence.GOBboundary[i] > 0)
continue; /* no filtering across GOB boundaries */
pYc = frame->pY + (stepYc << 4)*i;
pCbc = frame->pCb + (stepCbc << 3)*i;
pCrc = frame->pCr + (stepCrc << 3)*i;
pMBinfo = pInfo->VideoSequence.MBinfo + mbPerRow*i;
for (j = 0; j < mbPerRow; j++) {
if (pMBinfo[j].type != IPPVC_MB_STUFFING) {
quant = pMBinfo[j].quant;
quant_c = VPic->oppmodes.modQuant ? h263_quant_c[quant] : quant;
H263_MB_HOR_DEBLOCKING(pYc, stepYc, pCbc, stepCbc, pCrc, stepCrc, quant, quant_c);
} else if (pMBinfo[j-mbPerRow].type != IPPVC_MB_STUFFING) {
quant = pMBinfo[j-mbPerRow].quant;
quant_c = VPic->oppmodes.modQuant ? h263_quant_c[quant] : quant;
H263_MB_HOR_DEBLOCKING(pYc, stepYc, pCbc, stepCbc, pCrc, stepCrc, quant, quant_c);
}
pYc += 16;
pCbc += 8;
pCrc += 8;
}
}
/* Vertical */
for (i = 0; i < mbPerCol; i++) {
if (pInfo->VideoSequence.GOBboundary[i] > 1)
continue; /* the row belongs to a skipped GOB */
pYc = frame->pY + (stepYc << 4)*i;
pCbc = frame->pCb + (stepCbc << 3)*i;
pCrc = frame->pCr + (stepCrc << 3)*i;
pMBinfo = pInfo->VideoSequence.MBinfo + mbPerRow*i;
if (pMBinfo[0].type != IPPVC_MB_STUFFING) {
H263_MB_INTERNAL_VER_DEBLOCKING_LUM(pYc, stepYc, quant);
}
for (j = 1; j < mbPerRow; j++) {
pYc += 16;
pCbc += 8;
pCrc += 8;
if (pMBinfo[j].type != IPPVC_MB_STUFFING) {
quant = pMBinfo[j].quant;
quant_c = VPic->oppmodes.modQuant ? h263_quant_c[quant] : quant;
H263_MB_VER_DEBLOCKING(pYc, stepYc, pCbc, stepCbc, pCrc, stepCrc, quant, quant_c);
H263_MB_INTERNAL_VER_DEBLOCKING_LUM(pYc, stepYc, quant);
} else if (pMBinfo[j-1].type != IPPVC_MB_STUFFING) {
quant = pMBinfo[j-1].quant;
quant_c = VPic->oppmodes.modQuant ? h263_quant_c[quant] : quant;
H263_MB_VER_DEBLOCKING(pYc, stepYc, pCbc, stepCbc, pCrc, stepCrc, quant, quant_c);
}
}
}
}
void h263_DeblockingFilter_I(h263_Info *pInfo, h263_Frame *frame)
{
Ipp8u *pYc, *pCbc, *pCrc;
Ipp32s stepYc, stepCbc, stepCrc, mbPerRow, mbPerCol;
h263_MacroBlock *pMBinfo;
Ipp32s quant, quant_c;
Ipp32s i, j;
h263_VideoPicture *VPic = &pInfo->VideoSequence.VideoPicture;
Ipp32s modQ = VPic->oppmodes.modQuant;
stepYc = frame->stepY;
stepCbc = frame->stepCb;
stepCrc = frame->stepCr;
mbPerRow = frame->mbPerRow;
mbPerCol = frame->mbPerCol;
for (i = 1; i < mbPerCol; i++) {
pYc = frame->pY + (stepYc << 4)*i;
pCbc = frame->pCb + (stepCbc << 3)*i;
pCrc = frame->pCr + (stepCrc << 3)*i;
pMBinfo = pInfo->VideoSequence.MBinfo + mbPerRow*i;
if (pInfo->VideoSequence.GOBboundary[i] > 0) {
if (pInfo->VideoSequence.GOBboundary[i] > 1) {
continue; /* the row belongs to a skipped GOB */
} else { /* no horizontal filtering across GOB boundary */
quant = pMBinfo[-mbPerRow].quant;
H263_MB_INTERNAL_VER_DEBLOCKING_LUM(pYc-16*stepYc, stepYc, quant);
for (j = 1; j < mbPerRow; j++) {
pYc += 16;
pCbc += 8;
pCrc += 8;
quant = pMBinfo[j-mbPerRow].quant;
quant_c = modQ ? h263_quant_c[quant] : quant;
H263_MB_VER_DEBLOCKING(pYc-16*stepYc, stepYc, pCbc-8*stepCbc, stepCbc, pCrc-8*stepCrc, stepCrc, quant, quant_c);
H263_MB_INTERNAL_VER_DEBLOCKING_LUM(pYc - 16*stepYc, stepYc, quant);
}
}
} else {
quant = pMBinfo[0].quant;
quant_c = modQ ? h263_quant_c[quant] : quant;
H263_MB_HOR_DEBLOCKING(pYc, stepYc, pCbc, stepCbc, pCrc, stepCrc, quant, quant_c);
H263_MB_INTERNAL_VER_DEBLOCKING_LUM(pYc - 16*stepYc, stepYc, pMBinfo[-mbPerRow].quant);
for (j = 1; j < mbPerRow; j++) {
pYc += 16;
pCbc += 8;
pCrc += 8;
quant = pMBinfo[j].quant;
quant_c = modQ ? h263_quant_c[quant] : quant;
H263_MB_HOR_DEBLOCKING(pYc, stepYc, pCbc, stepCbc, pCrc, stepCrc, quant, quant_c);
quant = pMBinfo[j-mbPerRow].quant;
quant_c = modQ ? h263_quant_c[quant] : quant;
H263_MB_VER_DEBLOCKING(pYc-16*stepYc, stepYc, pCbc-8*stepCbc, stepCbc, pCrc-8*stepCrc, stepCrc, quant, quant_c);
H263_MB_INTERNAL_VER_DEBLOCKING_LUM(pYc - 16*stepYc, stepYc, quant);
}
}
}
pYc = frame->pY + (stepYc << 4)*(mbPerCol - 1);
pCbc = frame->pCb + (stepCbc << 3)*(mbPerCol - 1);
pCrc = frame->pCr + (stepCrc << 3)*(mbPerCol - 1);
pMBinfo = pInfo->VideoSequence.MBinfo + mbPerRow*(mbPerCol - 1);
quant = pMBinfo[0].quant;
quant_c = modQ ? h263_quant_c[quant] : quant;
H263_MB_INTERNAL_VER_DEBLOCKING_LUM(pYc, stepYc, quant);
for (j = 1; j < mbPerRow; j++) {
pYc += 16;
pCbc += 8;
pCrc += 8;
quant = pMBinfo[j].quant;
quant_c = modQ ? h263_quant_c[quant] : quant;
H263_MB_VER_DEBLOCKING(pYc, stepYc, pCbc, stepCbc, pCrc, stepCrc, quant, quant_c);
H263_MB_INTERNAL_VER_DEBLOCKING_LUM(pYc, stepYc, quant);
}
}
#ifdef _OMP_KARABAS
Ipp32s h263_GetNumOfThreads(void)
{
Ipp32s maxThreads = 1;
#ifdef _OPENMP
#pragma omp parallel shared(maxThreads)
#endif
{
#ifdef _OPENMP
#pragma omp master
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -