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

📄 umc_vc1_dec_mb_ppic_adv.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/* /////////////////////////////////////////////////////////////////////////////
//
//                  INTEL CORPORATION PROPRIETARY INFORMATION
//     This software is supplied under the terms of a license agreement or
//     nondisclosure agreement with Intel Corporation and may not be copied
//     or disclosed except in accordance with the terms of that agreement.
//          Copyright(c) 2004-2007 Intel Corporation. All Rights Reserved.
//
//
//          VC-1 (VC1) decoder, MB Layer in P picture for advanced profile
//
*/
#include "umc_defs.h"

#if defined (UMC_ENABLE_VC1_VIDEO_DECODER)

#include "umc_vc1_dec_seq.h"
#include "umc_vc1_dec_debug.h"
#include "umc_vc1_common_blk_order_tbl.h"
#include "umc_vc1_common_interlace_mb_mode_tables.h"
#include "umc_vc1_common_zigzag_tbl.h"


#include "umc_vc1_dec_time_statistics.h"

typedef void (*MV_PREDICT_4MV)(VC1MB* pCurrMB,
                               Ipp16s pPredMV[4][2],
                               Ipp16s validPredictors[4],
                               Ipp16s MV_px[4][3],
                               Ipp16s MV_py[4][3],
                               ...);

typedef void (*DCPrediction)(VC1Context* pContext);
static const DCPrediction PDCPredictionTable[] =
{
        (DCPrediction)(GetPDCPredictors),
        (DCPrediction)(GetPScaleDCPredictors),
        (DCPrediction)(GetPScaleDCPredictors)
};

static VC1Status MBLayer_ProgressivePskipped(VC1Context* pContext)
{
    Ipp32s blk_num;
    Ipp16s X = 0, Y = 0;
    VC1MB* pCurrMB = pContext->m_pCurrMB;

    pCurrMB->m_cbpBits = 0;

    for(blk_num = 0; blk_num < VC1_NUM_OF_BLOCKS/*VC1_NUM_OF_LUMA*/; blk_num++)
    {
        pCurrMB->m_pBlocks[blk_num].blkType = VC1_BLK_INTER8X8;
    }

    if(VC1_GET_MBTYPE(pCurrMB->mbType) == VC1_MB_4MV_INTER)
    {
        Progressive4MVPrediction(pContext);

        for (blk_num = 0; blk_num < VC1_NUM_OF_LUMA; blk_num++)
        {
            CalculateProgressive4MV_Adv(pContext,&X, &Y, blk_num);
            ApplyMVPrediction(pContext, blk_num, &X, &Y, 0, 0, 0);
        }
    }
    else
    {
        //MV prediction
        Progressive1MVPrediction(pContext);
        CalculateProgressive1MV(pContext,&X,&Y);
        ApplyMVPrediction(pContext, 0, &X, &Y, 0, 0, 0);
    }


    return VC1_OK;
}

static VC1Status MBLayer_ProgressivePpicture1MV(VC1Context* pContext)
{
    IppStatus ret;
    Ipp16s dmv_x;
    Ipp16s dmv_y;
    Ipp16u last_intra_flag = 0;
    Ipp32s i;
    VC1MB* pCurrMB = pContext->m_pCurrMB;
    VC1PictureLayerHeader* picLayerHeader = pContext->m_picLayerHeader;

    //MVDATA is a variable sized field present in P picture macroblocks
    //This field encodes the motion vector(s) for the macroblock.

    Ipp16s hpelfl = (Ipp16s)((picLayerHeader->MVMODE==VC1_MVMODE_HPEL_1MV) ||
        (picLayerHeader->MVMODE==VC1_MVMODE_HPELBI_1MV));

    last_intra_flag = DecodeMVDiff(pContext,hpelfl,&dmv_x,&dmv_y);

    if(!(last_intra_flag&0x10))
        pCurrMB->m_cbpBits = 0;

    dmv_x = dmv_x * (1+hpelfl);
    dmv_y = dmv_y * (1+hpelfl);

    for(i = 0; i < VC1_NUM_OF_LUMA; i++)
    {
        pCurrMB->m_pBlocks[i].blkType  = (last_intra_flag&0x1)?(Ipp8u)VC1_BLK_INTRA:(Ipp8u)VC1_BLK_INTER8X8;
    }

    // all blocks are intra
    if (last_intra_flag&0x1)
        pCurrMB->mbType   = VC1_MB_INTRA;

    //motion vector predictors are calculated only for non-intra blocks, otherwise they are equal to zero (8.3.5.3)
    if(pCurrMB->mbType != VC1_MB_INTRA)
    {
        Ipp16s X = 0, Y = 0;
        // HYBRIDPRED is decoded in function PredictProgressive1MV
        //PredictProgressive1MV (pContext,&X, &Y);
        Progressive1MVPrediction(pContext);
        CalculateProgressive1MV(pContext,&X,&Y);
        ApplyMVPrediction(pContext, 0, &X, &Y, dmv_x, dmv_y, 0);
    }

    // all blocks in macroblock have one block type. So croma block have the same block type
    pCurrMB->m_pBlocks[4].blkType = pCurrMB->m_pBlocks[0].blkType;
    pCurrMB->m_pBlocks[5].blkType = pCurrMB->m_pBlocks[0].blkType;


    if(pCurrMB->mbType ==VC1_MB_INTRA && (!(last_intra_flag&0x10)))
    {
        if(picLayerHeader->m_PQuant_mode >= VC1_ALTPQUANT_MB_LEVEL)
            GetMQUANT(pContext);

        //AC prediction if intra
        VC1_GET_BITS(1, pContext->m_pSingleMB->ACPRED);

    }
    else if(last_intra_flag&0x10)
    {
        //AC prediction if intra55
        if(pCurrMB->mbType == VC1_MB_INTRA)
            VC1_GET_BITS(1, pContext->m_pSingleMB->ACPRED);
        //CBPCY decoding
        ret = ippiDecodeHuffmanOne_1u32s(&pContext->m_bitstream.pBitstream,
            &pContext->m_bitstream.bitOffset,
            &pCurrMB->m_cbpBits,
            picLayerHeader->m_pCurrCBPCYtbl);

        VM_ASSERT(ret == ippStsNoErr);

        //MB quant calculations
        if (picLayerHeader->m_PQuant_mode >= VC1_ALTPQUANT_MB_LEVEL)
            GetMQUANT(pContext);
    }
    else
    {
        //nothing more to do
        pCurrMB->m_cbpBits = 0;
    }

    //TTMB info is decoded in MBLayer_ProgressivePpicture
    return VC1_OK;
}

static VC1Status MBLayer_ProgressivePpicture4MV(VC1Context* pContext)
{
    Ipp32s i;
    VC1MB* pCurrMB = pContext->m_pCurrMB;
    VC1SingletonMB* sMB = pContext->m_pSingleMB;
    VC1PictureLayerHeader* picLayerHeader = pContext->m_picLayerHeader;

    IppStatus ret;
    Ipp32s Count_inter=0;
    Ipp32s n_block=0;
    Ipp16s dmv_x = 0;
    Ipp16s dmv_y = 0;

    Ipp32u LeftTopRightPositionFlag = pCurrMB->LeftTopRightPositionFlag;

    ret = ippiDecodeHuffmanOne_1u32s(&pContext->m_bitstream.pBitstream,
                                    &pContext->m_bitstream.bitOffset,
                                    &pCurrMB->m_cbpBits,
                                    picLayerHeader->m_pCurrCBPCYtbl);
    VM_ASSERT(ret == ippStsNoErr);

    if (ret!=ippStsNoErr)
        return VC1_FAIL;

    Progressive4MVPrediction(pContext);

    for (i=0;i<4;i++)
    {
        if (pCurrMB->m_cbpBits&(1<<(5-i)))
        {
            Ipp16u last_intra_flag = 0;

            //BLKMVDATA
            // for 4MV blocks hpelfl = 0
            last_intra_flag = DecodeMVDiff(pContext,0,&dmv_x,&dmv_y);

            pCurrMB->m_pBlocks[i].blkType = (last_intra_flag&0x1)?
                                                (Ipp8u)VC1_BLK_INTRA:(Ipp8u)VC1_BLK_INTER8X8;
            if(!(last_intra_flag&0x10))
                pCurrMB->m_cbpBits = (Ipp8u)(pCurrMB->m_cbpBits & ~(1 << (5 - i)));
        }
        else
        {
            dmv_x = 0;
            dmv_y = 0;
            pCurrMB->m_pBlocks[i].blkType = (Ipp8u)(picLayerHeader->TTFRM);
        }

        if (!(pCurrMB->m_pBlocks[i].blkType & VC1_BLK_INTRA))
        {
            Ipp16s X,Y;
            // HYBRIDPRED is decoded in function PredictProgressive4MV
            CalculateProgressive4MV_Adv(pContext,&X, &Y, i);
            ApplyMVPrediction(pContext, i, &X, &Y, dmv_x, dmv_y, 0);
            // croma MVs are calculated in DeriveProgMV and it is called in function Interpolate block.
            Count_inter++;
            n_block = i;
        }
    }//end for

    //type for chroma blocks
    if (Count_inter>1)
    {
        pCurrMB->m_pBlocks[4].blkType = pCurrMB->m_pBlocks[n_block].blkType;
        pCurrMB->m_pBlocks[5].blkType = pCurrMB->m_pBlocks[n_block].blkType;
    }
    else
    {
        pCurrMB->m_pBlocks[4].blkType = VC1_BLK_INTRA;
        pCurrMB->m_pBlocks[5].blkType = VC1_BLK_INTRA;
    }
    if (Count_inter==4&&(pCurrMB->m_cbpBits==0))
        return VC1_OK;

    // MQDIFF, ABSMQ (7.1.3.4)

    if (picLayerHeader->m_PQuant_mode >= VC1_ALTPQUANT_MB_LEVEL)
        GetMQUANT(pContext);

    // if macroblock have predicted => ACPRED (7.1.3.2)
    {
        Ipp8u c[6];
        Ipp8u a[6];
        Ipp32s count=0;

        memset(a,0,6*sizeof(Ipp8s));
        memset(c,0,6*sizeof(Ipp8s));
        pContext->m_pSingleMB->ACPRED =0;

        if (VC1_IS_NO_LEFT_MB(LeftTopRightPositionFlag))
        {
            c[0] = (Ipp8u)((pCurrMB - 1)->m_pBlocks[1].blkType&VC1_BLK_INTRA);
            c[2] = (Ipp8u)((pCurrMB - 1)->m_pBlocks[3].blkType&VC1_BLK_INTRA);
            c[4] = (Ipp8u)((pCurrMB - 1)->m_pBlocks[4].blkType&VC1_BLK_INTRA);
            c[5] = (Ipp8u)((pCurrMB - 1)->m_pBlocks[5].blkType&VC1_BLK_INTRA);
        }
        if (VC1_IS_NO_TOP_MB(LeftTopRightPositionFlag))
        {
            a[0] = (Ipp8u)((pCurrMB - sMB->widthMB)->m_pBlocks[2].blkType&VC1_BLK_INTRA);
            a[1] = (Ipp8u)((pCurrMB - sMB->widthMB)->m_pBlocks[3].blkType&VC1_BLK_INTRA);
            a[4] = (Ipp8u)((pCurrMB - sMB->widthMB)->m_pBlocks[4].blkType&VC1_BLK_INTRA);
            a[5] = (Ipp8u)((pCurrMB - sMB->widthMB)->m_pBlocks[5].blkType&VC1_BLK_INTRA);
        }
        c[1]=(Ipp8u)(pCurrMB->m_pBlocks[0].blkType& VC1_BLK_INTRA);
        c[3]=(Ipp8u)(pCurrMB->m_pBlocks[2].blkType& VC1_BLK_INTRA);
        a[2]=(Ipp8u)(pCurrMB->m_pBlocks[0].blkType& VC1_BLK_INTRA);
        a[3]=(Ipp8u)(pCurrMB->m_pBlocks[1].blkType& VC1_BLK_INTRA);

        for (i=0;i<VC1_NUM_OF_BLOCKS;i++)
        {
            count+=((pCurrMB->m_pBlocks[i].blkType& VC1_BLK_INTRA)&&((c[i])||(a[i])));
        }

        if (count)
            VC1_GET_BITS(1,sMB->ACPRED);
    }
    return VC1_OK;
}

static VC1Status MBLayer_InterlacePskipped(VC1Context* pContext)
{
    Ipp32s blk_num;
    VC1MB* pCurrMB = pContext->m_pCurrMB;

    Ipp16s X = 0, Y = 0;

    static const  Ipp32u predict_offset[6] = {0,8,128,136,256,320};

    pCurrMB->mbType = VC1_MB_1MV_INTER | VC1_MB_FORWARD;
    pCurrMB->m_cbpBits = 0;
    pCurrMB->FIELDTX = 0;


    for(blk_num = 0; blk_num < VC1_NUM_OF_BLOCKS; blk_num++)
    {
        pCurrMB->m_pBlocks[blk_num].blkType =  VC1_BLK_INTER8X8;
    }

    PredictInterlaceFrame1MV(pContext);
    CalculateInterlaceFrame1MV_P(&pContext->MVPred, &X, &Y);

    ApplyMVPrediction(pContext, 0, &X, &Y, 0, 0, 0);
    for( blk_num = 0;  blk_num < VC1_NUM_OF_LUMA;  blk_num++)
    {
        pCurrMB->m_pBlocks[blk_num].mv_bottom[0][0] = X;
        pCurrMB->m_pBlocks[blk_num].mv_bottom[0][1] = Y;
    }

#ifdef VC1_DEBUG_ON
        VM_Debug::GetInstance(VC1DebugRoutine).vm_debug_frame(-1,VC1_RESPEL,VM_STRING("Skip\n"));
#endif

    return VC1_OK;
}

static VC1Status MBLayer_InterlacePpicture1MV(VC1Context* pContext)
{
    VC1MB* pCurrMB = pContext->m_pCurrMB;

    Ipp16s dmv_x = 0;
    Ipp16s dmv_y = 0;
    Ipp32s blk_num;
    Ipp16s X =0;
    Ipp16s Y = 0;
    //VM_Debug::GetInstance().vm_debug_frame(-1,VC1_MV,VM_STRING("Interlace 1 MV\n"));

    if(VC1_MB_Mode_PBPic_MVPresent_Table[pContext->m_pSingleMB->MBMODEIndex])
        DecodeMVDiff_Adv(pContext,&dmv_x,&dmv_y);

    PredictInterlaceFrame1MV(pContext);
    CalculateInterlaceFrame1MV_P(&pContext->MVPred, &X, &Y);

    ApplyMVPrediction(pContext, 0, &X, &Y, dmv_x, dmv_y,0);
    for( blk_num = 0;  blk_num < 4;  blk_num++)
    {
        pCurrMB->m_pBlocks[blk_num].mv_bottom[0][0] = X;
        pCurrMB->m_pBlocks[blk_num].mv_bottom[0][1] = Y;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -