⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wmv3_volheaddec.c

📁 瑞星微公司RK27XX系列芯片的SDK开发包
💻 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 + -