📄 swdec_motiontextureutils.c
字号:
break;
/*lint --e(744) */
}
mv->hor += hor;
mv->ver += ver;
}
/*------------------------------------------------------------------------------
5.7 Function name: SwDec_MedianFilter
Purpose: median filtering of three input values
Input:
a,b,c input values to be median filtered
Output:
median of three input values
------------------------------------------------------------------------------*/
i32 SwDec_MedianFilter(i32 a, i32 b, i32 c)
{
i32 max,min,med;
max = min = med = a;
if (b > max)
{
max = b;
}
else if (b < min)
{
min = b;
}
if (c > max)
{
med = max;
}
else if (c < min)
{
med = min;
}
else
{
med = c;
}
return(med);
}
/*------------------------------------------------------------------------------
5.8 Function name: SwDec_GetLeftMvCandidate
Purpose: get left motion vector candidate for differential decoding
Input:
pMbDesc pointer to decMbDesc_t array
mbNum
mbNum [0,3]
column
vpBoundaryMb
Output:
motion vector of block on the left if valid, otherwise NON_VALID_MV
------------------------------------------------------------------------------*/
mv_t SwDec_GetLeftMvCandidate(decMbDesc_t *pMbDesc, u32 mbNum, u32 mvNum,
u32 column, u32 vpBoundaryMb)
{
mv_t mv = {NON_VALID_MV,NON_VALID_MV};
ASSERT(pMbDesc);
ASSERT(mbNum >= vpBoundaryMb);
ASSERT(mvNum < 4);
if (mvNum & 0x1)
{
mv.hor = pMbDesc[mbNum].data[2*(mvNum-1)];
mv.ver = pMbDesc[mbNum].data[2*(mvNum-1)+1];
}
else if (column && (mbNum > vpBoundaryMb))
{
if (pMbDesc[--mbNum].flags & INTER_MB_MASK)
{
mv.hor = pMbDesc[mbNum].data[2+2*mvNum];
mv.ver = pMbDesc[mbNum].data[3+2*mvNum];
}
else
{
mv.hor = mv.ver = 0;
}
}
return(mv);
}
/*------------------------------------------------------------------------------
5.9 Function name: SwDec_GetAboveMvCandidate
Purpose: get above motion vector candidate for differential decoding
Input:
pMbDesc pointer to decMbDesc_t array
mbNum
mbNum [0,3]
width width of vop in macro blocks
vpBoundaryMb
Output:
motion vector of block above if valid, otherwise NON_VALID_MV
------------------------------------------------------------------------------*/
mv_t SwDec_GetAboveMvCandidate(decMbDesc_t *pMbDesc, u32 mbNum, u32 mvNum,
u32 width, u32 vpBoundaryMb)
{
u32 tmp;
mv_t mv = {NON_VALID_MV,NON_VALID_MV};
ASSERT(pMbDesc);
ASSERT(width);
ASSERT(mbNum >= vpBoundaryMb);
ASSERT(mvNum < 4);
if (mvNum >= 2)
{
mv.hor = pMbDesc[mbNum].data[0];
mv.ver = pMbDesc[mbNum].data[1];
}
else if ((mbNum >= width) && ((tmp = mbNum-width) >= vpBoundaryMb))
{
if (pMbDesc[tmp].flags & INTER_MB_MASK)
{
mv.hor = pMbDesc[tmp].data[4+2*mvNum];
mv.ver = pMbDesc[tmp].data[5+2*mvNum];
}
else
{
mv.hor = mv.ver = 0;
}
}
return(mv);
}
/*------------------------------------------------------------------------------
5.10 Function name: SwDec_GetRightMvCandidate
Purpose: get right motion vector candidate for differential decoding
Input:
pMbDesc pointer to decMbDesc_t array
mbNum
mbNum [0,3]
width widht of vop in macro blocks
column
vpBoundaryMb
Output:
motion vector of block on the right if valid, otherwise NON_VALID_MV
------------------------------------------------------------------------------*/
mv_t SwDec_GetRightMvCandidate(decMbDesc_t *pMbDesc, u32 mbNum, u32 mvNum,
u32 width, u32 column, u32 vpBoundaryMb)
{
u32 tmp;
mv_t mv = {NON_VALID_MV,NON_VALID_MV};
ASSERT(pMbDesc);
ASSERT(width);
ASSERT(mbNum >= vpBoundaryMb);
ASSERT((mbNum%width) == column);
ASSERT(mvNum < 4);
if (mvNum >= 2)
{
mv.hor = pMbDesc[mbNum].data[2];
mv.ver = pMbDesc[mbNum].data[3];
}
else if ( (column != (width-1)) && (mbNum >= width) &&
((tmp = mbNum-width+1) >= vpBoundaryMb) )
{
if (pMbDesc[tmp].flags & INTER_MB_MASK)
{
mv.hor = pMbDesc[tmp].data[4];
mv.ver = pMbDesc[tmp].data[5];
}
else
{
mv.hor = mv.ver = 0;
}
}
return(mv);
}
/*------------------------------------------------------------------------------
5.11 Function name: SwDec_UseIntraDcVlc
Purpose: determine whether to use intra DC vlc or not
Input:
Pointer to decContainer_t structure
u32 MbNumber
Output:
0 don't use intra dc vlc
1 use intra dc vlc
------------------------------------------------------------------------------*/
#ifndef MP4DEC_H263_ONLY
u32 SwDec_UseIntraDcVlc(decContainer_t *pDecContainer, u32 mbNumber)
{
u32 QP;
ASSERT(pDecContainer);
ASSERT(mbNumber >= pDecContainer->StrmStorage.vpFirstCodedMb);
ASSERT(mbNumber < pDecContainer->VopDesc.totalMbInVop);
ASSERT(pDecContainer->StrmStorage.QP < 32);
ASSERT(pDecContainer->StrmStorage.prevQP < 32);
if (pDecContainer->StrmStorage.shortVideo)
{
pDecContainer->MbDesc[mbNumber].flags |= USE_INTRA_DC_VLC_MASK;
return(1);
}
if (mbNumber == pDecContainer->StrmStorage.vpFirstCodedMb)
{
QP = pDecContainer->StrmStorage.QP;
}
else
{
QP = pDecContainer->StrmStorage.prevQP;
}
if (QP < IntraDcQp[pDecContainer->VopDesc.intraDcVlcThr])
{
pDecContainer->MbDesc[mbNumber].flags |= USE_INTRA_DC_VLC_MASK;
return(1);
}
else
{
return(0);
}
}
/*------------------------------------------------------------------------------
5.12 Function name: SwDec_ScanDir
Purpose: determine scanning direction and store dc predictor
Input:
Pointer to decContainer_t structure
u32 MbNum
u32 BlockNum
Output:
SCAN_ZIGZAG, SCAN_HOR, SCAN_VER
------------------------------------------------------------------------------*/
u32 SwDec_ScanDir(decContainer_t *pDecContainer, u32 mbNum, u32 blockNum)
{
dcPred_t left, above;
i32 corner;
u32 col;
u32 width;
ASSERT(pDecContainer);
ASSERT(mbNum < pDecContainer->VopDesc.totalMbInVop);
ASSERT(mbNum >= pDecContainer->StrmStorage.vpMbNumber);
ASSERT(blockNum < 6);
ASSERT(pDecContainer->VopDesc.vopWidth);
/* zigzan scan for inter macro blocks or all macro blocks (short video) */
if (MB_IS_INTER(mbNum) || pDecContainer->StrmStorage.shortVideo)
{
return(SCAN_ZIGZAG);
}
col = pDecContainer->StrmStorage.col[mbNum];
width = pDecContainer->VopDesc.vopWidth;
left = SwDec_GetLeftCoeff(pDecContainer->MbDesc, mbNum, blockNum,
col, pDecContainer->StrmStorage.vpMbNumber);
above = SwDec_GetAboveCoeff(pDecContainer->MbDesc, mbNum, blockNum,
width, pDecContainer->StrmStorage.vpMbNumber);
corner = SwDec_GetCornerCoeff(pDecContainer->MbDesc, mbNum, blockNum,
width, col, pDecContainer->StrmStorage.vpMbNumber);
if (ABS(left.coeff-corner) < ABS(above.coeff-corner))
{
pDecContainer->StrmStorage.predictor = above.coeff;
pDecContainer->StrmStorage.isDefaultPredictor =
above.isDefault;
pDecContainer->StrmStorage.predictorQP = above.QP;
if (pDecContainer->MbDesc[mbNum].flags & AC_PRED_FLAG_MASK)
return(SCAN_HOR);
else
return(SCAN_ZIGZAG);
}
else
{
pDecContainer->StrmStorage.predictor = left.coeff;
pDecContainer->StrmStorage.isDefaultPredictor =
left.isDefault;
pDecContainer->StrmStorage.predictorQP = left.QP;
if (pDecContainer->MbDesc[mbNum].flags & AC_PRED_FLAG_MASK)
return(SCAN_VER);
else
return(SCAN_ZIGZAG);
}
}
/*------------------------------------------------------------------------------
5.13 Function name: SwDec_GetLeftCoeff
Purpose: get dc coefficient of block on the left
Input:
pMbDesc pointer to decMbDesc_t array
mbNum
blockNum
column
vpBoundaryMb
Output:
dcPred_t structure containing dc coeff and qp of block on the left
if valid, otherwise set to default values
------------------------------------------------------------------------------*/
dcPred_t SwDec_GetLeftCoeff(decMbDesc_t *pMbDesc, u32 mbNum, u32 blockNum,
u32 column, u32 vpBoundaryMb)
{
u32 refMbNum;
dcPred_t pred;
ASSERT(pMbDesc);
ASSERT(mbNum >= vpBoundaryMb);
ASSERT(blockNum < 6);
pred.isDefault = 0;
if ( (blockNum != 1) && (blockNum != 3) )
{
refMbNum = mbNum - 1;
if ( !column ||
(refMbNum < vpBoundaryMb) ||
(pMbDesc[refMbNum].flags & INTER_MB_MASK))
{
pred.coeff = DEFAULT_PREDICTOR;
pred.QP = 0;
pred.isDefault = 1;
}
else
{
if (blockNum < 4)
blockNum++;
pred.coeff = pMbDesc[refMbNum].data[blockNum];
pred.QP = pMbDesc[refMbNum].QP;
}
}
else
{
pred.coeff = pMbDesc[mbNum].data[blockNum-1];
pred.QP = pMbDesc[mbNum].QP;
}
return pred;
}
/*------------------------------------------------------------------------------
5.14 Function name: SwDec_GetAboveCoeff
Purpose: get dc coefficient of block above
Input:
pMbDesc pointer to decMbDesc_t array
mbNum
blockNum
width width of vop in macro blocks
vpBoundaryMb
Output:
dcPred_t structure containing dc coeff and qp of block above
if valid, otherwise set to default values
------------------------------------------------------------------------------*/
dcPred_t SwDec_GetAboveCoeff(decMbDesc_t *pMbDesc, u32 mbNum, u32 blockNum,
u32 width, u32 vpBoundaryMb)
{
u32 refMbNum;
dcPred_t pred;
ASSERT(pMbDesc);
ASSERT(mbNum >= vpBoundaryMb);
ASSERT(blockNum < 6);
ASSERT(width);
pred.isDefault = 0;
if ( (blockNum != 2) && (blockNum != 3) )
{
refMbNum = mbNum - width;
if ( (mbNum < width) ||
(refMbNum < vpBoundaryMb) ||
(pMbDesc[refMbNum].flags & INTER_MB_MASK))
{
pred.coeff = DEFAULT_PREDICTOR;
pred.QP = 0;
pred.isDefault = 1;
}
else
{
if (blockNum < 4)
blockNum += 2;
pred.coeff = pMbDesc[refMbNum].data[blockNum];
pred.QP = pMbDesc[refMbNum].QP;
}
}
else
{
pred.coeff = pMbDesc[mbNum].data[blockNum-2];
pred.QP = pMbDesc[mbNum].QP;
}
return(pred);
}
/*------------------------------------------------------------------------------
5.15 Function name: SwDec_GetCornerCoeff
Purpose: get dc coefficient of block on the left above
Input:
pMbDesc pointer to decMbDesc_t array
mbNum
blockNum
width width of vop in macro blocks
column
vpBoundaryMb
Output:
dc coeff of block above left if valid, otherwise set to default
value
------------------------------------------------------------------------------*/
i32 SwDec_GetCornerCoeff(decMbDesc_t *pMbDesc, u32 mbNum, u32 blockNum,
u32 width, u32 column, u32 vpBoundaryMb)
{
i32 refMbNum;
i32 coeff = 0;
static const u32 refBlockNum[6] = {3,2,1,0,4,5};
ASSERT(pMbDesc);
ASSERT(mbNum >= vpBoundaryMb);
ASSERT(blockNum < 6);
ASSERT(width);
ASSERT((mbNum%width) == column);
refMbNum = (i32)mbNum;
switch (blockNum)
{
case 1:
refMbNum -= (i32)width;
break;
case 2:
if (!column)
refMbNum = -1;
else
refMbNum--;
break;
case 0:
case 4:
case 5:
if (!column)
refMbNum = -1;
else
refMbNum -= (i32)width + 1;
break;
/*lint --e(744) */
}
if ( (refMbNum < (i32)vpBoundaryMb) ||
(pMbDesc[refMbNum].flags & INTER_MB_MASK))
{
coeff = DEFAULT_PREDICTOR;
}
else
{
coeff = pMbDesc[refMbNum].data[refBlockNum[blockNum]];
}
return(coeff);
}
#endif
/*lint +e701 +e702 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -