libpromeki 1.0.0-alpha
PROfessional MEdia toolKIt
 
Loading...
Searching...
No Matches
pacinggate.h
Go to the documentation of this file.
1
8#pragma once
9
10
11#include <promeki/config.h>
12#if PROMEKI_ENABLE_CORE
13#include <promeki/namespace.h>
14#include <promeki/clock.h>
15#include <promeki/duration.h>
16#include <promeki/error.h>
18
19PROMEKI_NAMESPACE_BEGIN
20
30enum class PacingVerdict {
32 OnTime,
36 Late,
40 Skip,
44 Reanchor,
45};
46
51struct PacingResult {
53 PacingVerdict verdict = PacingVerdict::OnTime;
54
65 Duration slack;
66
77 int skippedTicks = 0;
78
89 Error error = Error::Ok;
90};
91
143class PacingGate {
144 public:
146 static constexpr int DefaultReanchorMultiple = 8;
147
149 PacingGate() = default;
150
156 explicit PacingGate(const Clock::Ptr &clock, const Duration &period = Duration::zero());
157
158 // ---- Configuration ----
159
170 void setClock(const Clock::Ptr &clock);
171
173 const Clock::Ptr &clock() const { return _clock; }
174
176 bool hasClock() const { return _clock.isValid(); }
177
191 void setPeriod(const Duration &period);
192
194 const Duration &period() const { return _period; }
195
203 void setSkipThreshold(const Duration &t);
204
206 const Duration &skipThreshold() const { return _skipThreshold; }
207
216 void setReanchorThreshold(const Duration &t);
217
219 const Duration &reanchorThreshold() const { return _reanchorThreshold; }
220
229 void rearm();
230
231 // ---- Wait ----
232
257 PacingResult wait(const Duration &advance);
258
263 PacingResult wait() { return wait(_period); }
264
300 bool tryAcquire(const Duration &advance);
301
306 bool tryAcquire() { return tryAcquire(_period); }
307
308 // ---- Telemetry ----
309
311 int64_t ticksOnTime() const { return _ticksOnTime; }
312
314 int64_t ticksLate() const { return _ticksLate; }
315
317 int64_t ticksSkipped() const { return _ticksSkipped; }
318
320 int64_t reanchors() const { return _reanchors; }
321
323 int64_t tryAcquireRejected() const { return _tryAcquireRejected; }
324
326 bool isArmed() const { return _armed; }
327
336 const MediaTimeStamp &anchor() const { return _anchor; }
337
339 const Duration &accumulated() const { return _accumulated; }
340
341 private:
342 Clock::Ptr _clock;
343 // _period defaults to zero so the documented
344 // "defaults to zero — the no-arg @ref wait is a
345 // no-op" contract still holds for callers that
346 // don't supply a period at construction.
347 Duration _period = Duration::zero();
348 Duration _skipThreshold = Duration::zero();
349 Duration _reanchorThreshold = Duration::zero();
350 MediaTimeStamp _anchor;
351 // _accumulated is incremented per wait() — start at
352 // an explicit zero so the first += produces a valid
353 // sum (rather than invalid + valid = invalid).
354 Duration _accumulated = Duration::zero();
355 bool _armed = false;
356 bool _customSkipThreshold = false;
357 bool _customReanchorThreshold = false;
358 int64_t _ticksOnTime = 0;
359 int64_t _ticksLate = 0;
360 int64_t _ticksSkipped = 0;
361 int64_t _reanchors = 0;
362 int64_t _tryAcquireRejected = 0;
363};
364
365PROMEKI_NAMESPACE_END
366
367#endif // PROMEKI_ENABLE_CORE