📄 umc_h264_task_supplier.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_H264_VIDEO_DECODER)
#include "umc_h264_task_supplier.h"
#include "umc_h264_frame_list.h"
#include "umc_automatic_mutex.h"
#include "umc_h264_nal_spl.h"
#include "umc_h264_bitstream.h"
#include "umc_h264_dec_defs_dec.h"
#include "vm_sys_info.h"
#include "umc_h264_segment_decoder_mt.h"
#include "umc_h264_task_broker.h"
#include "umc_video_processing.h"
#include "umc_structures.h"
#if 0
#include <cstdarg>
inline
void Trace(vm_char * format, ...)
{
va_list(arglist);
va_start(arglist, format);
vm_char cStr[256];
vsprintf(cStr, format, arglist);
//OutputDebugString(cStr);
printf("%s", cStr);
//fflush(stdout);
}
#if defined _DEBUG
#define DEBUG_PRINT(x) Trace x
Ipp32s frame_count = 0;
#else
#define DEBUG_PRINT(x)
#endif
#else
#define DEBUG_PRINT(x)
#endif
namespace UMC
{
inline ColorFormat GetColorFormat(Ipp32s color_format)
{
ColorFormat format;
switch(color_format)
{
case 0:
format = GRAY;
break;
case 2:
format = YUV422;
break;
case 3:
format = YUV444;
break;
case 1:
default:
format = YUV420;
break;
}
return format;
}
void OnSlideWindow(H264DecoderFrame *pRefFrame, H264DecoderFrame *pCurrentFrame, NotifiersChain * defaultChain, bool force)
{
if (!pRefFrame)
return;
if (!pRefFrame->IsFrameExist())
{
pRefFrame->setWasOutputted();
return;
}
if (force || (!pRefFrame->isShortTermRef() && !pRefFrame->isLongTermRef()))
{
NotifiersChain *notif = defaultChain;
if (pCurrentFrame && pCurrentFrame->GetBusyState() >= 2)
{
VM_ASSERT(pCurrentFrame);
notif = pCurrentFrame->GetNotifiersChain();
}
if (notif)
{
pRefFrame->IncrementBusyState();
notif->AddNotifier(new notifier0<H264DecoderFrame>
(pRefFrame, &H264DecoderFrame::DecrementBusyState));
}
}
}
bool CutPlanes(H264DecoderFrame * , H264SeqParamSet * );
#if 0
void CheckRef(H264DecoderFrame ** refs, H264DecoderFrame *pFrame)
{
for (Ipp32s i = 0; refs[i]; i++)
{
if (refs[i] == pFrame)
{
__asm int 3;
}
}
}
void CheckReferences(UMC::H264DecoderFrame * pFrame, UMC::H264DecoderFrame * start)
{
if (pFrame)
{
H264DecoderFrame * pTemp = start;
while (pTemp)
{
if (pTemp == pFrame)
{
pTemp = pTemp->future();
continue;
}
H264DecoderFrameInfo * auInfo = pTemp->GetAU(0);
if (auInfo->GetStatus() != H264DecoderFrameInfo::STATUS_COMPLETED)
{
for (Ipp32s i = 0; i < auInfo->m_SliceCount; i++)
{
H264Slice * slice = auInfo->m_pSliceQueue[i];
H264DecoderFrame ** refs = pTemp->GetRefPicList(slice->GetSliceNum(), 0)->m_RefPicList;
CheckRef(refs, pFrame);
refs = pTemp->GetRefPicList(slice->GetSliceNum(), 1)->m_RefPicList;
CheckRef(refs, pFrame);
}
for (Ipp32s i = 0; i < auInfo->m_SliceCountNonActual; i++)
{
H264Slice * slice = auInfo->m_pSliceQueueNonActual[i];
H264DecoderFrame ** refs = pTemp->GetRefPicList(slice->GetSliceNum(), 0)->m_RefPicList;
CheckRef(refs, pFrame);
refs = pTemp->GetRefPicList(slice->GetSliceNum(), 1)->m_RefPicList;
CheckRef(refs, pFrame);
}
}
auInfo = pTemp->GetAU(1);
if (auInfo->GetStatus() != H264DecoderFrameInfo::STATUS_COMPLETED)
{
for (Ipp32s i = 0; i < auInfo->m_SliceCount; i++)
{
H264Slice * slice = auInfo->m_pSliceQueue[i];
H264DecoderFrame ** refs = pTemp->GetRefPicList(slice->GetSliceNum(), 0)->m_RefPicList;
CheckRef(refs, pFrame);
refs = pTemp->GetRefPicList(slice->GetSliceNum(), 1)->m_RefPicList;
CheckRef(refs, pFrame);
}
for (Ipp32s i = 0; i < auInfo->m_SliceCountNonActual; i++)
{
H264Slice * slice = auInfo->m_pSliceQueueNonActual[i];
H264DecoderFrame ** refs = pTemp->GetRefPicList(slice->GetSliceNum(), 0)->m_RefPicList;
CheckRef(refs, pFrame);
refs = pTemp->GetRefPicList(slice->GetSliceNum(), 1)->m_RefPicList;
CheckRef(refs, pFrame);
}
}
pTemp = pTemp->future();
}
}
}
#endif
/****************************************************************************************************/
// Skipping class routine
/****************************************************************************************************/
Skipping::Skipping()
: m_VideoDecodingSpeed(0)
, m_SkipCycle(1)
, m_ModSkipCycle(1)
, m_SkipFlag(0)
, m_PermanentTurnOffDeblocking(0)
, m_NumberOfSkippedFrames(0)
{
}
void Skipping::Reset()
{
m_VideoDecodingSpeed = 0;
m_SkipCycle = 0;
m_ModSkipCycle = 0;
m_PermanentTurnOffDeblocking = 0;
m_NumberOfSkippedFrames = 0;
}
bool Skipping::IsShouldSkipDeblocking(H264DecoderFrame * pFrame, Ipp32s field)
{
return (IS_SKIP_DEBLOCKING_MODE_PERMANENT ||
(IS_SKIP_DEBLOCKING_MODE_NON_REF && !pFrame->GetAU(field)->IsReference()));
}
bool Skipping::IsShouldSkipFrame(H264DecoderFrame * pFrame, Ipp32s /*field*/)
{
bool isShouldSkip = false;
//bool isReference = pFrame->GetAU(field)->IsReference();
bool isReference0 = pFrame->GetAU(0)->IsReference();
bool isReference1 = pFrame->GetAU(1)->IsReference();
bool isReference = isReference0 || isReference1;
if ((m_VideoDecodingSpeed > 0) && !isReference)
{
if ((m_SkipFlag % m_ModSkipCycle) == 0)
{
isShouldSkip = true;
}
m_SkipFlag++;
if (m_SkipFlag >= m_SkipCycle)
m_SkipFlag = 0;
}
if (isShouldSkip)
m_NumberOfSkippedFrames++;
return isShouldSkip;
}
void Skipping::ChangeVideoDecodingSpeed(Ipp32s & num)
{
m_VideoDecodingSpeed += num;
if (m_VideoDecodingSpeed < 0)
m_VideoDecodingSpeed = 0;
if (m_VideoDecodingSpeed > 7)
m_VideoDecodingSpeed = 7;
num = m_VideoDecodingSpeed;
if (m_VideoDecodingSpeed > 6)
{
m_SkipCycle = 1;
m_ModSkipCycle = 1;
m_PermanentTurnOffDeblocking = 2;
}
else if (m_VideoDecodingSpeed > 5)
{
m_SkipCycle = 1;
m_ModSkipCycle = 1;
m_PermanentTurnOffDeblocking = 0;
}
else if (m_VideoDecodingSpeed > 4)
{
m_SkipCycle = 3;
m_ModSkipCycle = 2;
m_PermanentTurnOffDeblocking = 1;
}
else if (m_VideoDecodingSpeed > 3)
{
m_SkipCycle = 3;
m_ModSkipCycle = 2;
m_PermanentTurnOffDeblocking = 0;
}
else if (m_VideoDecodingSpeed > 2)
{
m_SkipCycle = 2;
m_ModSkipCycle = 2;
m_PermanentTurnOffDeblocking = 0;
}
else if (m_VideoDecodingSpeed > 1)
{
m_SkipCycle = 3;
m_ModSkipCycle = 3;
m_PermanentTurnOffDeblocking = 0;
}
else if (m_VideoDecodingSpeed == 1)
{
m_SkipCycle = 4;
m_ModSkipCycle = 4;
m_PermanentTurnOffDeblocking = 0;
}
else
{
m_PermanentTurnOffDeblocking = 0;
}
}
H264VideoDecoder::SkipInfo Skipping::GetSkipInfo() const
{
H264VideoDecoder::SkipInfo info;
info.isDeblockingTurnedOff = (m_VideoDecodingSpeed == 5) || (m_VideoDecodingSpeed == 7);
info.numberOfSkippedFrames = m_NumberOfSkippedFrames;
return info;
}
struct H264IntraTypesProp
{
Ipp32s m_nSize; // (Ipp32s) size of allocated intra type array
MemID m_mid; // (MemID) mem id of allocated buffer for intra types
void Reset(void)
{
m_nSize = 0;
m_mid = 0;
}
};
/****************************************************************************************************/
// TaskSupplier
/****************************************************************************************************/
TaskSupplier::TaskSupplier(VideoData &lastDecodedFrame, BaseCodec *&postProcessing)
: m_pDecodedFramesList(0)
, m_MaxLongTermFrameIdx(0)
, m_pNALSplitter(0)
, m_pFirstUncompletedFrame(0)
, m_pTaskBroker(0)
, m_midParsedData(0)
, m_pParsedData(0)
, m_parsedDataLength(0)
, m_PostProcessing(postProcessing)
, m_LastDecodedFrame(lastDecodedFrame)
, m_iThreadNum(0)
, m_maxDecFrameBuffering(1)
, m_dpbSize(1)
, m_DPBSizeEx(0)
, m_TrickModeSpeed(1)
, m_UIDFrameCounter(0)
, m_pSegmentDecoder(0)
, m_ppMBIntraTypes(0)
, m_piMBIntraProp(0)
, m_pMBInfo(0)
, m_pLastDisplayed(0)
{
}
TaskSupplier::~TaskSupplier()
{
Close();
}
Status TaskSupplier::Init(BaseCodecParams *pInit)
{
VideoDecoderParams *init = DynamicCast<VideoDecoderParams> (pInit);
if (NULL == init)
return UMC_ERR_NULL_PTR;
Close();
m_dpbSize = 0;
m_DPBSizeEx = 0;
m_pCurrentFrame = 0;
m_iCurrentResource = 0;
if (ABSOWN(init->dPlaybackRate - 1) > 0.0001)
{
m_TrickModeSpeed = 2;
}
else
{
m_TrickModeSpeed = 1;
}
Ipp32s nAllowedThreadNumber = init->numThreads;
if(nAllowedThreadNumber < 0) nAllowedThreadNumber = 0;
if(nAllowedThreadNumber > 8) nAllowedThreadNumber = 8;
#ifdef _DEBUG
if (!nAllowedThreadNumber)
nAllowedThreadNumber = 1;
#endif // _DEBUG
// calculate number of slice decoders.
// It should be equal to CPU number
m_iThreadNum = (0 == nAllowedThreadNumber) ? (vm_sys_info_get_cpu_num()) : (nAllowedThreadNumber);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -