libpromeki 1.0.0-alpha
PROfessional MEdia toolKIt
 
Loading...
Searching...
No Matches
rtpsession.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 <promeki/atomic.h>
15#include <promeki/list.h>
16#include <promeki/mutex.h>
17#include <promeki/objectbase.h>
18#include <promeki/error.h>
19#include <promeki/buffer.h>
20#include <promeki/clockdomain.h>
21#include <promeki/duration.h>
22#include <promeki/enums_rtp.h>
24#include <promeki/queue.h>
25#include <promeki/rtcppacket.h>
27#include <promeki/ntptime.h>
28#include <promeki/rtppacket.h>
31#include <promeki/string.h>
32#include <promeki/timestamp.h>
33
34PROMEKI_NAMESPACE_BEGIN
35
36class Thread;
37class RtpSeqTracker;
38class RtpSeqReorderBuffer;
39
93class RtpSession : public ObjectBase {
94 PROMEKI_OBJECT(RtpSession, ObjectBase)
95 public:
100 RtpSession(ObjectBase *parent = nullptr);
101
103 ~RtpSession() override;
104
116 Error start(const SocketAddress &localAddr);
117
129 Error start(PacketTransport *transport);
130
164 Error start(PacketTransport *primary, PacketTransport *secondary);
165
167 void stop();
168
170 bool isRunning() const { return _running; }
171
182 void setRemote(const SocketAddress &dest) { _remote = dest; }
183
185 const SocketAddress &remote() const { return _remote; }
186
195 void setRemoteSecondary(const SocketAddress &dest) { _remoteSecondary = dest; }
196
198 const SocketAddress &remoteSecondary() const { return _remoteSecondary; }
199
201 bool hasSecondaryLeg() const { return _transportSecondary != nullptr; }
202
212 Error sendPacket(const Buffer &payload, uint32_t timestamp, uint8_t payloadType, bool marker = false);
213
250 Error sendPackets(RtpPacketBatch &batch);
251
274 struct StreamReceiver {
279 RtpPacket::Queue *outQueue = nullptr;
280
283 RtpSeqTracker *seqTracker = nullptr;
284
288 RtpSeqReorderBuffer *reorderBuffer = nullptr;
289
300 uint32_t clockRateHz = 0;
301
312 uint8_t payloadType = 0;
313 };
314
361 Error startReceiving(List<StreamReceiver> receivers,
362 const String &threadName = "rtp-rx");
363
372 void stopReceiving();
373
375 bool isReceiving() const { return _receiving.value(); }
376
387 void setReceivePollIntervalMs(unsigned int timeoutMs) {
388 _receivePollMs = timeoutMs == 0 ? 200 : timeoutMs;
389 }
390
392 unsigned int receivePollIntervalMs() const { return _receivePollMs; }
393
409 Error setPacingRate(uint64_t bytesPerSec);
410
426 void setScheduler(PacketScheduler::UPtr scheduler);
427
429 PacketScheduler *scheduler() const { return _scheduler.get(); }
430
444 void setSchedulerSecondary(PacketScheduler::UPtr scheduler);
445
447 PacketScheduler *schedulerSecondary() const { return _schedulerSecondary.get(); }
448
462 Error configureScheduler(const PacketScheduler::Spec &spec);
463
465 uint32_t ssrc() const { return _ssrc; }
466
468 void setSsrc(uint32_t ssrc) { _ssrc = ssrc; }
469
471 uint16_t sequenceNumber() const { return _sequenceNumber; }
472
474 void setPayloadType(uint8_t pt) { _payloadType = pt; }
475
477 uint8_t payloadType() const { return _payloadType; }
478
480 void setClockRate(uint32_t hz) { _clockRate = hz; }
481
483 uint32_t clockRate() const { return _clockRate; }
484
522 void setRtpAnchor(NtpTime captureNtp, uint32_t rtpTs);
523
555 void setRtpAnchor(const ClockDomain &domain, uint32_t rtpTs);
556
565 NtpTime anchorNtp() const;
566
571 uint32_t anchorRtpTs() const;
572
604 void noteRtpEmission(uint32_t rtpTs);
605
615 bool hasEmissionRecord() const;
616
618 const String &cname() const { return _cname; }
619
621 void setCname(const String &cname) { _cname = cname; }
622
644 Error emitRtcpSr(uint32_t senderPacketCount, uint32_t senderOctetCount);
645
664 Error emitRtcpRr(const RtcpPacket::ReportBlock &block);
665
676 Error emitRtcpBye();
677
692 struct ReceivedSr {
693 NtpTime ntp;
694 uint32_t rtpTs = 0;
695 TimeStamp arrivedAt;
696 bool valid = false;
697 };
698
710 ReceivedSr receivedSr() const;
711
721 uint32_t srObservedCount() const;
722
732 TimeStamp firstSrAt() const;
733
749 NtpTime currentSrNtp() const;
750
762 PacketTransport *transport() const { return _transport; }
763
772 PROMEKI_SIGNAL(packetReceived, Buffer, uint32_t, uint8_t, bool);
773
775 PROMEKI_SIGNAL(ssrcCollision, uint32_t);
776
791 PROMEKI_SIGNAL(ssrcChange, uint32_t, uint32_t, uint8_t);
792
804 PROMEKI_SIGNAL(byeReceived, uint32_t);
805
806 private:
807 class ReceiveThread;
808 friend class ReceiveThread;
809
828 void handleRtcp(const uint8_t *data, size_t size);
829
830 void fillHeader(RtpPacket &pkt, uint8_t pt, bool marker, uint32_t timestamp);
842 void fillTransportHeader(RtpPacket &pkt);
843 void generateSsrc();
844
845 PacketTransport *_transport = nullptr;
846 PacketTransport::UPtr _ownedTransport;
847 PacketScheduler::UPtr _scheduler;
848
849 // ST 2022-7 dual-leg state. When _transportSecondary is
850 // non-null sendPackets stamps the RTP header once and
851 // fans the resulting Datagram list out to both
852 // transports — leg-specific destinations are taken from
853 // _remote (primary) and _remoteSecondary; each scheduler
854 // is bound to its own transport so back-pressure on
855 // one leg cannot stall the other. Receive side: a
856 // second receive thread services the secondary transport
857 // and joins the primary thread on shutdown. Both
858 // recv threads dispatch through _dispatchMutex so the
859 // per-stream seq tracker / SSRC pin / reorder buffer
860 // stay coherent.
861 PacketTransport *_transportSecondary = nullptr;
862 PacketTransport::UPtr _ownedTransportSecondary;
863 PacketScheduler::UPtr _schedulerSecondary;
864 SocketAddress _remoteSecondary;
865
866 bool _running = false;
867 SocketAddress _remote;
868 uint32_t _ssrc = 0;
869 uint16_t _sequenceNumber = 0;
870 uint8_t _payloadType = 96;
871 uint32_t _clockRate = 90000;
872
873 // RTCP SR / SDES state. CNAME is the SDES item every
874 // SR-bearing compound packet carries. The
875 // capture-anchor is established once at openStream
876 // time and refined by the first arriving Frame's
877 // @ref Frame::captureTime; thereafter, @c emitRtcpSr
878 // derives the SR's NTP from
879 // @c anchorNtp + (lastEmissionRtpTs - anchorRtpTs) /
880 // clockRate without sampling the system clock.
881 // @c _hasEmission gates SR emission on whether any
882 // packet has actually gone out, so the scheduler
883 // never sends an SR for a session that has yet to
884 // produce wire activity. Mutex-guarded because the
885 // noter runs on the per-stream TX thread while the
886 // scheduler runs on its own thread.
887 mutable Mutex _rtcpMutex;
888 NtpTime _anchorNtp;
889 uint32_t _anchorRtpTs = 0;
890 uint32_t _lastEmissionRtpTs = 0;
891 bool _hasEmission = false;
892 String _cname;
897 uint32_t _srObservedCount = 0;
904 TimeStamp _firstSrAt;
905
906 // Most-recently parsed inbound SR. The receive thread
907 // demuxes RTCP from RTP via the second byte of every
908 // datagram (PT in [200..223] → RTCP) and walks each
909 // RTCP compound for SRs. Reader-side helpers like
910 // @ref RtpStreamClock pick this up via
911 // @ref receivedSr to map any future RTP-TS on this
912 // session to a wallclock instant for cross-stream
913 // alignment.
914 ReceivedSr _lastReceivedSr;
915
916 // Receive path. @c _streamReceivers is populated
917 // by @ref startReceiving and consumed by the recv
918 // socket thread; per-stream depacketizer threads
919 // pull from the post-reorder queues each entry
920 // points at.
921 using ReceiveThreadUPtr = UniquePtr<ReceiveThread>;
922 ReceiveThreadUPtr _receiveThread;
923 ReceiveThreadUPtr _receiveThreadSecondary;
924 Mutex _dispatchMutex;
925 List<StreamReceiver> _streamReceivers;
926 Atomic<bool> _receiving;
927 unsigned int _receivePollMs = 200;
928
929 // Per-stream-receiver SSRC pin state. Sized to
930 // match @c _streamReceivers.size() at
931 // @c startReceiving time. Index-parallel — entry
932 // @c i tracks the SSRC pin for receivers[i].
933 struct SsrcPinState {
934 uint32_t expectedSsrc = 0;
935 bool pinned = false;
936 uint32_t mismatchCount = 0;
937 TimeStamp mismatchFirstTime;
938 };
939 List<SsrcPinState> _ssrcPinStates;
940};
941
942PROMEKI_NAMESPACE_END
943
944#endif // PROMEKI_ENABLE_NETWORK