11#include <promeki/config.h>
12#if PROMEKI_ENABLE_PROAV
35PROMEKI_NAMESPACE_BEGIN
99 enum class InputOverflowPolicy {
126 FrameNumber frameIndex{0};
130 FrameCount framesRepeated{0};
134 FrameCount framesDropped{0};
147 explicit FrameSync(
const String &name);
152 FrameSync(
const FrameSync &) =
delete;
153 FrameSync &operator=(
const FrameSync &) =
delete;
154 FrameSync(FrameSync &&) =
delete;
155 FrameSync &operator=(FrameSync &&) =
delete;
158 void setName(
const String &name) { _name = name; }
161 const String &name()
const {
return _name; }
170 void setTargetFrameRate(
const FrameRate &fps);
173 const FrameRate &targetFrameRate()
const {
return _targetFrameRate; }
182 void setTargetAudioDesc(
const AudioDesc &desc);
185 const AudioDesc &targetAudioDesc()
const {
return _targetAudioDesc; }
194 void setClock(
const Clock::Ptr &clock);
197 Clock::Ptr clock()
const {
return _clock; }
209 void setInputQueueCapacity(
int capacity);
212 int inputQueueCapacity()
const {
return _queueCapacity; }
220 void setInputOverflowPolicy(InputOverflowPolicy policy);
223 InputOverflowPolicy inputOverflowPolicy()
const {
return _overflowPolicy; }
244 void reset(int64_t originNs);
257 Error pushFrame(
const Frame &frame);
267 void pushEndOfStream();
290 Result<PullResult> pullFrame(
bool blockOnEmpty =
true);
307 void clearInterrupt();
326 void resetSourceRateEstimator();
331 FrameCount framesIn()
const {
return FrameCount(_framesIn.value()); }
334 FrameCount framesOut()
const {
return FrameCount(_framesOut.value()); }
337 FrameCount framesRepeated()
const {
return FrameCount(_framesRepeated.value()); }
340 FrameCount framesDropped()
const {
return FrameCount(_framesDropped.value()); }
343 FrameCount overflowDrops()
const {
return FrameCount(_overflowDrops.value()); }
346 Duration accumulatedError()
const {
return Duration::fromNanoseconds(_accumulatedErrorNs); }
349 double currentResampleRatio()
const {
return _currentResampleRatio; }
352 double currentSourceAudioRate()
const {
return _sourceAudioRateHz; }
357 double currentSourceVideoRate()
const {
return _sourceVideoRateHz; }
362 int64_t videoTsNs = 0;
363 bool hasVideoTs =
false;
364 int64_t audioTsNs = 0;
365 bool hasAudioTs =
false;
369 void ensureInitialised();
370 void resetLocked(
bool setExplicitOrigin, int64_t originNs);
373 void selectVideo(int64_t sourceTimeNs, int64_t nextSourceTimeNs, VideoPayload::Ptr &outVideo,
374 int64_t &outRepeated, int64_t &outDropped);
375 PcmAudioPayload::Ptr produceAudio(int64_t targetSamples);
376 void updateSourceAudioRate(
const PcmAudioPayload &audio, int64_t audioTsNs);
377 void updateSourceVideoRate(int64_t videoTsNs);
380 void periodicDebugLog(int64_t nowNs);
384 FrameRate _targetFrameRate;
385 AudioDesc _targetAudioDesc;
387 SyntheticClock *_syntheticClock =
nullptr;
388 int _queueCapacity = 8;
389 InputOverflowPolicy _overflowPolicy = InputOverflowPolicy::DropOldest;
392 mutable Mutex _mutex;
396 List<QueuedFrame> _queue;
398 bool _interrupted =
false;
401 bool _started =
false;
402 bool _explicitOrigin =
false;
403 int64_t _originNs = 0;
404 int64_t _framePeriodNs = 0;
405 FrameCount _frameCount{0};
408 bool _sourceOriginValid =
false;
409 int64_t _sourceVideoOriginNs = 0;
410 int64_t _sourceAudioOriginNs = 0;
415 VideoPayload::Ptr _heldVideo;
416 int64_t _heldVideoSourceTsNs = 0;
417 bool _hasHeldVideo =
false;
428 int64_t _pendingFrameSyncDrops = 0;
429 int64_t _frameSyncRepeatIndex = 0;
434#if PROMEKI_ENABLE_SRC
435 AudioResampler::UPtr _resampler;
437 List<PcmAudioPayload::Ptr> _audioInput;
438 int64_t _audioSamplesConsumed = 0;
441 double _sourceAudioRateHz = 0.0;
442 double _sourceVideoRateHz = 0.0;
443 double _currentResampleRatio = 1.0;
444 int64_t _lastAudioTsForRateNs = 0;
445 int64_t _lastAudioTsSamples = 0;
446 int64_t _lastVideoTsForRateNs = 0;
449 int64_t _accumulatedErrorNs = 0;
450 int64_t _lastPeriodicLogNs = 0;
451 FrameCount _frameCountAtLastLog{0};
452 FrameCount _lastEmitFrameCount = FrameCount::unknown();
459 int64_t _deadlineBiasNs = 0;
462 Atomic<int64_t> _framesIn;
463 Atomic<int64_t> _framesOut;
464 Atomic<int64_t> _framesRepeated;
465 Atomic<int64_t> _framesDropped;
466 Atomic<int64_t> _overflowDrops;