📄 umc_dv100_decoder.cpp
字号:
VideoData *pVideoDataOut = DynamicCast<VideoData> (pOutData);
Status status = UMC_OK;
Ipp32s ThreadNum;
if (!m_bInitSuccess)
return UMC_ERR_NOT_INITIALIZED;
if ((NULL == pVideoDataOut))
return UMC_ERR_NULL_PTR;
if ((NULL == pInData))
{
return UMC_ERR_NOT_ENOUGH_DATA;
}
m_pStreamStart = reinterpret_cast<Ipp8u *> (pInData->GetDataPointer());
//Check modes(systems) of DV100
status = GetSystemSubtype();
if(UMC_OK != status)
return status;
if (!m_PostProcessing) {
m_PostProcessing = m_allocatedPostProcessing = createVideoProcessing();
}
#if 0
if (m_allocatedPostProcessing /* post processing is default */ &&
YUY2 == lpVData->GetColorFormat() &&
m_nWidth == pVideoDataOut->GetWidth() &&
m_nHeight == pVideoDataOut->GetHeight())
{
m_pDestination = (Ipp8u*) pVideoDataOut->GetPlanePointer(0);
m_nDestPitch = pVideoDataOut->GetPlanePitch(0);
} else
#endif
{
m_pInternalFrameBuffer = (Ipp8u*) m_pMemoryAllocator->Lock(m_InternalFrameBufferMID);
if( m_pInternalFrameBuffer == NULL )
return UMC_ERR_NULL_PTR;
m_pDestination = m_pInternalFrameBuffer;
m_nDestPitch = align_value<Ipp32s> (2 * m_nWidth, WIDTH_ALIGN);
}
Ipp8u *pDCTBlocksBuffer = (Ipp8u*)m_pMemoryAllocator->Lock(m_DCTBlocksBufferMID);
if(pDCTBlocksBuffer == NULL)
return UMC_ERR_NULL_PTR;
for (ThreadNum = 0; ThreadNum < m_nNumberOfThreads; ThreadNum += 1)
m_ppDecodedDCTBlocks[ThreadNum] = (Ipp16s*)( ((Ipp8u*)(pDCTBlocksBuffer)) + DV100_VideoSegmentSize * ThreadNum );
// start additional thread(s)
for (ThreadNum = 1; ThreadNum < m_nNumberOfThreads; ThreadNum += 1)
vm_event_signal(m_pStartEvents + ThreadNum);
DecomressDIFSequences(0);
// wait additional thread(s)
for (ThreadNum = 1;ThreadNum < m_nNumberOfThreads;ThreadNum += 1)
vm_event_wait(m_pStopEvents + ThreadNum);
m_pMemoryAllocator->Unlock(m_DCTBlocksBufferMID);
#ifdef _DEBUG
memset(m_ppDecodedDCTBlocks, 0, sizeof(Ipp16u*) * m_nNumberOfThreads);
#endif
if ((m_System == System720_60p)|| (m_System == System720_50p))
{
if(m_nSystem720_LastDecodedChannel == 0)
m_nSystem720_LastDecodedChannel = 2;
else
m_nSystem720_LastDecodedChannel = 0;
}
pVideoDataOut->SetFrameType(I_PICTURE);
pVideoDataOut->SetTime(pInData->GetTime());
if (m_LastDecodedFrame.GetColorFormat() != YUY2) {
m_LastDecodedFrame.Init(m_nWidth,
m_nHeight,
YUY2);
}
m_LastDecodedFrame.SetFrameType(I_PICTURE);
m_LastDecodedFrame.SetTime(pInData->GetTime());
m_LastDecodedFrame.SetPlanePointer((void*)m_pDestination, 0);
m_LastDecodedFrame.SetPlanePitch(m_nDestPitch, 0);
if (m_pDestination == m_pInternalFrameBuffer)
{
status = m_PostProcessing->GetFrame(&m_LastDecodedFrame, pVideoDataOut);
m_pMemoryAllocator->Unlock(m_InternalFrameBufferMID);
m_pInternalFrameBuffer = NULL;
}
if (System1080_60i == m_System) {
pInData->MoveDataPointer(120000*4);
pInData->SetTime(pInData->GetTime() + 2.0/59.96);
}
else if(System1080_50i == m_System)
{
pInData->MoveDataPointer(144000*4);
pInData->SetTime(pInData->GetTime() + 1.0/25);
}
else if (System720_60p == m_System)
{
pInData->MoveDataPointer(120000*2);
pInData->SetTime(pInData->GetTime() + 1.0/59.96);
}
else if (System720_50p == m_System)
{
pInData->MoveDataPointer(144000*2);
pInData->SetTime(pInData->GetTime() + 1.0/25);
}
return status;
}
void DV100VideoDecoder::DecomressDIFSequences(Ipp32s nThreadNum)
{
Ipp32s nChannelNum, nDIFSeqNum, nVideoSegmentNum, nDIFSeqInChannel;
Ipp32s nDIFSeqInFrame, nStartDIFSeqNum, nEndDIFSeqNum;
Ipp16s TempBlock[64];
switch(m_System)
{
case System1080_50i: nDIFSeqInFrame = 12*4; break;
case System1080_60i: nDIFSeqInFrame = 10*4; break;
case System720_60p: nDIFSeqInFrame = 10*2; break;
case System720_50p: nDIFSeqInFrame = 12*2; break;
default: nDIFSeqInFrame = 0;
}
nStartDIFSeqNum = nDIFSeqInFrame * nThreadNum / m_nNumberOfThreads;
nEndDIFSeqNum = nDIFSeqInFrame * (nThreadNum+1) / m_nNumberOfThreads;
Ipp16s* pDecodedDCTBlocks = m_ppDecodedDCTBlocks[nThreadNum];
union
{
BlockParam BlParam[40];
Ipp32u BlParamBuffer[40];
};
nDIFSeqInChannel = ((m_System == System1080_50i)|| (m_System == System720_50p)) ? 12 : 10;
for(nDIFSeqNum=nStartDIFSeqNum; nDIFSeqNum < nEndDIFSeqNum; nDIFSeqNum++)
{
if(m_System == System1080_50i && (nDIFSeqNum == 23 || nDIFSeqNum == 35 || nDIFSeqNum == 47))
continue;
if ((m_System == System720_50p) &&((nDIFSeqNum == 10)|| (nDIFSeqNum == 11) || (nDIFSeqNum == 22) || (nDIFSeqNum == 23)))
continue;
nChannelNum = nDIFSeqNum / nDIFSeqInChannel;
for(nVideoSegmentNum=0; nVideoSegmentNum < 27; nVideoSegmentNum++)
{
Ipp32s nMBNum, nDCTBlockNum, bl_index, eob;
Ipp16s *pCurrDCTBlock;
Ipp8u *pVideoSegmentStart = m_pStreamStart +
nDIFSeqNum * DIFSequenceLength +
//nChannelNum * ChannelLength +
//(nDIFSeqNum % nDIFSeqInChannel) * DIFSequenceLength +
(6 + (nVideoSegmentNum/3 + 1) + nVideoSegmentNum*5) * 80;
memset(pDecodedDCTBlocks, 0, DV100_VideoSegmentSize);
ippiHuffmanDecodeSegment_DV100_8u16s(pVideoSegmentStart,
DVVideoDecoder::_INTERNAL_DEZIGZAG_TABLE_0,//ZigzagTable,
m_pHuffTable,
pDecodedDCTBlocks,
BlParamBuffer);
pCurrDCTBlock = pDecodedDCTBlocks;
for(nMBNum = 0; nMBNum < 5; nMBNum++)
{
Ipp8u QNO = BlParam[nMBNum * 8].qno;
Ipp8u M0 = BlParam[nMBNum * 8].m0;// In contrast to DVSD in dv100 the same DCT mode
//(8-8-frame or 8-8-field) is applied to all DCT blocks in a Macro block. The DCT
//mode is stored in the FIRST DCT BLOCK of the macro block. m0 values of other
//DCT blocks ARE IGNORED.
for(nDCTBlockNum = 0; nDCTBlockNum < 8; nDCTBlockNum++)
{
Ipp8u ClassNumber = BlParam[nMBNum * 8 + nDCTBlockNum].cl;
Ipp32s QuantStep = QuantizationSteps[QNO*4 + ClassNumber];
bl_index = (BlParamBuffer[nMBNum * 8 + nDCTBlockNum] >> 8) & 0xff;
eob = BlParamBuffer[nMBNum * 8 + nDCTBlockNum] & 0x01;
//Ipp32s ElemNum;
const Ipp16s *pQuantizeTable;
//Dequantize block
if ((m_System == System720_60p) || (m_System == System720_50p))
pQuantizeTable = (nDCTBlockNum < 4) ? LumaQuantizeMatrix_720System : ChromaQuantizeMatrix_720System;
else
pQuantizeTable = (nDCTBlockNum < 4) ? LumaQuantizeMatrix_1080System : ChromaQuantizeMatrix_1080System;
//Do quantization and weighting
ippiQuantWeightBlockInv_DV100_16s_C1I(pCurrDCTBlock, (Ipp16s *)pQuantizeTable, QuantStep);
//Do inverse DCT
if ((eob == 0)||( 10 > bl_index))
{
ippiDCT8x8Inv_4x4_16s_C1I(pCurrDCTBlock);
}
else
ippiDCT8x8Inv_16s_C1I(pCurrDCTBlock);
pCurrDCTBlock += 64;
}//for nDCTBlockNum = 0 to 7
if(M0 == 1)
{
Ipp16s x,y;
//Rearrange pixeles in vertically adjacent DCT blocks
for(nDCTBlockNum =0; nDCTBlockNum < 4; nDCTBlockNum++)
{
Ipp16s *pUpperDCTBlock, *pLowerDCTBlock;
if(nDCTBlockNum < 2)
{
pUpperDCTBlock = pDecodedDCTBlocks + (8*nMBNum + nDCTBlockNum)*64;
pLowerDCTBlock = pUpperDCTBlock + 2*64;
}
else
{
pUpperDCTBlock = pDecodedDCTBlocks + (8*nMBNum + nDCTBlockNum*2)*64;
pLowerDCTBlock = pUpperDCTBlock + 64;
}
memcpy(TempBlock, pUpperDCTBlock, 64*sizeof(Ipp16s));
for(y=0; y<4; y++)
{
for(x=0; x<8; x++)
{
pUpperDCTBlock[ y*2*8 + x] = TempBlock[y*8 + x];
pUpperDCTBlock[(y*2+1)*8 + x] = pLowerDCTBlock[y*8 + x];
}
}
for(y=0; y<4; y++)
{
for(x=0; x<8; x++)
{
pLowerDCTBlock[ y*2*8 + x] = TempBlock[(4+y)*8 + x];
pLowerDCTBlock[(y*2+1)*8 + x] = pLowerDCTBlock[(4+y)*8 + x];
}
}
}
}
}//for nMBNum = 0 to 4
if ((m_System == System720_60p) || (m_System == System720_50p))
{
Store_System720_60p_Segment(pDecodedDCTBlocks, nChannelNum + m_nSystem720_LastDecodedChannel, (nDIFSeqNum % nDIFSeqInChannel), nVideoSegmentNum);
}
else if(m_System == System1080_50i)
{
Store_System1080_50i_Segment(pDecodedDCTBlocks, nChannelNum, (nDIFSeqNum % nDIFSeqInChannel), nVideoSegmentNum);
}
else
{
Store_System1080_60i_Segment(pDecodedDCTBlocks, nChannelNum, (nDIFSeqNum % nDIFSeqInChannel), nVideoSegmentNum);
}
}//for nVideoSegmentNum = 0 to 26
}//for nDIFSeqNum = 0 to nDIFSeqInChannel-1 (9 or 11)
//}//for nChannelNum = 0 to 1 or 3
}
Ipp32u DV100VideoDecoder::ThreadWorkingRoutine(void *lpv)
{
THREAD_ID *pThreadId;
DV100VideoDecoder *pOwner;
// check error(s)
if (NULL == lpv)
return 0x0bad;
pThreadId = reinterpret_cast<THREAD_ID *> (lpv);
pOwner = reinterpret_cast<DV100VideoDecoder *> (pThreadId->m_lpOwner);
// wait for start
vm_event_wait(pOwner->m_pStartEvents + pThreadId->m_nNumber);
while (VM_TIMEOUT == vm_event_timed_wait(&(pOwner->m_Quit), 0))
{
// decompress part of frame
pOwner->DecomressDIFSequences(pThreadId->m_nNumber);
// set finish
vm_event_signal(pOwner->m_pStopEvents + pThreadId->m_nNumber);
// wait for start
vm_event_wait(pOwner->m_pStartEvents + pThreadId->m_nNumber);
};
return pThreadId->m_nNumber;
}
// Get decoder performance
Status DV100VideoDecoder::GetPerformance(Ipp64f *perf)
{
if (perf != NULL)
*perf = 1.0;
return UMC_OK;
}
// Reset decoder into initial state
Status DV100VideoDecoder::Reset()
{
if (!m_bInitSuccess)
return UMC_ERR_NOT_INITIALIZED;
else
return UMC_OK;
}
Status DV100VideoDecoder::GetInfo(BaseCodecParams* info)
{
VideoDecoderParams *pParams;
if(info == NULL)
return UMC_ERR_NULL_PTR;
if (m_bInitSuccess == false)
return UMC_ERR_NOT_INITIALIZED;
pParams = DynamicCast<VideoDecoderParams> (info);
if ((NULL != pParams) && (m_bInitSuccess == true) ) {
pParams->info = m_ClipInfo;
pParams->lpMemoryAllocator = m_pMemoryAllocator;
pParams->pPostProcessing = m_PostProcessing;
pParams->numThreads = m_nNumberOfThreads;
}
return UMC_OK;
} // Status DV100VideoDecoder::GetInfo(void)
}//namespace UMC
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -