📄 umc_h264_task_supplier.cpp
字号:
DEBUG_PRINT((VM_STRING("frame gap - %d\n"), frameNumGap));
// Fill the frame_num gap with non-existing frames. For each missing
// frame:
// - allocate a frame
// - set frame num and pic num
// - update FrameNumWrap for all reference frames
// - use sliding window frame marking to free oldest reference
// - mark the frame as short-term reference
// The picture part of the generated frames is unimportant -- it will
// not be used for reference.
// set to first missing frame. Note that if frame number wrapped during
// the gap, the first missing frame_num could be larger than the
// current frame_num. If that happened, FrameNumGap will be negative.
//VM_ASSERT((Ipp32s)sliceHeader->frame_num > frameNumGap);
Ipp32s frame_num = sliceHeader->frame_num - frameNumGap;
while ((frame_num != sliceHeader->frame_num) &&
(umcRes == UMC_OK))
{
// allocate a frame
// Traverse list for next disposable frame
H264DecoderFrame *pFrame = GetFreeFrame();
// Did we find one?
if (!pFrame)
{
return UMC_ERR_ALLOC;
}
m_pDecodedFramesList->MoveToTail(pFrame);
Status umcRes = InitFreeFrame(pFrame, slice);
if (umcRes != UMC_OK)
{
return UMC_ERR_ALLOC;
}
pFrame->DefaultFill(2, false);
frameNumGap--;
if (sps->pic_order_cnt_type != 0)
{
Ipp32s tmp1 = sliceHeader->delta_pic_order_cnt[0];
Ipp32s tmp2 = sliceHeader->delta_pic_order_cnt[1];
sliceHeader->delta_pic_order_cnt[0] = sliceHeader->delta_pic_order_cnt[1] = 0;
DecodePictureOrderCount(slice, frame_num);
sliceHeader->delta_pic_order_cnt[0] = tmp1;
sliceHeader->delta_pic_order_cnt[1] = tmp2;
}
// Set frame num and pic num for the missing frame
pFrame->setFrameNum(frame_num);
m_PrevFrameRefNum = frame_num;
m_FrameNum = frame_num;
if (sliceHeader->field_pic_flag)
{
pFrame->setPicOrderCnt(m_PicOrderCnt,0);
pFrame->setPicOrderCnt(m_PicOrderCnt,1);
}
else
{
pFrame->setPicOrderCnt(m_TopFieldPOC, 0);
pFrame->setPicOrderCnt(m_BottomFieldPOC, 1);
}
DEBUG_PRINT((VM_STRING("frame gap - with poc %d %d added\n"), pFrame->m_PicOrderCnt[0], pFrame->m_PicOrderCnt[1]));
if (sliceHeader->field_pic_flag == 0)
{
pFrame->setPicNum(frame_num, 0);
}
else
{
pFrame->setPicNum(frame_num*2+1, 0);
pFrame->setPicNum(frame_num*2+1, 1);
}
// Update frameNumWrap and picNum for all decoded frames
H264DecoderFrame *pFrm;
H264DecoderFrame * pHead = m_pDecodedFramesList->head();
for (pFrm = pHead; pFrm; pFrm = pFrm->future())
{
// TBD: modify for fields
pFrm->UpdateFrameNumWrap(frame_num,
uMaxFrameNum,
pFrame->m_PictureStructureForRef+
pFrame->m_bottom_field_flag[field]);
}
// sliding window ref pic marking
SlideWindow(slice, 0);
pFrame->SetisShortTermRef(0);
pFrame->SetisShortTermRef(1);
{
// reset frame global data
H264DecoderMacroblockGlobalInfo *pMBInfo = pFrame->m_mbinfo.mbs;
memset(pMBInfo, 0, pFrame->totalMBs*sizeof(H264DecoderMacroblockGlobalInfo));
// DEBUG : temporal fix !!! for deblocking
/*memset(pFrame->m_mbinfo.MV[0], 0, iMBCount*sizeof(H264DecoderMacroblockMVs));
memset(pFrame->m_mbinfo.MV[1], 0, iMBCount*sizeof(H264DecoderMacroblockMVs));
memset(pFrame->m_mbinfo.RefIdxs[0], 0, iMBCount*sizeof(H264DecoderMacroblockRefIdxs));
memset(pFrame->m_mbinfo.RefIdxs[0], 0, iMBCount*sizeof(H264DecoderMacroblockRefIdxs));*/
}
// next missing frame
frame_num++;
if (frame_num >= uMaxFrameNum)
frame_num = 0;
// Set current as displayable and was outputted.
pFrame->SetBusyState(2);
pFrame->SetisDisplayable();
pFrame->SetSkipped(true);
pFrame->SetFrameExistFlag(false);
} // while
return m_pDecodedFramesList->IsDisposableExist() ? UMC_OK : UMC_ERR_ALLOC;
} // ProcessFrameNumGap
Status TaskSupplier::SetDPBSize()
{
Status umcRes = UMC_OK;
Ipp32u MaxDPBx2;
Ipp32u dpbLevel;
Ipp32u dpbSize;
H264SeqParamSet* sps = m_Headers.GetSeqParamSet(m_CurrentSeqParamSet);
// MaxDPB, per Table A-1, Level Limits
switch (sps->level_idc)
{
case 10:
MaxDPBx2 = 297;
break;
case 11:
MaxDPBx2 = 675;
break;
case 12:
case 13:
case 20:
MaxDPBx2 = 891*2;
break;
case 21:
MaxDPBx2 = 1782*2;
break;
case 22:
case 30:
MaxDPBx2 = 6075;
break;
case 31:
MaxDPBx2 = 6750*2;
break;
case 32:
MaxDPBx2 = 7680*2;
break;
case 40:
case 41:
case 42:
MaxDPBx2 = 12288*2;
break;
case 50:
MaxDPBx2 = 41400*2;
break;
case 51:
MaxDPBx2 = 69120*2;
break;
default:
MaxDPBx2 = 69120*2; //get as much as we may
//umcRes = UMC_ERR_INVALID_STREAM;
}
if (umcRes == UMC_OK)
{
Ipp32u width, height;
width = sps->frame_width_in_mbs*16;
height = sps->frame_height_in_mbs*16;
dpbLevel = (MaxDPBx2 * 512) / ((width * height) + ((width * height)>>1));
dpbSize = IPP_MIN(16, dpbLevel);
// we must have enough additional frames to do good frame parallelization
m_dpbSize = dpbSize;
}
return umcRes;
} // setDPBSize
bool TaskSupplier::GetFrameToDisplay(MediaData *dst, bool force)
{
// Perform output color conversion and video effects, if we didn't
// already write our output to the application's buffer.
VideoData *pVData = DynamicCast<VideoData> (dst);
if (!pVData)
return false;
m_pLastDisplayed = 0;
H264DecoderFrame * pFrame = GetFrameToDisplayInternal(dst, force);
if (!pFrame)
{
return false;
}
m_pLastDisplayed = pFrame;
pVData->SetInvalid(pFrame->GetError());
if (m_pLastDisplayed->IsSkipped())
{
pVData->SetDataSize(1);
pFrame->setWasOutputted();
return true;
}
InitColorConverter(pFrame, 0);
m_LastDecodedFrame.SetTime(dst->GetTime());
{
if (m_PostProcessing->GetFrame(&m_LastDecodedFrame, pVData) != UMC_OK)
{
pVData->SetDataSize(0);
pFrame->setWasOutputted();
return false;
}
}
pVData->SetDataSize(pVData->GetMappingSize());
pFrame->setWasOutputted();
return true;
}
bool TaskSupplier::IsWantToShowFrame(bool force)
{
if (m_pDecodedFramesList->countNumDisplayable() > m_maxDecFrameBuffering ||
force)
{
H264DecoderFrame * pTmp = m_pDecodedFramesList->findOldestDisplayable(m_dpbSize);
return !!pTmp;
}
return false;
}
H264DecoderFrame *TaskSupplier::GetFrameToDisplayInternal(MediaData *dst, bool force)
{
H264DecoderFrame *pTmp;
if (!dst)
return 0;
for (;;)
{
// show oldest frame
if (m_pDecodedFramesList->countNumDisplayable() >= m_maxDecFrameBuffering ||
force)
{
pTmp = m_pDecodedFramesList->findOldestDisplayable(m_dpbSize);
if (pTmp && pTmp->GetBusyState() < 2)
{
Ipp64f time;
if (!pTmp->IsFrameExist())
{
pTmp->setWasOutputted();
continue;
}
// set time
if (pTmp->m_dFrameTime > -1.0)
{
time = pTmp->m_dFrameTime;
dst->SetTime(time);
//m_LastDecodedFrame.SetTime(time);
m_local_frame_time = time;
}
else
{
//m_LastDecodedFrame.SetTime(m_local_frame_time);
pTmp->m_dFrameTime = m_local_frame_time;
dst->SetTime(m_local_frame_time);
}
if (!pTmp->post_procces_complete)
{
//static Ipp32s count = 0;
m_local_frame_time += m_local_delta_frame_time;
pTmp->post_procces_complete = true;
DEBUG_PRINT((VM_STRING("Outputted POC - %d, busyState - %d\n"), pTmp->m_PicOrderCnt[0], pTmp->GetBusyState()));
/*if (!CutPlanes(pTmp, m_Headers.GetSeqParamSet(m_CurrentSeqParamSet)))
{
m_pDecodedFramesList->DebugPrint();
}*/
}
if (pTmp->IsSkipped())
{
return pTmp;
}
}
else
{
return 0;
}
return pTmp;
}
else // there are no frames to show
return NULL;
}
}
void TaskSupplier::SetMBMap(H264DecoderFrame *frame)
{
Ipp32u mbnum, i;
Ipp32s prevMB;
Ipp32u uNumMBCols;
Ipp32u uNumMBRows;
Ipp32u uNumSliceGroups;
Ipp32u uNumMapUnits;
H264Slice * slice = frame->GetAU(0)->GetAnySlice();
H264PicParamSet *pps = slice->GetPicParam();
H264SliceHeader * sliceHeader = slice->GetSliceHeader();
Ipp32s PrevMapUnit[MAX_NUM_SLICE_GROUPS];
Ipp32s SliceGroup, FirstMB;
Ipp8u *pMap = NULL;
bool bSetFromMap = false;
uNumMBCols = frame->macroBlockSize().width;
uNumMBRows = frame->macroBlockSize().height;
FirstMB = 0;
// TBD: update for fields:
uNumMapUnits = uNumMBCols*uNumMBRows;
uNumSliceGroups = pps->num_slice_groups;
if (uNumSliceGroups == 1)
{
m_pMBInfo[frame->m_iResourceNumber].active_next_mb_table = next_mb_tables[0];
}
else
{
Ipp32s times = frame->m_PictureStructureForDec < FRM_STRUCTURE ? 2 : 1;
for (Ipp32s j = 0; j < times; j++)
{
if (frame->m_PictureStructureForDec < FRM_STRUCTURE)
{
if (j)
{
FirstMB = frame->totalMBs;
uNumMapUnits <<= 1;
}
else
{
uNumMapUnits >>= 1;
uNumMBRows >>= 1;
}
}
//since main profile doesn't allow slice groups to be >1 and in baseline no fields (or mbaffs) allowed
//the following memset is ok.
// > 1 slice group
switch (pps->SliceGroupInfo.slice_group_map_type)
{
case 0:
{
// interleaved slice groups: run_length for each slice group,
// repeated until all MB's are assigned to a slice group
Ipp32u NumThisGroup;
// Init PrevMapUnit to -1 (none), for first unit of each slice group
for (i=0; i<uNumSliceGroups; i++)
PrevMapUnit[i] = -1;
SliceGroup = 0;
NumThisGroup = 0;
prevMB = -1;
for (mbnum = FirstMB; mbnum < uNumMapUnits; mbnum++)
{
if (NumThisGroup == pps->SliceGroupInfo.run_length[SliceGroup])
{
// new slice group
PrevMapUnit[SliceGroup] = prevMB;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -