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

📄 umc_vc1_video_decoder.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/*//////////////////////////////////////////////////////////////////////////////
//
//                  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.
//
*/

#include "umc_defs.h"

#if defined (UMC_ENABLE_VC1_VIDEO_DECODER)

#include "umc_vc1_video_decoder.h"
#include "umc_video_data.h"
#include "vm_time.h"
#include "umc_media_data_ex.h"
#include "umc_vc1_dec_debug.h"
#include "umc_vc1_dec_seq.h"
#include "vm_sys_info.h"
#include "vm_thread.h"
#include "vm_types.h"
#include "umc_vc1_dec_task_store.h"
#include "umc_vc1_dec_task.h"
#include "umc_color_space_conversion.h"

#include "umc_memory_allocator.h"
#include "umc_vc1_dec_time_statistics.h"
#include "umc_vc1_common.h"
#include "umc_vc1_common_defs.h"
#include "assert.h"
#include "umc_vc1_dec_exception.h"







#include "ipps.h"

using namespace UMC;
using namespace UMC::VC1Common;
using namespace UMC::VC1Exceptions;

namespace UMC
{
    VideoDecoder *CreateVC1Decoder() { return (new VC1VideoDecoder); }
}

VC1VideoDecoder::VC1VideoDecoder():m_pContext(NULL),
                                   m_pdecoder(NULL),
                                   m_iThreadDecoderNum(0),
                                   m_dataBuffer(NULL),
                                   m_frameData(NULL),
                                   m_stCodes(NULL),
                                   m_decoderInitFlag(0),
                                   m_decoderFlags(0),
                                   m_pNewMemID((MemID)(-1)),
                                   m_pts(0),
                                   m_pts_dif(0),
                                   m_bIsWMPSplitter(false),
                                   m_iMaxFramesInProcessing(0),
                                   m_bIsFrameToOut(false),
                                   m_iRefFramesDst(0),
                                   m_iBFramesDst(0),
                                   m_pPrevDescriptor(NULL),
                                   m_lFrameCount(0),
                                   m_bLastFrameNeedDisplay(false),
                                   m_bIsWarningStream(false),
                                   m_pSelfDecoder(NULL),
                                   m_pStore(NULL),
                                   m_va(NULL),
                                   m_CurrentMode(Routine)

#ifdef CREATE_ES
                                   ,m_fPureVideo(NULL)
#endif

{
#ifdef  VC1_THREAD_STATISTIC
    m_parallelStat = NULL;
#endif
}

VC1VideoDecoder::~VC1VideoDecoder()
{
#ifdef  VC1_THREAD_STATISTIC
    if (m_parallelStat)
        fclose(m_parallelStat);
#endif

    Close();
}


Status VC1VideoDecoder::Init(BaseCodecParams *pInit)
{
    MediaData *data;
    Status umcRes = UMC_OK;
    Ipp32u i;
    Ipp32u frameSize;
    Ipp32u readSize = 0;
    m_pSelfDecoder = this;

    Close();

    VideoDecoderParams *init = DynamicCast<VideoDecoderParams, BaseCodecParams>(pInit);
    if(!init)
        return UMC_ERR_INIT;

    assert(init->info.stream_subtype != 0);

    m_decoderFlags = init->lFlags;
    data = init->m_pData;

    m_ClipInfo = init->info;



    if (WMV_VIDEO == init->info.stream_type)
        m_bIsWMPSplitter = true;

    m_PostProcessing = init->pPostProcessing;

    //MEMORY ALLOCATION
    {
        //common context for all Frame Descriptors
        m_pContext = (VC1Context*)ippsMalloc_8u(sizeof(VC1Context));
        if(!m_pContext)
        {
            Close();
            return UMC_ERR_ALLOC;
        }

        memset(m_pContext, 0, sizeof(VC1Context));

        m_pContext->m_seqLayerHeader = (VC1SequenceLayerHeader*)ippsMalloc_8u(sizeof(VC1SequenceLayerHeader));
        if(!m_pContext->m_seqLayerHeader)
        {
            Close();
            return UMC_ERR_ALLOC;
        }
        memset(m_pContext->m_seqLayerHeader, 0, sizeof(VC1SequenceLayerHeader));

        ////VLCTables
        m_pContext->m_vlcTbl = (VC1VLCTables*)ippsMalloc_8u(sizeof(VC1VLCTables));
        if(!m_pContext->m_vlcTbl)
        {
            Close();
            return UMC_ERR_ALLOC;
        }
        memset(m_pContext->m_vlcTbl, 0, sizeof(VC1VLCTables));
    }


    m_pContext->m_bIntensityCompensation = 0;

    if(data!=NULL && (Ipp32s*)data->GetDataPointer() != NULL)
    {
        if(!((m_decoderFlags & FLAG_VDEC_4BYTE_ACCESS) == FLAG_VDEC_4BYTE_ACCESS))
        {
            //need to create buffer for swap data
            CreateFrameBuffer();
            m_pContext->m_FrameSize    = (Ipp32u)data->GetDataSize();

            if(init->info.stream_subtype == VC1_VIDEO_VC1)
            {
                umcRes = GetStartCodes(data, m_frameData, &readSize);
                m_pContext->m_FrameSize = m_frameData->GetDataSize();
            }
            else
            {
                if(data->GetDataSize()<= m_frameData->GetBufferSize())
                    ippsCopy_8u((Ipp8u*)data->GetBufferPointer(),  m_dataBuffer, (Ipp32u)data->GetDataSize());
                else
                {
                    while(data->GetDataSize() > m_frameData->GetBufferSize())
                        ResizeBuffer();

                    ippsCopy_8u((Ipp8u*)data->GetBufferPointer(),  m_dataBuffer, (Ipp32u)data->GetDataSize());
                }

                readSize = m_pContext->m_FrameSize;
            }

            m_pContext->m_pBufferStart  = (Ipp8u*)m_dataBuffer;
            m_pContext->m_bitstream.pBitstream  = (Ipp32u*)(m_pContext->m_pBufferStart);

            //swap data
            SwapData((Ipp8u*)m_frameData->GetBufferPointer(),
                         (Ipp32u)m_frameData->GetDataSize());
        }
        else
        {
            m_pContext->m_bitstream.pBitstream = (Ipp32u*)data->GetDataPointer();
            m_pContext->m_pBufferStart  = (Ipp8u*)data->GetBufferPointer();
            m_pContext->m_FrameSize     = (Ipp32u)data->GetDataSize();
        }

        m_pContext->m_bitstream.bitOffset    = 31;
        frameSize = DecodeBegin(m_pContext, init->info.stream_subtype);

        if ( (WMV_VIDEO == init->info.stream_type)&&
             (WMV3_VIDEO == init->info.stream_subtype) )
        {
            Ipp32u height;
            Ipp32u width;
            m_pContext->m_seqLayerHeader->MAX_CODED_HEIGHT = init->info.clip_info.height/2 - 1;
            m_pContext->m_seqLayerHeader->MAX_CODED_WIDTH = init->info.clip_info.width/2 - 1;

            m_pContext->m_seqLayerHeader->widthMB
                = (Ipp16u)((init->info.clip_info.width+15)/VC1_PIXEL_IN_LUMA);

            m_pContext->m_seqLayerHeader->heightMB
                = (Ipp16u)((init->info.clip_info.height+15)/VC1_PIXEL_IN_LUMA);

            height = m_pContext->m_seqLayerHeader->heightMB*VC1_PIXEL_IN_LUMA;
            width = ((m_pContext->m_seqLayerHeader->widthMB * VC1_PIXEL_IN_LUMA) & 0xFFFFFF80)+ 0x080;
            frameSize = (height + 128)*(width + 128)
                + ((height / 2 + 64)*(width / 2 + 64))*2;
        }

// extract pure video from wmv
#ifdef CREATE_ES
        if (!m_fPureVideo)
        {
            m_fPureVideo = fopen("output_es.es","wb");
            if (!m_fPureVideo)
                return UMC_ERR_ALLOC;
            Ipp32u begin = 0x0000000F;
            fwrite(&begin, 1, 3, m_fPureVideo);
            begin = 0xC5;
            fwrite(&begin, 1, 1, m_fPureVideo);
            begin = 0x0000004;
            fwrite(&begin, 1, 4, m_fPureVideo);
            Ipp32u seqHead = *m_pContext->m_pBufferStart;
            SwapData((Ipp8u*)(m_pContext->m_pBufferStart),4);
            fwrite(m_pContext->m_pBufferStart, 1, 4, m_fPureVideo);
            Ipp32u picSize[2] = {(m_pContext->m_seqLayerHeader->MAX_CODED_HEIGHT+1)*2, (m_pContext->m_seqLayerHeader->MAX_CODED_WIDTH+1)*2};
            fwrite(picSize, 1, 8, m_fPureVideo);
            begin = 0x0000000C;
            fwrite(&begin, 1, 4, m_fPureVideo);
            fwrite(&begin, 1, 12, m_fPureVideo);
        }
#endif

        if(frameSize == 0)
        {
            Close();
            return UMC_ERR_SYNC;
        }

        GetFPS();
        GetPTS(data->GetTime());

        data->MoveDataPointer(readSize);
        m_decoderInitFlag = 1;
    }
    else
    {
        //NULL input data, no sequence header
        Ipp32u width = 0;
        Ipp32u height = 0;

        if(init->info.stream_subtype == VC1_VIDEO_VC1)
            m_pContext->m_seqLayerHeader->PROFILE = VC1_PROFILE_ADVANCED;
        else
            m_pContext->m_seqLayerHeader->PROFILE = VC1_PROFILE_MAIN;


        m_pContext->m_seqLayerHeader->MAX_CODED_HEIGHT = init->info.clip_info.height/2 - 1;
        m_pContext->m_seqLayerHeader->MAX_CODED_WIDTH = init->info.clip_info.width/2 - 1;

        m_pContext->m_seqLayerHeader->widthMB
            = (Ipp16u)((init->info.clip_info.width+15)/VC1_PIXEL_IN_LUMA);

        m_pContext->m_seqLayerHeader->heightMB
            = (Ipp16u)((init->info.clip_info.height+15)/VC1_PIXEL_IN_LUMA);

        if(init->info.interlace_type)
            m_pContext->m_seqLayerHeader->INTERLACE  = 1;

        height = m_pContext->m_seqLayerHeader->heightMB*VC1_PIXEL_IN_LUMA;
        width = ((m_pContext->m_seqLayerHeader->widthMB * VC1_PIXEL_IN_LUMA) & 0xFFFFFF80)+ 0x080;
        frameSize = (height + 128)*(width + 128) + ((height / 2 + 64)*(width / 2 + 64))*2;

        if(!((m_decoderFlags & FLAG_VDEC_4BYTE_ACCESS) == FLAG_VDEC_4BYTE_ACCESS))
        {
            //need to create buffer for swap data
            CreateFrameBuffer();
        }

    }

    //MEMORY ALLOCATOR
    if (UMC_OK != BaseCodec::Init(pInit) )
    {
        Close();
        return UMC_ERR_INIT;
    }

    // get allowed thread numbers
    Ipp32s nAllowedThreadNumber = init->numThreads;
    printf("nAllowedThreadNumber = %d\n",nAllowedThreadNumber);

#if defined (_WIN32) && (_DEBUG)
#ifdef VC1_DEBUG_ON
    VM_Debug::GetInstance(VC1DebugAlloc);
#endif
#endif

#ifdef THREADS
    nAllowedThreadNumber = THREADS_NUM;
#endif

    if(nAllowedThreadNumber < 0) nAllowedThreadNumber = 0;
    else
        if(nAllowedThreadNumber > 8) nAllowedThreadNumber = 8;

    //nAllowedThreadNumber = 1;


    m_iThreadDecoderNum = (0 == nAllowedThreadNumber) ? (vm_sys_info_get_cpu_num()) : (nAllowedThreadNumber);

    umcRes = InitVAEnvironment(frameSize);
    if (umcRes != UMC_OK)
        return umcRes;

    if (!m_pSelfDecoder->InitAlloc(m_pContext,m_iMaxFramesInProcessing))
        return UMC_ERR_ALLOC;


    if(!((m_decoderFlags & FLAG_VDEC_4BYTE_ACCESS) == FLAG_VDEC_4BYTE_ACCESS))
    {
        ResizeBuffer();
    }

    try
    // memory allocation and Init all env for frames/tasks store - VC1TaskStore object
    {
        m_pStore = new VC1TaskStore(m_pMemoryAllocator);
        if (!m_pStore->Init(m_iThreadDecoderNum,
                            m_iMaxFramesInProcessing,
                            this) )
            return UMC_ERR_ALLOC;

        m_pStore->CreateDSQueue(m_pContext);

        m_pStore->CreateOutBuffersQueue();
        m_pStore->SetDefinition(m_pContext->m_seqLayerHeader);
    }
    catch(...)
    {
        // only allocation here
        return UMC_ERR_ALLOC;
    }

    // create thread decoders for multithreading support
    {
        m_pdecoder = new VC1ThreadDecoder *[m_iThreadDecoderNum];
        if (NULL == m_pdecoder)
            return UMC_ERR_ALLOC;
        memset(m_pdecoder, 0, sizeof(VC1ThreadDecoder*) * m_iThreadDecoderNum);
        printf("ThreadNum = %d\n",m_iThreadDecoderNum);

⌨️ 快捷键说明

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