Phase 7 step 1
All checks were successful
CI / React UI Build (push) Successful in 10s
CI / Native Windows Build And Tests (push) Successful in 2m47s
CI / Windows Release Package (push) Successful in 2m53s

This commit is contained in:
Aiden
2026-05-11 20:39:01 +10:00
parent 0da6ad6802
commit 6b0638336a
7 changed files with 374 additions and 16 deletions

View File

@@ -26,46 +26,86 @@ void VideoBackend::ReleaseResources()
{
if (mVideoIODevice)
mVideoIODevice->ReleaseResources();
if (!VideoBackendLifecycle::CanTransition(mLifecycle.State(), VideoBackendLifecycleState::Stopped))
ApplyLifecycleFailure("Video backend resources released before lifecycle completed.");
ApplyLifecycleTransition(VideoBackendLifecycleState::Stopped, "Video backend resources released.");
}
VideoBackendLifecycleState VideoBackend::LifecycleState() const
{
return mLifecycle.State();
}
bool VideoBackend::DiscoverDevicesAndModes(const VideoFormatSelection& videoModes, std::string& error)
{
return mVideoIODevice->DiscoverDevicesAndModes(videoModes, error);
ApplyLifecycleTransition(VideoBackendLifecycleState::Discovering, "Discovering video backend devices and modes.");
if (mVideoIODevice->DiscoverDevicesAndModes(videoModes, error))
return ApplyLifecycleTransition(VideoBackendLifecycleState::Discovered, "Video backend devices and modes discovered.");
ApplyLifecycleFailure(error.empty() ? "Video backend discovery failed." : error);
return false;
}
bool VideoBackend::SelectPreferredFormats(const VideoFormatSelection& videoModes, bool outputAlphaRequired, std::string& error)
{
return mVideoIODevice->SelectPreferredFormats(videoModes, outputAlphaRequired, error);
ApplyLifecycleTransition(VideoBackendLifecycleState::Configuring, "Selecting preferred video backend formats.");
if (mVideoIODevice->SelectPreferredFormats(videoModes, outputAlphaRequired, error))
return true;
ApplyLifecycleFailure(error.empty() ? "Video backend format selection failed." : error);
return false;
}
bool VideoBackend::ConfigureInput(const VideoFormat& inputVideoMode, std::string& error)
{
return mVideoIODevice->ConfigureInput(
if (mLifecycle.State() != VideoBackendLifecycleState::Configuring)
ApplyLifecycleTransition(VideoBackendLifecycleState::Configuring, "Configuring video backend input.");
if (!mVideoIODevice->ConfigureInput(
[this](const VideoIOFrame& frame) { HandleInputFrame(frame); },
inputVideoMode,
error);
error))
{
ApplyLifecycleFailure(error.empty() ? "Video backend input configuration failed." : error);
return false;
}
return true;
}
bool VideoBackend::ConfigureOutput(const VideoFormat& outputVideoMode, bool externalKeyingEnabled, std::string& error)
{
return mVideoIODevice->ConfigureOutput(
if (mLifecycle.State() != VideoBackendLifecycleState::Configuring)
ApplyLifecycleTransition(VideoBackendLifecycleState::Configuring, "Configuring video backend output.");
if (!mVideoIODevice->ConfigureOutput(
[this](const VideoIOCompletion& completion) { HandleOutputFrameCompletion(completion); },
outputVideoMode,
externalKeyingEnabled,
error);
error))
{
ApplyLifecycleFailure(error.empty() ? "Video backend output configuration failed." : error);
return false;
}
return ApplyLifecycleTransition(VideoBackendLifecycleState::Configured, "Video backend configured.");
}
bool VideoBackend::Start()
{
ApplyLifecycleTransition(VideoBackendLifecycleState::Prerolling, "Video backend preroll starting.");
const bool started = mVideoIODevice->Start();
PublishBackendStateChanged(started ? "started" : "start-failed", started ? "Video backend started." : StatusMessage());
if (started)
ApplyLifecycleTransition(VideoBackendLifecycleState::Running, "Video backend started.");
else
ApplyLifecycleFailure(StatusMessage().empty() ? "Video backend start failed." : StatusMessage());
return started;
}
bool VideoBackend::Stop()
{
ApplyLifecycleTransition(VideoBackendLifecycleState::Stopping, "Video backend stopping.");
const bool stopped = mVideoIODevice->Stop();
PublishBackendStateChanged(stopped ? "stopped" : "stop-failed", stopped ? "Video backend stopped." : StatusMessage());
if (stopped)
ApplyLifecycleTransition(VideoBackendLifecycleState::Stopped, "Video backend stopped.");
else
ApplyLifecycleFailure(StatusMessage().empty() ? "Video backend stop failed." : StatusMessage());
return stopped;
}
@@ -198,7 +238,7 @@ void VideoBackend::PublishStatus(bool externalKeyingConfigured, const std::strin
externalKeyingConfigured,
ExternalKeyingActive(),
StatusMessage());
PublishBackendStateChanged("status", StatusMessage());
PublishBackendStateChanged(VideoBackendLifecycle::StateName(mLifecycle.State()), StatusMessage());
}
void VideoBackend::ReportNoInputDeviceSignalStatus()
@@ -240,7 +280,7 @@ void VideoBackend::HandleOutputFrameCompletion(const VideoIOCompletion& completi
AccountForCompletionResult(completion.result);
if (!rendered)
{
PublishBackendStateChanged("output-render-failed", "Output frame render request failed; skipping schedule for this frame.");
ApplyLifecycleTransition(VideoBackendLifecycleState::Degraded, "Output frame render request failed; skipping schedule for this frame.");
return;
}
@@ -283,6 +323,32 @@ void VideoBackend::RecordFramePacing(VideoIOCompletionResult completionResult)
PublishTimingSample("VideoBackend", "smoothedCompletionInterval", mSmoothedCompletionIntervalMilliseconds, "ms");
}
bool VideoBackend::ApplyLifecycleTransition(VideoBackendLifecycleState state, const std::string& message)
{
const VideoBackendLifecycleTransition transition = mLifecycle.TransitionTo(state, message);
if (!transition.accepted)
{
PublishBackendStateChanged(VideoBackendLifecycle::StateName(transition.current), transition.errorMessage);
return false;
}
PublishBackendStateChanged(VideoBackendLifecycle::StateName(transition.current), message);
return true;
}
bool VideoBackend::ApplyLifecycleFailure(const std::string& message)
{
const VideoBackendLifecycleTransition transition = mLifecycle.Fail(message);
if (!transition.accepted)
{
PublishBackendStateChanged(VideoBackendLifecycle::StateName(transition.current), transition.errorMessage);
return false;
}
PublishBackendStateChanged(VideoBackendLifecycle::StateName(transition.current), message);
return true;
}
void VideoBackend::PublishBackendStateChanged(const std::string& state, const std::string& message)
{
try