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

📄 umc_dv_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) 2003-2007 Intel Corporation. All Rights Reserved.
//
//
*/
#include "umc_defs.h"
#if defined (UMC_ENABLE_DV_VIDEO_DECODER)

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

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

namespace UMC
{

VideoDecoder *CreateDVDecoder() { return new DVVideoDecoder(); }

DVVideoDecoder::DVVideoDecoder()
{
    StoreDVSegment      = NULL;

    m_nSystem           = SYSTEM_UNK;
    m_nPitch            = 0;
    m_lSizeSubSampled   = 0;
    m_bDCOnly           = false;
    m_bInitSuccess      = false;

    m_nNumberOfThreads  = 0;
    vm_event_set_invalid(&m_Quit);

    m_lpThreads         = NULL;
    m_lpStartEvent      = NULL;
    m_lpStopEvent       = NULL;
    m_lpThreadsID       = NULL;

    // pointer to hold allocated memory
    m_pHuffTable        = NULL;
    m_ppShortBlocks     = NULL;

    m_lpADequantizeLineTable            = NULL;

    // working pointer
    m_lpADequantizeTable = NULL;
    m_lpvInternalFrameBuffer = NULL;

    m_InternalFrameBufferMID = 0;
    m_DCTBlocksBufferMID = 0;
    m_DequantizeTableMID = 0;
} // DVVideoDecoder::DVVideoDecoder()

DVVideoDecoder::~DVVideoDecoder()
{
    Close();

} // DVVideoDecoder::~DVVideoDecoder()

Status DVVideoDecoder::Close()
{
    Ipp32u i;

    // let all threads to exit
    if (m_lpThreads)
    {
        vm_event_signal(&m_Quit);

        for (i = 1;i < m_nNumberOfThreads;i += 1)
            vm_event_signal(m_lpStartEvent + i);

        for (i = 1;i < m_nNumberOfThreads;i += 1)
        {
            if (vm_thread_is_valid(m_lpThreads + i))
                vm_thread_wait(m_lpThreads + i);
        }
    }

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

    if (m_lpThreads)
    {
        for (i = 1;i < m_nNumberOfThreads;i += 1)
            vm_thread_set_invalid(m_lpThreads + i);

        delete [] m_lpThreads;
        m_lpThreads = NULL;
    }

    if (m_lpStartEvent)
    {
        for (i = 1;i < m_nNumberOfThreads;i += 1)
        {
            if (vm_event_is_valid(m_lpStartEvent + i))
            {
                vm_event_destroy(m_lpStartEvent + i);
                vm_event_set_invalid(m_lpStartEvent + i);
            }
        }

        delete [] m_lpStartEvent;
        m_lpStartEvent = NULL;
    }

    if (m_lpStopEvent)
    {
        for (i = 1;i < m_nNumberOfThreads;i += 1)
        {
            if (vm_event_is_valid(m_lpStopEvent + i))
            {
                vm_event_destroy(m_lpStopEvent + i);
                vm_event_set_invalid(m_lpStopEvent + i);
            }
        }

        delete [] m_lpStopEvent;
        m_lpStopEvent = NULL;
    }

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

    if (m_pHuffTable)
    {
        ippiFreeHuffmanTable_DV_32u((Ipp32u *)m_pHuffTable);
        m_pHuffTable = NULL;
    }

    if(m_ppShortBlocks)
    {
        delete [] m_ppShortBlocks;
        m_ppShortBlocks = 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;
        }

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

    if (m_lpADequantizeLineTable)
    {
        m_lpADequantizeLineTable = NULL;
    }

    BaseCodec::Close(); // delete own allocator

    m_nSystem = SYSTEM_UNK;

    m_bDCOnly = false;

    m_nPitch = 0;

    StoreDVSegment = NULL;

    // working pointer
    m_lpADequantizeTable = NULL;
    m_lpvInternalFrameBuffer = NULL;

    return UMC_OK;

} // Status DVVideoDecoder::Close()


Status DVVideoDecoder::Init(BaseCodecParams *lpInit)
{
    VideoDecoderParams *init_param = DynamicCast<VideoDecoderParams> (lpInit);
    Ipp32u i;

    if (NULL == init_param)
        return UMC_ERR_NULL_PTR;

    Close();

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

    if(init_param->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 = init_param->numThreads;


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

    // allocate working buffer(s)
    if( m_pMemoryAllocator->Alloc(&m_DCTBlocksBufferMID,
                                  SIZE_OF_VIDEO_SEGMENT * m_nNumberOfThreads,
                                  UMC_ALLOC_PERSISTENT,
                                  16) != UMC_OK )
        return UMC_ERR_ALLOC;

    m_ppShortBlocks = new Ipp16u* [m_nNumberOfThreads];
    if (NULL == m_ppShortBlocks)
        return UMC_ERR_ALLOC;
    memset(m_ppShortBlocks, 0, sizeof(Ipp16u*) * m_nNumberOfThreads);

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

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

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

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

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

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

    // check parameters
    if ((WIDTH_DV != m_nWidth) || ((HEIGHT_625 != m_nHeight) && (HEIGHT_525 != m_nHeight)))
        return UMC_ERR_INVALID_STREAM;

    // set working system
    m_nSystem = ((HEIGHT_625 == m_nHeight) ? (SYSTEM_625) : (SYSTEM_525));
    m_nMaxNumberOfDIFSequences = ((HEIGHT_625 == m_nHeight) ? (12) : (10));
    if (SYSTEM_525 == m_nSystem) {
        m_nSourceFrameSize = 120000;
    } else  {
        m_nSourceFrameSize = 144000;
    }

    m_PostProcessing = init_param->pPostProcessing;

    m_ClipInfo = init_param->info;
    m_ClipInfo.clip_info.width = m_nWidth;
    m_ClipInfo.clip_info.height = m_nHeight;

    // allocate internal frame buffer
    {
        m_nPitch = align_value<Ipp32u> (2 * m_nWidth, WIDTH_ALIGN);

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

    // allocate buffer(s)
    if (ippStsOk != ippiInitAllocHuffmanTable_DV_32u((Ipp32s *) dvTable1,
                                                     (Ipp32s *) dvTable2,
                                                     reinterpret_cast<Ipp32u **> (&m_pHuffTable)))
        return UMC_ERR_ALLOC;

    if (DVCreateADequantizeTable())
        return UMC_ERR_ALLOC;

    m_bInitSuccess = true;

    return UMC_OK;
}

void DVVideoDecoder::CheckSetCorrectParams(int byteDSF)
{
    if ( byteDSF == 0x00)               //NTSC
    {
        m_ClipInfo.clip_info.height = 480;
        m_nHeight = 480;
        m_nSourceFrameSize = 120000;
        m_nMaxNumberOfDIFSequences = 10;
    }
    else if (byteDSF == 0x080)          //PAL
    {
        m_ClipInfo.clip_info.height = 576;
        m_nHeight = 576;
        m_nSourceFrameSize = 144000;
        m_nMaxNumberOfDIFSequences = 12;
    }
}
void DVVideoDecoder::SelectStoreFunction(void *pSource)
{
    Ipp8u *lp = reinterpret_cast<Ipp8u *> (pSource);
    Ipp32u nStreamType = DVSD_STREAM;
    Ipp8u APT = (*(lp+4)) & 0x07;
    Ipp8u AP1 = (*(lp+5)) & 0x07;
    Ipp8u AP2 = (*(lp+6)) & 0x07;
    Ipp8u AP3 = (*(lp+7)) & 0x07;
    // check error(s)
    if ((APT == AP1) &&
        (AP2 == AP3) &&
        (APT == AP3))
    {
      // check real stream type
      switch (APT)
      {
        // Consumer digital VCR
      case 0:
        nStreamType = DVSD_STREAM;
        break;

        // DVCPRO VCR
        //case 1:
      default:
        nStreamType = DV25_STREAM;
        break;
      }
    }

    // set right function
    switch (nStreamType)
    {
    case DVSD_STREAM:

⌨️ 快捷键说明

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