📄 umc_vc1_dec_frame_descr.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.
//
//
// VC-1 (VC1) decoder, Frame Processing for multi-frame threading model
//
*/
#include "umc_defs.h"
#if defined (UMC_ENABLE_VC1_VIDEO_DECODER)
#include "umc_vc1_dec_job.h"
#include "umc_vc1_dec_seq.h"
#include "umc_vc1_dec_time_statistics.h"
#include "umc_vc1_dec_task_store.h"
#include "umc_vc1_dec_task.h"
#include "umc_vc1_dec_debug.h"
#include "umc_vc1_common_blk_order_tbl.h"
#include "umc_vc1_common.h"
#include "umc_vc1_dec_frame_descr.h"
#include "ipps.h"
#include "umc_vc1_dec_exception.h"
using namespace UMC;
using namespace UMC::VC1Exceptions;
bool VC1FrameDescriptor::Init(Ipp32u DescriporID,
VC1Context* pContext,
VC1TaskStore* pStore)
{
VC1SequenceLayerHeader* seqLayerHeader = pContext->m_seqLayerHeader;
m_pStore = pStore;
// memory for diffs for each FrameDescriptor
{
if(m_pMemoryAllocator->Alloc(&m_pDiffMemID, sizeof(Ipp16s)*seqLayerHeader->widthMB*seqLayerHeader->heightMB*8*8*6,
UMC_ALLOC_PERSISTENT, 16) != UMC_OK )
{
return false;
}
m_pDiffMem = (Ipp16s*)m_pMemoryAllocator->Lock(m_pDiffMemID);
}
// memory for prediction
{
if(m_pMemoryAllocator->Alloc(&m_pPredBlockID, sizeof(Ipp8u)*seqLayerHeader->widthMB*seqLayerHeader->heightMB*8*8*6,
UMC_ALLOC_PERSISTENT, 16) != UMC_OK )
{
return false;
}
m_pPred = (Ipp8u*)m_pMemoryAllocator->Lock(m_pPredBlockID);
}
memset(m_pDiffMem,0,sizeof(Ipp16s)*seqLayerHeader->heightMB*seqLayerHeader->widthMB);
Ipp32u buffSize = (seqLayerHeader->heightMB*VC1_PIXEL_IN_LUMA + 128)*
(seqLayerHeader->widthMB*VC1_PIXEL_IN_LUMA + 128)
+ ((seqLayerHeader->heightMB*VC1_PIXEL_IN_CHROMA + 64)
*(seqLayerHeader->widthMB*VC1_PIXEL_IN_CHROMA + 64))*2;
m_pContext = (VC1Context*)ippsMalloc_8u(sizeof(VC1Context));
if(!m_pContext)
return false;
memset(m_pContext, 0, sizeof(VC1Context));
//buf size should be divisible by 4
if(buffSize & 0x00000003)
buffSize = (buffSize&0xFFFFFFFC) + 4;
m_pContext->m_pBufferStart = (Ipp8u*)ippsMalloc_8u(buffSize*sizeof(Ipp8u));
if(m_pContext->m_pBufferStart==NULL)
{
return false;
}
memset(m_pContext->m_pBufferStart, 0, buffSize);
m_pContext->m_vlcTbl = pContext->m_vlcTbl;
m_pContext->pRefDist = &pContext->RefDist;
m_pContext->m_frmBuff.m_pFrames = pContext->m_frmBuff.m_pFrames;
m_pContext->m_frmBuff.m_iDisplayIndex = 0;
m_pContext->m_frmBuff.m_iCurrIndex = 0;
m_pContext->m_frmBuff.m_iPrevIndex = 0;
m_pContext->m_frmBuff.m_iNextIndex = 1;
m_pContext->m_frmBuff.m_iICompFieldIndex = pContext->m_frmBuff.m_iICompFieldIndex;
m_pContext->m_seqLayerHeader = pContext->m_seqLayerHeader;
m_pContext->m_MBs = (VC1MB*)ippsMalloc_8u(sizeof(VC1MB)*
m_pContext->m_seqLayerHeader->heightMB
*m_pContext->m_seqLayerHeader->widthMB);
if(NULL == m_pContext->m_MBs )
{
return false;
}
memset(m_pContext->m_MBs, 0, (sizeof(VC1MB)*seqLayerHeader->heightMB*seqLayerHeader->widthMB));
m_pContext->m_picLayerHeader = (VC1PictureLayerHeader*)ippsMalloc_8u(sizeof(VC1PictureLayerHeader)*VC1_MAX_SLICE_NUM);
if(!m_pContext->m_picLayerHeader)
return false;
m_pContext->m_InitPicLayer = m_pContext->m_picLayerHeader;
memset(m_pContext->m_picLayerHeader, 0, sizeof(VC1PictureLayerHeader)*VC1_MAX_SLICE_NUM);
m_pContext->DCACParams = (VC1DCMBParam*)ippsMalloc_8u(sizeof(VC1DCMBParam)*seqLayerHeader->heightMB*seqLayerHeader->widthMB);
if(m_pContext->DCACParams == NULL)
{
return false;
}
memset(m_pContext->DCACParams,0,sizeof(VC1DCMBParam)*seqLayerHeader->heightMB*seqLayerHeader->widthMB);
m_pContext->savedMV=(Ipp16s*)ippsMalloc_8u(sizeof(Ipp16s)*seqLayerHeader->heightMB*seqLayerHeader->widthMB*4*2*2);
if (!m_pContext->savedMV)
return false;
memset(m_pContext->savedMV, 0, sizeof(Ipp16s)*seqLayerHeader->heightMB*seqLayerHeader->widthMB*4*2*2);
m_pContext->savedMVSamePolarity = (Ipp8u*)ippsMalloc_8u(sizeof(Ipp8u)*seqLayerHeader->heightMB*seqLayerHeader->widthMB*4);
if (!m_pContext->savedMVSamePolarity)
return false;
memset(m_pContext->savedMVSamePolarity, 0, sizeof(Ipp8u)*seqLayerHeader->heightMB*seqLayerHeader->widthMB*4);
m_pContext->savedMV_Curr = pContext->savedMV_Curr;
m_pContext->savedMVSamePolarity_Curr = pContext->savedMVSamePolarity_Curr;
//Bitplane pool
m_pContext->m_pBitplane.m_databits = (Ipp8u*)ippsMalloc_8u(sizeof(Ipp8u)*seqLayerHeader->heightMB*
seqLayerHeader->widthMB*
VC1_MAX_BITPANE_CHUNCKS);
if(NULL == m_pContext->m_pBitplane.m_databits)
return false;
memset(m_pContext->m_pBitplane.m_databits, 0,sizeof(Ipp8u)*seqLayerHeader->heightMB*
seqLayerHeader->widthMB*
VC1_MAX_BITPANE_CHUNCKS);
m_iSelfID = DescriporID;
return true;
}
void VC1FrameDescriptor::Reset()
{
m_iFrameCounter = 0;
m_iRefFramesDst = 0;
m_bIsReadyToLoad = true;
m_iSelfID = 0;
m_iRefFramesDst = 0;
m_iBFramesDst = 0;
m_bIsReferenceReady = false;
m_bIsBReady = false;
m_bIsReadyToDisplay = false;
m_bIsSkippedFrame = false;
m_bIsReadyToProcess = false;
}
void VC1FrameDescriptor::Release()
{
if (m_pContext)
{
if (m_pContext->savedMV)
{
ippsFree(m_pContext->savedMV);
m_pContext->savedMV = NULL;
}
if (m_pContext->savedMVSamePolarity)
{
ippsFree(m_pContext->savedMVSamePolarity);
m_pContext->savedMVSamePolarity = NULL;
}
if (m_pContext->m_InitPicLayer)
{
ippsFree(m_pContext->m_InitPicLayer);
m_pContext->m_picLayerHeader = NULL;
}
if(m_pContext->m_pBitplane.m_databits)
{
ippsFree(m_pContext->m_pBitplane.m_databits);
m_pContext->m_pBitplane.m_databits = NULL;
}
if(m_pContext->m_MBs)
{
ippsFree(m_pContext->m_MBs);
m_pContext->m_MBs = NULL;
}
if(m_pContext->DCACParams)
{
ippsFree(m_pContext->DCACParams);
m_pContext->DCACParams = NULL;
}
if (m_pContext->m_pBufferStart)
{
ippsFree(m_pContext->m_pBufferStart);
m_pContext->m_pBufferStart = NULL;
}
if (m_pContext)
{
ippsFree(m_pContext);
m_pContext = NULL;
}
if(m_pMemoryAllocator)
{
m_pMemoryAllocator->Unlock(m_pDiffMemID);
m_pMemoryAllocator->Unlock(m_pPredBlockID);
m_pMemoryAllocator->Free(m_pDiffMemID);
m_pMemoryAllocator->Free(m_pPredBlockID);
m_pDiffMemID = (MemID)-1;
m_pPredBlockID = (MemID)-1;
}
}
}
void VC1FrameDescriptor::processFrame(Ipp32u* pOffsets,
Ipp32u* pValues)
{
SliceParams slparams;
memset(&slparams,0,sizeof(SliceParams));
VC1Task task(0);
Ipp32u temp_value = 0;
Ipp32u* bitstream;
Ipp32s bitoffset = 31;
bool isSecondField = false;
slparams.MBStartRow = 0;
slparams.is_continue = 1;
slparams.MBEndRow = m_pContext->m_seqLayerHeader->heightMB;
if (m_pContext->m_picLayerHeader->PTYPE == VC1_SKIPPED_FRAME)
{
m_bIsSkippedFrame = true;
m_bIsReadyToProcess = false;
return;
}
else
{
m_bIsSkippedFrame = false;
}
if (m_pContext->m_seqLayerHeader->PROFILE == VC1_PROFILE_ADVANCED)
DecodePicHeader(m_pContext);
else
Decode_PictureLayer(m_pContext);
slparams.m_pstart = m_pContext->m_bitstream.pBitstream;
slparams.m_bitOffset = m_pContext->m_bitstream.bitOffset;
slparams.m_picLayerHeader = m_pContext->m_picLayerHeader;
slparams.m_vlcTbl = m_pContext->m_vlcTbl;
if (m_pContext->m_seqLayerHeader->PROFILE != VC1_PROFILE_ADVANCED)
{
slparams.MBRowsToDecode = slparams.MBEndRow-slparams.MBStartRow;
task.m_pSlice = &slparams;
task.setSliceParams(m_pContext);
task.m_isFieldReady = true;
m_pStore->AddSampleTask(&task,m_iSelfID);
task.m_pSlice = NULL;
m_pStore->DistributeTasks(m_iSelfID);
return;
}
if (*(pValues+1) == 0x0B010000)
{
bitstream = reinterpret_cast<Ipp32u*>(m_pContext->m_pBufferStart + *(pOffsets+1));
VC1BitstreamParser::GetNBits(bitstream,bitoffset,32, temp_value);
bitoffset = 31;
VC1BitstreamParser::GetNBits(bitstream,bitoffset,9, slparams.MBEndRow); //SLICE_ADDR
m_pContext->m_picLayerHeader->is_slice = 1;
}
else if(*(pValues+1) == 0x0C010000)
{
slparams.m_picLayerHeader->CurrField = 0;
slparams.m_picLayerHeader->PTYPE = m_pContext->m_picLayerHeader->PTypeField1;
slparams.m_picLayerHeader->BottomField = (Ipp8u)(1 - m_pContext->m_picLayerHeader->TFF);
slparams.MBEndRow = m_pContext->m_seqLayerHeader->heightMB/2;
}
slparams.MBRowsToDecode = slparams.MBEndRow-slparams.MBStartRow;
task.m_pSlice = &slparams;
#ifdef SLICE_INFO
Ipp32s slice_counter = 0;
printf("Slice number %d\n", slice_counter);
printf("Number MB rows to decode =%d\n", slparams.MBRowsToDecode);
++slice_counter;
#endif
task.setSliceParams(m_pContext);
task.m_isFieldReady = true;
m_pStore->AddSampleTask(&task,m_iSelfID);
pOffsets++;
pValues++;
while (*pOffsets)
{
task.m_isFirstInSecondSlice = false;
if (*(pValues) == 0x0C010000)
{
isSecondField = true;
task.m_isFirstInSecondSlice = true;
m_pContext->m_bitstream.pBitstream = reinterpret_cast<Ipp32u*>(m_pContext->m_pBufferStart + *pOffsets);
m_pContext->m_bitstream.pBitstream += 1; // skip start code
m_pContext->m_bitstream.bitOffset = 31;
//m_pContext->m_picLayerHeader = m_pContext->m_InitPicLayer + 1;
++m_pContext->m_picLayerHeader;
*m_pContext->m_picLayerHeader = *m_pContext->m_InitPicLayer;
m_pContext->m_picLayerHeader->BottomField = (Ipp8u)m_pContext->m_InitPicLayer->TFF;
m_pContext->m_picLayerHeader->PTYPE = m_pContext->m_InitPicLayer->PTypeField2;
m_pContext->m_picLayerHeader->CurrField = 1;
m_pContext->m_frmBuff.m_pFrames[m_pContext->m_frmBuff.m_iCurrIndex].RANGE_MAPY = m_pContext->m_seqLayerHeader->RANGE_MAPY;
m_pContext->m_frmBuff.m_pFrames[m_pContext->m_frmBuff.m_iCurrIndex].RANGE_MAPUV = m_pContext->m_seqLayerHeader->RANGE_MAPUV;
m_pContext->m_picLayerHeader->is_slice = 0;
DecodePicHeader(m_pContext);
//VC1BitstreamParser::GetNBits(m_pContext->m_pbs,m_pContext->m_bitOffset,32, temp_value);
slparams.MBStartRow = m_pContext->m_seqLayerHeader->heightMB/2;
if (*(pOffsets+1) && *(pValues+1) == 0x0B010000)
{
bitstream = reinterpret_cast<Ipp32u*>(m_pContext->m_pBufferStart + *(pOffsets+1));
VC1BitstreamParser::GetNBits(bitstream,bitoffset,32, temp_value);
bitoffset = 31;
VC1BitstreamParser::GetNBits(bitstream,bitoffset,9, slparams.MBEndRow);
} else
slparams.MBEndRow = m_pContext->m_seqLayerHeader->heightMB;
slparams.m_picLayerHeader = m_pContext->m_picLayerHeader;
slparams.m_vlcTbl = m_pContext->m_vlcTbl;
slparams.m_pstart = m_pContext->m_bitstream.pBitstream;
slparams.m_bitOffset = m_pContext->m_bitstream.bitOffset;
slparams.MBRowsToDecode = slparams.MBEndRow-slparams.MBStartRow;
task.m_pSlice = &slparams;
task.setSliceParams(m_pContext);
if (isSecondField)
task.m_isFieldReady = false;
else
task.m_isFieldReady = true;
m_pStore->AddSampleTask(&task,m_iSelfID);
slparams.MBStartRow = slparams.MBEndRow;
++pOffsets;
++pValues;
}
else if (*(pValues) == 0x0B010000)
{
m_pContext->m_bitstream.pBitstream = reinterpret_cast<Ipp32u*>(m_pContext->m_pBufferStart + *pOffsets);
VC1BitstreamParser::GetNBits(m_pContext->m_bitstream.pBitstream,m_pContext->m_bitstream.bitOffset,32, temp_value);
m_pContext->m_bitstream.bitOffset = 31;
VC1BitstreamParser::GetNBits(m_pContext->m_bitstream.pBitstream,m_pContext->m_bitstream.bitOffset,9, slparams.MBStartRow); //SLICE_ADDR
VC1BitstreamParser::GetNBits(m_pContext->m_bitstream.pBitstream,m_pContext->m_bitstream.bitOffset,1, temp_value); //PIC_HEADER_FLAG
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -