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

📄 umc_dv100_decoder.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) 2006-2007 Intel Corporation. All Rights Reserved.
//
*/

#include <ippi.h>
#include <ipps.h>
#include <ippvc.h>
#include "umc_dv100_decoder.h"
#include "umc_video_data.h"
#include "umc_dv_internal.h"
#include "vm_event.h"
#include "vm_thread.h"
#include "vm_sys_info.h"
#include "umc_dv_decoder.h"
#include "umc_memory_allocator.h"

#ifdef _OPENMP
#include "omp.h"
#endif


namespace UMC
{

DV100VideoDecoder::DV100VideoDecoder(void) :
    m_pHuffTable(NULL),
    m_ppDecodedDCTBlocks(NULL),
    m_pDestination(NULL),
    m_System(SystemUnknown),
    m_pInternalFrameBuffer(NULL),
    m_pThreads(NULL),
    m_pStartEvents(NULL),
    m_pStopEvents(NULL),
    m_pThreadsID(NULL),
    m_DCTBlocksBufferMID(0),
    m_InternalFrameBufferMID(0),
    m_nSystem720_LastDecodedChannel(0),
    m_bInitSuccess(false)

{
    vm_event_set_invalid(&m_Quit);
}

DV100VideoDecoder::~DV100VideoDecoder(void)
{
}

static const Ipp32s DV100_VideoSegmentSize = 64 * 8 * 5 * sizeof(Ipp16s);

// Initialize DV decoder
Status DV100VideoDecoder::Init(BaseCodecParams *lpInit)
{
    Ipp32s ThreadNum;
    VideoDecoderParams *pParams = DynamicCast<VideoDecoderParams> (lpInit);

    if (NULL == pParams)
        return UMC_ERR_NULL_PTR;

    Close();

    // Initializes external memory allocator
    if (UMC_OK != BaseCodec::Init(lpInit))
        return UMC_ERR_INIT;

    if(pParams->numThreads == 0)
    {
#ifdef _OPENMP
        m_nNumberOfThreads = omp_get_max_threads();
#else //_OPENMP
        m_nNumberOfThreads = vm_sys_info_get_cpu_num();
#endif //_OPENMP
    }
    else
        m_nNumberOfThreads = pParams->numThreads;

    if (0 >= m_nNumberOfThreads)
        m_nNumberOfThreads = 1;
    else if (8 < m_nNumberOfThreads)
        m_nNumberOfThreads = 8;

    //Alloc internal buffers for DCT blocks
    if( m_pMemoryAllocator->Alloc(&m_DCTBlocksBufferMID,
                                  DV100_VideoSegmentSize * m_nNumberOfThreads,
                                  UMC_ALLOC_PERSISTENT,
                                  16) != UMC_OK )
        return UMC_ERR_ALLOC;

    m_ppDecodedDCTBlocks = new Ipp16s* [m_nNumberOfThreads];
    if (NULL == m_ppDecodedDCTBlocks)
        return UMC_ERR_ALLOC;

    // create threading tools
    if (1 < m_nNumberOfThreads)
    {
        // create quit event
        if (VM_OK != vm_event_init(&m_Quit, 1, 0))
            return UMC_ERR_INIT;

        // create start event(s)
        m_pStartEvents = new vm_event[m_nNumberOfThreads];
        if (NULL == m_pStartEvents)
            return UMC_ERR_ALLOC;
        for (ThreadNum = 1;ThreadNum < m_nNumberOfThreads;ThreadNum += 1)
        {
            vm_event_set_invalid(m_pStartEvents + ThreadNum);
            if (VM_OK != vm_event_init(m_pStartEvents + ThreadNum, 0, 0))
                return UMC_ERR_INIT;
        }

        // create stop event(s)
        m_pStopEvents = new vm_event[m_nNumberOfThreads];
        if (NULL == m_pStopEvents)
            return UMC_ERR_ALLOC;
        for (ThreadNum = 1;ThreadNum < m_nNumberOfThreads;ThreadNum += 1)
        {
            vm_event_set_invalid(m_pStopEvents + ThreadNum);
            if (VM_OK != vm_event_init(m_pStopEvents + ThreadNum, 0, 0))
                return UMC_ERR_INIT;
        }

        // allocate thread ID(s)
        m_pThreadsID = new THREAD_ID[m_nNumberOfThreads];
        if (NULL == m_pThreadsID)
            return UMC_ERR_ALLOC;

        // starting thread(s)
        m_pThreads = new vm_thread[m_nNumberOfThreads];
        if (NULL == m_pThreads)
            return UMC_ERR_ALLOC;
        for (ThreadNum = 1;ThreadNum < m_nNumberOfThreads;ThreadNum += 1)
        {
            vm_thread_set_invalid(m_pThreads + ThreadNum);
            m_pThreadsID[ThreadNum].m_nNumber = ThreadNum;
            m_pThreadsID[ThreadNum].m_lpOwner = this;
            if (0 == vm_thread_create(m_pThreads + ThreadNum, ThreadWorkingRoutine, m_pThreadsID + ThreadNum))
                return UMC_ERR_INIT;
        }

    }

    m_nHeight = pParams->info.clip_info.height;
    m_nWidth = pParams->info.clip_info.width;

    // check parameters
    if ( !((SYSTEM_1080_WIDTH == m_nWidth && SYSTEM_1080_HEIGHT == m_nHeight) ||
         (SYSTEM_720_WIDTH == m_nWidth && SYSTEM_720_HEIGHT == m_nHeight) ||
         (960 == m_nWidth && SYSTEM_720_HEIGHT == m_nHeight) ||
         (1280 == m_nWidth && SYSTEM_1080_HEIGHT == m_nHeight) ||
         (1400 == m_nWidth && SYSTEM_1080_HEIGHT == m_nHeight) ))
    {
        return UMC_ERR_INVALID_STREAM;
    }

    m_ClipInfo = pParams->info;

    //Codec always alloc maximal internal buffer 1920*1080*2 = 4147200 byte
    //Internal color format is YUY2
    m_nDestPitch = align_value<Ipp32s> (2 * 1920, WIDTH_ALIGN);

    if( m_pMemoryAllocator->Alloc(&m_InternalFrameBufferMID,
                                   m_nDestPitch * m_nHeight,
                                   UMC_ALLOC_PERSISTENT,
                                   16) != UMC_OK )
      return UMC_ERR_ALLOC;

    m_PostProcessing = pParams->pPostProcessing;

    if (ippStsOk != ippiInitAllocHuffmanTable_DV_32u(DVVideoDecoder::dvTable1, DVVideoDecoder::dvTable2, &m_pHuffTable))
        return UMC_ERR_ALLOC;

    m_bInitSuccess = true;

    return UMC_OK;
}

// Close decoder
Status DV100VideoDecoder::Close()
{
    Ipp32s ThreadNum;
    // let all threads exit
    if (m_pThreads)
    {
        vm_event_signal(&m_Quit);

        for (ThreadNum = 1;ThreadNum < m_nNumberOfThreads;ThreadNum += 1)
            vm_event_signal(m_pStartEvents + ThreadNum);

        for (ThreadNum = 1;ThreadNum < m_nNumberOfThreads;ThreadNum += 1)
        {
            if (vm_thread_is_valid(m_pThreads + ThreadNum))
                vm_thread_wait(m_pThreads + ThreadNum);
        }
    }

    // delete all threading tools
    if (vm_event_is_valid(&m_Quit))
    {
        vm_event_destroy(&m_Quit);
        vm_event_set_invalid(&m_Quit);
    }

    if (m_pThreads)
    {
        for (ThreadNum = 1;ThreadNum < m_nNumberOfThreads;ThreadNum += 1)
            vm_thread_set_invalid(m_pThreads + ThreadNum);

        delete [] m_pThreads;
        m_pThreads = NULL;
    }

    if (m_pStartEvents)
    {
        for (ThreadNum = 1;ThreadNum < m_nNumberOfThreads;ThreadNum += 1)
        {
            if (vm_event_is_valid(m_pStartEvents + ThreadNum))
            {
                vm_event_destroy(m_pStartEvents + ThreadNum);
                vm_event_set_invalid(m_pStartEvents + ThreadNum);
            }
        }

        delete [] m_pStartEvents;
        m_pStartEvents = NULL;
    }

    if (m_pStopEvents)
    {
        for (ThreadNum = 1;ThreadNum < m_nNumberOfThreads;ThreadNum += 1)
        {
            if (vm_event_is_valid(m_pStopEvents + ThreadNum))
            {
                vm_event_destroy(m_pStopEvents + ThreadNum);
                vm_event_set_invalid(m_pStopEvents + ThreadNum);
            }
        }

        delete [] m_pStopEvents;
        m_pStopEvents = NULL;
    }

    if (m_pThreadsID)
    {
        delete [] m_pThreadsID;
        m_pThreadsID = NULL;
    }


    if(m_pHuffTable != NULL)
        ippiFreeHuffmanTable_DV_32u(m_pHuffTable);
    m_pHuffTable = NULL;

    if(m_ppDecodedDCTBlocks != NULL)
        delete[] m_ppDecodedDCTBlocks;
    m_ppDecodedDCTBlocks = NULL;

    if( m_pMemoryAllocator )
    {
        if(m_DCTBlocksBufferMID != 0)
        {
            m_pMemoryAllocator->Free(m_DCTBlocksBufferMID);
            m_DCTBlocksBufferMID= 0;
        }

        if(m_InternalFrameBufferMID != 0)
        {
            m_pMemoryAllocator->Free(m_InternalFrameBufferMID);
            m_InternalFrameBufferMID = 0;
        }
    }

    // delete memory allocator if internal
    BaseCodec::Close();

    m_System = SystemUnknown;

    return UMC_OK;
}

//Distinguish 1080/60i and 1080/50i systems
Status DV100VideoDecoder::GetSystemSubtype()
{
    Ipp8u vaux_framerate = 0;
    Ipp8u vaux_system = 0;
    Ipp8u byte_PC0_of_VAUX  = 0;
    Ipp8u byte_PC3_of_VAUX = 0;
    //VAUX section 3, offfset from start of a DIF sequence 3*80 = 240 byte
    //Length of each section is 80 byte
    //Offset to VAUX source pack is 3 + 5*9 = 48 byte
    byte_PC0_of_VAUX = (Ipp8u) m_pStreamStart[240 + 48 + 0 + 2*80];
    byte_PC3_of_VAUX = (Ipp8u) m_pStreamStart[240 + 48 + 3 + 2*80];

    //check VAUX section
    if (0x60 != byte_PC0_of_VAUX)
        return UMC_ERR_INVALID_STREAM;
    else
    {
        vaux_framerate = (byte_PC3_of_VAUX>>5) &0x1;
        vaux_system = byte_PC3_of_VAUX &0x1f;
        if ((0 == vaux_framerate) &&( (0x14 == vaux_system) || (0x15 == vaux_system)) )
        {
            m_System = System1080_60i;
            m_nWidth = SYSTEM_1080_60I_WIDTH_NOT_STRETCHED;
            m_nHeight = SYSTEM_1080_HEIGHT;
        }
        if ((0 == vaux_framerate) && (0x18 == vaux_system) )
        {
            m_System = System720_60p;
            m_nWidth = SYSTEM_720_WIDTH_NOT_STRETCHED;
            m_nHeight = SYSTEM_720_HEIGHT;
        }
        if ((1 == vaux_framerate) && (0x14 == vaux_system) )
        {
            m_System = System1080_50i;
            m_nWidth = SYSTEM_1080_50I_WIDTH_NOT_STRETCHED;
            m_nHeight = SYSTEM_1080_HEIGHT;
        }
        if ((1 == vaux_framerate) && (0x18 == vaux_system) )
        {
            m_System = System720_50p;
            m_nWidth = SYSTEM_720_WIDTH_NOT_STRETCHED;
            m_nHeight = SYSTEM_720_HEIGHT;
        }
    }

    m_ClipInfo.clip_info.width = m_nWidth;
    m_ClipInfo.clip_info.height = m_nHeight;

    return UMC_OK;
}

const size_t DIFSequenceLength = 150 * 80; //150 DIF blocks by 80 bytes

// Decode next frame
Status DV100VideoDecoder::GetFrame(MediaData *pInData, MediaData *pOutData)
{

⌨️ 快捷键说明

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