From 7f317a5dd71389250c97a0d280d0550cd2bb5c36 Mon Sep 17 00:00:00 2001 From: "Zhu, Steve R" Date: Wed, 17 Jul 2024 22:50:14 +0000 Subject: [PATCH] [Decode] Upstream VVC pxp files This patch is to upstream vvc pxp files --- _studio/mfx_lib/pxp/CMakeLists.txt | 3 + .../mfx_lib/pxp/include/mfx_pxp_vvc_nal_spl.h | 50 +++++++ .../pxp/include/mfx_pxp_vvc_supplier.h | 54 ++++++++ .../mfx_lib/pxp/src/mfx_pxp_vvc_nal_spl.cpp | 122 ++++++++++++++++++ .../mfx_lib/pxp/src/mfx_pxp_vvc_supplier.cpp | 83 ++++++++++++ 5 files changed, 312 insertions(+) create mode 100644 _studio/mfx_lib/pxp/include/mfx_pxp_vvc_nal_spl.h create mode 100644 _studio/mfx_lib/pxp/include/mfx_pxp_vvc_supplier.h create mode 100644 _studio/mfx_lib/pxp/src/mfx_pxp_vvc_nal_spl.cpp create mode 100644 _studio/mfx_lib/pxp/src/mfx_pxp_vvc_supplier.cpp diff --git a/_studio/mfx_lib/pxp/CMakeLists.txt b/_studio/mfx_lib/pxp/CMakeLists.txt index 0d881c3d05..08123c4416 100644 --- a/_studio/mfx_lib/pxp/CMakeLists.txt +++ b/_studio/mfx_lib/pxp/CMakeLists.txt @@ -7,6 +7,8 @@ set(sources src/mfx_pxp_h264_nal_spl.cpp src/mfx_pxp_h265_supplier.cpp src/mfx_pxp_h265_nal_spl.cpp + src/mfx_pxp_vvc_supplier.cpp + src/mfx_pxp_vvc_nal_spl.cpp ) add_library(pxp_hw STATIC ${sources}) @@ -18,6 +20,7 @@ target_include_directories(pxp_hw ${MSDK_UMC_ROOT}/io/umc_va/include ${MSDK_UMC_ROOT}/codec/h264_dec/include ${MSDK_UMC_ROOT}/codec/h265_dec/include + ${MSDK_UMC_ROOT}/codec/vvc_dec/include ${OPENCL_INCLUDE} ) diff --git a/_studio/mfx_lib/pxp/include/mfx_pxp_vvc_nal_spl.h b/_studio/mfx_lib/pxp/include/mfx_pxp_vvc_nal_spl.h new file mode 100644 index 0000000000..23dadeca76 --- /dev/null +++ b/_studio/mfx_lib/pxp/include/mfx_pxp_vvc_nal_spl.h @@ -0,0 +1,50 @@ +// Copyright (c) 2022 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 +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#include "umc_defs.h" +#ifdef MFX_ENABLE_VVC_VIDEO_DECODE + +#ifndef __MFX_PXP_VVC_NAL_SPL_H +#define __MFX_PXP_VVC_NAL_SPL_H + +#include "mfx_common.h" + +#if defined(MFX_ENABLE_PXP) + +#include "umc_vvc_au_splitter.h" +#include "mfx_pxp_video_accelerator.h" + +#include "mfx_pxp_video_accelerator_vaapi.h" + +namespace UMC_VVC_DECODER +{ + class PXPNALUnitSplitter_VVC : public Splitter_VVC + { + public: + virtual UMC::MediaDataEx* GetNalUnits(UMC::MediaData* pSource) override; + UMC::Status MergeEncryptedNalUnit(UMC::MediaDataEx* nalUnit, UMC::MediaData* pSource); + void SetVA(UMC::VideoAccelerator* va) { m_va = va; } + private: + UMC::VideoAccelerator* m_va = nullptr; + }; +} +#endif // MFX_ENABLE_PXP +#endif // __MFX_PXP_VVC_NAL_SPL_H +#endif // MFX_ENABLE_VVC_VIDEO_DECODE diff --git a/_studio/mfx_lib/pxp/include/mfx_pxp_vvc_supplier.h b/_studio/mfx_lib/pxp/include/mfx_pxp_vvc_supplier.h new file mode 100644 index 0000000000..a89704d62f --- /dev/null +++ b/_studio/mfx_lib/pxp/include/mfx_pxp_vvc_supplier.h @@ -0,0 +1,54 @@ +// Copyright (c) 2022 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 +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#include "umc_defs.h" +#ifdef MFX_ENABLE_VVC_VIDEO_DECODE + +#ifndef __MFX_PXP_VVC_SUPPLIER_H +#define __MFX_PXP_VVC_SUPPLIER_H + +#include "mfx_common.h" + +#if defined(MFX_ENABLE_PXP) + +#include "umc_vvc_decoder_va.h" +#include "umc_vvc_au_splitter.h" +#include "mfx_pxp_video_accelerator.h" +#include "mfx_pxp_vvc_nal_spl.h" + +#include "mfx_pxp_video_accelerator_vaapi.h" + +namespace UMC_VVC_DECODER +{ + +class PXPVVCSupplier : public VVCDecoderVA +{ +public: + PXPVVCSupplier(); + virtual ~PXPVVCSupplier() {}; + + virtual UMC::Status Init(UMC::BaseCodecParams* pInit) override; + virtual UMC::Status AddOneFrame(UMC::MediaData* pSource) override; + UMC::Status UpdatePXPParams(UMC::MediaData const* pSource); +}; +} +#endif // MFX_ENABLE_PXP +#endif // __MFX_PXP_VVC_SUPPLIER_H +#endif // MFX_ENABLE_VVC_VIDEO_DECODE diff --git a/_studio/mfx_lib/pxp/src/mfx_pxp_vvc_nal_spl.cpp b/_studio/mfx_lib/pxp/src/mfx_pxp_vvc_nal_spl.cpp new file mode 100644 index 0000000000..8c0869d41d --- /dev/null +++ b/_studio/mfx_lib/pxp/src/mfx_pxp_vvc_nal_spl.cpp @@ -0,0 +1,122 @@ +// Copyright (c) 2022 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 +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#include "umc_defs.h" +#ifdef MFX_ENABLE_VVC_VIDEO_DECODE + +#include "mfx_pxp_vvc_nal_spl.h" + +#if defined(MFX_ENABLE_PXP) + +namespace UMC_VVC_DECODER +{ + UMC::MediaDataEx* PXPNALUnitSplitter_VVC::GetNalUnits(UMC::MediaData* pSource) + { + UMC::MediaDataEx* nalUnit = Splitter_VVC::GetNalUnits(pSource); + + if (nalUnit && m_va && m_va->GetProtectedVA() && static_cast(m_va->GetProtectedVA())->GetPXPParams()) + { + UMC::MediaDataEx::_MediaDataEx* pMediaDataEx = nalUnit->GetExData(); + NalUnitType unitType = (NalUnitType)pMediaDataEx->values[pMediaDataEx->index]; + if ( NAL_UNIT_CODED_SLICE_TRAIL == unitType + || NAL_UNIT_CODED_SLICE_STSA == unitType + || NAL_UNIT_CODED_SLICE_RADL == unitType + || NAL_UNIT_CODED_SLICE_RASL == unitType + || NAL_UNIT_CODED_SLICE_IDR_W_RADL == unitType + || NAL_UNIT_CODED_SLICE_IDR_N_LP == unitType + || NAL_UNIT_CODED_SLICE_CRA == unitType + || NAL_UNIT_CODED_SLICE_GDR == unitType + ) + { + UMC_CHECK(UMC::UMC_ERR_INVALID_PARAMS != MergeEncryptedNalUnit(nalUnit, pSource), nullptr); + } + } + + return nalUnit; + } + + UMC::Status PXPNALUnitSplitter_VVC::MergeEncryptedNalUnit(UMC::MediaDataEx* nalUnit, UMC::MediaData* pSource) + { + UMC_CHECK(nalUnit != nullptr, UMC::UMC_ERR_INVALID_PARAMS); + UMC_CHECK(pSource != nullptr, UMC::UMC_ERR_INVALID_PARAMS); + + uint32_t cur_segment_length = 0; + uint32_t start_code_length = 3; + UMC::PXPVA* pxpva = static_cast(m_va->GetProtectedVA()); + + cur_segment_length = (static_cast(pxpva->GetPXPParams())->segment_info + pxpva->m_curSegment)->segment_length - start_code_length; + + while (cur_segment_length != nalUnit->GetBufferSize()) + { + // middleclr mode has multi segments in one slice + if (cur_segment_length < nalUnit->GetBufferSize()) + { + pxpva->m_curSegment++; + + cur_segment_length += (static_cast(pxpva->GetPXPParams())->segment_info + pxpva->m_curSegment)->segment_length; + } + // additional NAL after encryption + else if (cur_segment_length > nalUnit->GetBufferSize()) + { + // additional 00 at the end of NAL + uint8_t* end_nal_ptr = (uint8_t*)nalUnit->GetBufferPointer() + nalUnit->GetBufferSize(); + uint32_t end_nal_index = 0; + uint32_t ext_buf_size = cur_segment_length - nalUnit->GetBufferSize(); + while (end_nal_index < ext_buf_size && *end_nal_ptr == 0) + { + end_nal_ptr++; + end_nal_index++; + } + if (end_nal_index >= ext_buf_size) + { + nalUnit->SetBufferPointer((uint8_t*)nalUnit->GetBufferPointer(), cur_segment_length); + nalUnit->SetDataSize(cur_segment_length); + + pxpva->m_curSegment++; + return UMC::UMC_OK; + } + + // additional start code, read next NAL + uint8_t* prev_buffer_ptr = (uint8_t*)nalUnit->GetBufferPointer(); + uint32_t prev_buffer_size = nalUnit->GetBufferSize(); + UMC::MediaDataEx::_MediaDataEx* pMediaDataEx = nalUnit->GetExData(); + int32_t prev_iCode = pMediaDataEx->values[0]; + + nalUnit = Splitter_VVC::GetNalUnits(pSource); + if (!nalUnit) + { + return UMC::UMC_ERR_NULL_PTR; + } + + uint32_t newBufferSize = prev_buffer_size + 3 + nalUnit->GetBufferSize(); + nalUnit->SetBufferPointer(prev_buffer_ptr, newBufferSize); + nalUnit->SetDataSize(newBufferSize); + pMediaDataEx->values[0] = prev_iCode; + pMediaDataEx->offsets[1] = newBufferSize; + } + } + pxpva->m_curSegment++; + + return UMC::UMC_OK; + } + +} +#endif // MFX_ENABLE_PXP +#endif // MFX_ENABLE_VVC_VIDEO_DECODE diff --git a/_studio/mfx_lib/pxp/src/mfx_pxp_vvc_supplier.cpp b/_studio/mfx_lib/pxp/src/mfx_pxp_vvc_supplier.cpp new file mode 100644 index 0000000000..0ec1f030d7 --- /dev/null +++ b/_studio/mfx_lib/pxp/src/mfx_pxp_vvc_supplier.cpp @@ -0,0 +1,83 @@ +// Copyright (c) 2022 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 +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +#include "umc_defs.h" +#ifdef MFX_ENABLE_VVC_VIDEO_DECODE + +#include "mfx_pxp_vvc_supplier.h" + +#if defined(MFX_ENABLE_PXP) + +namespace UMC_VVC_DECODER +{ + +PXPVVCSupplier::PXPVVCSupplier() +{ +} + +UMC::Status PXPVVCSupplier::Init(UMC::BaseCodecParams* pInit) +{ + UMC::Status umcRes = VVCDecoder::Init(pInit); + if (m_va->GetProtectedVA()) + { + static_cast(m_splitter.get())->SetVA(m_va); + } + return umcRes; +} + +UMC::Status PXPVVCSupplier::AddOneFrame(UMC::MediaData * pSource) +{ + if (m_va->GetProtectedVA()) + { + if (!m_lastSlice && pSource) + { + UMC::Status umcRes = UpdatePXPParams(pSource); + if(umcRes != UMC::UMC_OK) + return umcRes; + } + } + return VVCDecoder::AddOneFrame(pSource); +} + +UMC::Status PXPVVCSupplier::UpdatePXPParams(UMC::MediaData const* pSource) +{ + UMC_CHECK(pSource != nullptr, UMC::UMC_ERR_INVALID_PARAMS); + + static_cast(m_va->GetProtectedVA())->SetPXPParams(nullptr); + static_cast(m_va->GetProtectedVA())->m_curSegment = 0; + + mfxPXPCtxHDL curPXPCtxHdl = static_cast(static_cast(m_va->GetProtectedVA())->GetPXPCtxHdl()); + + auto mapptr = std::find_if(curPXPCtxHdl->decodeParamMapHdl, curPXPCtxHdl->decodeParamMapHdl + curPXPCtxHdl->decodeParamMapCnt, + [key = (uint8_t*)pSource->GetBufferPointer()](const mfxDecodeParamMap & data) + { return data.pMfxBitstream->Data == key; } + ); + UMC_CHECK(mapptr != curPXPCtxHdl->decodeParamMapHdl + curPXPCtxHdl->decodeParamMapCnt, UMC::UMC_ERR_FAILED); + + static_cast(m_va->GetProtectedVA())->SetPXPParams(mapptr->pPXPParams); + + UMC_CHECK(static_cast(m_va->GetProtectedVA())->GetPXPParams() != nullptr, UMC::UMC_ERR_INVALID_PARAMS); + + return UMC::UMC_OK; +} + +} +#endif // MFX_ENABLE_PXP +#endif // MFX_ENABLE_VVC_VIDEO_DECODE