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 Sinks
19// C++ header
20
21#ifndef _RTP_SINK_HH
22#define _RTP_SINK_HH
23
24#ifndef _MEDIA_SINK_HH
25#include "MediaSink.hh"
26#endif
27#ifndef _RTP_INTERFACE_HH
28#include "RTPInterface.hh"
29#endif
30
31class RTPTransmissionStatsDB; // forward
32
33class RTPSink: public MediaSink {
34public:
35 static Boolean lookupByName(UsageEnvironment& env, char const* sinkName,
36 RTPSink*& resultSink);
37
38 // used by RTSP servers:
39 Groupsock const& groupsockBeingUsed() const { return *(fRTPInterface.gs()); }
40 Groupsock& groupsockBeingUsed() { return *(fRTPInterface.gs()); }
41
42 unsigned char rtpPayloadType() const { return fRTPPayloadType; }
43 unsigned rtpTimestampFrequency() const { return fTimestampFrequency; }
44 void setRTPTimestampFrequency(unsigned freq) {
45 fTimestampFrequency = freq;
46 }
47 char const* rtpPayloadFormatName() const {return fRTPPayloadFormatName;}
48
49 unsigned numChannels() const { return fNumChannels; }
50
51 virtual char const* sdpMediaType() const; // for use in SDP m= lines
52 virtual char* rtpmapLine() const; // returns a string to be delete[]d
53 virtual char const* auxSDPLine();
54 // optional SDP line (e.g. a=fmtp:...)
55
56 u_int16_t currentSeqNo() const { return fSeqNo; }
57 u_int32_t presetNextTimestamp();
58 // ensures that the next timestamp to be used will correspond to
59 // the current 'wall clock' time.
60
61 RTPTransmissionStatsDB& transmissionStatsDB() const {
62 return *fTransmissionStatsDB;
63 }
64
65 Boolean nextTimestampHasBeenPreset() const { return fNextTimestampHasBeenPreset; }
66 Boolean& enableRTCPReports() { return fEnableRTCPReports; }
67
68 void getTotalBitrate(unsigned& outNumBytes, double& outElapsedTime);
69 // returns the number of bytes sent since the last time that we
70 // were called, and resets the counter.
71
72 struct timeval const& creationTime() const { return fCreationTime; }
73 struct timeval const& initialPresentationTime() const { return fInitialPresentationTime; }
74 struct timeval const& mostRecentPresentationTime() const { return fMostRecentPresentationTime; }
75 void resetPresentationTimes();
76
77 // Hacks to allow sending RTP over TCP (RFC 2236, section 10.12):
78 void setStreamSocket(int sockNum, unsigned char streamChannelId) {
79 fRTPInterface.setStreamSocket(sockNum, streamChannelId);
80 }
81 void addStreamSocket(int sockNum, unsigned char streamChannelId) {
82 fRTPInterface.addStreamSocket(sockNum, streamChannelId);
83 }
84 void removeStreamSocket(int sockNum, unsigned char streamChannelId) {
85 fRTPInterface.removeStreamSocket(sockNum, streamChannelId);
86 }
87 unsigned& estimatedBitrate() { return fEstimatedBitrate; } // kbps; usually 0 (i.e., unset)
88
89 u_int32_t SSRC() const {return fSSRC;}
90 // later need a means of changing the SSRC if there's a collision #####
91
92protected:
93 RTPSink(UsageEnvironment& env,
94 Groupsock* rtpGS, unsigned char rtpPayloadType,
95 u_int32_t rtpTimestampFrequency,
96 char const* rtpPayloadFormatName,
97 unsigned numChannels);
98 // abstract base class
99
100 virtual ~RTPSink();
101
102 // used by RTCP:
103 friend class RTCPInstance;
104 friend class RTPTransmissionStats;
105 u_int32_t convertToRTPTimestamp(struct timeval tv);
106 unsigned packetCount() const {return fPacketCount;}
107 unsigned octetCount() const {return fOctetCount;}
108
109protected:
110 RTPInterface fRTPInterface;
111 unsigned char fRTPPayloadType;
112 unsigned fPacketCount, fOctetCount, fTotalOctetCount /*incl RTP hdr*/;
113 struct timeval fTotalOctetCountStartTime, fInitialPresentationTime, fMostRecentPresentationTime;
114 u_int32_t fCurrentTimestamp;
115 u_int16_t fSeqNo;
116
117private:
118 // redefined virtual functions:
119 virtual Boolean isRTPSink() const;
120
121private:
122 u_int32_t fSSRC, fTimestampBase;
123 unsigned fTimestampFrequency;
124 Boolean fNextTimestampHasBeenPreset;
125 Boolean fEnableRTCPReports; // whether RTCP "SR" reports should be sent for this sink (default: True)
126 char const* fRTPPayloadFormatName;
127 unsigned fNumChannels;
128 struct timeval fCreationTime;
129 unsigned fEstimatedBitrate; // set on creation if known; otherwise 0
130
131 RTPTransmissionStatsDB* fTransmissionStatsDB;
132};
133
134
135class RTPTransmissionStats; // forward
136
137class RTPTransmissionStatsDB {
138public:
139 unsigned numReceivers() const { return fNumReceivers; }
140
141 class Iterator {
142 public:
143 Iterator(RTPTransmissionStatsDB& receptionStatsDB);
144 virtual ~Iterator();
145
146 RTPTransmissionStats* next();
147 // NULL if none
148
149 private:
150 HashTable::Iterator* fIter;
151 };
152
153 // The following is called whenever a RTCP RR packet is received:
154 void noteIncomingRR(u_int32_t SSRC, struct sockaddr_in const& lastFromAddress,
155 unsigned lossStats, unsigned lastPacketNumReceived,
156 unsigned jitter, unsigned lastSRTime, unsigned diffSR_RRTime);
157
158 // The following is called when a RTCP BYE packet is received:
159 void removeRecord(u_int32_t SSRC);
160
161 RTPTransmissionStats* lookup(u_int32_t SSRC) const;
162
163private: // constructor and destructor, called only by RTPSink:
164 friend class RTPSink;
165 RTPTransmissionStatsDB(RTPSink& rtpSink);
166 virtual ~RTPTransmissionStatsDB();
167
168private:
169 void add(u_int32_t SSRC, RTPTransmissionStats* stats);
170
171private:
172 friend class Iterator;
173 unsigned fNumReceivers;
174 RTPSink& fOurRTPSink;
175 HashTable* fTable;
176};
177
178class RTPTransmissionStats {
179public:
180 u_int32_t SSRC() const {return fSSRC;}
181 struct sockaddr_in const& lastFromAddress() const {return fLastFromAddress;}
182 unsigned lastPacketNumReceived() const {return fLastPacketNumReceived;}
183 unsigned firstPacketNumReported() const {return fFirstPacketNumReported;}
184 unsigned totNumPacketsLost() const {return fTotNumPacketsLost;}
185 unsigned jitter() const {return fJitter;}
186 unsigned lastSRTime() const { return fLastSRTime; }
187 unsigned diffSR_RRTime() const { return fDiffSR_RRTime; }
188 unsigned roundTripDelay() const;
189 // The round-trip delay (in units of 1/65536 seconds) computed from
190 // the most recently-received RTCP RR packet.
191 struct timeval const& timeCreated() const {return fTimeCreated;}
192 struct timeval const& lastTimeReceived() const {return fTimeReceived;}
193 void getTotalOctetCount(u_int32_t& hi, u_int32_t& lo);
194 void getTotalPacketCount(u_int32_t& hi, u_int32_t& lo);
195
196 // Information which requires at least two RRs to have been received:
197 unsigned packetsReceivedSinceLastRR() const;
198 u_int8_t packetLossRatio() const { return fPacketLossRatio; }
199 // as an 8-bit fixed-point number
200 int packetsLostBetweenRR() const;
201
202private:
203 // called only by RTPTransmissionStatsDB:
204 friend class RTPTransmissionStatsDB;
205 RTPTransmissionStats(RTPSink& rtpSink, u_int32_t SSRC);
206 virtual ~RTPTransmissionStats();
207
208 void noteIncomingRR(struct sockaddr_in const& lastFromAddress,
209 unsigned lossStats, unsigned lastPacketNumReceived,
210 unsigned jitter,
211 unsigned lastSRTime, unsigned diffSR_RRTime);
212
213private:
214 RTPSink& fOurRTPSink;
215 u_int32_t fSSRC;
216 struct sockaddr_in fLastFromAddress;
217 unsigned fLastPacketNumReceived;
218 u_int8_t fPacketLossRatio;
219 unsigned fTotNumPacketsLost;
220 unsigned fJitter;
221 unsigned fLastSRTime;
222 unsigned fDiffSR_RRTime;
223 struct timeval fTimeCreated, fTimeReceived;
224 Boolean fAtLeastTwoRRsHaveBeenReceived;
225 unsigned fOldLastPacketNumReceived;
226 unsigned fOldTotNumPacketsLost;
227 Boolean fFirstPacket;
228 unsigned fFirstPacketNumReported;
229 u_int32_t fLastOctetCount, fTotalOctetCount_hi, fTotalOctetCount_lo;
230 u_int32_t fLastPacketCount, fTotalPacketCount_hi, fTotalPacketCount_lo;
231};
232
233#endif
234