libpromeki 1.0.0-alpha
PROfessional MEdia toolKIt
 
Loading...
Searching...
No Matches
rtpaggregatorthread.h
Go to the documentation of this file.
1
8#pragma once
9
10
11#include <promeki/config.h>
12#if PROMEKI_ENABLE_NETWORK
13#include <cstdint>
14#include <functional>
15#include <promeki/function.h>
16#include <promeki/atomic.h>
17#include <promeki/audiobuffer.h>
18#include <promeki/audiodesc.h>
19#include <promeki/clockdomain.h>
20#include <promeki/duration.h>
21#include <promeki/frame.h>
22#include <promeki/framenumber.h>
23#include <promeki/framerate.h>
24#include <promeki/namespace.h>
25#include <promeki/queue.h>
28#include <promeki/string.h>
29#include <promeki/thread.h>
30#include <promeki/timestamp.h>
31
32PROMEKI_NAMESPACE_BEGIN
33
47struct RtpAggregatorVideoStream {
51 Queue<RxVideoFrame> *payloadQueue = nullptr;
52
61 const Atomic<int64_t> *lastPacketArrivalNs = nullptr;
62};
63
81struct RtpAggregatorAudioStream {
83 Queue<RxAudioChunk> *payloadQueue = nullptr;
84
89 bool active = false;
90
96 const AudioDesc *readerAudioDesc = nullptr;
97
104 const RtpStreamClock *streamClock = nullptr;
105
111 const bool *hasSr = nullptr;
112
116 ClockDomain clockDomain;
117};
118
126struct RtpAggregatorDataStream {
128 Queue<RxDataMessage> *payloadQueue = nullptr;
129
132 bool active = false;
133
137 ClockDomain clockDomain;
138};
139
151struct RtpAggregatorAncStream {
153 Queue<RxAncFrame> *payloadQueue = nullptr;
154
157 bool active = false;
158
162 ClockDomain clockDomain;
163};
164
190struct RtpAggregatorContext {
200 FrameRate frameRate;
201
209 bool videoWatchdogEnabled = false;
210
218 RtpAggregatorVideoStream video;
219 RtpAggregatorAudioStream audio;
220 RtpAggregatorDataStream data;
221 RtpAggregatorAncStream anc;
222
232 Queue<Frame> *readerQueue = nullptr;
233
240 Function<void(Frame)> pushFrame;
241};
242
299class RtpAggregatorThread : public Thread {
300 public:
303 enum class Mode {
304 Video,
305 AudioOnly,
306 DataOnly,
307 AncOnly
309 };
310
318 static constexpr int kStallNFrames = 4;
319
324 static constexpr unsigned int kPopCapMs = 50;
325
329 static constexpr unsigned int kPopFloorMs = 5;
330
345 RtpAggregatorThread(RtpAggregatorContext ctx, Mode mode,
346 const String &name = String("RtpAggregator"));
347
350 ~RtpAggregatorThread() override;
351
352 RtpAggregatorThread(const RtpAggregatorThread &) = delete;
353 RtpAggregatorThread &operator=(const RtpAggregatorThread &) = delete;
354
365 void requestStop();
366
369 bool isStopRequested() const { return _stopRequested.value(); }
370
373 Mode mode() const { return _mode; }
374
389 void runOnce(unsigned int popMs = kPopCapMs);
390
395 const AudioBuffer &audioFifo() const { return _audioFifo; }
396
401 TimeStamp emittedFrameCursor() const { return _emittedFrameCursor; }
402
407 bool inWatchdog() const { return _inWatchdog; }
408
409 protected:
412 void run() override;
413
414 private:
415 Duration frameDuration() const;
416
417 void runVideoMode();
418 void runAudioOnlyMode();
419 void runDataOnlyMode();
420 void runAncOnlyMode();
421
427 void drainAudioIntoFifoBefore(const TimeStamp &windowEnd);
428
436 bool drainDataBefore(const TimeStamp &windowEnd, RxDataMessage &out);
437
444 bool drainAncBefore(const TimeStamp &windowEnd, RxAncFrame &out);
445
451 bool stepVideoMode(unsigned int popMs);
452
454 bool stepAudioOnlyMode(unsigned int popMs);
455
457 bool stepDataOnlyMode(unsigned int popMs);
458
460 bool stepAncOnlyMode(unsigned int popMs);
461
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);
466
470 bool ensureAudioFifo(const AudioDesc &wireDesc);
471
476 unsigned int videoPopMs(const Duration &fd) const;
477
478 RtpAggregatorContext _ctx;
479 Mode _mode;
480 Atomic<bool> _stopRequested;
481
486 AudioBuffer _audioFifo;
487
493 uint32_t _audioFifoFrontRtpTs = 0;
494
498 bool _audioFifoHasFront = false;
499
502 FrameNumber _videoFrameIndex{0};
503
511 TimeStamp _emittedFrameCursor;
512
516 bool _inWatchdog = false;
517
522 RxDataMessage _pendingData;
523
526 bool _hasPendingData = false;
527
530 RxAncFrame _pendingAnc;
531
534 bool _hasPendingAnc = false;
535
541 bool _firstVideoSeen = false;
542};
543
544PROMEKI_NAMESPACE_END
545
546#endif // PROMEKI_ENABLE_NETWORK