You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
Refactor player sessions Fix PixelStreamingAudioComponent had delayed audio. Fix audio bitrate from Unreal Engine to browser was set to a low default causing compressed audio quality in stream. The new default is now Opus maximum value of 510kb/s. Fix the Selective Forwarding Unit (SFU) not being added to the Pixel Streaming samples folder for a packaged project Fix default max bitrate not being high enough to support 4k. Fix reconnections not autoplaying in the browser. Add datachannel support to SFU. Add WebRTC c++ client behaviour to pixel streaming system. This is used for developing unit tests. Add a unit test that will start streaming, connect a client and check that a data channel message can be sent. Add the ability for a user to start/stop streaming as needed through the use of PixelStreaming.StartStreaming and PixelStreaming.StopStreaming Add the ability for the stream resolution to be changed at runtime Notes: AVEncoder no longer stores a width and height; These properties have been moved to the FVideoEncoderInput. This input is now the source of truth and both AMF and NVENC will adapt their resolution to the input resolution. #rb luke.bermingham #fyi mattias.jansson, nick.pace, matthew.cotton, aidan.possemiers, sandor.hadas #preflight 6204c7aba65a8a28464df03c #jira none [CL 18948482 by William Belcher in ue5-main branch]
170 lines
5.5 KiB
C++
170 lines
5.5 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#pragma once
|
|
|
|
#include "VideoEncoderInput.h"
|
|
#include "Containers/Queue.h"
|
|
#include "Misc/ScopeLock.h"
|
|
#include "Templates/RefCounting.h"
|
|
#include "CudaModule.h"
|
|
|
|
// HACK (M84FIX) need to break these dependencies
|
|
#if PLATFORM_WINDOWS
|
|
struct ID3D11DeviceContext;
|
|
#endif
|
|
|
|
namespace AVEncoder
|
|
{
|
|
class FVideoEncoderInputFrameImpl;
|
|
|
|
class FVideoEncoderInputImpl : public FVideoEncoderInput
|
|
{
|
|
public:
|
|
FVideoEncoderInputImpl() = default;
|
|
virtual ~FVideoEncoderInputImpl();
|
|
|
|
// --- properties
|
|
|
|
uint32 GetNumActiveFrames() const { FScopeLock Guard(&ProtectFrames); return ActiveFrames.Num(); }
|
|
bool GetHasFreeFrames() const { FScopeLock Guard(&ProtectFrames); return !AvailableFrames.IsEmpty(); }
|
|
|
|
// --- construct video encoder input based on expected input frame format
|
|
|
|
bool SetupForDummy();
|
|
bool SetupForYUV420P(uint32 InWidth, uint32 InHeight);
|
|
|
|
// set up for an encoder that encodes a D3D11 texture (nvenc)
|
|
bool SetupForD3D11(void* InApplicationD3DDevice);
|
|
|
|
// set up for an encoder that encodes a D3D11 texture within a feature level 11.1 D3D11 device (amf)
|
|
bool SetupForD3D11Shared(void* InApplicationD3DDevice);
|
|
|
|
// set up for an encoder that encodes a D3D12 texture (amf)
|
|
bool SetupForD3D12(void* InApplicationD3DDevice);
|
|
|
|
// set up for an encoder that encodes a D3D12 texture in the context of a D3D11 device (i.e. nvenc)
|
|
bool SetupForD3D12Shared(void* InApplicationD3DDevice);
|
|
|
|
// set up an encoder that encodes a CUArray in a CUDA context
|
|
bool SetupForCUDA(void* InApplicationContext);
|
|
|
|
#if PLATFORM_DESKTOP && !PLATFORM_APPLE
|
|
// set up an encoder that encodes a VkImage in the context of a VkDevice
|
|
bool SetupForVulkan(VkInstance InApplicationVulkanInstance, VkPhysicalDevice InApplicationVulkanPhysicalDevice, VkDevice InApplicationVulkanDevice);
|
|
#endif
|
|
|
|
// --- available encoders
|
|
|
|
// get a list of supported video encoders
|
|
const TArray<FVideoEncoderInfo>& GetAvailableEncoders() override;
|
|
|
|
// --- encoder input frames - user managed
|
|
|
|
// create a user managed buffer
|
|
FVideoEncoderInputFrame* CreateBuffer(OnFrameReleasedCallback InOnFrameReleased) override;
|
|
// destroy user managed buffer
|
|
void DestroyBuffer(FVideoEncoderInputFrame* Buffer) override;
|
|
|
|
// --- encoder input frames - managed by this object
|
|
|
|
// obtain a video frame that can be used as a buffer for input to a video encoder
|
|
FVideoEncoderInputFrame* ObtainInputFrame() override;
|
|
|
|
// release (free) an input frame and make it available for future use
|
|
void ReleaseInputFrame(FVideoEncoderInputFrame* InFrame) override;
|
|
|
|
// destroy/release any frames that are not currently in use
|
|
void Flush() override;
|
|
|
|
// indicates whether a given frame is a user managed frame or not
|
|
bool IsUserManagedFrame(const FVideoEncoderInputFrame* InBuffer) const;
|
|
|
|
// --- input properties
|
|
|
|
#if PLATFORM_WINDOWS
|
|
TRefCountPtr<ID3D11Device> GetD3D11EncoderDevice() const override;
|
|
TRefCountPtr<ID3D12Device> GetD3D12EncoderDevice() const override;
|
|
#endif
|
|
|
|
CUcontext GetCUDAEncoderContext() const override;
|
|
|
|
#if PLATFORM_DESKTOP && !PLATFORM_APPLE
|
|
void* GetVulkanEncoderDevice() const override;
|
|
#endif
|
|
|
|
private:
|
|
|
|
// collect any encoder that can handle frame format
|
|
void CollectAvailableEncoders();
|
|
|
|
TArray<FVideoEncoderInfo> AvailableEncoders;
|
|
|
|
FVideoEncoderInputFrameImpl* CreateFrame();
|
|
void SetupFrameYUV420P(FVideoEncoderInputFrameImpl* Frame);
|
|
void SetupFrameD3D11(FVideoEncoderInputFrameImpl* Frame);
|
|
void SetupFrameD3D12(FVideoEncoderInputFrameImpl* Frame);
|
|
void SetupFrameVulkan(FVideoEncoderInputFrameImpl* Frame);
|
|
void SetupFrameCUDA(FVideoEncoderInputFrameImpl* Frame);
|
|
|
|
struct FFrameInfoDummy
|
|
{
|
|
} FrameInfoDummy;
|
|
|
|
struct FFrameInfoYUV420P
|
|
{
|
|
uint32 StrideY = 0;
|
|
uint32 StrideU = 0;
|
|
uint32 StrideV = 0;
|
|
} FrameInfoYUV420P;
|
|
|
|
#if PLATFORM_WINDOWS
|
|
struct FFrameInfoD3D
|
|
{
|
|
TRefCountPtr<ID3D11Device> EncoderDeviceD3D11;
|
|
TRefCountPtr<ID3D11DeviceContext> EncoderDeviceContextD3D11;
|
|
TRefCountPtr<ID3D12Device> EncoderDeviceD3D12;
|
|
} FrameInfoD3D;
|
|
#endif
|
|
|
|
struct FFrameInfoCUDA
|
|
{
|
|
CUcontext EncoderContextCUDA;
|
|
} FrameInfoCUDA;
|
|
|
|
#if PLATFORM_DESKTOP && !PLATFORM_APPLE
|
|
FVulkanDataStruct FrameInfoVulkan;
|
|
#endif
|
|
|
|
mutable FCriticalSection ProtectFrames;
|
|
TQueue<FVideoEncoderInputFrameImpl*> AvailableFrames;
|
|
TArray<FVideoEncoderInputFrameImpl*> ActiveFrames;
|
|
using UserManagedFrame = TPair<FVideoEncoderInputFrameImpl*, OnFrameReleasedCallback>;
|
|
TArray<UserManagedFrame> UserManagedFrames;
|
|
};
|
|
|
|
class FVideoEncoderInputFrameImpl : public FVideoEncoderInputFrame
|
|
{
|
|
public:
|
|
explicit FVideoEncoderInputFrameImpl(FVideoEncoderInputImpl* InInput);
|
|
FVideoEncoderInputFrameImpl(const FVideoEncoderInputFrameImpl& InCloneFrom) = delete;
|
|
explicit FVideoEncoderInputFrameImpl(const FVideoEncoderInputFrameImpl& InCloneFrom, FCloneDestroyedCallback InCloneDestroyedCallback);
|
|
~FVideoEncoderInputFrameImpl();
|
|
|
|
// Clone frame - this will create a copy that references the original until destroyed
|
|
const FVideoEncoderInputFrame* Clone(FCloneDestroyedCallback InCloneDestroyedCallback) const override;
|
|
|
|
// Release (decrease reference count) of this input frame
|
|
void Release() const override;
|
|
|
|
void SetFormat(EVideoFrameFormat InFormat) { Format = InFormat; }
|
|
void SetWidth(uint32 InWidth) { Width = InWidth; }
|
|
void SetHeight(uint32 InHeight) { Height = InHeight; }
|
|
|
|
private:
|
|
FVideoEncoderInputImpl* Input;
|
|
const FVideoEncoderInputFrame* ClonedReference = nullptr;
|
|
const FCloneDestroyedCallback OnCloneDestroyed;
|
|
};
|
|
|
|
} /* namespace AVEncoder */
|