📄 swdec_motiontextureutils.c
字号:
/*------------------------------------------------------------------------------
-- --
-- This software is confidential and proprietary and may be used --
-- only as expressly authorized by a licensing agreement from --
-- --
-- Hantro Products Oy. --
-- --
-- In the event of publication, the following notice is applicable: --
-- --
-- (C) COPYRIGHT 2004 HANTRO PRODUCTS OY --
-- ALL RIGHTS RESERVED --
-- --
-- The entire notice above must be reproduced on all copies. --
-- --
--------------------------------------------------------------------------------
--
-- Abstract : Utility functions for motion texture decoding
--
-------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
Table of contents
1. Include headers
2. External identifiers
3. Module defines
4. Module identifiers
5. Fuctions
5.1 SwDec_DecodeMcbpc
5.2 SwDec_DecodeCbpy
5.3 SwDec_DecodeDcCoeff
5.4 SwDec_DecodeMv
5.5 SwDec_DecodeMvVlc
5.6 SwDec_DecodeMvDifferential
5.7 SwDec_MedianFilter
5.8 SwDec_GetLeftMvCandidate
5.9 SwDec_GetAboveMvCandidate
5.10 SwDec_GetRightMvCandidate
5.11 SwDec_UseIntraDcVlc
5.12 SwDec_ScanDir
5.13 SwDec_GetLeftCoeff
5.14 SwDec_GetAboveCoeff
5.15 SwDec_GetCornerCoeff
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
1. Include headers
------------------------------------------------------------------------------*/
#include "SwDec_MotionTextureUtils.h"
#include "SwDec_Utils.h"
/*------------------------------------------------------------------------------
2. External identifiers
------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------
3. Module defines
------------------------------------------------------------------------------*/
typedef struct {
u32 len;
i32 val;
} mvTable_t;
typedef struct {
i32 hor;
i32 ver;
} mv_t;
#ifndef MP4DEC_H263_ONLY
enum { DEFAULT_PREDICTOR = 1024 };
typedef struct {
i32 coeff;
u32 QP;
u32 isDefault;
} dcPred_t;
#endif
enum { NON_VALID_MV = 0x7FFF };
/*lint -e701 -e702 */
/*------------------------------------------------------------------------------
4. Module indentifiers
------------------------------------------------------------------------------*/
static const u32 TableMcbpcInter[24] = {
0x0, 0x090500,0x090403,0x090402,0x090401,0x090103, 0x080302,0x080302,
0x080301,0x080301,0x080203, 0x080203,0x070303,0x070303,0x070303,0x070303,
0x070202,0x070202,0x070202,0x070202,0x070201, 0x070201,0x070201,0x070201 };
#ifndef MP4DEC_H263_ONLY
/* intra DC vlc used at threshold i if QP less than value IntraDcQp[i] */
static const u32 IntraDcQp[8] = {32,13,15,17,19,21,23,0};
#endif
/* motion vector vlc tables */
static const mvTable_t MvTable1[14] =
{
{5,3},{5,-3},{4,2},{4,2},{4,-2},{4,-2},
{3,1},{3,1},{3,1},{3,1},{3,-1},{3,-1},{3,-1},{3,-1}
};
static const mvTable_t MvTable2[8] =
{
{8,6},{8,-6},{8,5},{8,-5},{7,4},{7,4},{7,-4},{7,-4}
};
static const mvTable_t MvTable3[32] =
{
{11,12},{11,-12},{11,11},{11,-11},{10,10},{10,10},{10,-10},{10,-10},
{10,9},{10,9},{10,-9},{10,-9},{10,8},{10,8},{10,-8},{10,-8},
{8,7},{8,7},{8,7},{8,7},{8,7},{8,7},{8,7},{8,7},
{8,-7},{8,-7},{8,-7},{8,-7},{8,-7},{8,-7},{8,-7},{8,-7}
};
static const mvTable_t MvTable4[12] =
{
{11,24},{11,23},{11,22},{11,21},{11,20},{11,19},
{11,18},{11,17},{11,16},{11,15},{11,14},{11,13}
};
static const mvTable_t MvTable5[28] =
{
{13,32},{13,-32},{13,31},{13,-31},{12,30},{12,30},{12,-30},{12,-30},
{12,29},{12,29},{12,-29},{12,-29},{12,28},{12,28},{12,-28},{12,-28},
{12,27},{12,27},{12,-27},{12,-27},{12,26},{12,26},{12,-26},{12,-26},
{12,25},{12,25},{12,-25},{12,-25}
};
STATIC u32 SwDec_DecodeMvVlc(u32 buffer, i32 *motionVector);
STATIC void SwDec_DecodeMvDifferential(decContainer_t *pDecContainer, mv_t *mv,
u32 mbNum, u32 mvNum);
/* functions to get left, above and above-right motion vector candidates for
* prediction */
STATIC mv_t SwDec_GetLeftMvCandidate(decMbDesc_t *pMbDesc, u32 mbNum,
u32 mvNum, u32 column, u32 vpBoundaryMb);
STATIC mv_t SwDec_GetAboveMvCandidate(decMbDesc_t *pMbDesc, u32 mbNum,
u32 mvNum, u32 width, u32 vpBoundaryMb);
STATIC mv_t SwDec_GetRightMvCandidate(decMbDesc_t *pMbDesc, u32 mbNum,
u32 mvNum, u32 width, u32 column, u32 vpBoundaryMb);
STATIC i32 SwDec_MedianFilter(i32 a, i32 b, i32 c);
#ifndef MP4DEC_H263_ONLY
/* functions to get left, above and above-left dc coefficients for determination
* of scanning direction and dc predictor */
STATIC dcPred_t SwDec_GetLeftCoeff(decMbDesc_t *pMbDesc, u32 mbNum,
u32 blockNum, u32 column, u32 vpBoundaryMb);
STATIC dcPred_t SwDec_GetAboveCoeff(decMbDesc_t *pMbDesc, u32 mbNum,
u32 blockNum, u32 width, u32 vpBoundaryMb);
STATIC i32 SwDec_GetCornerCoeff(decMbDesc_t *pMbDesc, u32 mbNum,
u32 blockNum, u32 width, u32 column, u32 vpBoundaryMb);
#endif
/*------------------------------------------------------------------------------
5.1 Function name:
SwDec_DecodeMcbpc
Purpose:
decodes variable length coded mb-type and cbpc from
stream.
Input:
Pointer to decContainer_t structure
Macro block number
Output:
u32 status HANTRO_OK/HANTRO_NOK/END_OF_STREAM
------------------------------------------------------------------------------*/
u32 SwDec_DecodeMcbpc(decContainer_t *pDecContainer, u32 mbNum)
{
u32 buffer;
u32 status;
u32 length, mbType, cbpc;
ASSERT(pDecContainer);
ASSERT(mbNum < pDecContainer->VopDesc.totalMbInVop);
ASSERT(pDecContainer->VopDesc.vopCodingType < 2);
buffer = SwDec_ShowBits(pDecContainer,9);
if (pDecContainer->VopDesc.vopCodingType == IVOP)
{
if (buffer >= 32)
{
if ( buffer>=256 ){
length = 1;
mbType = MB_INTRA;
cbpc = 0;
} else if ( buffer>=192 ){
length = 3;
mbType = MB_INTRA;
cbpc = 3;
} else if ( buffer>=128 ){
length = 3;
mbType = MB_INTRA;
cbpc = 2;
} else if ( buffer>=64 ){
length = 3;
mbType = MB_INTRA;
cbpc = 1;
} else {
length = 4;
mbType = MB_INTRAQ;
cbpc = 0;
}
}
else
{
if ( buffer>=24 ){
length = 6;
mbType = MB_INTRAQ;
cbpc = 3;
} else if ( buffer>=16 ){
length = 6;
mbType = MB_INTRAQ;
cbpc = 2;
} else if ( buffer>=8 ){
length = 6;
mbType = MB_INTRAQ;
cbpc = 1;
} else if ( buffer==1 ){
length = 9;
mbType = MB_STUFFING;
cbpc = 0;
} else return(HANTRO_NOK);
}
}
else /* PVOP */
{
if (buffer >= 48)
{
if ( buffer>=256 ){
length = 1;
mbType = MB_INTER;
cbpc = 0;
} else if ( buffer>=192 ){
length = 3;
mbType = MB_INTERQ;
cbpc = 0;
} else if ( buffer>=128 ){
length = 3;
mbType = MB_INTER4V;
cbpc = 0;
} else if ( buffer>=96 ) {
length = 4;
mbType = MB_INTER;
cbpc = 1;
} else if ( buffer>=64 ) {
length = 4;
mbType = MB_INTER;
cbpc = 2;
} else {
length = 5;
mbType = MB_INTRA;
cbpc = 0;
}
}
else
{
if ( buffer>=40 ){
length = 6;
mbType = MB_INTER;
cbpc = 3;
} else if ( buffer>=32 ){
length = 6;
mbType = MB_INTRAQ;
cbpc = 0;
} else if ( buffer>=28 ){
length = 7;
mbType = MB_INTERQ;
cbpc = 1;
} else if ( buffer>=24 ){
length = 7;
mbType = MB_INTERQ;
cbpc = 2;
} else {
length = (TableMcbpcInter[buffer] & 0xFF0000)>>16;
mbType = (TableMcbpcInter[buffer] & 0xFF00)>>8;
cbpc = (TableMcbpcInter[buffer] & 0xFF);
}
}
}
if(length==0)
return(HANTRO_NOK);
status = SwDec_FlushBits(pDecContainer,length);
pDecContainer->MbDesc[mbNum].typeOfMb = (u8)mbType;
if (mbType < 3)
pDecContainer->MbDesc[mbNum].flags = INTER_MB_MASK;
else
pDecContainer->MbDesc[mbNum].flags = 0;
pDecContainer->MbDesc[mbNum].codedBits = (u8)cbpc;
return(status);
}
/*------------------------------------------------------------------------------
5.2 Function name:
SwDec_DecodeCbpy
Purpose:
decodes variable length coded cbpy from stream
Input:
Pointer to decContainer_t structure
Macro block number
Output:
u32 status HANTRO_OK/HANTRO_NOK/END_OF_STREAM
------------------------------------------------------------------------------*/
u32 SwDec_DecodeCbpy(decContainer_t *pDecContainer, u32 mbNum)
{
u32 cbpy;
u32 buffer;
u32 len;
u32 status;
ASSERT(pDecContainer);
ASSERT(mbNum < pDecContainer->VopDesc.totalMbInVop);
ASSERT(pDecContainer->MbDesc[mbNum].typeOfMb < MB_STUFFING);
buffer = SwDec_ShowBits(pDecContainer,6);
if ( buffer>=16 )
{
if ( buffer>=48 ){
len = 2;
if ( MB_IS_INTRA(mbNum) )
cbpy = 15;
else
cbpy = 0;
} else if ( buffer>=44 ){
len = 4;
if ( MB_IS_INTRA(mbNum) )
cbpy = 7;
else
cbpy = 8;
} else if ( buffer>=40 ){
len = 4;
if ( MB_IS_INTRA(mbNum) )
cbpy = 11;
else
cbpy = 4;
} else if ( buffer>= 36 ){
len = 4;
if ( MB_IS_INTRA(mbNum) )
cbpy = 3;
else
cbpy = 12;
} else if ( buffer>= 32 ){
len = 4;
if ( MB_IS_INTRA(mbNum) )
cbpy = 13;
else
cbpy = 2;
} else if ( buffer>= 28 ){
len = 4;
if ( MB_IS_INTRA(mbNum) )
cbpy = 5;
else
cbpy = 10;
} else if ( buffer>= 24 ){
len = 4;
if ( MB_IS_INTRA(mbNum) )
cbpy = 14;
else
cbpy = 1;
} else if ( buffer>= 20 ){
len = 4;
if ( MB_IS_INTRA(mbNum) )
cbpy = 10;
else
cbpy = 5;
} else {
len = 4;
if ( MB_IS_INTRA(mbNum) )
cbpy = 12;
else
cbpy = 3;
}
}
else
{
if ( buffer>=12 ){
len = 4;
if ( MB_IS_INTRA(mbNum) )
cbpy = 0;
else
cbpy = 15;
} else if ( buffer>=10 ){
len = 5;
if ( MB_IS_INTRA(mbNum) )
cbpy = 1;
else
cbpy = 14;
} else if ( buffer>=8 ){
len = 5;
if ( MB_IS_INTRA(mbNum) )
cbpy = 2;
else
cbpy = 13;
} else if ( buffer>=6 ){
len = 5;
if ( MB_IS_INTRA(mbNum) )
cbpy = 4;
else
cbpy = 11;
} else if ( buffer>= 4) {
len = 5;
if ( MB_IS_INTRA(mbNum) )
cbpy = 8;
else
cbpy = 7;
} else if ( buffer>= 3 ){
len = 6;
if ( MB_IS_INTRA(mbNum) )
cbpy = 9;
else
cbpy = 6;
} else if ( buffer>=2 ){
len = 6;
if ( MB_IS_INTRA(mbNum) )
cbpy = 6;
else
cbpy = 9;
} else {
return(HANTRO_NOK);
}
}
pDecContainer->MbDesc[mbNum].codedBits |= (u8)(cbpy<<2);
status = SwDec_FlushBits(pDecContainer,len);
return(status);
}
/*------------------------------------------------------------------------------
5.3 Function name: SwDec_DecodeDcCoeff
Purpose: Decode separately coded dc coefficient. Decodes vlc coded
dct_dc_size and differential dc additional components.
This function is called for each block.
Input:
pointer to decContainer_t
macro block number
block number
Output:
HANTRO_OK/HANTRO_NOK/END_OF_STREAM
------------------------------------------------------------------------------*/
u32 SwDec_DecodeDcCoeff(decContainer_t *pDecContainer, u32 mbNum, u32 blockNum)
{
#ifndef MP4DEC_H263_ONLY
u32 buffer;
u32 status;
u32 length;
u32 dctDcSize;
u32 sign;
u32 tmp;
#endif
i32 value = 0;
ASSERT(pDecContainer);
ASSERT(blockNum < 6);
ASSERT(mbNum < pDecContainer->VopDesc.totalMbInVop);
#ifdef MP4DEC_H263_ONLY
value = SwDec_GetBits(pDecContainer, 8);
CHECK_END_OF_STREAM(value);
/* values 0 and 128 are forbidden, but we pass them and check
* only value 255 */
if (value == 255)
{
value = 128;
}
#else
if (pDecContainer->StrmStorage.shortVideo)
{
value = (i32)SwDec_GetBits(pDecContainer, 8);
CHECK_END_OF_STREAM((u32)value);
/* values 0 and 128 are forbidden, but we pass them and check
* only value 255 */
if (value == 255)
{
value = 128;
}
}
/* normal mpeg4 case */
else
{
/* max length 9, max dct_dc_size 9 + possible marker -> 19 bits into
* buffer */
tmp = SwDec_ShowBits(pDecContainer, 19);
/* This is luminance case */
if (blockNum < 4)
{
/* max length 8 -> drop 11 bits */
buffer = tmp>>11;
if (buffer >= 192) /* 11xx xxxx */
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -