Clean up pass
This commit is contained in:
@@ -1,12 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "AppConfig.h"
|
||||
#include "AppConfigProvider.h"
|
||||
#include "../json/JsonWriter.h"
|
||||
#include "../logging/Logger.h"
|
||||
#include "../runtime/RuntimeShaderBridge.h"
|
||||
#include "../telemetry/CadenceTelemetryJson.h"
|
||||
#include "../telemetry/TelemetryPrinter.h"
|
||||
#include "../control/RuntimeStateJson.h"
|
||||
#include "../telemetry/TelemetryHealthMonitor.h"
|
||||
#include "../video/DeckLinkOutput.h"
|
||||
#include "../video/DeckLinkOutputThread.h"
|
||||
|
||||
@@ -55,7 +53,7 @@ public:
|
||||
mFrameExchange(frameExchange),
|
||||
mConfig(config),
|
||||
mOutputThread(mOutput, mFrameExchange, mConfig.outputThread),
|
||||
mTelemetry(mConfig.telemetry)
|
||||
mTelemetryHealth(mConfig.telemetry)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -69,18 +67,6 @@ public:
|
||||
|
||||
bool Start(std::string& error)
|
||||
{
|
||||
Log("app", "Initializing DeckLink output.");
|
||||
if (!mOutput.Initialize(
|
||||
mConfig.deckLink,
|
||||
[this](const VideoIOCompletion& completion) {
|
||||
mFrameExchange.ReleaseScheduledByBytes(completion.outputFrameBuffer);
|
||||
},
|
||||
error))
|
||||
{
|
||||
LogError("app", "DeckLink output initialization failed: " + error);
|
||||
return false;
|
||||
}
|
||||
|
||||
Log("app", "Starting render thread.");
|
||||
if (!detail::StartRenderThread(mRenderThread, error, 0))
|
||||
{
|
||||
@@ -99,33 +85,8 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
Log("app", "Starting DeckLink output thread.");
|
||||
if (!mOutputThread.Start())
|
||||
{
|
||||
error = "DeckLink output thread failed to start.";
|
||||
LogError("app", error);
|
||||
Stop();
|
||||
return false;
|
||||
}
|
||||
|
||||
Log("app", "Waiting for DeckLink preroll frames.");
|
||||
if (!WaitForPreroll())
|
||||
{
|
||||
error = "Timed out waiting for DeckLink preroll frames.";
|
||||
LogError("app", error);
|
||||
Stop();
|
||||
return false;
|
||||
}
|
||||
|
||||
Log("app", "Starting DeckLink scheduled playback.");
|
||||
if (!mOutput.StartScheduledPlayback(error))
|
||||
{
|
||||
LogError("app", "DeckLink scheduled playback failed: " + error);
|
||||
Stop();
|
||||
return false;
|
||||
}
|
||||
|
||||
mTelemetry.Start(mFrameExchange, mOutput, mOutputThread, mRenderThread);
|
||||
StartOptionalVideoOutput();
|
||||
mTelemetryHealth.Start(mFrameExchange, mOutput, mOutputThread, mRenderThread);
|
||||
StartHttpServer();
|
||||
Log("app", "RenderCadenceCompositor started.");
|
||||
mStarted = true;
|
||||
@@ -135,7 +96,7 @@ public:
|
||||
void Stop()
|
||||
{
|
||||
mHttpServer.Stop();
|
||||
mTelemetry.Stop();
|
||||
mTelemetryHealth.Stop();
|
||||
mOutputThread.Stop();
|
||||
mOutput.Stop();
|
||||
StopRuntimeShaderBuild();
|
||||
@@ -150,6 +111,58 @@ public:
|
||||
const DeckLinkOutput& Output() const { return mOutput; }
|
||||
|
||||
private:
|
||||
void StartOptionalVideoOutput()
|
||||
{
|
||||
std::string outputError;
|
||||
Log("app", "Initializing optional DeckLink output.");
|
||||
if (!mOutput.Initialize(
|
||||
mConfig.deckLink,
|
||||
[this](const VideoIOCompletion& completion) {
|
||||
mFrameExchange.ReleaseScheduledByBytes(completion.outputFrameBuffer);
|
||||
},
|
||||
outputError))
|
||||
{
|
||||
DisableVideoOutput("DeckLink output unavailable: " + outputError);
|
||||
return;
|
||||
}
|
||||
|
||||
Log("app", "Starting DeckLink output thread.");
|
||||
if (!mOutputThread.Start())
|
||||
{
|
||||
DisableVideoOutput("DeckLink output thread failed to start.");
|
||||
return;
|
||||
}
|
||||
|
||||
Log("app", "Waiting for DeckLink preroll frames.");
|
||||
if (!WaitForPreroll())
|
||||
{
|
||||
DisableVideoOutput("Timed out waiting for DeckLink preroll frames.");
|
||||
return;
|
||||
}
|
||||
|
||||
Log("app", "Starting DeckLink scheduled playback.");
|
||||
if (!mOutput.StartScheduledPlayback(outputError))
|
||||
{
|
||||
DisableVideoOutput("DeckLink scheduled playback failed: " + outputError);
|
||||
return;
|
||||
}
|
||||
|
||||
mVideoOutputEnabled = true;
|
||||
mVideoOutputStatus = "DeckLink scheduled output running.";
|
||||
Log("app", mVideoOutputStatus);
|
||||
}
|
||||
|
||||
void DisableVideoOutput(const std::string& reason)
|
||||
{
|
||||
mOutputThread.Stop();
|
||||
mOutput.Stop();
|
||||
mOutput.ReleaseResources();
|
||||
mFrameExchange.Clear();
|
||||
mVideoOutputEnabled = false;
|
||||
mVideoOutputStatus = reason;
|
||||
LogWarning("app", reason + " Continuing without video output.");
|
||||
}
|
||||
|
||||
void StartHttpServer()
|
||||
{
|
||||
HttpControlServerCallbacks callbacks;
|
||||
@@ -168,65 +181,13 @@ private:
|
||||
std::string BuildStateJson()
|
||||
{
|
||||
CadenceTelemetrySnapshot telemetry = mHttpTelemetry.Sample(mFrameExchange, mOutput, mOutputThread, mRenderThread);
|
||||
|
||||
JsonWriter writer;
|
||||
writer.BeginObject();
|
||||
writer.Key("app");
|
||||
writer.BeginObject();
|
||||
writer.KeyUInt("serverPort", mHttpServer.Port());
|
||||
writer.KeyUInt("oscPort", mConfig.oscPort);
|
||||
writer.KeyString("oscBindAddress", mConfig.oscBindAddress);
|
||||
writer.KeyDouble("oscSmoothing", mConfig.oscSmoothing);
|
||||
writer.KeyBool("autoReload", mConfig.autoReload);
|
||||
writer.KeyUInt("maxTemporalHistoryFrames", static_cast<uint64_t>(mConfig.maxTemporalHistoryFrames));
|
||||
writer.KeyDouble("previewFps", mConfig.previewFps);
|
||||
writer.KeyBool("enableExternalKeying", mConfig.deckLink.externalKeyingEnabled);
|
||||
writer.KeyString("inputVideoFormat", mConfig.inputVideoFormat);
|
||||
writer.KeyString("inputFrameRate", mConfig.inputFrameRate);
|
||||
writer.KeyString("outputVideoFormat", mConfig.outputVideoFormat);
|
||||
writer.KeyString("outputFrameRate", mConfig.outputFrameRate);
|
||||
writer.EndObject();
|
||||
|
||||
writer.Key("runtime");
|
||||
writer.BeginObject();
|
||||
writer.KeyUInt("layerCount", 0);
|
||||
writer.KeyBool("compileSucceeded", true);
|
||||
writer.KeyString("compileMessage", "Runtime state is not ported into RenderCadenceCompositor yet.");
|
||||
writer.EndObject();
|
||||
|
||||
writer.KeyNull("video");
|
||||
writer.KeyNull("decklink");
|
||||
writer.KeyNull("videoIO");
|
||||
|
||||
writer.Key("performance");
|
||||
writer.BeginObject();
|
||||
writer.KeyDouble("frameBudgetMs", FrameDurationMillisecondsFromRateString(mConfig.outputFrameRate));
|
||||
writer.KeyNull("renderMs");
|
||||
writer.KeyNull("smoothedRenderMs");
|
||||
writer.KeyNull("budgetUsedPercent");
|
||||
writer.KeyNull("completionIntervalMs");
|
||||
writer.KeyNull("smoothedCompletionIntervalMs");
|
||||
writer.KeyNull("maxCompletionIntervalMs");
|
||||
writer.KeyUInt("lateFrameCount", telemetry.displayedLate);
|
||||
writer.KeyUInt("droppedFrameCount", telemetry.dropped);
|
||||
writer.KeyNull("flushedFrameCount");
|
||||
writer.Key("cadence");
|
||||
WriteCadenceTelemetryJson(writer, telemetry);
|
||||
writer.EndObject();
|
||||
|
||||
writer.KeyNull("backendPlayout");
|
||||
writer.KeyNull("runtimeEvents");
|
||||
writer.Key("shaders");
|
||||
writer.BeginArray();
|
||||
writer.EndArray();
|
||||
writer.Key("stackPresets");
|
||||
writer.BeginArray();
|
||||
writer.EndArray();
|
||||
writer.Key("layers");
|
||||
writer.BeginArray();
|
||||
writer.EndArray();
|
||||
writer.EndObject();
|
||||
return writer.StringValue();
|
||||
return RuntimeStateToJson(RuntimeStateJsonInput{
|
||||
mConfig,
|
||||
telemetry,
|
||||
mHttpServer.Port(),
|
||||
mVideoOutputEnabled,
|
||||
mVideoOutputStatus
|
||||
});
|
||||
}
|
||||
|
||||
bool WaitForPreroll() const
|
||||
@@ -270,10 +231,12 @@ private:
|
||||
AppConfig mConfig;
|
||||
DeckLinkOutput mOutput;
|
||||
DeckLinkOutputThread<SystemFrameExchange> mOutputThread;
|
||||
TelemetryPrinter mTelemetry;
|
||||
TelemetryHealthMonitor mTelemetryHealth;
|
||||
CadenceTelemetry mHttpTelemetry;
|
||||
HttpControlServer mHttpServer;
|
||||
RuntimeShaderBridge mShaderBridge;
|
||||
bool mStarted = false;
|
||||
bool mVideoOutputEnabled = false;
|
||||
std::string mVideoOutputStatus = "DeckLink output not started.";
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user