11#include <promeki/config.h>
12#if PROMEKI_ENABLE_NETWORK
32PROMEKI_NAMESPACE_BEGIN
47struct RtpAggregatorVideoStream {
51 Queue<RxVideoFrame> *payloadQueue =
nullptr;
61 const Atomic<int64_t> *lastPacketArrivalNs =
nullptr;
81struct RtpAggregatorAudioStream {
83 Queue<RxAudioChunk> *payloadQueue =
nullptr;
96 const AudioDesc *readerAudioDesc =
nullptr;
104 const RtpStreamClock *streamClock =
nullptr;
111 const bool *hasSr =
nullptr;
116 ClockDomain clockDomain;
126struct RtpAggregatorDataStream {
128 Queue<RxDataMessage> *payloadQueue =
nullptr;
137 ClockDomain clockDomain;
151struct RtpAggregatorAncStream {
153 Queue<RxAncFrame> *payloadQueue =
nullptr;
162 ClockDomain clockDomain;
190struct RtpAggregatorContext {
209 bool videoWatchdogEnabled =
false;
218 RtpAggregatorVideoStream video;
219 RtpAggregatorAudioStream audio;
220 RtpAggregatorDataStream data;
221 RtpAggregatorAncStream anc;
232 Queue<Frame> *readerQueue =
nullptr;
240 Function<void(Frame)> pushFrame;
299class RtpAggregatorThread :
public Thread {
318 static constexpr int kStallNFrames = 4;
324 static constexpr unsigned int kPopCapMs = 50;
329 static constexpr unsigned int kPopFloorMs = 5;
345 RtpAggregatorThread(RtpAggregatorContext ctx, Mode mode,
346 const String &name = String(
"RtpAggregator"));
350 ~RtpAggregatorThread()
override;
352 RtpAggregatorThread(
const RtpAggregatorThread &) =
delete;
353 RtpAggregatorThread &operator=(
const RtpAggregatorThread &) =
delete;
369 bool isStopRequested()
const {
return _stopRequested.value(); }
373 Mode mode()
const {
return _mode; }
389 void runOnce(
unsigned int popMs = kPopCapMs);
395 const AudioBuffer &audioFifo()
const {
return _audioFifo; }
401 TimeStamp emittedFrameCursor()
const {
return _emittedFrameCursor; }
407 bool inWatchdog()
const {
return _inWatchdog; }
415 Duration frameDuration()
const;
418 void runAudioOnlyMode();
419 void runDataOnlyMode();
420 void runAncOnlyMode();
427 void drainAudioIntoFifoBefore(
const TimeStamp &windowEnd);
436 bool drainDataBefore(
const TimeStamp &windowEnd, RxDataMessage &out);
444 bool drainAncBefore(
const TimeStamp &windowEnd, RxAncFrame &out);
451 bool stepVideoMode(
unsigned int popMs);
454 bool stepAudioOnlyMode(
unsigned int popMs);
457 bool stepDataOnlyMode(
unsigned int popMs);
460 bool stepAncOnlyMode(
unsigned int popMs);
462 void emitFrameForVideo(RxVideoFrame video,
const Duration &fd);
463 void emitWatchdogFrame(
const Duration &fd);
464 void emitAudioOnlyAtFrameRate(
const RxAudioChunk &c);
465 void emitAudioOnlyPerChunk(
const RxAudioChunk &c);
470 bool ensureAudioFifo(
const AudioDesc &wireDesc);
476 unsigned int videoPopMs(
const Duration &fd)
const;
478 RtpAggregatorContext _ctx;
480 Atomic<bool> _stopRequested;
486 AudioBuffer _audioFifo;
493 uint32_t _audioFifoFrontRtpTs = 0;
498 bool _audioFifoHasFront =
false;
502 FrameNumber _videoFrameIndex{0};
511 TimeStamp _emittedFrameCursor;
516 bool _inWatchdog =
false;
522 RxDataMessage _pendingData;
526 bool _hasPendingData =
false;
530 RxAncFrame _pendingAnc;
534 bool _hasPendingAnc =
false;
541 bool _firstVideoSeen =
false;