📄 umc_dv50_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) 2004-2007 Intel Corporation. All Rights Reserved.
//
//
*/
#include "umc_defs.h"
#if defined (UMC_ENABLE_DV50_VIDEO_DECODER)
#include <ippi.h>
#include <ipps.h>
#include <ippvc.h>
#include "vm_event.h"
#include "vm_thread.h"
#include "vm_sys_info.h"
#include "umc_dv50_decoder.h"
#include "umc_dv50_internal.h"
#include "umc_dv_internal.h"
#include "umc_video_data.h"
#ifdef _OPENMP
#include "omp.h"
#endif
namespace UMC
{
DV50VideoDecoder::DV50VideoDecoder()
{
} // DV50VideoDecoder::DV50VideoDecoder()
DV50VideoDecoder::~DV50VideoDecoder()
{
Close();
} // DV50VideoDecoder::~DV50VideoDecoder()
Status DV50VideoDecoder::Close()
{
return DVVideoDecoder::Close();
} // Status DV50VideoDecoder::Close()
Status DV50VideoDecoder::Init(BaseCodecParams *lpInit)
{
Status umcRes;
// initialize parent class
umcRes = DVVideoDecoder::Init(lpInit);
if (UMC_OK != umcRes)
return umcRes;
// set working system
m_nMaxNumberOfDIFSequences = ((HEIGHT_625 == m_nHeight) ? (24) : (20));
if (SYSTEM_525 == m_nSystem) {
m_nSourceFrameSize = 240000;
} else {
m_nSourceFrameSize = 288000;
}
return UMC_OK;
} // Status DV50VideoDecoder::Init(BaseCodecParams *init_param)
void DV50VideoDecoder::CheckSetCorrectParams(int byteDSF)
{
if ( byteDSF == 0x00) //NTSC
{
m_ClipInfo.clip_info.height = 480;
m_nHeight = 480;
m_nSourceFrameSize = 2*120000;
m_nMaxNumberOfDIFSequences = 2*10;
}
else if (byteDSF == 0x080) //PAL
{
m_ClipInfo.clip_info.height = 576;
m_nHeight = 576;
m_nSourceFrameSize = 2*144000;
m_nMaxNumberOfDIFSequences = 2*12;
}
}
void DV50VideoDecoder::SelectStoreFunction(void* /*pSource*/)
{
// set storing function
switch (m_lSizeSubSampled)
{
case 2:
StoreDVSegment = &DV50VideoDecoder::StoreDV50Segment_2s;
break;
case 4:
StoreDVSegment = &DV50VideoDecoder::StoreDV50Segment_4s;
break;
case 8:
StoreDVSegment = &DV50VideoDecoder::StoreDV50Segment_8s;
break;
default:
StoreDVSegment = &DV50VideoDecoder::StoreDV50Segment;
break;
}
}
void DV50VideoDecoder::DecompressSegment(Ipp32u nThreadNum)
{
Ipp32u i, k;
Ipp32u b;
Ipp32u i_start, i_stop;
Ipp32u nTemp;
Ipp8u *lpSrc;
static Ipp32u BlockNumber[4] = {0, 2, 4, 5};
// check error(s)
if (nThreadNum >= m_nNumberOfThreads)
return;
// set working i & k
nTemp = m_nMaxNumberOfDIFSequences;
i_start = (nTemp * (nThreadNum)) / m_nNumberOfThreads;
i_stop = (nTemp * (nThreadNum + 1)) / m_nNumberOfThreads;
Ipp16u *lpsBlocks = m_ppShortBlocks[nThreadNum];
if (false == m_bDCOnly)
{
Ipp32u BlParamBuffer[30];
Ipp32u b_num, mb_num, block_type, block_quant_class, qno, bl_index, eob;
Ipp16u *lpsTable;
for (i = i_start;i < i_stop;i += 1)
{
for (k = 0;k < 27;k += 1)
{
// get source pointer
lpSrc = m_lpSource + SIZE_OF_DV_SEGMENT * (i * 150 + 6 + (k / 3 + 1) + k * 5);
//reset working block
memset(lpsBlocks, 0, SIZE_OF_VIDEO_SEGMENT);
// start video decompressing
if(m_lSizeSubSampled == 2)
ippiHuffmanDecodeSegmentOnePass_DV_8u16s((Ipp8u *) lpSrc,
(Ipp32u *) _INTERNAL_DEZIGZAG_TABLE_0,
(Ipp32u *) m_pHuffTable,
(Ipp16s *) lpsBlocks,
(Ipp32u *) BlParamBuffer,
64);
else
ippiHuffmanDecodeSegment_DV_8u16s( (Ipp8u *) lpSrc,
(Ipp32u *) _INTERNAL_DEZIGZAG_TABLE_0,
(Ipp32u *) m_pHuffTable,
(Ipp16s *) lpsBlocks,
(Ipp32u *) BlParamBuffer);
// do dequantize and iDCT
for (mb_num = 0;mb_num < 5;mb_num += 1)
{
// get quantization number
qno = (BlParamBuffer[mb_num * 6] >> 16) & 0x0F;
// decompress each block
for (b = 0;b < 4;b += 1)
{
b_num = BlockNumber[b];
block_quant_class = (BlParamBuffer[mb_num * 6 + b_num] >> 4) & 0x03;
block_type = (BlParamBuffer[mb_num * 6 + b_num] >> 6) & 0x01;
bl_index = (BlParamBuffer[mb_num * 6 + b_num] >> 8) & 0xff;
eob = BlParamBuffer[mb_num * 6 + b_num] & 0x01;
// get beginning of arrays of dequantize tables
lpsTable = m_lpADequantizeTable +
// get needed array of tables, depending on block class
(block_type * 64 * 14) +
// get offset of needed table, depending on quantization class
// & quantization number
64 * m_lpADequantizeLineTable[qno + block_quant_class * 16];
// do inverse and adaptive dequantization
ippiQuantInv_DV_16s_C1I((Ipp16s *) (lpsBlocks + 64 * (b_num + 6 * mb_num)), (Ipp16s *) lpsTable);
// do iDCT
if (0 == block_type)
{
if(m_lSizeSubSampled == 2)
ippiDCT8x4x2To4x4Inv_DV_16s_C1I((Ipp16s *) (lpsBlocks + 64 * (b_num +6 * mb_num)));
else if ((eob == 0)||( 10 > bl_index))
{
ippiDCT8x8Inv_4x4_16s_C1I((Ipp16s *) (lpsBlocks + 64 * (b_num + 6 * mb_num)));
}
else
ippiDCT8x8Inv_16s_C1I((Ipp16s *) (lpsBlocks + 64 * (b_num + 6 * mb_num)));
}
else
{
if(m_lSizeSubSampled == 2)
ippiDCT8x4x2To4x4Inv_DV_16s_C1I((Ipp16s *) (lpsBlocks + 64 * (b_num +6 * mb_num)));
else
ippiDCT2x4x8Inv_16s_C1I((Ipp16s *) (lpsBlocks + 64 * (b_num +6 * mb_num)));
}
}
}
// store data to memory
(this->*(StoreDVSegment))(i, k, nThreadNum);
}
}
}
else
{
for (i = i_start;i < i_stop;i += 1)
{
for (k = 0;k < 27;k += 1)
{
// get source pointer
lpSrc = m_lpSource + SIZE_OF_DV_SEGMENT * (i * 150 + 6 + (k / 3 + 1) + k * 5);
HuffmanDecodeSegment_DV_DC_only(lpSrc, lpsBlocks);
// store data to memory
(this->*StoreDVSegment)(i, k, nThreadNum);
}
}
}
} // void DV50VideoDecoder::DecompressSegment(Ipp32u ThreadNum)
Status DV50VideoDecoder::GetPerformance(Ipp64f *perf)
{
if (perf)
*perf = 1.0;
return UMC_OK;
} // Status DV50VideoDecoder::GetPerformance(Ipp64f *perf)
Status DV50VideoDecoder::Reset(void)
{
if (!m_bInitSuccess)
return UMC_ERR_NOT_INITIALIZED;
else
return UMC_OK;
} // Status DV50VideoDecoder::Reset(void)
} // end namespace UMC
#endif //(UMC_ENABLE_DV50_VIDEO_DECODER)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -