📄 umc_dv_decoder.cpp
字号:
/*
// 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 + -