V2 working
This commit is contained in:
89
apps/RenderCadenceCompositor/telemetry/CadenceTelemetry.h
Normal file
89
apps/RenderCadenceCompositor/telemetry/CadenceTelemetry.h
Normal file
@@ -0,0 +1,89 @@
|
||||
#pragma once
|
||||
|
||||
#include "../video/DeckLinkOutput.h"
|
||||
#include "../video/DeckLinkOutputThread.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
namespace RenderCadenceCompositor
|
||||
{
|
||||
struct CadenceTelemetrySnapshot
|
||||
{
|
||||
double sampleSeconds = 0.0;
|
||||
double renderFps = 0.0;
|
||||
double scheduleFps = 0.0;
|
||||
std::size_t freeFrames = 0;
|
||||
std::size_t completedFrames = 0;
|
||||
std::size_t scheduledFrames = 0;
|
||||
uint64_t renderedTotal = 0;
|
||||
uint64_t scheduledTotal = 0;
|
||||
uint64_t completedPollMisses = 0;
|
||||
uint64_t scheduleFailures = 0;
|
||||
uint64_t completions = 0;
|
||||
uint64_t displayedLate = 0;
|
||||
uint64_t dropped = 0;
|
||||
bool deckLinkBufferedAvailable = false;
|
||||
uint64_t deckLinkBuffered = 0;
|
||||
double deckLinkScheduleCallMilliseconds = 0.0;
|
||||
};
|
||||
|
||||
class CadenceTelemetry
|
||||
{
|
||||
public:
|
||||
template <typename SystemFrameExchange, typename OutputThread>
|
||||
CadenceTelemetrySnapshot Sample(
|
||||
const SystemFrameExchange& exchange,
|
||||
const DeckLinkOutput& output,
|
||||
const OutputThread& outputThread)
|
||||
{
|
||||
const auto now = Clock::now();
|
||||
const double seconds = mHasLastSample
|
||||
? std::chrono::duration_cast<std::chrono::duration<double>>(now - mLastSampleTime).count()
|
||||
: 0.0;
|
||||
|
||||
const auto exchangeMetrics = exchange.Metrics();
|
||||
const DeckLinkOutputMetrics outputMetrics = output.Metrics();
|
||||
const auto threadMetrics = outputThread.Metrics();
|
||||
|
||||
CadenceTelemetrySnapshot snapshot;
|
||||
snapshot.sampleSeconds = seconds;
|
||||
snapshot.renderedTotal = exchangeMetrics.completedFrames;
|
||||
snapshot.scheduledTotal = exchangeMetrics.scheduledFrames;
|
||||
snapshot.freeFrames = exchangeMetrics.freeCount;
|
||||
snapshot.completedFrames = exchangeMetrics.completedCount;
|
||||
snapshot.scheduledFrames = exchangeMetrics.scheduledCount;
|
||||
snapshot.completedPollMisses = threadMetrics.completedPollMisses;
|
||||
snapshot.scheduleFailures = outputMetrics.scheduleFailures > threadMetrics.scheduleFailures
|
||||
? outputMetrics.scheduleFailures
|
||||
: threadMetrics.scheduleFailures;
|
||||
snapshot.completions = outputMetrics.completions;
|
||||
snapshot.displayedLate = outputMetrics.displayedLate;
|
||||
snapshot.dropped = outputMetrics.dropped;
|
||||
snapshot.deckLinkBufferedAvailable = outputMetrics.actualBufferedFramesAvailable;
|
||||
snapshot.deckLinkBuffered = outputMetrics.actualBufferedFrames;
|
||||
snapshot.deckLinkScheduleCallMilliseconds = outputMetrics.scheduleCallMilliseconds;
|
||||
|
||||
if (mHasLastSample && seconds > 0.0)
|
||||
{
|
||||
snapshot.renderFps = static_cast<double>(snapshot.renderedTotal - mLastRenderedFrames) / seconds;
|
||||
snapshot.scheduleFps = static_cast<double>(snapshot.scheduledTotal - mLastScheduledFrames) / seconds;
|
||||
}
|
||||
|
||||
mLastSampleTime = now;
|
||||
mLastRenderedFrames = snapshot.renderedTotal;
|
||||
mLastScheduledFrames = snapshot.scheduledTotal;
|
||||
mHasLastSample = true;
|
||||
return snapshot;
|
||||
}
|
||||
|
||||
private:
|
||||
using Clock = std::chrono::steady_clock;
|
||||
|
||||
Clock::time_point mLastSampleTime = Clock::now();
|
||||
uint64_t mLastRenderedFrames = 0;
|
||||
uint64_t mLastScheduledFrames = 0;
|
||||
bool mHasLastSample = false;
|
||||
};
|
||||
}
|
||||
86
apps/RenderCadenceCompositor/telemetry/TelemetryPrinter.h
Normal file
86
apps/RenderCadenceCompositor/telemetry/TelemetryPrinter.h
Normal file
@@ -0,0 +1,86 @@
|
||||
#pragma once
|
||||
|
||||
#include "CadenceTelemetry.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
|
||||
namespace RenderCadenceCompositor
|
||||
{
|
||||
struct TelemetryPrinterConfig
|
||||
{
|
||||
std::chrono::milliseconds interval = std::chrono::seconds(1);
|
||||
};
|
||||
|
||||
class TelemetryPrinter
|
||||
{
|
||||
public:
|
||||
explicit TelemetryPrinter(TelemetryPrinterConfig config = TelemetryPrinterConfig()) :
|
||||
mConfig(config)
|
||||
{
|
||||
}
|
||||
|
||||
TelemetryPrinter(const TelemetryPrinter&) = delete;
|
||||
TelemetryPrinter& operator=(const TelemetryPrinter&) = delete;
|
||||
|
||||
~TelemetryPrinter()
|
||||
{
|
||||
Stop();
|
||||
}
|
||||
|
||||
template <typename SystemFrameExchange, typename OutputThread>
|
||||
void Start(const SystemFrameExchange& exchange, const DeckLinkOutput& output, const OutputThread& outputThread)
|
||||
{
|
||||
if (mRunning)
|
||||
return;
|
||||
mStopping = false;
|
||||
mThread = std::thread([this, &exchange, &output, &outputThread]() {
|
||||
CadenceTelemetry telemetry;
|
||||
while (!mStopping)
|
||||
{
|
||||
std::this_thread::sleep_for(mConfig.interval);
|
||||
Print(telemetry.Sample(exchange, output, outputThread));
|
||||
}
|
||||
});
|
||||
mRunning = true;
|
||||
}
|
||||
|
||||
void Stop()
|
||||
{
|
||||
mStopping = true;
|
||||
if (mThread.joinable())
|
||||
mThread.join();
|
||||
mRunning = false;
|
||||
}
|
||||
|
||||
private:
|
||||
static void Print(const CadenceTelemetrySnapshot& snapshot)
|
||||
{
|
||||
std::cout << std::fixed << std::setprecision(1)
|
||||
<< "renderFps=" << snapshot.renderFps
|
||||
<< " scheduleFps=" << snapshot.scheduleFps
|
||||
<< " free=" << snapshot.freeFrames
|
||||
<< " completed=" << snapshot.completedFrames
|
||||
<< " scheduled=" << snapshot.scheduledFrames
|
||||
<< " completedPollMisses=" << snapshot.completedPollMisses
|
||||
<< " scheduleFailures=" << snapshot.scheduleFailures
|
||||
<< " completions=" << snapshot.completions
|
||||
<< " late=" << snapshot.displayedLate
|
||||
<< " dropped=" << snapshot.dropped
|
||||
<< " decklinkBuffered=";
|
||||
if (snapshot.deckLinkBufferedAvailable)
|
||||
std::cout << snapshot.deckLinkBuffered;
|
||||
else
|
||||
std::cout << "n/a";
|
||||
std::cout << " scheduleCallMs=" << snapshot.deckLinkScheduleCallMilliseconds << "\n";
|
||||
}
|
||||
|
||||
TelemetryPrinterConfig mConfig;
|
||||
std::thread mThread;
|
||||
std::atomic<bool> mStopping{ false };
|
||||
std::atomic<bool> mRunning{ false };
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user