📄 wmv3_volheaddec.c
字号:
/*
* WMV3_VOLHeadDec.c
*/
#include <string.h>
#include "WMV3_VOLHeadDec.h"
I32_WMV g_iBInverse[] = { 256, 128, 85, 64, 51, 43, 37, 32 };
static U32_WMV BS_getBits(tWMVBS *bs, U32_WMV dwNumBits)
{
U32_WMV tmp;
while (bs->m_incnt <= 24)
{
bs->m_bsbfr |= (U32_WMV)(bs->m_pbits[bs->m_bsptr++]) << (24 - bs->m_incnt);
bs->m_incnt += 8;
}
tmp = bs->m_bsbfr >> (32 - dwNumBits);
bs->m_bsbfr <<= dwNumBits;
bs->m_incnt -= dwNumBits;
return tmp;
}
static tWMVDecodeStatus decodeSpriteVOLHead(tWMVDecInternalMember *pWMVDec)
{
int m_iFrameRate;
pWMVDec->m_iFrmWidthSrc = BS_getBits(pWMVDec->m_pbitstrmIn, 11);
pWMVDec->m_iFrmHeightSrc = BS_getBits(pWMVDec->m_pbitstrmIn, 11);
if (pWMVDec->m_iFrmWidthSrc == 0 || pWMVDec->m_iFrmHeightSrc == 0)
return ICERR_ERROR;
m_iFrameRate = BS_getBits(pWMVDec->m_pbitstrmIn, 5);
pWMVDec->m_bRndCtrlOn = TRUE;
pWMVDec->m_bMixedPel = FALSE;
pWMVDec->m_bXformSwitch = FALSE;
pWMVDec->m_bLoopFilter = FALSE;
pWMVDec->m_bXintra8Switch = BS_getBits(pWMVDec->m_pbitstrmIn, 1);
pWMVDec->m_bDCTTable_MB_ENABLED = BS_getBits(pWMVDec->m_pbitstrmIn, 1);
pWMVDec->m_iSliceCode = BS_getBits(pWMVDec->m_pbitstrmIn, NUMBITS_SLICE_SIZE_WMV2);
return ICERR_OK;
}
/****************************************************************************************
SetMVRangeFlag : set MV range and flags
****************************************************************************************/
static Void_WMV SetMVRangeFlag(tWMVDecInternalMember *pWMVDec, I32_WMV iRangeIndex)
{
I32_WMV iXRange[] = { 9, 10, 12, 13 };
I32_WMV iYRange[] = { 8, 9, 10, 11 };
pWMVDec->m_iMVRangeIndex = iRangeIndex;
pWMVDec->m_iLogXRange = iXRange[iRangeIndex];
pWMVDec->m_iLogYRange = iYRange[iRangeIndex];
pWMVDec->m_iXMVRange = 1 << (pWMVDec->m_iLogXRange - 1);
pWMVDec->m_iYMVRange = 1 << (pWMVDec->m_iLogYRange - 1);
pWMVDec->m_iXMVFlag = 2 * pWMVDec->m_iXMVRange - 1;
pWMVDec->m_iYMVFlag = 2 * pWMVDec->m_iYMVRange - 1;
}
static tWMVDecodeStatus decodeVOLHead_WMV3(tWMVDecInternalMember *pWMVDec)
{
// read WMV3 profile
I32_WMV iProfile = BS_getBits(pWMVDec->m_pbitstrmIn, 2);
Bool_WMV bValidProfile = TRUE;
if (iProfile == 0)
{
pWMVDec->m_iWMV3Profile = WMV3_SIMPLE_PROFILE;
}
else if (iProfile == 1)
{
pWMVDec->m_iWMV3Profile = WMV3_MAIN_PROFILE;
}
else if (iProfile == 2)
{
pWMVDec->m_iWMV3Profile = WMV3_PC_PROFILE;
}
pWMVDec->m_bInterlaceCodingOn = BS_getBits(pWMVDec->m_pbitstrmIn, 1);
pWMVDec->m_bSpriteMode = BS_getBits(pWMVDec->m_pbitstrmIn, 1);
// redo Dquant parameters (may have changed)
//ComputeDQuantDecParam ();
pWMVDec->m_iFrameRate = BS_getBits(pWMVDec->m_pbitstrmIn, 3); // midpoint of bin
pWMVDec->m_iBitRate = BS_getBits(pWMVDec->m_pbitstrmIn, 5);
pWMVDec->m_iFrameRate = 4 * pWMVDec->m_iFrameRate + 2; // midpoint of bin
pWMVDec->m_iBitRate = 64 * pWMVDec->m_iBitRate + 32;
pWMVDec->m_bRndCtrlOn = TRUE_WMV;
pWMVDec->m_bLoopFilter = BS_getBits(pWMVDec->m_pbitstrmIn, 1);
pWMVDec->m_bV9LoopFilter = pWMVDec->m_bLoopFilter;
// pWMVDec->m_bXformSwitch = BS_getBits(pWMVDec->m_pbitstrmIn,1);
pWMVDec->m_bXintra8Switch = BS_getBits(pWMVDec->m_pbitstrmIn, 1);
pWMVDec->m_bMultiresEnabled = BS_getBits(pWMVDec->m_pbitstrmIn, 1);
pWMVDec->m_b16bitXform = BS_getBits(pWMVDec->m_pbitstrmIn, 1);
pWMVDec->m_bUVHpelBilinear = BS_getBits(pWMVDec->m_pbitstrmIn, 1);
pWMVDec->m_bBroadcastMode = BS_getBits(pWMVDec->m_pbitstrmIn, 1);
pWMVDec->m_iDQuantCodingOn = BS_getBits(pWMVDec->m_pbitstrmIn, 2);
// common to main, simple, interlace
pWMVDec->m_bXformSwitch = BS_getBits(pWMVDec->m_pbitstrmIn, 1);
pWMVDec->m_bDCTTable_MB_ENABLED = BS_getBits(pWMVDec->m_pbitstrmIn, 1);
// pWMVDec->m_iSliceCode = BS_getBits(pWMVDec->m_pbitstrmIn,NUMBITS_SLICE_SIZE_WMV2);
pWMVDec->m_bSequenceOverlap = BS_getBits(pWMVDec->m_pbitstrmIn, 1);
pWMVDec->m_bStartCode = BS_getBits(pWMVDec->m_pbitstrmIn, 1);
//#ifdef PREPROCRANGE
pWMVDec->m_bPreProcRange = BS_getBits(pWMVDec->m_pbitstrmIn, 1);
//#endif
pWMVDec->m_iNumBFrames = BS_getBits(pWMVDec->m_pbitstrmIn, 3);
pWMVDec->m_bExplicitSeqQuantizer = BS_getBits(pWMVDec->m_pbitstrmIn, 1);
if (pWMVDec->m_bExplicitSeqQuantizer)
pWMVDec->m_bUse3QPDZQuantizer = BS_getBits(pWMVDec->m_pbitstrmIn, 1);
else
pWMVDec->m_bExplicitFrameQuantizer = BS_getBits(pWMVDec->m_pbitstrmIn, 1);
pWMVDec->m_bExplicitQuantizer = pWMVDec->m_bExplicitSeqQuantizer || pWMVDec->m_bExplicitFrameQuantizer;
pWMVDec->m_bSeqFrameInterpolation = BS_getBits(pWMVDec->m_pbitstrmIn, 1);
// Verify Profile
if (!pWMVDec->m_bSpriteMode)
{
if (pWMVDec->m_iWMV3Profile == WMV3_SIMPLE_PROFILE)
{
bValidProfile = (pWMVDec->m_bXintra8Switch == FALSE) &&
(pWMVDec->m_b16bitXform == TRUE) &&
(pWMVDec->m_bUVHpelBilinear == TRUE) &&
(pWMVDec->m_bStartCode == FALSE);
(pWMVDec->m_bBroadcastMode == FALSE) &&
(pWMVDec->m_bV9LoopFilter == FALSE) &&
(pWMVDec->m_bInterlaceCodingOn == FALSE) &&
(pWMVDec->m_bMultiresEnabled == FALSE) &&
(pWMVDec->m_iDQuantCodingOn == 0) &&
(pWMVDec->m_iNumBFrames == 0) &&
(pWMVDec->m_bPreProcRange == FALSE);
}
else if (pWMVDec->m_iWMV3Profile == WMV3_MAIN_PROFILE)
{
bValidProfile = (pWMVDec->m_bXintra8Switch == FALSE) &&
(pWMVDec->m_b16bitXform == TRUE);
}
if (!bValidProfile)
{
return WMV_Failed;
}
}
pWMVDec->m_iBFrameReciprocal = g_iBInverse[pWMVDec->m_iNumBFrames];
//SetProfileVariablesWMV3 (pWMVDec);
if (pWMVDec->m_bInterlaceCodingOn)
pWMVDec->m_bXintra8Switch = pWMVDec->m_bXintra8 = FALSE;
SetMVRangeFlag(pWMVDec, 0);
// recompute DQuant because pWMVDec->m_bNewDCQuant is set in SetProfileVariablesWMV3
//ComputeDQuantDecParam (pWMVDec);
// old/unused stuff
pWMVDec->m_bMixedPel = pWMVDec->m_bFrmHybridMVOn = FALSE_WMV;
// may have to override transform function pointers
if (pWMVDec->m_b16bitXform)
{
// m_InitIDCT_Dec (TRUE);
//decideMMXRoutines (pWMVDec);
//m_InitFncPtrAndZigzag(pWMVDec);
//pWMVDec->m_pSp->m_pIDCT_Dec = pWMVDec->m_pIntraX9IDCT_Dec;
//pWMVDec->m_pDecodeInverseInterBlockQuantize = DecodeInverseInterBlockQuantize16;
}
if (pWMVDec->m_bSpriteMode)
{
if (!pWMVDec->m_bXintra8Switch &&
!pWMVDec->m_bDCTTable_MB_ENABLED &&
!pWMVDec->m_bInterlaceCodingOn &&
pWMVDec->m_bSpriteMode &&
!pWMVDec->m_bV9LoopFilter &&
!pWMVDec->m_bMultiresEnabled &&
pWMVDec->m_b16bitXform &&
!pWMVDec->m_bUVHpelBilinear &&
!pWMVDec->m_bBroadcastMode &&
!pWMVDec->m_iDQuantCodingOn &&
!pWMVDec->m_bXformSwitch &&
!pWMVDec->m_bStartCode &&
!pWMVDec->m_bPreProcRange &&
!pWMVDec->m_bExplicitSeqQuantizer &&
!pWMVDec->m_bUse3QPDZQuantizer &&
!pWMVDec->m_bExplicitFrameQuantizer)
return decodeSpriteVOLHead(pWMVDec);
else
return WMV_Failed;
}
// The following bit determines wthe encoder used to generate the content:
// 0: Beta 1: RTM. Due to bugs, each version produces an incompatible
// bitstream. Parsing this value allows the decoder to properly decode the corresponding version.
// NOTE: default at this point is: m_bBetaContent = TRUE, m_bRTMContent = FALSE
// Depending on the detected encoder version, these values are overidden as follows:
pWMVDec->m_iBetaRTMMismatchIndex = 1;
if (BS_getBits(pWMVDec->m_pbitstrmIn, 1) == 1 /*&& !BS_invalid(pWMVDec->m_pbitstrmIn)*/)
{
// RTM content
pWMVDec->m_bRTMContent = TRUE;
pWMVDec->m_bBetaContent = FALSE;
pWMVDec->m_iBetaRTMMismatchIndex = 0;
}
return WMV_Succeeded;
}
tWMVDecodeStatus decodeVOLHead(tWMVDecInternalMember *pWMVDec)
{
pWMVDec->m_iFrameRate = BS_getBits(pWMVDec->m_pbitstrmIn, 5);
pWMVDec->m_iBitRate = BS_getBits(pWMVDec->m_pbitstrmIn, 11);
pWMVDec->m_bRndCtrlOn = TRUE_WMV;
pWMVDec->m_bMixedPel = BS_getBits(pWMVDec->m_pbitstrmIn, 1);
pWMVDec->m_bLoopFilter = BS_getBits(pWMVDec->m_pbitstrmIn, 1);
pWMVDec->m_bXformSwitch = BS_getBits(pWMVDec->m_pbitstrmIn, 1);
pWMVDec->m_bXintra8Switch = BS_getBits(pWMVDec->m_pbitstrmIn, 1);
//#ifdef _HYBRID_MV_
pWMVDec->m_bFrmHybridMVOn = BS_getBits(pWMVDec->m_pbitstrmIn, 1);
//#else
// pWMVDec->m_bFrmHybridMVOn = FALSE_WMV;
//#endif
// DCTTABLE S/W at MB level for WMV2.
pWMVDec->m_bDCTTable_MB_ENABLED = BS_getBits(pWMVDec->m_pbitstrmIn, 1);
pWMVDec->m_iSliceCode = BS_getBits(pWMVDec->m_pbitstrmIn, NUMBITS_SLICE_SIZE_WMV2);
return WMV_Succeeded;
}
I32_WMV WMVideoDecDecodeSequenceHeader(tWMVDecInternalMember *pWMVDec, U8_WMV *buffer, U8_WMV flag)
{
tWMVBS bitstrmIn;
tWMVDecodeStatus status;
memset(pWMVDec, 0, sizeof(tWMVDecInternalMember));
memset(&bitstrmIn, 0, sizeof(tWMVBS));
bitstrmIn.m_pbits = buffer;
pWMVDec->m_pbitstrmIn = &bitstrmIn;
if (flag)
status = decodeVOLHead_WMV3(pWMVDec);
else
status = decodeVOLHead(pWMVDec);
if (status != WMV_Succeeded)
return -1;
else
return bitstrmIn.m_bsptr;
}
#if 0
int main(int argc, char *argv[])
{
//FILE *pfInput;
U8_WMV *path;
U8_WMV buf[4096] = {0x4e, 0x71, 0x12, 0x01};
tWMVDecInternalMember WMVDec;
#if 0
if (argc < 2)
{
return printf("No input file\n");
}
else
{
path = argv[1];
}
pfInput = fopen(path, "rb");
if (fread(buf, 1, 4096, pfInput) < 4096)
return printf("Read bit stream error\n");
#endif
WMVideoDecDecodeSequenceHeader(&WMVDec, buf);
//fclose(pfInput);
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -