// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "Containers/Utf8String.h" #include "Video/DependencyDescriptor.h" #include "Video/GenericFrameInfo.h" #include "Video/VideoEncoder.h" #include "epic_rtc/containers/epic_rtc_array.h" #include "epic_rtc/containers/epic_rtc_string_view.h" #include "epic_rtc/core/video/video_buffer.h" #include "epic_rtc/core/video/video_codec_info.h" #include "epic_rtc_helper/memory/ref_count_impl_helper.h" FORCEINLINE bool operator==(const EpicRtcVideoResolution& Lhs, const EpicRtcVideoResolution& Rhs) { return Lhs._width == Rhs._width && Lhs._height == Rhs._height; } namespace UE::PixelStreaming2 { class PIXELSTREAMING2RTC_API FEpicRtcString : public EpicRtcStringInterface { public: FEpicRtcString() = default; FEpicRtcString(const FString& String) : String(String) { } virtual const char* Get() const override { return (const char*)*String; } virtual uint64_t Length() const override { return String.Len(); } private: FUtf8String String; public: // Begin EpicRtcRefCountInterface EPICRTC_REFCOUNT_INTERFACE_IN_PLACE // End EpicRtcRefCountInterface }; class PIXELSTREAMING2RTC_API FEpicRtcEncodedVideoBuffer : public EpicRtcEncodedVideoBufferInterface { public: FEpicRtcEncodedVideoBuffer() = default; FEpicRtcEncodedVideoBuffer(uint8_t* InData, uint64_t InSize) : Data(InData, InSize) { } virtual ~FEpicRtcEncodedVideoBuffer() = default; virtual const uint8_t* GetData() const override { return Data.GetData(); }; virtual uint64_t GetSize() const override { return Data.Num(); }; private: TArray Data; public: // Begin EpicRtcRefCountInterface EPICRTC_REFCOUNT_INTERFACE_IN_PLACE // End EpicRtcRefCountInterface }; class PIXELSTREAMING2RTC_API FEpicRtcParameterPairArray : public EpicRtcParameterPairArrayInterface { public: FEpicRtcParameterPairArray() = default; virtual ~FEpicRtcParameterPairArray() = default; FEpicRtcParameterPairArray(const TArray& ParameterPairs) : Data(ParameterPairs) { } FEpicRtcParameterPairArray(std::initializer_list ParameterPairs) : Data(ParameterPairs) { } virtual const EpicRtcParameterPair* Get() const override { return Data.GetData(); } virtual EpicRtcParameterPair* Get() override { return Data.GetData(); } virtual uint64_t Size() const override { return Data.Num(); } void Append(std::initializer_list ParameterPairs) { Data.Append(ParameterPairs); } private: TArray Data; public: // Begin EpicRtcRefCountInterface EPICRTC_REFCOUNT_INTERFACE_IN_PLACE // End EpicRtcRefCountInterface }; class PIXELSTREAMING2RTC_API FEpicRtcParameterPair : public EpicRtcParameterPairInterface { public: FEpicRtcParameterPair(EpicRtcStringInterface* Key, EpicRtcStringInterface* Value) : Key(Key) , Value(Value) { } virtual EpicRtcStringInterface* GetKey() override { return Key; } virtual EpicRtcStringInterface* GetValue() override { return Value; } private: TRefCountPtr Key; TRefCountPtr Value; public: // Begin EpicRtcRefCountInterface EPICRTC_REFCOUNT_INTERFACE_IN_PLACE // End EpicRtcRefCountInterface }; class PIXELSTREAMING2RTC_API FEpicRtcVideoParameterPairArray : public EpicRtcVideoParameterPairArrayInterface { public: FEpicRtcVideoParameterPairArray() = default; virtual ~FEpicRtcVideoParameterPairArray() { for (auto& ParameterPair : Data) { if (ParameterPair != nullptr) { ParameterPair->Release(); } } } FEpicRtcVideoParameterPairArray(const TArray>& ParameterPairs) { for (auto& ParameterPair : ParameterPairs) { Data.Add(ParameterPair.GetReference()); if (ParameterPair.GetReference() != nullptr) { ParameterPair->AddRef(); } } } FEpicRtcVideoParameterPairArray(const TArray& ParameterPairs) { for (auto& ParameterPair : ParameterPairs) { Data.Add(ParameterPair); if (ParameterPair != nullptr) { ParameterPair->AddRef(); } } } FEpicRtcVideoParameterPairArray(std::initializer_list ParameterPairs) { for (auto& ParameterPair : ParameterPairs) { Data.Add(ParameterPair); if (ParameterPair != nullptr) { ParameterPair->AddRef(); } } } virtual EpicRtcParameterPairInterface* const* Get() const override { return Data.GetData(); } virtual EpicRtcParameterPairInterface** Get() override { return Data.GetData(); } virtual uint64_t Size() const override { return Data.Num(); } void Append(std::initializer_list ParameterPairs) { for (auto& ParameterPair : ParameterPairs) { Data.Add(ParameterPair); if (ParameterPair != nullptr) { ParameterPair->AddRef(); } } } private: TArray Data; public: // Begin EpicRtcRefCountInterface EPICRTC_REFCOUNT_INTERFACE_IN_PLACE // End EpicRtcRefCountInterface }; class PIXELSTREAMING2RTC_API FEpicRtcScalabilityModeArray : public EpicRtcVideoScalabilityModeArrayInterface { public: FEpicRtcScalabilityModeArray() = default; virtual ~FEpicRtcScalabilityModeArray() = default; FEpicRtcScalabilityModeArray(const TArray& ScalabilityModes) : Data(ScalabilityModes) { } FEpicRtcScalabilityModeArray(std::initializer_list ScalabilityModes) : Data(ScalabilityModes) { } FEpicRtcScalabilityModeArray(const TArray& ScalabilityModes) { for (EScalabilityMode ScalabilityMode : ScalabilityModes) { Data.Add(static_cast(ScalabilityMode)); // HACK if the Enums become un-aligned } } virtual const EpicRtcVideoScalabilityMode* Get() const override { return Data.GetData(); } virtual EpicRtcVideoScalabilityMode* Get() override { return Data.GetData(); } virtual uint64_t Size() const override { return Data.Num(); } void Append(std::initializer_list ScalabilityModes) { Data.Append(ScalabilityModes); } private: TArray Data; public: // Begin EpicRtcRefCountInterface EPICRTC_REFCOUNT_INTERFACE_IN_PLACE // End EpicRtcRefCountInterface }; class PIXELSTREAMING2RTC_API FEpicRtcVideoCodecInfo : public EpicRtcVideoCodecInfoInterface { public: FEpicRtcVideoCodecInfo(EpicRtcVideoCodec Codec, bool bIsHardwareAccelerated = false, EpicRtcVideoParameterPairArrayInterface* Parameters = new FEpicRtcVideoParameterPairArray(), EpicRtcVideoScalabilityModeArrayInterface* ScalabilityModes = new FEpicRtcScalabilityModeArray()) : Codec(Codec) , bIsHardwareAccelerated(bIsHardwareAccelerated) , Parameters(Parameters) , ScalabilityModes(ScalabilityModes) { } virtual ~FEpicRtcVideoCodecInfo() = default; EpicRtcVideoCodec GetCodec() override { return Codec; } virtual EpicRtcVideoParameterPairArrayInterface* GetParameters() override { return Parameters; } EpicRtcVideoScalabilityModeArrayInterface* GetScalabilityModes() override { return ScalabilityModes; } EpicRtcBool IsHardwareAccelerated() override { return bIsHardwareAccelerated; } private: EpicRtcVideoCodec Codec; bool bIsHardwareAccelerated; TRefCountPtr Parameters; TRefCountPtr ScalabilityModes; public: // Begin EpicRtcRefCountInterface EPICRTC_REFCOUNT_INTERFACE_IN_PLACE // End EpicRtcRefCountInterface }; class PIXELSTREAMING2RTC_API FVideoCodecInfoArray : public EpicRtcVideoCodecInfoArrayInterface { public: FVideoCodecInfoArray() = default; virtual ~FVideoCodecInfoArray() { for (auto& Codec : Data) { if (Codec != nullptr) { Codec->Release(); } } } FVideoCodecInfoArray(const TArray>& Codecs) { for (auto& Codec : Codecs) { Data.Add(Codec.GetReference()); if (Codec.GetReference() != nullptr) { Codec->AddRef(); } } } FVideoCodecInfoArray(const TArray& Codecs) { for (auto& Codec : Codecs) { Data.Add(Codec); if (Codec != nullptr) { Codec->AddRef(); } } } FVideoCodecInfoArray(std::initializer_list Codecs) { for (auto& Codec : Codecs) { Data.Add(Codec); if (Codec != nullptr) { Codec->AddRef(); } } } virtual EpicRtcVideoCodecInfoInterface* const* Get() const override { return Data.GetData(); } virtual EpicRtcVideoCodecInfoInterface** Get() override { return Data.GetData(); } virtual uint64_t Size() const override { return Data.Num(); } private: TArray Data; public: // Begin EpicRtcRefCountInterface EPICRTC_REFCOUNT_INTERFACE_IN_PLACE // End EpicRtcRefCountInterface }; class PIXELSTREAMING2RTC_API FEpicRtcVideoResolutionBitrateLimitsArray : public EpicRtcVideoResolutionBitrateLimitsArrayInterface { public: FEpicRtcVideoResolutionBitrateLimitsArray() = default; virtual ~FEpicRtcVideoResolutionBitrateLimitsArray() = default; FEpicRtcVideoResolutionBitrateLimitsArray(const TArray& BitrateLimits) : Data(BitrateLimits) { } FEpicRtcVideoResolutionBitrateLimitsArray(std::initializer_list BitrateLimits) : Data(BitrateLimits) { } virtual const EpicRtcVideoResolutionBitrateLimits* Get() const override { return Data.GetData(); } virtual EpicRtcVideoResolutionBitrateLimits* Get() override { return Data.GetData(); } virtual uint64_t Size() const override { return Data.Num(); } private: TArray Data; public: // Begin EpicRtcRefCountInterface EPICRTC_REFCOUNT_INTERFACE_IN_PLACE // End EpicRtcRefCountInterface }; class PIXELSTREAMING2RTC_API FEpicRtcPixelFormatArray : public EpicRtcPixelFormatArrayInterface { public: FEpicRtcPixelFormatArray() = default; virtual ~FEpicRtcPixelFormatArray() = default; FEpicRtcPixelFormatArray(const TArray& PixelFormats) : Data(PixelFormats) { } FEpicRtcPixelFormatArray(std::initializer_list PixelFormats) : Data(PixelFormats) { } virtual const EpicRtcPixelFormat* Get() const override { return Data.GetData(); } virtual EpicRtcPixelFormat* Get() override { return Data.GetData(); } virtual uint64_t Size() const override { return Data.Num(); } private: TArray Data; public: // Begin EpicRtcRefCountInterface EPICRTC_REFCOUNT_INTERFACE_IN_PLACE // End EpicRtcRefCountInterface }; class PIXELSTREAMING2RTC_API FEpicRtcVideoFrameTypeArray : public EpicRtcVideoFrameTypeArrayInterface { public: FEpicRtcVideoFrameTypeArray() = default; virtual ~FEpicRtcVideoFrameTypeArray() = default; FEpicRtcVideoFrameTypeArray(const TArray& FrameTypes) : Data(FrameTypes) { } FEpicRtcVideoFrameTypeArray(std::initializer_list FrameTypes) : Data(FrameTypes) { } virtual const EpicRtcVideoFrameType* Get() const override { return Data.GetData(); } virtual uint64_t Size() const override { return Data.Num(); } private: TArray Data; public: // Begin EpicRtcRefCountInterface EPICRTC_REFCOUNT_INTERFACE_IN_PLACE // End EpicRtcRefCountInterface }; class PIXELSTREAMING2RTC_API FEpicRtcInt32Array : public EpicRtcInt32ArrayInterface { public: FEpicRtcInt32Array() = default; virtual ~FEpicRtcInt32Array() = default; FEpicRtcInt32Array(const TArray& Ints) : Data(Ints) { } FEpicRtcInt32Array(std::initializer_list Ints) : Data(Ints) { } virtual const int32_t* Get() const override { return Data.GetData(); } virtual int32_t* Get() override { return Data.GetData(); } virtual uint64_t Size() const override { return Data.Num(); } void Append(std::initializer_list Ints) { Data.Append(Ints); } private: TArray Data; public: // Begin EpicRtcRefCountInterface EPICRTC_REFCOUNT_INTERFACE_IN_PLACE // End EpicRtcRefCountInterface }; class PIXELSTREAMING2RTC_API FEpicRtcBoolArray : public EpicRtcBoolArrayInterface { public: FEpicRtcBoolArray() = default; virtual ~FEpicRtcBoolArray() = default; FEpicRtcBoolArray(const TArray& Bools) : Data(Bools) { } FEpicRtcBoolArray(const TArray& Bools) { Data.SetNum(Bools.Num()); for (size_t i = 0; i < Bools.Num(); i++) { Data[i] = Bools[i]; } } FEpicRtcBoolArray(std::initializer_list Bools) : Data(Bools) { } FEpicRtcBoolArray(std::initializer_list Bools) { for (auto& Bool : Bools) { Data.Add(Bool); } } virtual const EpicRtcBool* Get() const override { return Data.GetData(); } virtual EpicRtcBool* Get() override { return Data.GetData(); } virtual uint64_t Size() const override { return Data.Num(); } private: TArray Data; public: // Begin EpicRtcRefCountInterface EPICRTC_REFCOUNT_INTERFACE_IN_PLACE // End EpicRtcRefCountInterface }; class PIXELSTREAMING2RTC_API FEpicRtcDecodeTargetIndicationArray : public EpicRtcDecodeTargetIndicationArrayInterface { public: FEpicRtcDecodeTargetIndicationArray() = default; virtual ~FEpicRtcDecodeTargetIndicationArray() = default; FEpicRtcDecodeTargetIndicationArray(const TArray& DecodeTargetIndications) : Data(DecodeTargetIndications) { } FEpicRtcDecodeTargetIndicationArray(std::initializer_list DecodeTargetIndications) : Data(DecodeTargetIndications) { } // Helper method for converting array AVCodecs' EDecodeTargetIndication to array of EpicRtc's EpicRtcDecodeTargetIndication FEpicRtcDecodeTargetIndicationArray(const TArray& DecodeTargetIndications) { Data.SetNum(DecodeTargetIndications.Num()); for (size_t i = 0; i < DecodeTargetIndications.Num(); i++) { switch (DecodeTargetIndications[i]) { case EDecodeTargetIndication::NotPresent: Data[i] = EpicRtcDecodeTargetIndication::NotPresent; break; case EDecodeTargetIndication::Discardable: Data[i] = EpicRtcDecodeTargetIndication::Discardable; break; case EDecodeTargetIndication::Switch: Data[i] = EpicRtcDecodeTargetIndication::Switch; break; case EDecodeTargetIndication::Required: Data[i] = EpicRtcDecodeTargetIndication::Required; break; default: checkNoEntry(); } } } virtual const EpicRtcDecodeTargetIndication* Get() const override { return Data.GetData(); } virtual EpicRtcDecodeTargetIndication* Get() override { return Data.GetData(); } virtual uint64_t Size() const override { return Data.Num(); } private: TArray Data; public: // Begin EpicRtcRefCountInterface EPICRTC_REFCOUNT_INTERFACE_IN_PLACE // End EpicRtcRefCountInterface }; class PIXELSTREAMING2RTC_API FEpicRtcCodecBufferUsageArray : public EpicRtcCodecBufferUsageArrayInterface { public: FEpicRtcCodecBufferUsageArray() = default; virtual ~FEpicRtcCodecBufferUsageArray() = default; FEpicRtcCodecBufferUsageArray(const TArray& CodecBufferUsages) : Data(CodecBufferUsages) { } FEpicRtcCodecBufferUsageArray(std::initializer_list CodecBufferUsages) : Data(CodecBufferUsages) { } // Helper method for converting array AVCodecs' FCodecBufferUsage to array of EpicRtc's EpicRtcCodecBufferUsage FEpicRtcCodecBufferUsageArray(const TArray& CodecBufferUsages) { Data.SetNum(CodecBufferUsages.Num()); for (size_t i = 0; i < CodecBufferUsages.Num(); i++) { const FCodecBufferUsage& CodecBufferUsage = CodecBufferUsages[i]; Data[i] = EpicRtcCodecBufferUsage{ ._id = CodecBufferUsage.Id, ._referenced = CodecBufferUsage.bReferenced, ._updated = CodecBufferUsage.bUpdated }; } } virtual const EpicRtcCodecBufferUsage* Get() const override { return Data.GetData(); } virtual EpicRtcCodecBufferUsage* Get() override { return Data.GetData(); } virtual uint64_t Size() const override { return Data.Num(); } private: TArray Data; public: // Begin EpicRtcRefCountInterface EPICRTC_REFCOUNT_INTERFACE_IN_PLACE // End EpicRtcRefCountInterface }; class PIXELSTREAMING2RTC_API FEpicRtcVideoResolutionArray : public EpicRtcVideoResolutionArrayInterface { public: FEpicRtcVideoResolutionArray() = default; virtual ~FEpicRtcVideoResolutionArray() = default; FEpicRtcVideoResolutionArray(const TArray& Resolutions) : Data(Resolutions) { } FEpicRtcVideoResolutionArray(std::initializer_list Resolutions) : Data(Resolutions) { } // Helper method for converting array AVCodecs' FResolution to array of EpicRtc's EpicRtcVideoResolution FEpicRtcVideoResolutionArray(const TArray& Resolutions) { Data.SetNum(Resolutions.Num()); for (size_t i = 0; i < Resolutions.Num(); i++) { const FIntPoint& Resolution = Resolutions[i]; Data[i] = EpicRtcVideoResolution{ ._width = Resolution.X, ._height = Resolution.Y }; } } virtual const EpicRtcVideoResolution* Get() const override { return Data.GetData(); } virtual EpicRtcVideoResolution* Get() override { return Data.GetData(); } virtual uint64_t Size() const override { return Data.Num(); } private: TArray Data; public: // Begin EpicRtcRefCountInterface EPICRTC_REFCOUNT_INTERFACE_IN_PLACE // End EpicRtcRefCountInterface }; class PIXELSTREAMING2RTC_API FEpicRtcGenericFrameInfoArray : public EpicRtcGenericFrameInfoArrayInterface { public: FEpicRtcGenericFrameInfoArray() = default; virtual ~FEpicRtcGenericFrameInfoArray() { for (auto& GenericFrameInfo : Data) { if (GenericFrameInfo != nullptr) { GenericFrameInfo->Release(); } } } FEpicRtcGenericFrameInfoArray(const TArray>& GenericFrameInfos) { for (auto& GenericFrameInfo : GenericFrameInfos) { Data.Add(GenericFrameInfo.GetReference()); if (GenericFrameInfo.GetReference() != nullptr) { GenericFrameInfo->AddRef(); } } } FEpicRtcGenericFrameInfoArray(const TArray& GenericFrameInfos) { for (auto& GenericFrameInfo : GenericFrameInfos) { Data.Add(GenericFrameInfo); if (GenericFrameInfo != nullptr) { GenericFrameInfo->AddRef(); } } } FEpicRtcGenericFrameInfoArray(std::initializer_list GenericFrameInfos) { for (auto& GenericFrameInfo : GenericFrameInfos) { Data.Add(GenericFrameInfo); if (GenericFrameInfo != nullptr) { GenericFrameInfo->AddRef(); } } } virtual EpicRtcGenericFrameInfoInterface* const* Get() const override { return Data.GetData(); } virtual EpicRtcGenericFrameInfoInterface** Get() override { return Data.GetData(); } virtual uint64_t Size() const override { return Data.Num(); } private: TArray Data; public: // Begin EpicRtcRefCountInterface EPICRTC_REFCOUNT_INTERFACE_IN_PLACE // End EpicRtcRefCountInterface }; class PIXELSTREAMING2RTC_API FEpicRtcGenericFrameInfo : public EpicRtcGenericFrameInfoInterface { public: FEpicRtcGenericFrameInfo(const FGenericFrameInfo& GenericFrameInfo) : SpatialId(GenericFrameInfo.SpatialId) , TemporalId(GenericFrameInfo.TemporalId) , DecodeTargetIndications(MakeRefCount(GenericFrameInfo.DecodeTargetIndications)) , FrameDiffs(MakeRefCount(GenericFrameInfo.FrameDiffs)) , ChainDiffs(MakeRefCount(GenericFrameInfo.ChainDiffs)) , EncoderBuffers(MakeRefCount(GenericFrameInfo.EncoderBuffers)) , PartOfChain(MakeRefCount(GenericFrameInfo.PartOfChain)) , ActiveDecodeTargets(MakeRefCount(GenericFrameInfo.ActiveDecodeTargets)) { } virtual ~FEpicRtcGenericFrameInfo() = default; virtual int32_t GetSpatialLayerId() override { return SpatialId; } virtual int32_t GetTemporalLayerId() override { return TemporalId; } virtual EpicRtcDecodeTargetIndicationArrayInterface* GetDecodeTargetIndications() override { return DecodeTargetIndications; } virtual EpicRtcInt32ArrayInterface* GetFrameDiffs() override { return FrameDiffs; } virtual EpicRtcInt32ArrayInterface* GetChainDiffs() override { return ChainDiffs; } virtual EpicRtcCodecBufferUsageArrayInterface* GetEncoderBufferUsages() override { return EncoderBuffers; } virtual EpicRtcBoolArrayInterface* GetPartOfChain() override { return PartOfChain; } virtual EpicRtcBoolArrayInterface* GetActiveDecodeTargets() override { return ActiveDecodeTargets; } private: int32_t SpatialId; int32_t TemporalId; TRefCountPtr DecodeTargetIndications; TRefCountPtr FrameDiffs; TRefCountPtr ChainDiffs; TRefCountPtr EncoderBuffers; TRefCountPtr PartOfChain; TRefCountPtr ActiveDecodeTargets; public: // Begin EpicRtcRefCountInterface EPICRTC_REFCOUNT_INTERFACE_IN_PLACE // End EpicRtcRefCountInterface }; class PIXELSTREAMING2RTC_API FEpicRtcFrameDependencyStructure : public EpicRtcFrameDependencyStructure { public: FEpicRtcFrameDependencyStructure(const FFrameDependencyStructure& FrameDependencyStructure) : StructureId(FrameDependencyStructure.StructureId) , NumDecodeTargets(FrameDependencyStructure.NumDecodeTargets) , NumChains(FrameDependencyStructure.NumChains) , DecodeTargetProtectedByChain(MakeRefCount(FrameDependencyStructure.DecodeTargetProtectedByChain)) , Resolutions(MakeRefCount(FrameDependencyStructure.Resolutions)) { TArray GenericFrameInfoArray; GenericFrameInfoArray.SetNum(FrameDependencyStructure.Templates.Num()); for (size_t i = 0; i < FrameDependencyStructure.Templates.Num(); i++) { FGenericFrameInfo GenericFrameInfo; GenericFrameInfo.SpatialId = FrameDependencyStructure.Templates[i].SpatialId; GenericFrameInfo.TemporalId = FrameDependencyStructure.Templates[i].TemporalId; GenericFrameInfo.DecodeTargetIndications = FrameDependencyStructure.Templates[i].DecodeTargetIndications; GenericFrameInfo.FrameDiffs = FrameDependencyStructure.Templates[i].FrameDiffs; GenericFrameInfo.ChainDiffs = FrameDependencyStructure.Templates[i].ChainDiffs; GenericFrameInfoArray[i] = new FEpicRtcGenericFrameInfo(GenericFrameInfo); } Templates = MakeRefCount(GenericFrameInfoArray); } virtual ~FEpicRtcFrameDependencyStructure() = default; virtual int32_t GetStructureId() override { return StructureId; } virtual int32_t GetNumDecodeTargets() override { return NumDecodeTargets; } virtual int32_t GetNumChains() override { return NumChains; } virtual EpicRtcInt32ArrayInterface* GetDecodeTargetProtectedByChain() override { return DecodeTargetProtectedByChain; } virtual EpicRtcVideoResolutionArrayInterface* GetResolutions() override { return Resolutions; } virtual EpicRtcGenericFrameInfoArrayInterface* GetTemplates() override { return Templates; } friend bool operator==(FEpicRtcFrameDependencyStructure& Lhs, FEpicRtcFrameDependencyStructure& Rhs) { TArray LhsDecodeTargetProtectedByChain(Lhs.GetDecodeTargetProtectedByChain()->Get(), Lhs.GetDecodeTargetProtectedByChain()->Size()); TArray RhsDecodeTargetProtectedByChain(Rhs.GetDecodeTargetProtectedByChain()->Get(), Rhs.GetDecodeTargetProtectedByChain()->Size()); TArray LhsResolutions(Lhs.GetResolutions()->Get(), Lhs.GetResolutions()->Size()); TArray RhsResolutions(Rhs.GetResolutions()->Get(), Rhs.GetResolutions()->Size()); TArray LhsTemplates(Lhs.GetTemplates()->Get(), Lhs.GetTemplates()->Size()); TArray RhsTemplates(Rhs.GetTemplates()->Get(), Rhs.GetTemplates()->Size()); return Lhs.NumDecodeTargets == Rhs.NumDecodeTargets && Lhs.NumChains == Rhs.NumChains && LhsDecodeTargetProtectedByChain == RhsDecodeTargetProtectedByChain && LhsResolutions == RhsResolutions && LhsTemplates == RhsTemplates; } private: int StructureId; int NumDecodeTargets; int NumChains; TRefCountPtr DecodeTargetProtectedByChain; TRefCountPtr Resolutions; TRefCountPtr Templates; public: // Begin EpicRtcRefCountInterface EPICRTC_REFCOUNT_INTERFACE_IN_PLACE // End EpicRtcRefCountInterface }; } // namespace UE::PixelStreaming2