1/**********
2This library is free software; you can redistribute it and/or modify it under
3the terms of the GNU Lesser General Public License as published by the
4Free Software Foundation; either version 3 of the License, or (at your
5option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)
6
7This library is distributed in the hope that it will be useful, but WITHOUT
8ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
9FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
10more details.
11
12You should have received a copy of the GNU Lesser General Public License
13along with this library; if not, write to the Free Software Foundation, Inc.,
1451 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15**********/
16// "liveMedia"
17// Copyright (c) 1996-2020 Live Networks, Inc. All rights reserved.
18// RTP Sources
19// C++ header
20
21#ifndef _RTP_SOURCE_HH
22#define _RTP_SOURCE_HH
23
24#ifndef _FRAMED_SOURCE_HH
25#include "FramedSource.hh"
26#endif
27#ifndef _RTP_INTERFACE_HH
28#include "RTPInterface.hh"
29#endif
30
31class RTPReceptionStatsDB; // forward
32
33class RTPSource: public FramedSource {
34public:
35 static Boolean lookupByName(UsageEnvironment& env, char const* sourceName,
36 RTPSource*& resultSource);
37
38 Boolean curPacketMarkerBit() const { return fCurPacketMarkerBit; }
39
40 unsigned char rtpPayloadFormat() const { return fRTPPayloadFormat; }
41
42 virtual Boolean hasBeenSynchronizedUsingRTCP();
43
44 Groupsock* RTPgs() const { return fRTPInterface.gs(); }
45
46 virtual void setPacketReorderingThresholdTime(unsigned uSeconds) = 0;
47
48 // used by RTCP:
49 u_int32_t SSRC() const { return fSSRC; }
50 // Note: This is *our* SSRC, not the SSRC in incoming RTP packets.
51 // later need a means of changing the SSRC if there's a collision #####
52 void registerForMultiplexedRTCPPackets(class RTCPInstance* rtcpInstance) {
53 fRTCPInstanceForMultiplexedRTCPPackets = rtcpInstance;
54 }
55 void deregisterForMultiplexedRTCPPackets() { registerForMultiplexedRTCPPackets(NULL); }
56
57 unsigned timestampFrequency() const {return fTimestampFrequency;}
58
59 RTPReceptionStatsDB& receptionStatsDB() const {
60 return *fReceptionStatsDB;
61 }
62
63 u_int32_t lastReceivedSSRC() const { return fLastReceivedSSRC; }
64 // Note: This is the SSRC in the most recently received RTP packet; not *our* SSRC
65
66 Boolean& enableRTCPReports() { return fEnableRTCPReports; }
67 Boolean const& enableRTCPReports() const { return fEnableRTCPReports; }
68
69 void setStreamSocket(int sockNum, unsigned char streamChannelId) {
70 // hack to allow sending RTP over TCP (RFC 2236, section 10.12)
71 fRTPInterface.setStreamSocket(sockNum, streamChannelId);
72 }
73
74 void setAuxilliaryReadHandler(AuxHandlerFunc* handlerFunc,
75 void* handlerClientData) {
76 fRTPInterface.setAuxilliaryReadHandler(handlerFunc,
77 handlerClientData);
78 }
79
80 // Note that RTP receivers will usually not need to call either of the following two functions, because
81 // RTP sequence numbers and timestamps are usually not useful to receivers.
82 // (Our implementation of RTP reception already does all needed handling of RTP sequence numbers and timestamps.)
83 u_int16_t curPacketRTPSeqNum() const { return fCurPacketRTPSeqNum; }
84private: friend class MediaSubsession; // "MediaSubsession" is the only outside class that ever needs to see RTP timestamps!
85 u_int32_t curPacketRTPTimestamp() const { return fCurPacketRTPTimestamp; }
86
87protected:
88 RTPSource(UsageEnvironment& env, Groupsock* RTPgs,
89 unsigned char rtpPayloadFormat, u_int32_t rtpTimestampFrequency);
90 // abstract base class
91 virtual ~RTPSource();
92
93protected:
94 RTPInterface fRTPInterface;
95 u_int16_t fCurPacketRTPSeqNum;
96 u_int32_t fCurPacketRTPTimestamp;
97 Boolean fCurPacketMarkerBit;
98 Boolean fCurPacketHasBeenSynchronizedUsingRTCP;
99 u_int32_t fLastReceivedSSRC;
100 class RTCPInstance* fRTCPInstanceForMultiplexedRTCPPackets;
101
102private:
103 // redefined virtual functions:
104 virtual Boolean isRTPSource() const;
105 virtual void getAttributes() const;
106
107private:
108 unsigned char fRTPPayloadFormat;
109 unsigned fTimestampFrequency;
110 u_int32_t fSSRC;
111 Boolean fEnableRTCPReports; // whether RTCP "RR" reports should be sent for this source (default: True)
112
113 RTPReceptionStatsDB* fReceptionStatsDB;
114};
115
116
117class RTPReceptionStats; // forward
118
119class RTPReceptionStatsDB {
120public:
121 unsigned totNumPacketsReceived() const { return fTotNumPacketsReceived; }
122 unsigned numActiveSourcesSinceLastReset() const {
123 return fNumActiveSourcesSinceLastReset;
124 }
125
126 void reset();
127 // resets periodic stats (called each time they're used to
128 // generate a reception report)
129
130 class Iterator {
131 public:
132 Iterator(RTPReceptionStatsDB& receptionStatsDB);
133 virtual ~Iterator();
134
135 RTPReceptionStats* next(Boolean includeInactiveSources = False);
136 // NULL if none
137
138 private:
139 HashTable::Iterator* fIter;
140 };
141
142 // The following is called whenever a RTP packet is received:
143 void noteIncomingPacket(u_int32_t SSRC, u_int16_t seqNum,
144 u_int32_t rtpTimestamp,
145 unsigned timestampFrequency,
146 Boolean useForJitterCalculation,
147 struct timeval& resultPresentationTime,
148 Boolean& resultHasBeenSyncedUsingRTCP,
149 unsigned packetSize /* payload only */);
150
151 // The following is called whenever a RTCP SR packet is received:
152 void noteIncomingSR(u_int32_t SSRC,
153 u_int32_t ntpTimestampMSW, u_int32_t ntpTimestampLSW,
154 u_int32_t rtpTimestamp);
155
156 // The following is called when a RTCP BYE packet is received:
157 void removeRecord(u_int32_t SSRC);
158
159 RTPReceptionStats* lookup(u_int32_t SSRC) const;
160
161protected: // constructor and destructor, called only by RTPSource:
162 friend class RTPSource;
163 RTPReceptionStatsDB();
164 virtual ~RTPReceptionStatsDB();
165
166protected:
167 void add(u_int32_t SSRC, RTPReceptionStats* stats);
168
169protected:
170 friend class Iterator;
171 unsigned fNumActiveSourcesSinceLastReset;
172
173private:
174 HashTable* fTable;
175 unsigned fTotNumPacketsReceived; // for all SSRCs
176};
177
178class RTPReceptionStats {
179public:
180 u_int32_t SSRC() const { return fSSRC; }
181 unsigned numPacketsReceivedSinceLastReset() const {
182 return fNumPacketsReceivedSinceLastReset;
183 }
184 unsigned totNumPacketsReceived() const { return fTotNumPacketsReceived; }
185 double totNumKBytesReceived() const;
186
187 unsigned totNumPacketsExpected() const {
188 return (fHighestExtSeqNumReceived - fBaseExtSeqNumReceived) + 1;
189 }
190
191 unsigned baseExtSeqNumReceived() const { return fBaseExtSeqNumReceived; }
192 unsigned lastResetExtSeqNumReceived() const {
193 return fLastResetExtSeqNumReceived;
194 }
195 unsigned highestExtSeqNumReceived() const {
196 return fHighestExtSeqNumReceived;
197 }
198
199 unsigned jitter() const;
200
201 unsigned lastReceivedSR_NTPmsw() const { return fLastReceivedSR_NTPmsw; }
202 unsigned lastReceivedSR_NTPlsw() const { return fLastReceivedSR_NTPlsw; }
203 struct timeval const& lastReceivedSR_time() const {
204 return fLastReceivedSR_time;
205 }
206
207 unsigned minInterPacketGapUS() const { return fMinInterPacketGapUS; }
208 unsigned maxInterPacketGapUS() const { return fMaxInterPacketGapUS; }
209 struct timeval const& totalInterPacketGaps() const {
210 return fTotalInterPacketGaps;
211 }
212
213protected:
214 // called only by RTPReceptionStatsDB:
215 friend class RTPReceptionStatsDB;
216 RTPReceptionStats(u_int32_t SSRC, u_int16_t initialSeqNum);
217 RTPReceptionStats(u_int32_t SSRC);
218 virtual ~RTPReceptionStats();
219
220private:
221 void noteIncomingPacket(u_int16_t seqNum, u_int32_t rtpTimestamp,
222 unsigned timestampFrequency,
223 Boolean useForJitterCalculation,
224 struct timeval& resultPresentationTime,
225 Boolean& resultHasBeenSyncedUsingRTCP,
226 unsigned packetSize /* payload only */);
227 void noteIncomingSR(u_int32_t ntpTimestampMSW, u_int32_t ntpTimestampLSW,
228 u_int32_t rtpTimestamp);
229 void init(u_int32_t SSRC);
230 void initSeqNum(u_int16_t initialSeqNum);
231 void reset();
232 // resets periodic stats (called each time they're used to
233 // generate a reception report)
234
235protected:
236 u_int32_t fSSRC;
237 unsigned fNumPacketsReceivedSinceLastReset;
238 unsigned fTotNumPacketsReceived;
239 u_int32_t fTotBytesReceived_hi, fTotBytesReceived_lo;
240 Boolean fHaveSeenInitialSequenceNumber;
241 unsigned fBaseExtSeqNumReceived;
242 unsigned fLastResetExtSeqNumReceived;
243 unsigned fHighestExtSeqNumReceived;
244 int fLastTransit; // used in the jitter calculation
245 u_int32_t fPreviousPacketRTPTimestamp;
246 double fJitter;
247 // The following are recorded whenever we receive a RTCP SR for this SSRC:
248 unsigned fLastReceivedSR_NTPmsw; // NTP timestamp (from SR), most-signif
249 unsigned fLastReceivedSR_NTPlsw; // NTP timestamp (from SR), least-signif
250 struct timeval fLastReceivedSR_time;
251 struct timeval fLastPacketReceptionTime;
252 unsigned fMinInterPacketGapUS, fMaxInterPacketGapUS;
253 struct timeval fTotalInterPacketGaps;
254
255private:
256 // Used to convert from RTP timestamp to 'wall clock' time:
257 Boolean fHasBeenSynchronized;
258 u_int32_t fSyncTimestamp;
259 struct timeval fSyncTime;
260};
261
262
263Boolean seqNumLT(u_int16_t s1, u_int16_t s2);
264 // a 'less-than' on 16-bit sequence numbers
265
266#endif
267