generic telemetry
This commit is contained in:
@@ -42,16 +42,6 @@ struct VideoIOState
|
|||||||
bool keyerInterfaceAvailable = false;
|
bool keyerInterfaceAvailable = false;
|
||||||
bool externalKeyingActive = false;
|
bool externalKeyingActive = false;
|
||||||
double frameBudgetMilliseconds = 0.0;
|
double frameBudgetMilliseconds = 0.0;
|
||||||
bool actualDeckLinkBufferedFramesAvailable = false;
|
|
||||||
uint64_t actualDeckLinkBufferedFrames = 0;
|
|
||||||
double deckLinkScheduleCallMilliseconds = 0.0;
|
|
||||||
uint64_t deckLinkScheduleFailureCount = 0;
|
|
||||||
bool deckLinkScheduleLeadAvailable = false;
|
|
||||||
int64_t deckLinkPlaybackStreamTime = 0;
|
|
||||||
uint64_t deckLinkPlaybackFrameIndex = 0;
|
|
||||||
uint64_t deckLinkNextScheduleFrameIndex = 0;
|
|
||||||
int64_t deckLinkScheduleLeadFrames = 0;
|
|
||||||
uint64_t deckLinkScheduleRealignmentCount = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VideoIOFrame
|
struct VideoIOFrame
|
||||||
|
|||||||
@@ -72,17 +72,17 @@ DeckLinkOutputMetrics DeckLinkOutput::Metrics() const
|
|||||||
metrics.dropped = mDropped.load();
|
metrics.dropped = mDropped.load();
|
||||||
metrics.flushed = mFlushed.load();
|
metrics.flushed = mFlushed.load();
|
||||||
|
|
||||||
const VideoIOState& state = mSession.State();
|
const DeckLinkSessionTelemetry& telemetry = mSession.Telemetry();
|
||||||
metrics.scheduleFailures = state.deckLinkScheduleFailureCount;
|
metrics.scheduleFailures = telemetry.scheduleFailureCount;
|
||||||
metrics.actualBufferedFramesAvailable = state.actualDeckLinkBufferedFramesAvailable;
|
metrics.actualBufferedFramesAvailable = telemetry.actualBufferedFramesAvailable;
|
||||||
metrics.actualBufferedFrames = state.actualDeckLinkBufferedFrames;
|
metrics.actualBufferedFrames = telemetry.actualBufferedFrames;
|
||||||
metrics.scheduleCallMilliseconds = state.deckLinkScheduleCallMilliseconds;
|
metrics.scheduleCallMilliseconds = telemetry.scheduleCallMilliseconds;
|
||||||
metrics.scheduleLeadAvailable = state.deckLinkScheduleLeadAvailable;
|
metrics.scheduleLeadAvailable = telemetry.scheduleLeadAvailable;
|
||||||
metrics.playbackStreamTime = state.deckLinkPlaybackStreamTime;
|
metrics.playbackStreamTime = telemetry.playbackStreamTime;
|
||||||
metrics.playbackFrameIndex = state.deckLinkPlaybackFrameIndex;
|
metrics.playbackFrameIndex = telemetry.playbackFrameIndex;
|
||||||
metrics.nextScheduleFrameIndex = state.deckLinkNextScheduleFrameIndex;
|
metrics.nextScheduleFrameIndex = telemetry.nextScheduleFrameIndex;
|
||||||
metrics.scheduleLeadFrames = state.deckLinkScheduleLeadFrames;
|
metrics.scheduleLeadFrames = telemetry.scheduleLeadFrames;
|
||||||
metrics.scheduleRealignmentCount = state.deckLinkScheduleRealignmentCount;
|
metrics.scheduleRealignmentCount = telemetry.scheduleRealignmentCount;
|
||||||
return metrics;
|
return metrics;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -443,7 +443,7 @@ bool DeckLinkSession::ScheduleFrame(IDeckLinkMutableVideoFrame* outputVideoFrame
|
|||||||
{
|
{
|
||||||
if (outputVideoFrame == nullptr || output == nullptr)
|
if (outputVideoFrame == nullptr || output == nullptr)
|
||||||
{
|
{
|
||||||
++mState.deckLinkScheduleFailureCount;
|
++mTelemetry.scheduleFailureCount;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -459,9 +459,9 @@ bool DeckLinkSession::ScheduleFrame(IDeckLinkMutableVideoFrame* outputVideoFrame
|
|||||||
const auto scheduleStart = std::chrono::steady_clock::now();
|
const auto scheduleStart = std::chrono::steady_clock::now();
|
||||||
const HRESULT result = output->ScheduleVideoFrame(outputVideoFrame, scheduleTime.streamTime, scheduleTime.duration, scheduleTime.timeScale);
|
const HRESULT result = output->ScheduleVideoFrame(outputVideoFrame, scheduleTime.streamTime, scheduleTime.duration, scheduleTime.timeScale);
|
||||||
const auto scheduleEnd = std::chrono::steady_clock::now();
|
const auto scheduleEnd = std::chrono::steady_clock::now();
|
||||||
mState.deckLinkScheduleCallMilliseconds = std::chrono::duration_cast<std::chrono::duration<double, std::milli>>(scheduleEnd - scheduleStart).count();
|
mTelemetry.scheduleCallMilliseconds = std::chrono::duration_cast<std::chrono::duration<double, std::milli>>(scheduleEnd - scheduleStart).count();
|
||||||
if (result != S_OK)
|
if (result != S_OK)
|
||||||
++mState.deckLinkScheduleFailureCount;
|
++mTelemetry.scheduleFailureCount;
|
||||||
RefreshBufferedVideoFrameCount();
|
RefreshBufferedVideoFrameCount();
|
||||||
return result == S_OK;
|
return result == S_OK;
|
||||||
}
|
}
|
||||||
@@ -470,7 +470,7 @@ void DeckLinkSession::UpdateScheduleLeadTelemetry()
|
|||||||
{
|
{
|
||||||
if (output == nullptr)
|
if (output == nullptr)
|
||||||
{
|
{
|
||||||
mState.deckLinkScheduleLeadAvailable = false;
|
mTelemetry.scheduleLeadAvailable = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -478,7 +478,7 @@ void DeckLinkSession::UpdateScheduleLeadTelemetry()
|
|||||||
double playbackSpeed = 0.0;
|
double playbackSpeed = 0.0;
|
||||||
if (output->GetScheduledStreamTime(mScheduler.TimeScale(), &streamTime, &playbackSpeed) != S_OK || playbackSpeed <= 0.0)
|
if (output->GetScheduledStreamTime(mScheduler.TimeScale(), &streamTime, &playbackSpeed) != S_OK || playbackSpeed <= 0.0)
|
||||||
{
|
{
|
||||||
mState.deckLinkScheduleLeadAvailable = false;
|
mTelemetry.scheduleLeadAvailable = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -486,25 +486,25 @@ void DeckLinkSession::UpdateScheduleLeadTelemetry()
|
|||||||
? static_cast<uint64_t>(streamTime / mScheduler.FrameDuration())
|
? static_cast<uint64_t>(streamTime / mScheduler.FrameDuration())
|
||||||
: 0;
|
: 0;
|
||||||
const uint64_t nextScheduleFrameIndex = mScheduler.ScheduledFrameIndex();
|
const uint64_t nextScheduleFrameIndex = mScheduler.ScheduledFrameIndex();
|
||||||
mState.deckLinkScheduleLeadAvailable = true;
|
mTelemetry.scheduleLeadAvailable = true;
|
||||||
mState.deckLinkPlaybackStreamTime = streamTime;
|
mTelemetry.playbackStreamTime = streamTime;
|
||||||
mState.deckLinkPlaybackFrameIndex = playbackFrameIndex;
|
mTelemetry.playbackFrameIndex = playbackFrameIndex;
|
||||||
mState.deckLinkNextScheduleFrameIndex = nextScheduleFrameIndex;
|
mTelemetry.nextScheduleFrameIndex = nextScheduleFrameIndex;
|
||||||
mState.deckLinkScheduleLeadFrames = static_cast<int64_t>(nextScheduleFrameIndex) - static_cast<int64_t>(playbackFrameIndex);
|
mTelemetry.scheduleLeadFrames = static_cast<int64_t>(nextScheduleFrameIndex) - static_cast<int64_t>(playbackFrameIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeckLinkSession::MaybeRealignScheduleCursorForLowLead()
|
void DeckLinkSession::MaybeRealignScheduleCursorForLowLead()
|
||||||
{
|
{
|
||||||
if (!mState.deckLinkScheduleLeadAvailable)
|
if (!mTelemetry.scheduleLeadAvailable)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (mState.deckLinkScheduleLeadFrames >= kMinimumHealthyScheduleLeadFrames)
|
if (mTelemetry.scheduleLeadFrames >= kMinimumHealthyScheduleLeadFrames)
|
||||||
{
|
{
|
||||||
mProactiveScheduleRealignmentArmed = true;
|
mProactiveScheduleRealignmentArmed = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mProactiveScheduleRealignmentArmed || mState.deckLinkScheduleLeadFrames > kProactiveScheduleLeadFloorFrames)
|
if (!mProactiveScheduleRealignmentArmed || mTelemetry.scheduleLeadFrames > kProactiveScheduleLeadFloorFrames)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
RealignScheduleCursorToPlayback();
|
RealignScheduleCursorToPlayback();
|
||||||
@@ -523,7 +523,7 @@ void DeckLinkSession::RealignScheduleCursorToPlayback()
|
|||||||
|
|
||||||
const VideoPlayoutPolicy policy = NormalizeVideoPlayoutPolicy(mPlayoutPolicy);
|
const VideoPlayoutPolicy policy = NormalizeVideoPlayoutPolicy(mPlayoutPolicy);
|
||||||
mScheduler.AlignNextScheduleTimeToPlayback(streamTime, policy.targetPrerollFrames);
|
mScheduler.AlignNextScheduleTimeToPlayback(streamTime, policy.targetPrerollFrames);
|
||||||
++mState.deckLinkScheduleRealignmentCount;
|
++mTelemetry.scheduleRealignmentCount;
|
||||||
UpdateScheduleLeadTelemetry();
|
UpdateScheduleLeadTelemetry();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -593,19 +593,19 @@ void DeckLinkSession::RefreshBufferedVideoFrameCount()
|
|||||||
{
|
{
|
||||||
if (output == nullptr)
|
if (output == nullptr)
|
||||||
{
|
{
|
||||||
mState.actualDeckLinkBufferedFramesAvailable = false;
|
mTelemetry.actualBufferedFramesAvailable = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int bufferedFrameCount = 0;
|
unsigned int bufferedFrameCount = 0;
|
||||||
if (output->GetBufferedVideoFrameCount(&bufferedFrameCount) == S_OK)
|
if (output->GetBufferedVideoFrameCount(&bufferedFrameCount) == S_OK)
|
||||||
{
|
{
|
||||||
mState.actualDeckLinkBufferedFrames = bufferedFrameCount;
|
mTelemetry.actualBufferedFrames = bufferedFrameCount;
|
||||||
mState.actualDeckLinkBufferedFramesAvailable = true;
|
mTelemetry.actualBufferedFramesAvailable = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mState.actualDeckLinkBufferedFramesAvailable = false;
|
mTelemetry.actualBufferedFramesAvailable = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,20 @@
|
|||||||
|
|
||||||
class OpenGLComposite;
|
class OpenGLComposite;
|
||||||
|
|
||||||
|
struct DeckLinkSessionTelemetry
|
||||||
|
{
|
||||||
|
bool actualBufferedFramesAvailable = false;
|
||||||
|
uint64_t actualBufferedFrames = 0;
|
||||||
|
double scheduleCallMilliseconds = 0.0;
|
||||||
|
uint64_t scheduleFailureCount = 0;
|
||||||
|
bool scheduleLeadAvailable = false;
|
||||||
|
int64_t playbackStreamTime = 0;
|
||||||
|
uint64_t playbackFrameIndex = 0;
|
||||||
|
uint64_t nextScheduleFrameIndex = 0;
|
||||||
|
int64_t scheduleLeadFrames = 0;
|
||||||
|
uint64_t scheduleRealignmentCount = 0;
|
||||||
|
};
|
||||||
|
|
||||||
class DeckLinkSession
|
class DeckLinkSession
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -63,6 +77,7 @@ public:
|
|||||||
void SetStatusMessage(const std::string& message) { mState.statusMessage = message; }
|
void SetStatusMessage(const std::string& message) { mState.statusMessage = message; }
|
||||||
const VideoIOState& State() const { return mState; }
|
const VideoIOState& State() const { return mState; }
|
||||||
VideoIOState& MutableState() { return mState; }
|
VideoIOState& MutableState() { return mState; }
|
||||||
|
const DeckLinkSessionTelemetry& Telemetry() const { return mTelemetry; }
|
||||||
double FrameBudgetMilliseconds() const;
|
double FrameBudgetMilliseconds() const;
|
||||||
VideoPlayoutRecoveryDecision AccountForCompletionResult(VideoIOCompletionResult completionResult, uint64_t readyQueueDepth);
|
VideoPlayoutRecoveryDecision AccountForCompletionResult(VideoIOCompletionResult completionResult, uint64_t readyQueueDepth);
|
||||||
bool BeginOutputFrame(VideoIOOutputFrame& frame);
|
bool BeginOutputFrame(VideoIOOutputFrame& frame);
|
||||||
@@ -89,6 +104,7 @@ private:
|
|||||||
std::mutex mScheduledSystemFrameMutex;
|
std::mutex mScheduledSystemFrameMutex;
|
||||||
std::unordered_map<IDeckLinkVideoFrame*, void*> mScheduledSystemFrameBuffers;
|
std::unordered_map<IDeckLinkVideoFrame*, void*> mScheduledSystemFrameBuffers;
|
||||||
VideoIOState mState;
|
VideoIOState mState;
|
||||||
|
DeckLinkSessionTelemetry mTelemetry;
|
||||||
VideoPlayoutPolicy mPlayoutPolicy;
|
VideoPlayoutPolicy mPlayoutPolicy;
|
||||||
VideoPlayoutScheduler mScheduler;
|
VideoPlayoutScheduler mScheduler;
|
||||||
bool mScheduleRealignmentPending = false;
|
bool mScheduleRealignmentPending = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user