88 lines
1.9 KiB
C++
88 lines
1.9 KiB
C++
#pragma once
|
|
|
|
#include "DeckLinkInput.h"
|
|
|
|
#include <atomic>
|
|
#include <chrono>
|
|
#include <string>
|
|
#include <thread>
|
|
|
|
namespace RenderCadenceCompositor
|
|
{
|
|
struct DeckLinkInputThreadConfig
|
|
{
|
|
std::chrono::milliseconds idleSleep = std::chrono::milliseconds(100);
|
|
};
|
|
|
|
class DeckLinkInputThread
|
|
{
|
|
public:
|
|
DeckLinkInputThread(DeckLinkInput& input, DeckLinkInputThreadConfig config = DeckLinkInputThreadConfig()) :
|
|
mInput(input),
|
|
mConfig(config)
|
|
{
|
|
}
|
|
|
|
DeckLinkInputThread(const DeckLinkInputThread&) = delete;
|
|
DeckLinkInputThread& operator=(const DeckLinkInputThread&) = delete;
|
|
|
|
~DeckLinkInputThread()
|
|
{
|
|
Stop();
|
|
}
|
|
|
|
bool Start(std::string& error)
|
|
{
|
|
if (mThread.joinable())
|
|
return true;
|
|
mStartSucceeded.store(false, std::memory_order_release);
|
|
mStartCompleted.store(false, std::memory_order_release);
|
|
mStopping.store(false, std::memory_order_release);
|
|
mThread = std::thread([this]() { ThreadMain(); });
|
|
|
|
while (!mStartCompleted.load(std::memory_order_acquire))
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
|
|
|
if (mStartSucceeded.load(std::memory_order_acquire))
|
|
return true;
|
|
|
|
error = mStartError;
|
|
Stop();
|
|
return false;
|
|
}
|
|
|
|
void Stop()
|
|
{
|
|
mStopping.store(true, std::memory_order_release);
|
|
if (mThread.joinable())
|
|
mThread.join();
|
|
}
|
|
|
|
private:
|
|
void ThreadMain()
|
|
{
|
|
std::string error;
|
|
if (!mInput.Start(error))
|
|
{
|
|
mStartError = error;
|
|
mStartCompleted.store(true, std::memory_order_release);
|
|
return;
|
|
}
|
|
|
|
mStartSucceeded.store(true, std::memory_order_release);
|
|
mStartCompleted.store(true, std::memory_order_release);
|
|
while (!mStopping.load(std::memory_order_acquire))
|
|
std::this_thread::sleep_for(mConfig.idleSleep);
|
|
mInput.Stop();
|
|
}
|
|
|
|
DeckLinkInput& mInput;
|
|
DeckLinkInputThreadConfig mConfig;
|
|
std::thread mThread;
|
|
std::atomic<bool> mStopping{ false };
|
|
std::atomic<bool> mStartCompleted{ false };
|
|
std::atomic<bool> mStartSucceeded{ false };
|
|
std::string mStartError;
|
|
};
|
|
}
|