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

📄 umc_vc1_dec_frame_descr.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* /////////////////////////////////////////////////////////////////////////////
//
//                  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, Frame Processing for multi-frame threading model
//
*/
#include "umc_defs.h"

#if defined (UMC_ENABLE_VC1_VIDEO_DECODER)

#include "umc_vc1_dec_job.h"
#include "umc_vc1_dec_seq.h"

#include "umc_vc1_dec_time_statistics.h"

#include "umc_vc1_dec_task_store.h"
#include "umc_vc1_dec_task.h"
#include "umc_vc1_dec_debug.h"
#include "umc_vc1_common_blk_order_tbl.h"
#include "umc_vc1_common.h"
#include "umc_vc1_dec_frame_descr.h"
#include "ipps.h"
#include "umc_vc1_dec_exception.h"


using namespace UMC;
using namespace UMC::VC1Exceptions;



bool VC1FrameDescriptor::Init(Ipp32u DescriporID,
                              VC1Context*    pContext,
                              VC1TaskStore* pStore)
{
    VC1SequenceLayerHeader* seqLayerHeader = pContext->m_seqLayerHeader;
    m_pStore = pStore;

    // memory for diffs for each FrameDescriptor
    {
        if(m_pMemoryAllocator->Alloc(&m_pDiffMemID, sizeof(Ipp16s)*seqLayerHeader->widthMB*seqLayerHeader->heightMB*8*8*6,
                                      UMC_ALLOC_PERSISTENT, 16) != UMC_OK )
        {
            return false;
        }
        m_pDiffMem = (Ipp16s*)m_pMemoryAllocator->Lock(m_pDiffMemID);
    }

    // memory for prediction
    {
        if(m_pMemoryAllocator->Alloc(&m_pPredBlockID, sizeof(Ipp8u)*seqLayerHeader->widthMB*seqLayerHeader->heightMB*8*8*6,
                                      UMC_ALLOC_PERSISTENT, 16) != UMC_OK )
        {
            return false;
        }
        m_pPred = (Ipp8u*)m_pMemoryAllocator->Lock(m_pPredBlockID);
    }

    memset(m_pDiffMem,0,sizeof(Ipp16s)*seqLayerHeader->heightMB*seqLayerHeader->widthMB);

    Ipp32u buffSize =  (seqLayerHeader->heightMB*VC1_PIXEL_IN_LUMA + 128)*
                        (seqLayerHeader->widthMB*VC1_PIXEL_IN_LUMA + 128)
                        + ((seqLayerHeader->heightMB*VC1_PIXEL_IN_CHROMA + 64)
                        *(seqLayerHeader->widthMB*VC1_PIXEL_IN_CHROMA + 64))*2;


     m_pContext = (VC1Context*)ippsMalloc_8u(sizeof(VC1Context));
     if(!m_pContext)
         return false;
     memset(m_pContext, 0, sizeof(VC1Context));


    //buf size should be divisible by 4
    if(buffSize & 0x00000003)
        buffSize = (buffSize&0xFFFFFFFC) + 4;

    m_pContext->m_pBufferStart = (Ipp8u*)ippsMalloc_8u(buffSize*sizeof(Ipp8u));
    if(m_pContext->m_pBufferStart==NULL)
    {
        return false;
    }
    memset(m_pContext->m_pBufferStart, 0, buffSize);

    m_pContext->m_vlcTbl = pContext->m_vlcTbl;
    m_pContext->pRefDist = &pContext->RefDist;

    m_pContext->m_frmBuff.m_pFrames = pContext->m_frmBuff.m_pFrames;

    m_pContext->m_frmBuff.m_iDisplayIndex =  0;
    m_pContext->m_frmBuff.m_iCurrIndex    =  0;
    m_pContext->m_frmBuff.m_iPrevIndex    =  0;
    m_pContext->m_frmBuff.m_iNextIndex    =  1;
    m_pContext->m_frmBuff.m_iICompFieldIndex   =  pContext->m_frmBuff.m_iICompFieldIndex;

    m_pContext->m_seqLayerHeader = pContext->m_seqLayerHeader;
    m_pContext->m_MBs = (VC1MB*)ippsMalloc_8u(sizeof(VC1MB)*
                                              m_pContext->m_seqLayerHeader->heightMB
                                             *m_pContext->m_seqLayerHeader->widthMB);
    if(NULL == m_pContext->m_MBs )
    {
        return false;
    }
    memset(m_pContext->m_MBs, 0, (sizeof(VC1MB)*seqLayerHeader->heightMB*seqLayerHeader->widthMB));

    m_pContext->m_picLayerHeader = (VC1PictureLayerHeader*)ippsMalloc_8u(sizeof(VC1PictureLayerHeader)*VC1_MAX_SLICE_NUM);
    if(!m_pContext->m_picLayerHeader)
        return false;
    m_pContext->m_InitPicLayer = m_pContext->m_picLayerHeader;

    memset(m_pContext->m_picLayerHeader, 0, sizeof(VC1PictureLayerHeader)*VC1_MAX_SLICE_NUM);

    m_pContext->DCACParams = (VC1DCMBParam*)ippsMalloc_8u(sizeof(VC1DCMBParam)*seqLayerHeader->heightMB*seqLayerHeader->widthMB);
    if(m_pContext->DCACParams == NULL)
    {
        return false;
    }
   memset(m_pContext->DCACParams,0,sizeof(VC1DCMBParam)*seqLayerHeader->heightMB*seqLayerHeader->widthMB);


    m_pContext->savedMV=(Ipp16s*)ippsMalloc_8u(sizeof(Ipp16s)*seqLayerHeader->heightMB*seqLayerHeader->widthMB*4*2*2);
    if (!m_pContext->savedMV)
        return false;
    memset(m_pContext->savedMV, 0, sizeof(Ipp16s)*seqLayerHeader->heightMB*seqLayerHeader->widthMB*4*2*2);

    m_pContext->savedMVSamePolarity = (Ipp8u*)ippsMalloc_8u(sizeof(Ipp8u)*seqLayerHeader->heightMB*seqLayerHeader->widthMB*4);
    if (!m_pContext->savedMVSamePolarity)
        return false;
    memset(m_pContext->savedMVSamePolarity, 0, sizeof(Ipp8u)*seqLayerHeader->heightMB*seqLayerHeader->widthMB*4);

    m_pContext->savedMV_Curr = pContext->savedMV_Curr;
    m_pContext->savedMVSamePolarity_Curr = pContext->savedMVSamePolarity_Curr;



  //Bitplane pool
   m_pContext->m_pBitplane.m_databits = (Ipp8u*)ippsMalloc_8u(sizeof(Ipp8u)*seqLayerHeader->heightMB*
                                                                          seqLayerHeader->widthMB*
                                                                          VC1_MAX_BITPANE_CHUNCKS);
   if(NULL == m_pContext->m_pBitplane.m_databits)
       return false;

    memset(m_pContext->m_pBitplane.m_databits, 0,sizeof(Ipp8u)*seqLayerHeader->heightMB*
                                                             seqLayerHeader->widthMB*
                                                             VC1_MAX_BITPANE_CHUNCKS);

    m_iSelfID = DescriporID;
    return true;
}
void VC1FrameDescriptor::Reset()
{
    m_iFrameCounter = 0;
    m_iRefFramesDst = 0;
    m_bIsReadyToLoad = true;
    m_iSelfID = 0;
    m_iRefFramesDst = 0;
    m_iBFramesDst = 0;
    m_bIsReferenceReady = false;
    m_bIsBReady = false;
    m_bIsReadyToDisplay = false;
    m_bIsSkippedFrame = false;
    m_bIsReadyToProcess = false;
}
void VC1FrameDescriptor::Release()
{
    if (m_pContext)
    {
        if (m_pContext->savedMV)
        {
            ippsFree(m_pContext->savedMV);
            m_pContext->savedMV = NULL;
        }
        if (m_pContext->savedMVSamePolarity)
        {
            ippsFree(m_pContext->savedMVSamePolarity);
            m_pContext->savedMVSamePolarity = NULL;
        }
        if (m_pContext->m_InitPicLayer)
        {
            ippsFree(m_pContext->m_InitPicLayer);
            m_pContext->m_picLayerHeader = NULL;
        }

        if(m_pContext->m_pBitplane.m_databits)
        {
            ippsFree(m_pContext->m_pBitplane.m_databits);
            m_pContext->m_pBitplane.m_databits = NULL;

        }
        if(m_pContext->m_MBs)
        {
            ippsFree(m_pContext->m_MBs);
            m_pContext->m_MBs = NULL;
        }
        if(m_pContext->DCACParams)
        {
            ippsFree(m_pContext->DCACParams);
            m_pContext->DCACParams = NULL;
        }
        if (m_pContext->m_pBufferStart)
        {
            ippsFree(m_pContext->m_pBufferStart);
            m_pContext->m_pBufferStart = NULL;
        }

        if (m_pContext)
        {
            ippsFree(m_pContext);
            m_pContext = NULL;
        }

        if(m_pMemoryAllocator)
        {
            m_pMemoryAllocator->Unlock(m_pDiffMemID);
            m_pMemoryAllocator->Unlock(m_pPredBlockID);
            m_pMemoryAllocator->Free(m_pDiffMemID);
            m_pMemoryAllocator->Free(m_pPredBlockID);
            m_pDiffMemID = (MemID)-1;
            m_pPredBlockID = (MemID)-1;
        }
    }

}
void VC1FrameDescriptor::processFrame(Ipp32u*  pOffsets,
                                      Ipp32u*  pValues)
{
    SliceParams slparams;
    memset(&slparams,0,sizeof(SliceParams));
    VC1Task task(0);

    Ipp32u temp_value = 0;
    Ipp32u* bitstream;
    Ipp32s bitoffset = 31;

    bool isSecondField = false;


    slparams.MBStartRow = 0;
    slparams.is_continue = 1;

    slparams.MBEndRow = m_pContext->m_seqLayerHeader->heightMB;

    if (m_pContext->m_picLayerHeader->PTYPE == VC1_SKIPPED_FRAME)
    {
        m_bIsSkippedFrame = true;
        m_bIsReadyToProcess = false;
        return;
    }
    else
    {
        m_bIsSkippedFrame = false;
    }

    if (m_pContext->m_seqLayerHeader->PROFILE == VC1_PROFILE_ADVANCED)
        DecodePicHeader(m_pContext);
    else
        Decode_PictureLayer(m_pContext);



    slparams.m_pstart = m_pContext->m_bitstream.pBitstream;
    slparams.m_bitOffset = m_pContext->m_bitstream.bitOffset;
    slparams.m_picLayerHeader = m_pContext->m_picLayerHeader;
    slparams.m_vlcTbl = m_pContext->m_vlcTbl;

    if (m_pContext->m_seqLayerHeader->PROFILE != VC1_PROFILE_ADVANCED)
    {
        slparams.MBRowsToDecode = slparams.MBEndRow-slparams.MBStartRow;
        task.m_pSlice = &slparams;
        task.setSliceParams(m_pContext);
        task.m_isFieldReady = true;
        m_pStore->AddSampleTask(&task,m_iSelfID);
        task.m_pSlice = NULL;
        m_pStore->DistributeTasks(m_iSelfID);
        return;
    }


    if (*(pValues+1) == 0x0B010000)
    {
        bitstream = reinterpret_cast<Ipp32u*>(m_pContext->m_pBufferStart + *(pOffsets+1));
        VC1BitstreamParser::GetNBits(bitstream,bitoffset,32, temp_value);
        bitoffset = 31;
        VC1BitstreamParser::GetNBits(bitstream,bitoffset,9, slparams.MBEndRow);     //SLICE_ADDR

        m_pContext->m_picLayerHeader->is_slice = 1;
    }
    else if(*(pValues+1) == 0x0C010000)
    {
         slparams.m_picLayerHeader->CurrField = 0;
         slparams.m_picLayerHeader->PTYPE = m_pContext->m_picLayerHeader->PTypeField1;
         slparams.m_picLayerHeader->BottomField = (Ipp8u)(1 - m_pContext->m_picLayerHeader->TFF);
         slparams.MBEndRow = m_pContext->m_seqLayerHeader->heightMB/2;
    }


    slparams.MBRowsToDecode = slparams.MBEndRow-slparams.MBStartRow;
    task.m_pSlice = &slparams;
#ifdef SLICE_INFO
    Ipp32s slice_counter = 0;
    printf("Slice number %d\n", slice_counter);
    printf("Number MB rows to decode  =%d\n", slparams.MBRowsToDecode);
    ++slice_counter;
#endif
    task.setSliceParams(m_pContext);

    task.m_isFieldReady = true;
    m_pStore->AddSampleTask(&task,m_iSelfID);

    pOffsets++;
    pValues++;

    while (*pOffsets)
    {
        task.m_isFirstInSecondSlice = false;
        if (*(pValues) == 0x0C010000)
        {
            isSecondField = true;
            task.m_isFirstInSecondSlice = true;
            m_pContext->m_bitstream.pBitstream = reinterpret_cast<Ipp32u*>(m_pContext->m_pBufferStart + *pOffsets);
            m_pContext->m_bitstream.pBitstream += 1; // skip start code
            m_pContext->m_bitstream.bitOffset = 31;
            //m_pContext->m_picLayerHeader = m_pContext->m_InitPicLayer + 1;
            ++m_pContext->m_picLayerHeader;
            *m_pContext->m_picLayerHeader = *m_pContext->m_InitPicLayer;

            m_pContext->m_picLayerHeader->BottomField = (Ipp8u)m_pContext->m_InitPicLayer->TFF;
            m_pContext->m_picLayerHeader->PTYPE = m_pContext->m_InitPicLayer->PTypeField2;
            m_pContext->m_picLayerHeader->CurrField = 1;
            m_pContext->m_frmBuff.m_pFrames[m_pContext->m_frmBuff.m_iCurrIndex].RANGE_MAPY  = m_pContext->m_seqLayerHeader->RANGE_MAPY;
            m_pContext->m_frmBuff.m_pFrames[m_pContext->m_frmBuff.m_iCurrIndex].RANGE_MAPUV = m_pContext->m_seqLayerHeader->RANGE_MAPUV;

            m_pContext->m_picLayerHeader->is_slice = 0;
            DecodePicHeader(m_pContext);

            //VC1BitstreamParser::GetNBits(m_pContext->m_pbs,m_pContext->m_bitOffset,32, temp_value);

            slparams.MBStartRow = m_pContext->m_seqLayerHeader->heightMB/2;

            if (*(pOffsets+1) && *(pValues+1) == 0x0B010000)
            {
                bitstream = reinterpret_cast<Ipp32u*>(m_pContext->m_pBufferStart + *(pOffsets+1));
                VC1BitstreamParser::GetNBits(bitstream,bitoffset,32, temp_value);
                bitoffset = 31;
                VC1BitstreamParser::GetNBits(bitstream,bitoffset,9, slparams.MBEndRow);
            } else
                slparams.MBEndRow = m_pContext->m_seqLayerHeader->heightMB;

            slparams.m_picLayerHeader = m_pContext->m_picLayerHeader;
            slparams.m_vlcTbl = m_pContext->m_vlcTbl;
            slparams.m_pstart = m_pContext->m_bitstream.pBitstream;
            slparams.m_bitOffset = m_pContext->m_bitstream.bitOffset;
            slparams.MBRowsToDecode = slparams.MBEndRow-slparams.MBStartRow;
            task.m_pSlice = &slparams;
            task.setSliceParams(m_pContext);
            if (isSecondField)
                task.m_isFieldReady = false;
            else
                task.m_isFieldReady = true;
            m_pStore->AddSampleTask(&task,m_iSelfID);
            slparams.MBStartRow = slparams.MBEndRow;
            ++pOffsets;
            ++pValues;
        }
        else if (*(pValues) == 0x0B010000)
        {
            m_pContext->m_bitstream.pBitstream = reinterpret_cast<Ipp32u*>(m_pContext->m_pBufferStart + *pOffsets);
            VC1BitstreamParser::GetNBits(m_pContext->m_bitstream.pBitstream,m_pContext->m_bitstream.bitOffset,32, temp_value);
            m_pContext->m_bitstream.bitOffset = 31;

            VC1BitstreamParser::GetNBits(m_pContext->m_bitstream.pBitstream,m_pContext->m_bitstream.bitOffset,9, slparams.MBStartRow);     //SLICE_ADDR
            VC1BitstreamParser::GetNBits(m_pContext->m_bitstream.pBitstream,m_pContext->m_bitstream.bitOffset,1, temp_value);            //PIC_HEADER_FLAG

⌨️ 快捷键说明

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