📄 swdec_motiontextureutils.c
字号:
dctDcSize = 1;
length = 2;
}
else if (buffer >= 128) /* 10xx xxxx */
{
dctDcSize = 2;
length = 2;
}
else if (buffer >= 96) /* 011x xxxx */
{
dctDcSize = 0;
length = 3;
}
else if (buffer >= 64) /* 010x xxxx */
{
dctDcSize = 3;
length = 3;
}
else if (buffer >= 32) /* 001x xxxx */
{
dctDcSize = 4;
length = 3;
}
else if (buffer >= 16) /* 0001 xxxx */
{
dctDcSize = 5;
length = 4;
}
else if (buffer >= 8) /* 0000 1xxx */
{
dctDcSize = 6;
length = 5;
}
else if (buffer >= 4) /* 0000 01xx */
{
dctDcSize = 7;
length = 6;
}
else if (buffer >= 2) /* 0000 001x */
{
dctDcSize = 8;
length = 7;
}
else if (buffer == 1) /* 0000 0001 */
{
dctDcSize = 9;
length = 8;
}
else
{
return(HANTRO_NOK);
}
}
/* And this is chrominance */
else
{
/* max length 9 -> drop 10 bits */
buffer = tmp>>10;
if (buffer >= 384) /* 1 1xxx xxxx */
{
dctDcSize = 0;
length = 2;
}
else if (buffer >= 256) /* 1 0xxx xxxx */
{
dctDcSize = 1;
length = 2;
}
else if (buffer >= 128) /* 0 1xxx xxxx */
{
dctDcSize = 2;
length = 2;
}
else if (buffer >= 64) /* 0 01xx xxxx */
{
dctDcSize = 3;
length = 3;
}
else if (buffer >= 32) /* 0 001x xxxx */
{
dctDcSize = 4;
length = 4;
}
else if (buffer >= 16) /* 0 0001 xxxx */
{
dctDcSize = 5;
length = 5;
}
else if (buffer >= 8) /* 0 0000 1xxx */
{
dctDcSize = 6;
length = 6;
}
else if (buffer >= 4) /* 0 0000 01xx */
{
dctDcSize = 7;
length = 7;
}
else if (buffer >= 2) /* 0 0000 001x */
{
dctDcSize = 8;
length = 8;
}
else if (buffer == 1) /* 0 0000 0001 */
{
dctDcSize = 9;
length = 9;
}
else
{
return(HANTRO_NOK);
}
}
if (dctDcSize == 0)
{
value = 0;
}
else
{
/* mask used bits away and drop extra bits out */
buffer = (tmp>>(18-length-dctDcSize)) &
((1<<(dctDcSize+1))-1);
/* check marker bit if dct_dc_size > 8 */
if (dctDcSize > 8)
{
if ( !(buffer & 0x1) ) return(HANTRO_NOK);
length += 1;
}
/* drop marker */
buffer >>= 1;
length += dctDcSize;
/* msb indicates the sign (1 -> positive, 0 -> negative) */
sign = !(buffer >> (dctDcSize-1));
/* absolute value */
tmp = buffer & ((1<<(dctDcSize-1))-1);
/* negative value */
if (sign)
{
value = -(1<<dctDcSize) + 1 + (i32)tmp;
}
/* positive value */
else
{
value = (i32)((1<<(dctDcSize-1)) + tmp);
}
}
status = SwDec_FlushBits(pDecContainer, length);
CHECK_END_OF_STREAM(status);
}
#endif
pDecContainer->MbDesc[mbNum].data[blockNum] = (i16)value;
return(HANTRO_OK);
}
/*------------------------------------------------------------------------------
5.4 Function name: SwDec_DecodeMv
Purpose: decode motion vectors of one macro block. Decodes vlc coded
motion vectors, residual motion vectors and differential coding of mvs
Input:
pointer to decContainer_t
macro block number
Output:
HANTRO_OK/HANTRO_NOK/END_OF_STREAM
------------------------------------------------------------------------------*/
u32 SwDec_DecodeMv(decContainer_t *pDecContainer, u32 mbNum)
{
u32 i,tmp;
mv_t mv;
i32 high,low,range;
i16 *pi16;
u32 len = 0;
u32 numMvs = 0;
#ifndef MP4DEC_H263_ONLY
u32 rsize;
tmpBuffer_t buffer;
ASSERT(pDecContainer->VopDesc.fcodeFwd &&
(pDecContainer->VopDesc.fcodeFwd < 8));
#endif
ASSERT(pDecContainer);
ASSERT(mbNum < pDecContainer->VopDesc.totalMbInVop);
ASSERT(MB_IS_INTER(mbNum));
pi16 = pDecContainer->MbDesc[mbNum].data;
#ifdef MP4DEC_H263_ONLY
high = 31;
low = -32;
range = 64;
tmp = SwDec_ShowBits(pDecContainer, 13);
/* vlc code for horizontal motion vector */
len = SwDec_DecodeMvVlc(tmp, &(mv.hor));
if (!len) return(HANTRO_NOK);
tmp = SwDec_FlushBits(pDecContainer, len);
CHECK_END_OF_STREAM(tmp);
tmp = SwDec_ShowBits(pDecContainer, 13);
/* vlc code for vertical motion vector */
len = SwDec_DecodeMvVlc(tmp, &(mv.ver));
if (!len) return(HANTRO_NOK);
tmp = SwDec_FlushBits(pDecContainer, len);
CHECK_END_OF_STREAM(tmp);
SwDec_DecodeMvDifferential(pDecContainer, &mv, mbNum, numMvs);
if (mv.hor < low)
{
mv.hor += range;
}
else if (mv.hor > high)
{
mv.hor -= range;
}
if (mv.ver < low)
{
mv.ver += range;
}
else if (mv.ver > high)
{
mv.ver -= range;
}
#else
/* [low,high] and range determined based on vop_fcode_forward */
rsize = pDecContainer->VopDesc.fcodeFwd - 1;
high = (32 << rsize) - 1;
low = -(32 << rsize);
range = (64 << rsize);
if (pDecContainer->MbDesc[mbNum].typeOfMb == MB_INTER4V)
{
numMvs = 4;
}
else
{
numMvs = 1;
}
BUFFER_INIT(buffer);
for (i = 0; i < numMvs; i++)
{
BUFFER_SHOW(buffer,tmp,13);
/* vlc code for horizontal motion vector */
len = SwDec_DecodeMvVlc(tmp, &(mv.hor));
if (!len) break;
BUFFER_FLUSH(buffer,len);
/* residual motion vector */
if ( (rsize != 0) && (mv.hor != 0) )
{
BUFFER_GET(buffer,tmp,rsize);
if (mv.hor > 0)
{
mv.hor = ((mv.hor - 1) << rsize) + (i32)tmp + 1;
}
else
{
mv.hor = -((-mv.hor - 1) << rsize) - (i32)tmp - 1;
}
}
BUFFER_SHOW(buffer, tmp, 13);
/* vlc code for vertical motion vector */
len = SwDec_DecodeMvVlc(tmp, &(mv.ver));
if (!len) break;
BUFFER_FLUSH(buffer,len);
/* residual motion vector */
if ( (rsize != 0) && (mv.ver != 0) )
{
BUFFER_GET(buffer,tmp,rsize);
if (mv.ver > 0)
{
mv.ver = ((mv.ver - 1) << rsize) + (i32)tmp + 1;
}
else
{
mv.ver = -((-mv.ver - 1) << rsize) - (i32)tmp - 1;
}
}
SwDec_DecodeMvDifferential(pDecContainer, &mv, mbNum, i);
if (mv.hor < low)
{
mv.hor += range;
}
else if (mv.hor > high)
{
mv.hor -= range;
}
if (mv.ver < low)
{
mv.ver += range;
}
else if (mv.ver > high)
{
mv.ver -= range;
}
*pi16++ = (i16)mv.hor;
*pi16++ = (i16)mv.ver;
}
tmp = SwDec_FlushBits(pDecContainer,32-buffer.bits);
CHECK_END_OF_STREAM(tmp);
if (!len) return(HANTRO_NOK);
#endif
/* just one motion vector -> copy value to other three locations */
for (i = numMvs; i < 4; i++)
{
/*lint --e(771) */
*pi16++ = (i16)mv.hor;
*pi16++ = (i16)mv.ver;
}
return(HANTRO_OK);
}
/*------------------------------------------------------------------------------
5.5 Function name: SwDec_DecodeMvVlc
Purpose: decode vlc coded motion vector
Input:
buffer: buffer container 13 coded bits
motionVector: pointer to motion vector
Output:
length of decoded code word, 0 if not found
------------------------------------------------------------------------------*/
u32 SwDec_DecodeMvVlc(u32 buffer, i32 *motionVector)
{
mvTable_t tab;
ASSERT(motionVector);
ASSERT(buffer < 8192);
if (buffer > 4095)
{
tab.val = 0;
tab.len = 1;
}
else if (buffer > 511)
{
tab = MvTable1[(buffer>>8)-2];
}
else if (buffer > 255)
{
tab = MvTable2[(buffer>>5)-8];
}
else if (buffer > 127)
{
tab = MvTable3[(buffer>>2)-32];
}
else if (buffer > 31)
{
tab = MvTable4[(buffer>>3)-4];
/* sign */
if (buffer & 0x4)
tab.val = -tab.val;
}
else if (buffer > 3)
{
tab = MvTable5[buffer-4];
}
else
{
return(0);
}
*motionVector = tab.val;
return(tab.len);
}
/*------------------------------------------------------------------------------
5.6 Function name: SwDec_DecodeMvDifferential
Purpose: decode motion vector differential coding
Input:
pointer to decContainer_t
pointer to horizontal motion vector to be updated
pointer to vertical motion vector to be updated
macro block number
mvNum indicates which motion vector is decoded, [0,3], max
4 mvs
Output:
------------------------------------------------------------------------------*/
void SwDec_DecodeMvDifferential(decContainer_t *pDecContainer, mv_t *mv,
u32 mbNum, u32 mvNum)
{
u32 validCount;
mv_t mvLeft, mvAbove, mvRight;
u32 vpBoundaryMb;
u32 width,column;
i32 hor, ver;
ASSERT(pDecContainer);
ASSERT(mv);
ASSERT(mvNum < 4);
ASSERT(mbNum < pDecContainer->VopDesc.totalMbInVop);
ASSERT(mbNum >= pDecContainer->StrmStorage.vpMbNumber);
ASSERT(pDecContainer->VopDesc.vopWidth);
ASSERT(pDecContainer->MbDesc);
width = pDecContainer->VopDesc.vopWidth;
column = pDecContainer->StrmStorage.col[mbNum];
/* normal mpeg4 stream or short video gob which started with gob header ->
* respect start of video packet (candidates outside packet invalid) */
#ifdef MP4DEC_H263_ONLY
if ( pDecContainer->StrmStorage.gobResyncFlag )
{
vpBoundaryMb = pDecContainer->StrmStorage.vpMbNumber;
}
#else
if ( !pDecContainer->StrmStorage.shortVideo ||
pDecContainer->StrmStorage.gobResyncFlag )
{
vpBoundaryMb = pDecContainer->StrmStorage.vpMbNumber;
}
#endif
/* short video and gob without header -> ignore video packet boundaries
* here */
else
{
vpBoundaryMb = 0;
}
mvLeft = SwDec_GetLeftMvCandidate(pDecContainer->MbDesc, mbNum, mvNum,
column, vpBoundaryMb);
mvAbove = SwDec_GetAboveMvCandidate(pDecContainer->MbDesc, mbNum, mvNum,
width, vpBoundaryMb);
mvRight = SwDec_GetRightMvCandidate(pDecContainer->MbDesc, mbNum, mvNum,
width, column, vpBoundaryMb);
/* number of valid candidates */
/*lint --e(514) */
validCount = (mvLeft.hor != NON_VALID_MV) +
(mvAbove.hor != NON_VALID_MV) +
(mvRight.hor != NON_VALID_MV);
hor = ver = 0;
switch (validCount)
{
/* case 0: all candidates set to zero -> predictor 0 -> do nothing */
case 1:
/* use the one and only valid value, 2 values equal to NON_VALID_MV
* -> add all three and subtract 2 non valid ones */
hor = mvLeft.hor + mvAbove.hor + mvRight.hor - 2*NON_VALID_MV;
ver = mvLeft.ver + mvAbove.ver + mvRight.ver - 2*NON_VALID_MV;
break;
case 2:
/* determine which one is non valid and set to 0 */
if (mvLeft.hor == NON_VALID_MV)
{
mvLeft.hor = mvLeft.ver = 0;
}
else if (mvAbove.hor == NON_VALID_MV)
{
mvAbove.hor = mvAbove.ver = 0;
}
else
{
mvRight.hor = mvRight.ver = 0;
}
/* FALLTHRU (or something) */
case 3:
hor = SwDec_MedianFilter(mvLeft.hor,mvAbove.hor,mvRight.hor);
ver = SwDec_MedianFilter(mvLeft.ver,mvAbove.ver,mvRight.ver);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -