Files
UnrealEngineUWP/Engine/Plugins/Media/HardwareEncoders/Source/EncoderAMF/Private/Amf_EncoderH264.h
William Belcher 24ba7c4cc9 Merge /UE5/Dev-Tensorworks to /UE5/Main. This includes:
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]
2022-02-10 21:16:24 -05:00

99 lines
2.9 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "Amf_Common.h"
#include "HAL/Thread.h"
#include "HAL/Event.h"
#include "VideoEncoderFactory.h"
#include "VideoEncoderInputImpl.h"
namespace AVEncoder
{
using namespace amf;
class FVideoEncoderAmf_H264 : public FVideoEncoder
{
public:
virtual ~FVideoEncoderAmf_H264() override;
// query whether or not encoder is supported and available
static bool GetIsAvailable(FVideoEncoderInputImpl &InInput, FVideoEncoderInfo &OutEncoderInfo);
// register encoder with video encoder factory
static void Register(FVideoEncoderFactory &InFactory);
bool Setup(TSharedRef<FVideoEncoderInput> input, FLayerConfig const& config) override;
void Encode(const TSharedPtr<FVideoEncoderInputFrame> frame, FEncodeOptions const& options) override;
void Flush();
void Shutdown() override;
protected:
FLayer* CreateLayer(uint32 layerIdx, FLayerConfig const& config) override;
void DestroyLayer(FLayer *layer) override;
private:
FVideoEncoderAmf_H264();
class FAMFLayer : public FLayer
{
public:
class FInputOutput
{
public:
void* TextureToCompress;
AMFSurfacePtr Surface;
};
FAMFLayer(uint32 layerIdx, FLayerConfig const& config, FVideoEncoderAmf_H264& encoder);
~FAMFLayer();
bool Setup();
bool CreateSession();
bool CreateInitialConfig();
void UpdateConfig();
template<class T>
bool GetProperty(const TCHAR* PropertyToQuery, T& outProperty, const T& (*func)(const AMFVariantStruct*)) const;
template<class T>
bool GetCapability(const TCHAR* CapToQuery, T& OutCap) const;
AMF_RESULT Encode(const TSharedPtr<FVideoEncoderInputFrameImpl> frame, FEncodeOptions const& options);
void Flush();
void Shutdown();
void UpdateBitrate(uint32 InMaxBitRate, uint32 InTargetBitRate);
void UpdateResolution(uint32 InMaxBitRate, uint32 InTargetBitRate);
void MaybeReconfigure();
void ProcessFrameBlocking();
TSharedPtr<FInputOutput> GetOrCreateSurface(const TSharedPtr<FVideoEncoderInputFrameImpl> InFrame);
bool CreateSurface(TSharedPtr<FInputOutput>& OutBuffer, const TSharedPtr<FVideoEncoderInputFrameImpl> SourceFrame, void* TextureToCompress);
FVideoEncoderAmf_H264& Encoder;
FAmfCommon& Amf;
uint32 LayerIndex;
AMFComponentPtr AmfEncoder = NULL;
FDateTime LastKeyFrameTime = 0;
bool bForceNextKeyframe = false;
TArray<TSharedPtr<FInputOutput>> CreatedSurfaces;
FThreadSafeBool bUpdateConfig = false;
uint32 CurrentWidth;
uint32 CurrentHeight;
uint32 CurrentFrameRate;
FThreadSafeBool bIsProcessingFrame = false;
};
FAmfCommon& Amf;
EVideoFrameFormat FrameFormat = EVideoFrameFormat::Undefined;
void* EncoderDevice;
uint32 MaxFramerate = 0;
amf_int64 MinQP = -1;
RateControlMode RateMode = RateControlMode::CBR;
bool FillData = false;
};
}