Added ndi receiver and sdi outputs

This commit is contained in:
mchara40
2025-08-25 13:16:29 +03:00
parent 11b8be19f6
commit d046828313
125 changed files with 14757 additions and 0 deletions

View File

@@ -0,0 +1,109 @@
/*
Copyright (C) 2024 Vizrt NDI AB. All rights reserved.
This file and its use within a Product is bound by the terms of NDI SDK license that was provided
as part of the NDI SDK. For more information, please review the license and the NDI SDK documentation.
*/
#pragma once
#include <CoreMinimal.h>
#include <Engine/TextureRenderTarget2D.h>
#include <AudioDevice.h>
#include <Misc/EngineVersionComparison.h>
#if (ENGINE_MAJOR_VERSION > 5) || ((ENGINE_MAJOR_VERSION == 5) && (ENGINE_MINOR_VERSION >= 3)) // 5.3 or later
#include <ISubmixBufferListener.h>
#endif
#include <Widgets/SWindow.h>
DECLARE_EVENT_OneParam(FNDICoreDelegates, FNDIConnectionServiceSendVideoEvent, int64)
DECLARE_EVENT_SixParams(FNDICoreDelegates, FNDIConnectionServiceSendAudioEvent, int64, float*, int32, int32, const int32, double)
/**
A service which runs and triggers updates for interested parties to be notified of
Audio and Video Frame events
*/
class NDIIO_API FNDIConnectionService final : public ISubmixBufferListener
{
public:
static FNDIConnectionServiceSendVideoEvent EventOnSendVideoFrame;
private:
static TMap<USoundSubmix*, FNDIConnectionServiceSendAudioEvent> SubmixSendAudioFrameEvents;
public:
/**
Constructs a new instance of this object
*/
FNDIConnectionService();
// Begin the service
bool Start();
// Stop the service
void Shutdown();
bool BeginBroadcastingActiveViewport();
void StopBroadcastingActiveViewport();
bool IsRunningInPIE() const
{
return bIsInPIEMode;
}
template <typename UserClass>
static void AddAudioSender(UserClass* InUserObject, USoundSubmix* Submix, typename TMemFunPtrType<false, UserClass, void (int64 /*time_code*/, float* /*AudioData*/, int32 /*NumSamples*/, int32 /*NumChannels*/, const int32 /*SampleRate*/, double /*AudioClock*/)>::Type InFunc)
{
FScopeLock Lock(&AudioSyncContext);
FNDIConnectionServiceSendAudioEvent& SendAudioEvent = SubmixSendAudioFrameEvents.FindOrAdd(Submix);
SendAudioEvent.AddUObject(InUserObject, InFunc);
}
template <typename UserClass>
static void RemoveAudioSender(UserClass* InUserObject)
{
FScopeLock Lock(&AudioSyncContext);
for (auto it = SubmixSendAudioFrameEvents.CreateIterator(); it; ++it)
{
it->Value.RemoveAll(InUserObject);
if (it->Value.IsBound() == false)
it.RemoveCurrent();
}
}
private:
// Handler for when the render thread frame has ended
void OnEndRenderFrame();
void BeginAudioCapture();
void StopAudioCapture();
void OnPostEngineInit();
void OnEnginePreExit();
// Handler for when the active viewport back buffer is about to be resized
void OnActiveViewportBackbufferPreResize(void* Backbuffer);
// Handler for when the back buffer is read to present to the end user
void OnActiveViewportBackbufferReadyToPresent(SWindow& Window, const FTextureRHIRef& Backbuffer);
FTextureResource* GetVideoTextureResource() const;
virtual void OnNewSubmixBuffer(const USoundSubmix* OwningSubmix, float* AudioData, int32 NumSamples, int32 NumChannels, const int32 SampleRate, double AudioClock) override final;
#if (ENGINE_MAJOR_VERSION > 5) || ((ENGINE_MAJOR_VERSION == 5) && (ENGINE_MINOR_VERSION >= 4)) // 5.4 or later
virtual const FString& GetListenerName() const override final;
#endif
private:
bool bIsInitialized = false;
bool bIsAudioInitialized = false;
bool bIsBroadcastingActiveViewport = false;
bool bIsInPIEMode = false;
static FCriticalSection AudioSyncContext;
static FCriticalSection RenderSyncContext;
UTextureRenderTarget2D* VideoTexture = nullptr;
class UNDIMediaSender* ActiveViewportSender = nullptr;
};

View File

@@ -0,0 +1,62 @@
/*
Copyright (C) 2024 Vizrt NDI AB. All rights reserved.
This file and its use within a Product is bound by the terms of NDI SDK license that was provided
as part of the NDI SDK. For more information, please review the license and the NDI SDK documentation.
*/
#pragma once
#include <CoreMinimal.h>
#include <HAL/Runnable.h>
#include <HAL/ThreadSafeBool.h>
#include <Structures/NDIConnectionInformation.h>
/**
A Runnable object used for Finding NDI network Sources, and updating interested parties
*/
class NDIIO_API FNDIFinderService : public FRunnable
{
public:
FNDIFinderService();
// Begin the service
virtual bool Start();
// Stop the service
virtual void Shutdown();
public:
/** Get the available sources on the network */
static const TArray<FNDIConnectionInformation> GetNetworkSourceCollection();
/** Call to update an existing collection of network sources to match the current collection */
static bool UpdateSourceCollection(TArray<FNDIConnectionInformation>& InSourceCollection);
/** Event which is triggered when the collection of network sources has changed */
DECLARE_EVENT(FNDICoreDelegates, FNDISourceCollectionChangedEvent)
static FNDISourceCollectionChangedEvent EventOnNDISourceCollectionChanged;
protected:
/** FRunnable Interface implementation for 'Init' */
virtual bool Init() override;
/** FRunnable Interface implementation for 'Stop' */
virtual void Stop() override;
/** FRunnable Interface implementation for 'Run' */
virtual uint32 Run() override;
private:
bool UpdateNetworkSourceCollection();
private:
bool bShouldWaitOneFrame = true;
bool bIsNetworkSourceCollectionDirty = false;
FThreadSafeBool bIsThreadRunning;
FRunnableThread* p_RunnableThread = nullptr;
static TArray<FNDIConnectionInformation> NetworkSourceCollection;
};