📄 umc_h264_task_supplier.cpp
字号:
m_pFirstUncompletedFrame = 0;
m_pDecodedFramesList = new H264DBPList();
if (!m_pDecodedFramesList)
return UMC_ERR_ALLOC;
if (init->info.stream_subtype == AVC1_VIDEO)
{
m_pNALSplitter = new NALUnitSplitterMP4(&m_Heap);
}
else
{
m_pNALSplitter = new NALUnitSplitter(&m_Heap);
}
m_pNALSplitter->Init();
switch(m_iThreadNum)
{
case 1:
m_pTaskBroker = new TaskBrokerSingleThread(this);
break;
case 4:
case 3:
case 2:
m_pTaskBroker = new TaskBrokerTwoThread(this);
break;
default:
m_pTaskBroker = new TaskBrokerTwoThread(this);
break;
};
m_pTaskBroker->Init(m_iThreadNum);
// create slice decoder(s)
m_pSegmentDecoder = new H264SegmentDecoderMultiThreaded *[m_iThreadNum];
if (NULL == m_pSegmentDecoder)
return UMC_ERR_ALLOC;
memset(m_pSegmentDecoder, 0, sizeof(H264SegmentDecoderMultiThreaded *) * m_iThreadNum);
Ipp32s i;
for (i = 0; i < m_iThreadNum; i += 1)
{
m_pSegmentDecoder[i] = new H264SegmentDecoderMultiThreaded(m_pTaskBroker);
if (NULL == m_pSegmentDecoder[i])
return UMC_ERR_ALLOC;
}
for (i = 0; i < m_iThreadNum; i += 1)
{
if (UMC_OK != m_pSegmentDecoder[i]->Init(i))
return UMC_ERR_INIT;
}
Ipp32s numberOfBuffers = 2*(m_iThreadNum);
m_pMBInfo = new H264DecoderLocalMacroblockDescriptor[numberOfBuffers];
if (NULL == m_pMBInfo)
return UMC_ERR_ALLOC;
m_ppMBIntraTypes = (Ipp32u **) ippsMalloc_8u((Ipp32s) (sizeof(Ipp32u *) * numberOfBuffers));
if (NULL == m_ppMBIntraTypes)
return UMC_ERR_ALLOC;
memset(m_ppMBIntraTypes, 0, sizeof(Ipp32u *) * numberOfBuffers);
// allocate intra MB types array's sizes
m_piMBIntraProp = (H264IntraTypesProp *) ippsMalloc_8u((Ipp32s) (sizeof(H264IntraTypesProp) * numberOfBuffers));
if (NULL == m_piMBIntraProp)
return UMC_ERR_ALLOC;
memset(m_piMBIntraProp, 0, sizeof(H264IntraTypesProp) * numberOfBuffers);
m_local_delta_frame_time = 1.0/30;
m_local_frame_time = 0;
if (0 < init->info.framerate)
{
m_local_delta_frame_time = 1 / init->info.framerate;
}
m_DPBSizeEx = m_iThreadNum + 1;
return UMC_OK;
}
Status TaskSupplier::SetParams(BaseCodecParams* params)
{
VideoDecoderParams *pParams = DynamicCast<VideoDecoderParams>(params);
if (NULL == pParams)
return UMC_ERR_NULL_PTR;
if (pParams->lTrickModesFlag == 7)
{
if (ABSOWN(pParams->dPlaybackRate - 1) > 0.0001)
m_TrickModeSpeed = 2;
else
m_TrickModeSpeed = 1;
}
return UMC_OK;
}
void TaskSupplier::Close()
{
Reset();
if (m_pTaskBroker)
{
m_pTaskBroker->Release();
}
for (Ipp32s i = 0; i < m_iThreadNum; i += 1)
{
delete m_pSegmentDecoder[i];
m_pSegmentDecoder[i] = 0;
}
Ipp32s numberOfBuffers = 2*(m_iThreadNum);
if (m_ppMBIntraTypes)
{
ippsFree(m_ppMBIntraTypes);
m_ppMBIntraTypes = 0;
}
if (m_piMBIntraProp)
{
for (Ipp32s i = 0; i < numberOfBuffers; i++)
{
if (m_piMBIntraProp[i].m_nSize == 0)
continue;
m_pMemoryAllocator->Unlock(m_piMBIntraProp[i].m_mid);
m_pMemoryAllocator->Free(m_piMBIntraProp[i].m_mid);
}
ippsFree(m_piMBIntraProp);
m_piMBIntraProp = 0;
}
delete[] m_pMBInfo;
m_pMBInfo = 0;
delete[] m_pSegmentDecoder;
m_pSegmentDecoder = 0;
delete m_pTaskBroker;
m_pTaskBroker = 0;
DeallocateBuffers();
m_Headers.Reset();
delete m_pNALSplitter;
m_pNALSplitter = 0;
delete m_pDecodedFramesList;
m_pDecodedFramesList = 0;
m_iThreadNum = 0;
m_bSeqParamSetRead = false;
m_bPicParamSetRead = false;
m_dpbSize = 1;
m_DPBSizeEx = 1;
m_maxDecFrameBuffering = 1;
m_CurrentSeqParamSet = -1;
m_CurrentPicParamSet = -1;
}
void TaskSupplier::Reset()
{
if (m_pTaskBroker)
m_pTaskBroker->Reset();
// DEBUG : need to stop threads before and Reset taskBroker
for (Ipp32s i = 1; i < m_iThreadNum; i += 1)
{
m_pSegmentDecoder[i]->Reset();
}
if (m_pDecodedFramesList)
{
for (H264DecoderFrame *pFrame = m_pDecodedFramesList->head(); pFrame; pFrame = pFrame->future())
{
pFrame->Reset();
}
m_pDecodedFramesList->removeAllRef();
m_pDecodedFramesList->removeAllDisplayable();
}
if (m_pNALSplitter)
m_pNALSplitter->Reset();
m_Headers.Reset(true);
Skipping::Reset();
m_SlicesHeap.Release();
m_Heap.Reset();
m_local_frame_time = 0;
m_field_index = 0;
m_WaitForIDR = true;
m_pLastDisplayed = 0;
m_pCurrentFrame = 0;
m_pFirstUncompletedFrame = 0;
m_iCurrentResource = 0;
m_PicOrderCnt = 0;
m_PicOrderCntMsb = 0;
m_PicOrderCntLsb = 0;
m_FrameNum = 0;
m_PrevFrameRefNum = 0;
m_FrameNumOffset = 0;
m_TopFieldPOC = 0;
m_BottomFieldPOC = 0;
if (m_pTaskBroker)
m_pTaskBroker->Init(m_iThreadNum);
}
void TaskSupplier::AfterErrorRestore()
{
if (m_pTaskBroker)
m_pTaskBroker->Reset();
// DEBUG : need to stop threads before and Reset taskBroker
for (Ipp32s i = 1; i < m_iThreadNum; i += 1)
{
m_pSegmentDecoder[i]->Reset();
}
if (m_pDecodedFramesList)
{
for (H264DecoderFrame *pFrame = m_pDecodedFramesList->head(); pFrame; pFrame = pFrame->future())
{
pFrame->Reset();
}
m_pDecodedFramesList->removeAllRef();
m_pDecodedFramesList->removeAllDisplayable();
}
if (m_pNALSplitter)
m_pNALSplitter->Reset();
m_Headers.Reset(true);
Skipping::Reset();
m_SlicesHeap.Release();
m_Heap.Reset();
m_field_index = 0;
m_pLastDisplayed = 0;
m_pCurrentFrame = 0;
m_pFirstUncompletedFrame = 0;
m_iCurrentResource = 0;
if (m_pTaskBroker)
m_pTaskBroker->Init(m_iThreadNum);
}
Status TaskSupplier::GetInfo(VideoDecoderParams *lpInfo)
{
Ipp32s seq_index = 0, pic_index = 0;
lpInfo->pPostProcessing = m_PostProcessing;
if (m_CurrentSeqParamSet == -1 && !m_bSeqParamSetRead)
{
return UMC_ERR_NOT_INITIALIZED;
}
else if (m_CurrentSeqParamSet != -1)
{
seq_index = m_CurrentSeqParamSet;
}
if (m_CurrentPicParamSet == -1 && !m_bPicParamSetRead)
{
return UMC_ERR_NOT_INITIALIZED;
}
else if(m_CurrentPicParamSet != -1)
{
pic_index = m_CurrentPicParamSet;
}
H264SeqParamSet *sps = m_Headers.GetSeqParamSet(seq_index);
H264PicParamSet *pps = m_Headers.GetPicParamSet(pic_index);
lpInfo->info.clip_info.height = sps->frame_height_in_mbs * 16 -
SubHeightC[sps->chroma_format_idc]*(2 - sps->frame_mbs_only_flag) *
(sps->frame_cropping_rect_top_offset + sps->frame_cropping_rect_bottom_offset);
lpInfo->info.clip_info.width = sps->frame_width_in_mbs * 16 - SubWidthC[sps->chroma_format_idc] *
(sps->frame_cropping_rect_left_offset + sps->frame_cropping_rect_right_offset);
if (0.0 < m_local_delta_frame_time)
lpInfo->info.framerate = 1.0 / m_local_delta_frame_time;
else
lpInfo->info.framerate = 0.0;
lpInfo->info.stream_type = H264_VIDEO;
lpInfo->profile = sps->profile_idc;
lpInfo->level = sps->level_idc;
lpInfo->numThreads = m_iThreadNum;
lpInfo->info.color_format = GetColorFormat(sps->chroma_format_idc);
if (sps->aspect_ratio_idc == 255)
{
lpInfo->info.aspect_ratio_width = sps->sar_width;
lpInfo->info.aspect_ratio_height = sps->sar_height;
}
else
{
lpInfo->info.aspect_ratio_width = SAspectRatio[sps->aspect_ratio_idc][0];
lpInfo->info.aspect_ratio_height = SAspectRatio[sps->aspect_ratio_idc][1];
}
Ipp32u multiplier = 1 << (6 + sps->bit_rate_scale);
lpInfo->info.bitrate = sps->bit_rate_value[0] * multiplier;
if (sps->frame_mbs_only_flag)
lpInfo->info.interlace_type = PROGRESSIVE;
else
{
if (0 <= sps->offset_for_top_to_bottom_field)
lpInfo->info.interlace_type = INTERLEAVED_TOP_FIELD_FIRST;
else
lpInfo->info.interlace_type = INTERLEAVED_BOTTOM_FIELD_FIRST;
}
H264VideoDecoderParams *lpH264Info = DynamicCast<H264VideoDecoderParams> (lpInfo);
if (lpH264Info)
{
m_CurrentSeqParamSet = seq_index;
SetDPBSize();
lpH264Info->m_DPBSize = m_dpbSize + m_DPBSizeEx;
IppiSize sz;
sz.width = sps->frame_width_in_mbs * 16;
sz.height = sps->frame_height_in_mbs * 16;
lpH264Info->m_fullSize = sz;
lpH264Info->m_entropy_coding_type = pps->entropy_coding_mode;
}
return UMC_OK;
}
Status TaskSupplier::AllocateBuffers(bool exactSizeRequested)
{
Status umcRes = UMC_OK;
IppiSize desiredPaddedSize;
H264SeqParamSet* sps = m_Headers.GetSeqParamSet(m_CurrentSeqParamSet);
IppiSize size;
size.width = sps->frame_width_in_mbs * 16;
size.height = sps->frame_height_in_mbs * 16;
desiredPaddedSize.width = (size.width + 15) & ~15;
desiredPaddedSize.height = (size.height + 15) & ~15;
// If our buffer and internal pointers are already set up for this
// image size, then there's nothing more to do.
// But if exactSizeRequested, we need to see if our existing
// buffer is oversized, and perhaps reallocate it.
if (m_paddedParsedDataSize.width == desiredPaddedSize.width &&
m_paddedParsedDataSize.height == desiredPaddedSize.height &&
!exactSizeRequested)
return umcRes;
// Determine how much space we need
Ipp32s MB_Frame_Width = desiredPaddedSize.width >> 4;
Ipp32s MB_Frame_Height = desiredPaddedSize.height >> 4;
Ipp32s uMBMapSize = MB_Frame_Width * MB_Frame_Height;
Ipp32s next_mb_size = (Ipp32s)(MB_Frame_Width*MB_Frame_Height*sizeof(H264DecoderMBAddr));
Ipp32s totalSize = 2*next_mb_size + uMBMapSize + YUV_ALIGNMENT;
// Reallocate our buffer if its size is not appropriate.
if (m_parsedDataLength < totalSize ||
(exactSizeRequested && (m_parsedDataLength != totalSize)))
{
DeallocateBuffers();
if (m_pMemoryAllocator->Alloc(&m_midParsedData,
totalSize,
UMC_ALLOC_PERSISTENT))
return UMC_ERR_ALLOC;
m_pParsedData = (Ipp8u *) m_pMemoryAllocator->Lock(m_midParsedData);
ippsZero_8u(m_pParsedData, totalSize);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -