Skip to content
This repository has been archived by the owner on May 17, 2023. It is now read-only.

Commit

Permalink
[h264d] Re-worked recent fix for frame gap handling
Browse files Browse the repository at this point in the history
Some streams have incorrect log2_max_frame_num value.
So we can't remove _at once_ ST when a gap is detected.
Instead, remove them at a next I frame(as a potential recovery point)
or at SEI recovery point.

Issue: MDP-46557

Signed-off-by: ZhiZhen Tang <[email protected]>
(cherry picked from commit 5fec4d2)
  • Loading branch information
TangZhiZhen authored and Oleg Nabiullin committed Oct 29, 2018
1 parent b96a7be commit 7a1261d
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 34 deletions.
9 changes: 5 additions & 4 deletions _studio/shared/umc/codec/h264_dec/include/umc_h264_frame.h
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
// Copyright (c) 2017 Intel Corporation
//
// Copyright (c) 2018 Intel Corporation
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
Expand Down Expand Up @@ -125,6 +125,7 @@ class H264DecoderFrame
bool m_isInterViewRef[2];

bool m_bIDRFlag;
bool m_bIFlag;

bool IsFullFrame() const;
void SetFullFrame(bool isFull);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -597,7 +597,6 @@ class TaskSupplier : public Skipping, public AU_Splitter, public SVC_Extension,
virtual void OnFullFrame(H264DecoderFrame * pFrame);
virtual bool ProcessNonPairedField(H264DecoderFrame * pFrame) = 0;

void DPBSanitize(H264DecoderFrame * pDPBHead, const H264DecoderFrame * pFrame);
void DBPUpdate(H264DecoderFrame * pFrame, int32_t field);

virtual void AddFakeReferenceFrame(H264Slice * pSlice);
Expand Down
10 changes: 6 additions & 4 deletions _studio/shared/umc/codec/h264_dec/src/umc_h264_frame.cpp
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
// Copyright (c) 2017 Intel Corporation
//
// Copyright (c) 2018 Intel Corporation
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
Expand Down Expand Up @@ -85,6 +85,7 @@ H264DecoderFrame::H264DecoderFrame(MemoryAllocator *pMemoryAllocator, H264_Heap_
m_LongTermPicNum[0] = m_PicNum[1] = -1;
m_PicOrderCnt[0] = m_PicOrderCnt[1] = 0;
m_bIDRFlag = false;
m_bIFlag = false;

// set memory managment tools
m_pMemoryAllocator = pMemoryAllocator;
Expand Down Expand Up @@ -160,6 +161,7 @@ void H264DecoderFrame::Reset()

post_procces_complete = false;
m_bIDRFlag = false;
m_bIFlag = false;

m_RefPicListResetCount[0] = m_RefPicListResetCount[1] = 0;
m_PicNum[0] = m_PicNum[1] = -1;
Expand Down
53 changes: 31 additions & 22 deletions _studio/shared/umc/codec/h264_dec/src/umc_h264_task_supplier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -632,6 +632,18 @@ Status DecReferencePictureMarking::UpdateRefPicMarking(ViewItem &view, H264Decod
// set MVC 'inter view flag'
pFrame->SetInterViewRef(0 != sliceHeader->nal_ext.mvc.inter_view_flag, field_index);

// corruption recovery
if (pFrame->m_bIFlag)
{
for (H264DecoderFrame *pCurr = view.GetDPBList(0)->head(); pCurr; pCurr = pCurr->future())
{
if (pCurr->GetError() & ERROR_FRAME_SHORT_TERM_STUCK)
{
AddItemAndRun(pFrame, pCurr, UNSET_REFERENCE | FULL_FRAME | SHORT_TERM);
}
}
}

if (pFrame->m_bIDRFlag)
{
// mark all reference pictures as unused
Expand Down Expand Up @@ -3659,14 +3671,6 @@ Status TaskSupplier::AddSlice(H264Slice * pSlice, bool force)
ViewItem &view = GetView(m_currentView);
view.pCurFrame = setOfSlices->m_frame;

if (lastSlice->GetSeqParam()->gaps_in_frame_num_value_allowed_flag != 1)
{
// Check if DPB has ST frames with frame_num duplicating frame_num of new slice_type
// If so, unmark such frames as ST
H264DecoderFrame * pHead = view.GetDPBList(0)->head();
DPBSanitize(pHead, view.pCurFrame);
}

const H264SliceHeader *sliceHeader = lastSlice->GetSliceHeader();
uint32_t field_index = setOfSlices->m_frame->GetNumberByParity(sliceHeader->bottom_field_flag);
if (!setOfSlices->m_frame->GetAU(field_index)->GetSliceCount())
Expand Down Expand Up @@ -3957,9 +3961,24 @@ void TaskSupplier::InitFrameCounter(H264DecoderFrame * pFrame, const H264Slice *
uint32_t NumShortTerm, NumLongTerm;
dpb->countActiveRefs(NumShortTerm, NumLongTerm);

//set error flag only we have some references in DPB
if ((NumShortTerm + NumLongTerm > 0))
{
//set error flag only we have some references in DPB
pFrame->SetErrorFlagged(ERROR_FRAME_REFERENCE_FRAME);

// Leaving aside a legal frame_num wrapping cases, when a rapid _decrease_ of frame_num occurs due to frame gaps,
// frames marked as short-term prior the gap may get stuck in DPB for a very long sequence (up to '(1 << log2_max_frame_num) - 1').
// Reference lists are generated incorrectly. A potential recovery point can be at next I frame (if GOP is closed).
// So let's mark these potentially dangereous ST frames
// to remove them later from DPB in UpdateRefPicMarking() (if they're still there) at next I frame or SEI recovery point.
for (H264DecoderFrame *pFrm = view.GetDPBList(0)->head(); pFrm; pFrm = pFrm->future())
{
if ((pFrm->FrameNum() > sliceHeader->frame_num) && pFrm->isShortTermRef())
{
pFrm->SetErrorFlagged(ERROR_FRAME_SHORT_TERM_STUCK);
}
}
}
}

if (sliceHeader->IdrPicFlag)
Expand All @@ -3971,6 +3990,9 @@ void TaskSupplier::InitFrameCounter(H264DecoderFrame * pFrame, const H264Slice *

pFrame->m_bIDRFlag = (sliceHeader->IdrPicFlag != 0);

const int32_t recoveryFrameNum = view.GetDPBList(0)->GetRecoveryFrameCnt();
pFrame->m_bIFlag = (sliceHeader->slice_type == INTRASLICE) || (recoveryFrameNum != -1 && pFrame->FrameNum() == recoveryFrameNum);

if (pFrame->m_bIDRFlag)
{
view.GetDPBList(0)->IncreaseRefPicListResetCount(pFrame);
Expand Down Expand Up @@ -4022,19 +4044,6 @@ void TaskSupplier::AddSliceToFrame(H264DecoderFrame *pFrame, H264Slice *pSlice)
au_info->AddSlice(pSlice);
}

void TaskSupplier::DPBSanitize(H264DecoderFrame * pDPBHead, const H264DecoderFrame * pFrame)
{
for (H264DecoderFrame *pFrm = pDPBHead; pFrm; pFrm = pFrm->future())
{
if ((pFrm != pFrame) &&
(pFrm->FrameNum() == pFrame->FrameNum()) &&
pFrm->isShortTermRef())
{
AddItemAndRun(pFrm, pFrm, UNSET_REFERENCE | FULL_FRAME | SHORT_TERM);
}
}
}

void TaskSupplier::DBPUpdate(H264DecoderFrame * pFrame, int32_t field)
{
H264DecoderFrameInfo *slicesInfo = pFrame->GetAU(field);
Expand Down
7 changes: 4 additions & 3 deletions _studio/shared/umc/core/umc/include/umc_structures.h
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
// Copyright (c) 2018 Intel Corporation
//
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
Expand Down Expand Up @@ -681,6 +681,7 @@ namespace UMC
ERROR_FRAME_RECOVERY = 0x00000010, // major artifacts at recovery point
ERROR_FRAME_TOP_FIELD_ABSENT = 0x00000020,
ERROR_FRAME_BOTTOM_FIELD_ABSENT = 0x00000040,
ERROR_FRAME_SHORT_TERM_STUCK = 0x00000100, // used to mark ST which potentially can get stuck in DPB due to frame gaps
ERROR_FRAME_DEVICE_FAILURE = 0x80000000 //if this bit is set, this means the error is [UMC::Status] code
};

Expand Down

0 comments on commit 7a1261d

Please sign in to comment.