From 88f2969954a1dc72b2dd95dad75668736aadf9a5 Mon Sep 17 00:00:00 2001 From: gfxVPLsdm Date: Wed, 8 May 2024 12:18:33 +0800 Subject: [PATCH] [Decode] Memory2.0 drc enabling for hevc (#6750) Only surfaces are reallocated when the frame's resolution changes Co-authored-by: chuanli1 --- .../decode/h265/src/mfx_h265_dec_decode.cpp | 2 +- .../shared/include/mfx_umc_alloc_wrapper.h | 2 ++ _studio/shared/src/mfx_umc_alloc_wrapper.cpp | 5 +++ .../h265_dec/include/umc_h265_task_supplier.h | 5 ++- .../h265_dec/include/umc_h265_va_supplier.h | 3 ++ .../h265_dec/src/umc_h265_mfx_supplier.cpp | 12 ++++++- .../h265_dec/src/umc_h265_task_supplier.cpp | 32 +++++++++++++++++-- .../h265_dec/src/umc_h265_va_supplier.cpp | 12 +++---- 8 files changed, 62 insertions(+), 11 deletions(-) diff --git a/_studio/mfx_lib/decode/h265/src/mfx_h265_dec_decode.cpp b/_studio/mfx_lib/decode/h265/src/mfx_h265_dec_decode.cpp index 455a1518e4..63a1f6358d 100644 --- a/_studio/mfx_lib/decode/h265/src/mfx_h265_dec_decode.cpp +++ b/_studio/mfx_lib/decode/h265/src/mfx_h265_dec_decode.cpp @@ -1036,7 +1036,7 @@ mfxStatus VideoDECODEH265::DecodeFrameCheck(mfxBitstream *bs, mfxFrameSurface1 * MFX_CHECK_STS(sts); umcRes = !m_surface_source->HasFreeSurface() ? - UMC::UMC_ERR_NEED_FORCE_OUTPUT : m_pH265VideoDecoder->AddSource(bs ? &src : 0); + UMC::UMC_ERR_NEED_FORCE_OUTPUT : m_pH265VideoDecoder->AddSource(bs ? &src : 0, m_core); umcFrameRes = umcRes; diff --git a/_studio/shared/include/mfx_umc_alloc_wrapper.h b/_studio/shared/include/mfx_umc_alloc_wrapper.h index a15c03769c..1882da6520 100644 --- a/_studio/shared/include/mfx_umc_alloc_wrapper.h +++ b/_studio/shared/include/mfx_umc_alloc_wrapper.h @@ -261,6 +261,8 @@ class SurfaceSource : public UMC::FrameAllocator bool HasFreeSurface(); + bool GetSurfaceType(); + void SetFreeSurfaceAllowedFlag(bool flag); protected: diff --git a/_studio/shared/src/mfx_umc_alloc_wrapper.cpp b/_studio/shared/src/mfx_umc_alloc_wrapper.cpp index 2a7a5af270..f8f208d9a3 100644 --- a/_studio/shared/src/mfx_umc_alloc_wrapper.cpp +++ b/_studio/shared/src/mfx_umc_alloc_wrapper.cpp @@ -2298,6 +2298,11 @@ bool SurfaceSource::HasFreeSurface() } } +bool SurfaceSource::GetSurfaceType() +{ + return m_redirect_to_vpl_path; +} + void SurfaceSource::SetFreeSurfaceAllowedFlag(bool flag) { if (m_redirect_to_vpl_path != !!m_vpl_cache_decoder_surfaces) diff --git a/_studio/shared/umc/codec/h265_dec/include/umc_h265_task_supplier.h b/_studio/shared/umc/codec/h265_dec/include/umc_h265_task_supplier.h index 8bd51d1ac4..abe22b17c0 100644 --- a/_studio/shared/umc/codec/h265_dec/include/umc_h265_task_supplier.h +++ b/_studio/shared/umc/codec/h265_dec/include/umc_h265_task_supplier.h @@ -306,7 +306,7 @@ class TaskSupplier_H265 : public Skipping_H265, public AU_Splitter_H265, public UMC::Status GetInfo(UMC::VideoDecoderParams *lpInfo); // Add a new bitstream data buffer to decoding - virtual UMC::Status AddSource(UMC::MediaData *pSource); + virtual UMC::Status AddSource(UMC::MediaData *pSource, VideoCORE* pCore); // Chose appropriate processing action for specified NAL unit UMC::Status ProcessNalUnit(UMC::MediaDataEx *nalUnit); @@ -448,6 +448,7 @@ class TaskSupplier_H265 : public Skipping_H265, public AU_Splitter_H265, public // Keep track of which parameter set is in use. bool m_WaitForIDR; + bool m_SpsChanged; bool m_prevSliceBroken; int32_t m_RA_POC; @@ -470,6 +471,8 @@ class TaskSupplier_H265 : public Skipping_H265, public AU_Splitter_H265, public bool m_isInitialized; + VideoCORE *m_pCore; + UMC::Mutex m_mGuard; private: diff --git a/_studio/shared/umc/codec/h265_dec/include/umc_h265_va_supplier.h b/_studio/shared/umc/codec/h265_dec/include/umc_h265_va_supplier.h index 9be27b946d..a61d3b6e46 100644 --- a/_studio/shared/umc/codec/h265_dec/include/umc_h265_va_supplier.h +++ b/_studio/shared/umc/codec/h265_dec/include/umc_h265_va_supplier.h @@ -71,6 +71,9 @@ class VATaskSupplier : uint32_t m_bufferedFrameNumber; + uint16_t m_drcFrameWidth = 0; + uint16_t m_drcFrameHeight = 0; + private: VATaskSupplier & operator = (VATaskSupplier &) { diff --git a/_studio/shared/umc/codec/h265_dec/src/umc_h265_mfx_supplier.cpp b/_studio/shared/umc/codec/h265_dec/src/umc_h265_mfx_supplier.cpp index 43f48d8dcd..cf7123fed8 100644 --- a/_studio/shared/umc/codec/h265_dec/src/umc_h265_mfx_supplier.cpp +++ b/_studio/shared/umc/codec/h265_dec/src/umc_h265_mfx_supplier.cpp @@ -34,6 +34,7 @@ #include "umc_h265_debug.h" #include "umc_h265_mfx_utils.h" +#include "mfx_umc_alloc_wrapper.h" namespace UMC_HEVC_DECODER { @@ -330,7 +331,16 @@ UMC::Status MFXTaskSupplier_H265::DecodeHeaders(UMC::MediaDataEx *nalUnit) m_firstVideoParams.mfx.FrameInfo.Height < (currSPS->pic_height_in_luma_samples) || (currSPS->m_pcPTL.GetGeneralPTL()->level_idc && m_firstVideoParams.mfx.CodecLevel && m_firstVideoParams.mfx.CodecLevel < currSPS->m_pcPTL.GetGeneralPTL()->level_idc)) { - return UMC::UMC_NTF_NEW_RESOLUTION; + auto frame_source = dynamic_cast(m_pFrameAllocator); + if (frame_source && frame_source->GetSurfaceType() && !m_SpsChanged) + { + return UMC::UMC_OK; + } + else + { + return UMC::UMC_NTF_NEW_RESOLUTION; + } + } } diff --git a/_studio/shared/umc/codec/h265_dec/src/umc_h265_task_supplier.cpp b/_studio/shared/umc/codec/h265_dec/src/umc_h265_task_supplier.cpp index 83d554889c..12f78e90d0 100755 --- a/_studio/shared/umc/codec/h265_dec/src/umc_h265_task_supplier.cpp +++ b/_studio/shared/umc/codec/h265_dec/src/umc_h265_task_supplier.cpp @@ -42,6 +42,7 @@ #include "umc_h265_debug.h" #include "mfx_common.h" // for trace routines +#include "mfx_umc_alloc_wrapper.h" namespace UMC_HEVC_DECODER { @@ -250,6 +251,22 @@ bool IsNeedSPSInvalidate(const H265SeqParamSet *old_sps, const H265SeqParamSet * return false; } +// Check if bitstream params has changed +static +bool IsNeedSPSChanged(const H265SeqParamSet* old_sps, const H265SeqParamSet* new_sps) +{ + if (!old_sps || !new_sps) + return false; + + if ((old_sps->bit_depth_luma != new_sps->bit_depth_luma) || + (old_sps->bit_depth_chroma != new_sps->bit_depth_chroma) || + (old_sps->m_pcPTL.GetGeneralPTL()->profile_idc != new_sps->m_pcPTL.GetGeneralPTL()->profile_idc) || + (old_sps->chroma_format_idc != new_sps->chroma_format_idc) || + (old_sps->sps_max_dec_pic_buffering[0] < new_sps->sps_max_dec_pic_buffering[0])) + return true; + + return false; +} /****************************************************************************************************/ // MVC_Extension_H265 class routine /****************************************************************************************************/ @@ -1127,6 +1144,7 @@ UMC::Status TaskSupplier_H265::xDecodeSPS(H265HeadersBitstream *bs) bool newResolution = false; if (IsNeedSPSInvalidate(old_sps, &sps)) { + m_SpsChanged = IsNeedSPSChanged(old_sps, &sps); newResolution = true; } @@ -1605,10 +1623,11 @@ UMC::Status TaskSupplier_H265::CompleteDecodedFrames(H265DecoderFrame ** decoded } // Add a new bitstream data buffer to decoding -UMC::Status TaskSupplier_H265::AddSource(UMC::MediaData * pSource) +UMC::Status TaskSupplier_H265::AddSource(UMC::MediaData * pSource, VideoCORE *pCore) { MFX_AUTO_LTRACE(MFX_TRACE_LEVEL_INTERNAL, __FUNCTION__); H265DecoderFrame* completed = 0; + m_pCore = pCore; UMC::Status umcRes = CompleteDecodedFrames(&completed); if (umcRes != UMC::UMC_OK) return pSource || !completed ? umcRes : UMC::UMC_OK; @@ -1850,7 +1869,15 @@ UMC::Status TaskSupplier_H265::AddOneFrame(UMC::MediaData * pSource) int32_t nalIndex = pMediaDataEx->index; int32_t size = pMediaDataEx->offsets[nalIndex + 1] - pMediaDataEx->offsets[nalIndex]; - m_checkCRAInsideResetProcess = true; + auto frame_source = dynamic_cast(m_pFrameAllocator); + if (frame_source && frame_source->GetSurfaceType() && !m_SpsChanged) + { + m_checkCRAInsideResetProcess = false; + } + else + { + m_checkCRAInsideResetProcess = true; + } if (AddSlice(0, !pSource) == UMC::UMC_OK) { @@ -1882,6 +1909,7 @@ UMC::Status TaskSupplier_H265::AddOneFrame(UMC::MediaData * pSource) GetView()->pDPB->IncreaseRefPicListResetCount(0); // for flushing DPB NoRaslOutputFlag = 0; m_bFirstSliceInSequence = true; + m_pocDecoding.Reset(); return UMC::UMC_OK; break; diff --git a/_studio/shared/umc/codec/h265_dec/src/umc_h265_va_supplier.cpp b/_studio/shared/umc/codec/h265_dec/src/umc_h265_va_supplier.cpp index f154ef56c9..6d06268b71 100755 --- a/_studio/shared/umc/codec/h265_dec/src/umc_h265_va_supplier.cpp +++ b/_studio/shared/umc/codec/h265_dec/src/umc_h265_va_supplier.cpp @@ -36,6 +36,7 @@ #include "mfx_common_int.h" #include "mfx_ext_buffers.h" + namespace UMC_HEVC_DECODER { @@ -150,27 +151,26 @@ UMC::Status VATaskSupplier::AllocateFrameData(H265DecoderFrame * pFrame, mfxSize info.Init(dimensions.width, dimensions.height, chroma_format_idc, bit_depth); UMC::FrameMemID frmMID; - UMC::Status sts = m_pFrameAllocator->Alloc(&frmMID, &info, 0); + UMC::Status sts = m_pFrameAllocator->Alloc(&frmMID, &info, mfx_UMC_ReallocAllowed); if (sts == UMC::UMC_ERR_ALLOC) return UMC::UMC_ERR_ALLOC; + UMC::FrameData frmData; + frmData.Init(&info, frmMID, m_pFrameAllocator); + + auto frame_source = dynamic_cast(m_pFrameAllocator); if (sts != UMC::UMC_OK) { throw h265_exception(UMC::UMC_ERR_ALLOC); } - UMC::FrameData frmData; - frmData.Init(&info, frmMID, m_pFrameAllocator); - - auto frame_source = dynamic_cast(m_pFrameAllocator); if (frame_source) { mfxFrameSurface1* surface = frame_source->GetSurfaceByIndex(frmMID); if (!surface) throw h265_exception(UMC::UMC_ERR_ALLOC); - #if defined (MFX_EXTBUFF_GPU_HANG_ENABLE) mfxExtBuffer* extbuf = GetExtendedBuffer(surface->Data.ExtParam, surface->Data.NumExtParam, MFX_EXTBUFF_GPU_HANG);