Fix building Image_NDI when Portaudio is not available

This commit is contained in:
Emmanuel Durand
2025-10-15 10:31:29 -04:00
parent 01ec82d79d
commit 9be552b42e
2 changed files with 27 additions and 2 deletions
+18
View File
@@ -11,7 +11,9 @@
#include <windows.h>
#endif
#if HAVE_PORTAUDIO
#include "./sound/speaker.h"
#endif
#include "./utils/log.h"
#include "./utils/ndi_loader.h"
#include "./utils/resizable_array.h"
@@ -50,8 +52,10 @@ Image_NDI::~Image_NDI()
_receive = false;
if (_recvThread.joinable())
_recvThread.join();
#if HAVE_PORTAUDIO
if (_audioThread.joinable())
_audioThread.join();
#endif
if (Utils::getNDILib()->lib)
Utils::getNDILib()->lib->recv_destroy(_ndiReceiver);
@@ -79,8 +83,10 @@ bool Image_NDI::connectByName(std::string_view name)
_receive = false;
if (_recvThread.joinable())
_recvThread.join();
#if HAVE_PORTAUDIO
if (_audioThread.joinable())
_audioThread.join();
#endif
// Connect to the source
std::unique_lock<std::mutex> lock(_ndiSourcesMutex);
@@ -100,8 +106,10 @@ bool Image_NDI::connectByName(std::string_view name)
}
lock.unlock();
#if HAVE_PORTAUDIO
// Run the audio loop
_audioThread = std::thread([&]() { audioLoop(); });
#endif
// Run a thread to grab audio and video frames
_receive = true;
@@ -109,11 +117,16 @@ bool Image_NDI::connectByName(std::string_view name)
while (_receive)
{
NDIlib_video_frame_v2_t videoFrame;
#if HAVE_PORTAUDIO
NDIlib_audio_frame_v3_t audioFrame;
switch (Utils::getNDILib()->lib->recv_capture_v3(_ndiReceiver, &videoFrame, &audioFrame, nullptr, 1000))
#else
switch (Utils::getNDILib()->lib->recv_capture_v3(_ndiReceiver, &videoFrame, nullptr, nullptr, 1000))
#endif
{
default:
break;
#if HAVE_PORTAUDIO
case NDIlib_frame_type_audio:
{
const auto timing = audioFrame.timecode;
@@ -154,6 +167,7 @@ bool Image_NDI::connectByName(std::string_view name)
_audioQueue.push_back(std::move(timedFrame));
break;
}
#endif
case NDIlib_frame_type_video:
{
auto readBuffer = readNDIVideoFrame(videoFrame);
@@ -439,6 +453,7 @@ void Image_NDI::findNDISources()
_ndiSources.swap(ndiSources);
}
#if HAVE_PORTAUDIO
/*************/
void Image_NDI::audioLoop()
{
@@ -463,6 +478,7 @@ void Image_NDI::audioLoop()
}
}
}
#endif
/*************/
void Image_NDI::registerAttributes()
@@ -501,6 +517,7 @@ void Image_NDI::registerAttributes()
addAttribute("NDI®", [&]() -> Values { return {"https://ndi.video"}; });
setAttributeDescription("NDI®", "Link to NDI® website\nNDI® is a registered trademark of Vizrt NDI AB");
#if HAVE_PORTAUDIO
addAttribute(
"audioDeviceOutput",
[&](const Values& args) {
@@ -510,6 +527,7 @@ void Image_NDI::registerAttributes()
[&]() -> Values { return {_audioDeviceOutput}; },
{'s'});
setAttributeDescription("audioDeviceOutput", "Name of the audio device to send the audio to");
#endif
}
} // namespace Splash
+9 -2
View File
@@ -25,7 +25,6 @@
#ifndef SPLASH_IMAGE_NDI2_H
#define SPLASH_IMAGE_NDI2_H
#include <cstddef>
#include <mutex>
#include <string>
#include <string_view>
@@ -34,7 +33,11 @@
#include <Processing.NDI.Lib.h>
#include "./config.h"
#include "./image/image.h"
#if HAVE_PORTAUDIO
#include "./sound/speaker.h"
#endif
namespace Splash
{
@@ -73,8 +76,8 @@ class Image_NDI final : public Image
std::mutex _recvMutex;
bool _receive = false;
std::thread _recvThread;
std::thread _audioThread;
#if HAVE_PORTAUDIO
struct TimedAudioFrame
{
ResizableArray<uint8_t> frame{};
@@ -84,6 +87,8 @@ class Image_NDI final : public Image
std::deque<TimedAudioFrame> _audioQueue;
std::string _audioDeviceOutput{""};
std::unique_ptr<Speaker> _speaker;
std::thread _audioThread;
#endif
/**
* Connect to an existing NDI source by its name
@@ -104,10 +109,12 @@ class Image_NDI final : public Image
*/
void findNDISources();
#if HAVE_PORTAUDIO
/**
* Audio loop
*/
void audioLoop();
#endif
/**
* Register new functors to modify attributes