NDI discovery
This commit is contained in:
@@ -148,11 +148,6 @@ bool NdiOutput::Initialize(const VideoOutputEdgeConfig& config, CompletionCallba
|
||||
return false;
|
||||
}
|
||||
|
||||
if (config.outputAlphaRequired)
|
||||
{
|
||||
mState.statusMessage = "NDI output can carry BGRA alpha when configured; output.keying.alphaRequired is a DeckLink-only requirement.";
|
||||
}
|
||||
|
||||
if (!AcquireNdiRuntime())
|
||||
{
|
||||
error = "NDI runtime initialization failed. The CPU/runtime might not support NDI.";
|
||||
@@ -175,6 +170,8 @@ bool NdiOutput::Initialize(const VideoOutputEdgeConfig& config, CompletionCallba
|
||||
|
||||
mInitialized.store(true, std::memory_order_release);
|
||||
mState.statusMessage = "NDI output sender '" + mSenderName + "' initialized.";
|
||||
if (config.outputAlphaRequired)
|
||||
mState.statusMessage += " Output alpha is enabled; external keying is ignored for NDI.";
|
||||
Log("ndi-output", mState.statusMessage);
|
||||
return true;
|
||||
}
|
||||
|
||||
72
src/video/ndi/NdiSourceDiscovery.cpp
Normal file
72
src/video/ndi/NdiSourceDiscovery.cpp
Normal file
@@ -0,0 +1,72 @@
|
||||
#include "NdiSourceDiscovery.h"
|
||||
|
||||
#include "NdiRuntime.h"
|
||||
|
||||
#include <Processing.NDI.Lib.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <utility>
|
||||
|
||||
namespace RenderCadenceCompositor
|
||||
{
|
||||
bool DiscoverNdiSources(std::vector<NdiSourceInfo>& sources, std::string& error, uint32_t waitMilliseconds)
|
||||
{
|
||||
sources.clear();
|
||||
if (!AcquireNdiRuntime())
|
||||
{
|
||||
error = "NDI runtime initialization failed. The CPU/runtime might not support NDI.";
|
||||
return false;
|
||||
}
|
||||
|
||||
NDIlib_find_create_t settings;
|
||||
std::memset(&settings, 0, sizeof(settings));
|
||||
settings.show_local_sources = true;
|
||||
|
||||
NDIlib_find_instance_t finder = NDIlib_find_create_v2(&settings);
|
||||
if (finder == nullptr)
|
||||
{
|
||||
ReleaseNdiRuntime();
|
||||
error = "NDI source finder creation failed.";
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t sourceCount = 0;
|
||||
const NDIlib_source_t* ndiSources = NDIlib_find_get_current_sources(finder, &sourceCount);
|
||||
if (sourceCount == 0 && waitMilliseconds > 0)
|
||||
{
|
||||
NDIlib_find_wait_for_sources(finder, waitMilliseconds);
|
||||
ndiSources = NDIlib_find_get_current_sources(finder, &sourceCount);
|
||||
}
|
||||
|
||||
if (ndiSources != nullptr)
|
||||
{
|
||||
sources.reserve(sourceCount);
|
||||
for (uint32_t index = 0; index < sourceCount; ++index)
|
||||
{
|
||||
const char* name = ndiSources[index].p_ndi_name;
|
||||
if (name == nullptr || name[0] == '\0')
|
||||
continue;
|
||||
|
||||
NdiSourceInfo source;
|
||||
source.name = name;
|
||||
if (ndiSources[index].p_url_address != nullptr)
|
||||
source.urlAddress = ndiSources[index].p_url_address;
|
||||
sources.push_back(std::move(source));
|
||||
}
|
||||
}
|
||||
|
||||
NDIlib_find_destroy(finder);
|
||||
ReleaseNdiRuntime();
|
||||
|
||||
std::sort(sources.begin(), sources.end(), [](const NdiSourceInfo& lhs, const NdiSourceInfo& rhs) {
|
||||
return lhs.name < rhs.name;
|
||||
});
|
||||
sources.erase(std::unique(sources.begin(), sources.end(), [](const NdiSourceInfo& lhs, const NdiSourceInfo& rhs) {
|
||||
return lhs.name == rhs.name;
|
||||
}), sources.end());
|
||||
|
||||
error.clear();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
16
src/video/ndi/NdiSourceDiscovery.h
Normal file
16
src/video/ndi/NdiSourceDiscovery.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace RenderCadenceCompositor
|
||||
{
|
||||
struct NdiSourceInfo
|
||||
{
|
||||
std::string name;
|
||||
std::string urlAddress;
|
||||
};
|
||||
|
||||
bool DiscoverNdiSources(std::vector<NdiSourceInfo>& sources, std::string& error, uint32_t waitMilliseconds = 250);
|
||||
}
|
||||
Reference in New Issue
Block a user