OPAL Version 3.10.4

- Main Page
- Related Pages
- Namespaces
- Data Structures
- Files

- File List
- Globals

rtp.h
Go to the documentation of this file.
1 /*
2 * rtp.h
3 *
4 * RTP protocol handler
5 *
6 * Open H323 Library
7 *
8 * Copyright (c) 1998-2001 Equivalence Pty. Ltd.
9 *
10 * The contents of this file are subject to the Mozilla Public License
11 * Version 1.0 (the "License"); you may not use this file except in
12 * compliance with the License. You may obtain a copy of the License at
13 * http://www.mozilla.org/MPL/
14 *
15 * Software distributed under the License is distributed on an "AS IS"
16 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
17 * the License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * The Original Code is Open H323 Library.
21 *
22 * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
23 *
24 * Portions of this code were written with the assisance of funding from
25 * Vovida Networks, Inc. http://www.vovida.com.
26 *
27 * Contributor(s): ______________________________________.
28 *
29 * $Revision: 26716 $
30 * $Author: rjongbloed $
31 * $Date: 2011-11-30 17:51:43 -0600 (Wed, 30 Nov 2011) $
32 */
33
34 #ifndef OPAL_RTP_RTP_H
35 #define OPAL_RTP_RTP_H
36
37 #ifdef P_USE_PRAGMA
38 #pragma interface
39 #endif
40
41 #include <opal/buildopts.h>
42
43 #include <ptlib/sockets.h>
44 #include <ptlib/safecoll.h>
45
46 #include <list>
47
48 #include <rtp/metrics.h>
49
50 class RTP_JitterBuffer;
51 class PNatMethod;
52 class OpalSecurityMode;
53
55 //
56 // class to hold the QoS definitions for an RTP channel
57
58 class RTP_QOS : public PObject
59 {
60 PCLASSINFO(RTP_QOS,PObject);
61 public:
62 PQoS dataQoS;
63 PQoS ctrlQoS;
64 };
65
67 // Real Time Protocol - IETF RFC1889 and RFC1890
68
71 class RTP_DataFrame : public PBYTEArray
72 {
73 PCLASSINFO(RTP_DataFrame, PBYTEArray);
74
75 public:
76 RTP_DataFrame(PINDEX payloadSize = 0, PINDEX bufferSize = 0);
77 RTP_DataFrame(const BYTE * data, PINDEX len, PBoolean dynamic = true);
78
79 enum {
80 ProtocolVersion = 2,
81 MinHeaderSize = 12,
82 // Max safe MTU size (576 bytes as per RFC879) minus IP, UDP an RTP headers
83 MaxMtuPayloadSize = (576-20-16-12)
84 };
85
86 enum PayloadTypes {
87 PCMU, // G.711 u-Law
88 FS1016, // Federal Standard 1016 CELP
89 G721, // ADPCM - Subsumed by G.726
90 G726 = G721,
91 GSM, // GSM 06.10
92 G7231, // G.723.1 at 6.3kbps or 5.3 kbps
93 DVI4_8k, // DVI4 at 8kHz sample rate
94 DVI4_16k, // DVI4 at 16kHz sample rate
95 LPC, // LPC-10 Linear Predictive CELP
96 PCMA, // G.711 A-Law
97 G722, // G.722
98 L16_Stereo, // 16 bit linear PCM
99 L16_Mono, // 16 bit linear PCM
100 G723, // G.723
101 CN, // Confort Noise
102 MPA, // MPEG1 or MPEG2 audio
103 G728, // G.728 16kbps CELP
104 DVI4_11k, // DVI4 at 11kHz sample rate
105 DVI4_22k, // DVI4 at 22kHz sample rate
106 G729, // G.729 8kbps
107 Cisco_CN, // Cisco systems comfort noise (unofficial)
108
109 CelB = 25, // Sun Systems Cell-B video
110 JPEG, // Motion JPEG
111 H261 = 31, // H.261
112 MPV, // MPEG1 or MPEG2 video
113 MP2T, // MPEG2 transport system
114 H263, // H.263
115
116 T38 = 38, // T.38 (internal)
117
118 LastKnownPayloadType,
119
120 DynamicBase = 96,
121 MaxPayloadType = 127,
122 IllegalPayloadType
123 };
124
125 unsigned GetVersion() const { return (theArray[0]>>6)&3; }
126
127 PBoolean GetExtension() const { return (theArray[0]&0x10) != 0; }
128 void SetExtension(PBoolean ext);
129
130 PBoolean GetMarker() const { return (theArray[1]&0x80) != 0; }
131 void SetMarker(PBoolean m);
132
133 bool GetPadding() const { return (theArray[0]&0x20) != 0; }
134 void SetPadding(bool v) { if (v) theArray[0] |= 0x20; else theArray[0] &= 0xdf; }
135 BYTE * GetPaddingPtr() const { return (BYTE *)(theArray+m_headerSize+m_payloadSize); }
136
137 unsigned GetPaddingSize() const { return m_paddingSize; }
138 bool SetPaddingSize(PINDEX sz);
139
140 PayloadTypes GetPayloadType() const { return (PayloadTypes)(theArray[1]&0x7f); }
141 void SetPayloadType(PayloadTypes t);
142
143 WORD GetSequenceNumber() const { return *(PUInt16b *)&theArray[2]; }
144 void SetSequenceNumber(WORD n) { *(PUInt16b *)&theArray[2] = n; }
145
146 DWORD GetTimestamp() const { return *(PUInt32b *)&theArray[4]; }
147 void SetTimestamp(DWORD t) { *(PUInt32b *)&theArray[4] = t; }
148
149 DWORD GetSyncSource() const { return *(PUInt32b *)&theArray[8]; }
150 void SetSyncSource(DWORD s) { *(PUInt32b *)&theArray[8] = s; }
151
152 PINDEX GetContribSrcCount() const { return theArray[0]&0xf; }
153 DWORD GetContribSource(PINDEX idx) const;
154 void SetContribSource(PINDEX idx, DWORD src);
155
156 PINDEX GetHeaderSize() const { return m_headerSize; }
157
158 int GetExtensionType() const; // -1 is no extension
159 void SetExtensionType(int type);
160 PINDEX GetExtensionSizeDWORDs() const; // get the number of 32 bit words in the extension (excluding the header).
161 bool SetExtensionSizeDWORDs(PINDEX sz); // set the number of 32 bit words in the extension (excluding the header)
162 BYTE * GetExtensionPtr() const;
163
164 PINDEX GetPayloadSize() const { return m_payloadSize; }
165 bool SetPayloadSize(PINDEX sz);
166 BYTE * GetPayloadPtr() const { return (BYTE *)(theArray+m_headerSize); }
167
168 virtual PObject * Clone() const { return new RTP_DataFrame(*this); }
169 virtual void PrintOn(ostream & strm) const;
170
171 // Note this sets the whole packet length, and calculates the various
172 // sub-section sizes: header payload and padding.
173 bool SetPacketSize(PINDEX sz);
174
175 protected:
176 PINDEX m_headerSize;
177 PINDEX m_payloadSize;
178 PINDEX m_paddingSize;
179
180 #if PTRACING
181 friend ostream & operator<<(ostream & o, PayloadTypes t);
182 #endif
183 };
184
185 PLIST(RTP_DataFrameList, RTP_DataFrame);
186
187
190 class RTP_ControlFrame : public PBYTEArray
191 {
192 PCLASSINFO(RTP_ControlFrame, PBYTEArray);
193
194 public:
195 RTP_ControlFrame(PINDEX compoundSize = 2048);
196
197 unsigned GetVersion() const { return (BYTE)theArray[compoundOffset]>>6; }
198
199 unsigned GetCount() const { return (BYTE)theArray[compoundOffset]&0x1f; }
200 void SetCount(unsigned count);
201
202 enum PayloadTypes {
203 e_IntraFrameRequest = 192,
204 e_SenderReport = 200,
205 e_ReceiverReport = 201,
206 e_SourceDescription = 202,
207 e_Goodbye = 203,
208 e_ApplDefined = 204,
209 e_TransportLayerFeedBack = 205, // RFC4585
210 e_PayloadSpecificFeedBack = 206,
211 e_ExtendedReport = 207 // RFC3611
212 };
213
214 unsigned GetPayloadType() const { return (BYTE)theArray[compoundOffset+1]; }
215 void SetPayloadType(unsigned t);
216
217 PINDEX GetPayloadSize() const { return 4*(*(PUInt16b *)&theArray[compoundOffset+2]); }
218 void SetPayloadSize(PINDEX sz);
219
220 BYTE * GetPayloadPtr() const;
221
222 PBoolean ReadNextPacket();
223 PBoolean StartNewPacket();
224 void EndPacket();
225
226 PINDEX GetCompoundSize() const;
227
228 void Reset(PINDEX size);
229
230 #pragma pack(1)
231 struct ReceiverReport {
232 PUInt32b ssrc; /* data source being reported */
233 BYTE fraction; /* fraction lost since last SR/RR */
234 BYTE lost[3]; /* cumulative number of packets lost (signed!) */
235 PUInt32b last_seq; /* extended last sequence number received */
236 PUInt32b jitter; /* interarrival jitter */
237 PUInt32b lsr; /* last SR packet from this source */
238 PUInt32b dlsr; /* delay since last SR packet */
239
240 unsigned GetLostPackets() const { return (lost[0]<<16U)+(lost[1]<<8U)+lost[2]; }
241 void SetLostPackets(unsigned lost);
242 };
243
244 struct SenderReport {
245 PUInt32b ntp_sec; /* NTP timestamp */
246 PUInt32b ntp_frac;
247 PUInt32b rtp_ts; /* RTP timestamp */
248 PUInt32b psent; /* packets sent */
249 PUInt32b osent; /* octets sent */
250 };
251
252 struct ExtendedReport {
253 /* VoIP Metrics Report Block */
254 BYTE bt; /* block type */
255 BYTE type_specific; /* determined by the block definition */
256 PUInt16b length; /* length of the report block */
257 PUInt32b ssrc; /* data source being reported */
258 BYTE loss_rate; /* fraction of RTP data packets lost */
259 BYTE discard_rate; /* fraction of RTP data packets discarded */
260 BYTE burst_density; /* fraction of RTP data packets within burst periods */
261 BYTE gap_density; /* fraction of RTP data packets within inter-burst gaps */
262 PUInt16b burst_duration; /* the mean duration, in ms, of burst periods */
263 PUInt16b gap_duration; /* the mean duration, in ms, of gap periods */
264 PUInt16b round_trip_delay; /* the most recently calculated round trip time */
265 PUInt16b end_system_delay; /* the most recently estimates end system delay */
266 BYTE signal_level; /* voice signal level related to 0 dBm */
267 BYTE noise_level; /* ratio of the silent background level to 0 dBm */
268 BYTE rerl; /* residual echo return loss */
269 BYTE gmin; /* gap threshold */
270 BYTE r_factor; /* voice quality metric of the call */
271 BYTE ext_r_factor; /* external R factor */
272 BYTE mos_lq; /* MOS for listen quality */
273 BYTE mos_cq; /* MOS for conversational quality */
274 BYTE rx_config; /* receiver configuration byte */
275 BYTE reserved; /* reserved for future definition */
276 PUInt16b jb_nominal; /* current nominal jitter buffer delay, in ms */
277 PUInt16b jb_maximum; /* current maximum jitter buffer delay, in ms */
278 PUInt16b jb_absolute; /* current absolute maximum jitter buffer delay, in ms */
279 };
280
281 enum DescriptionTypes {
282 e_END,
283 e_CNAME,
284 e_NAME,
285 e_EMAIL,
286 e_PHONE,
287 e_LOC,
288 e_TOOL,
289 e_NOTE,
290 e_PRIV,
291 NumDescriptionTypes
292 };
293
294 struct SourceDescription {
295 PUInt32b src; /* first SSRC/CSRC */
296 struct Item {
297 BYTE type; /* type of SDES item (enum DescriptionTypes) */
298 BYTE length; /* length of SDES item (in octets) */
299 char data[1]; /* text, not zero-terminated */
300
301 /* WARNING, SourceDescription may not be big enough to contain length and data, for
302 instance, when type == RTP_ControlFrame::e_END.
303 Be careful whan calling the following function of it may read to over to
304 memory allocated*/
305 unsigned int GetLengthTotal() const {return (unsigned int)(length + 2);}
306 const Item * GetNextItem() const { return (const Item *)((char *)this + length + 2); }
307 Item * GetNextItem() { return (Item *)((char *)this + length + 2); }
308 } item[1]; /* list of SDES items */
309 };
310
311 void StartSourceDescription(
312 DWORD src
313 );
314
315 void AddSourceDescriptionItem(
316 unsigned type,
317 const PString & data
318 );
319
320 // RFC4585 Feedback Message Type (FMT)
321 unsigned GetFbType() const { return (BYTE)theArray[compoundOffset]&0x1f; }
322 void SetFbType(unsigned type, PINDEX fciSize);
323
324 enum PayloadSpecificFbTypes {
325 e_PictureLossIndication = 1,
326 e_SliceLostIndication,
327 e_ReferencePictureSelectionIndication,
328 e_FullIntraRequest, //RFC5104
329 e_TemporalSpatialTradeOffRequest,
330 e_TemporalSpatialTradeOffNotification,
331 e_VideoBackChannelMessage,
332 e_ApplicationLayerFbMessage = 15
333 };
334
335 struct FbFCI {
336 PUInt32b senderSSRC; /* data source of sender of message */
337 PUInt32b mediaSSRC; /* data source of media */
338 };
339
340 struct FbFIR {
341 FbFCI fci;
342 PUInt32b requestSSRC;
343 BYTE sequenceNUmber;
344 };
345
346 struct FbTSTO {
347 FbFCI fci;
348 PUInt32b requestSSRC;
349 BYTE sequenceNUmber;
350 BYTE reserver[2];
351 BYTE tradeOff;
352 };
353
354 #pragma pack()
355
356 protected:
357 PINDEX compoundOffset;
358 PINDEX payloadSize;
359 };
360
361
362 class RTP_Session;
363
365
366 #if OPAL_STATISTICS
367
370 class OpalMediaStatistics : public PObject
371 {
372 PCLASSINFO(OpalMediaStatistics, PObject);
373 public:
374 OpalMediaStatistics();
375
376 // General info (typicallly from RTP)
377 PUInt64 m_totalBytes;
378 unsigned m_totalPackets;
379 unsigned m_packetsLost;
380 unsigned m_packetsOutOfOrder;
381 unsigned m_packetsTooLate;
382 unsigned m_packetOverruns;
383 unsigned m_minimumPacketTime;
384 unsigned m_averagePacketTime;
385 unsigned m_maximumPacketTime;
386
387 // Audio
388 unsigned m_averageJitter;
389 unsigned m_maximumJitter;
390 unsigned m_jitterBufferDelay;
391
392 // Video
393 unsigned m_totalFrames;
394 unsigned m_keyFrames;
395
396 // Fax
397 #if OPAL_FAX
398 enum {
399 FaxNotStarted = -2,
400 FaxInProgress = -1,
401 FaxSuccessful = 0,
402 FaxErrorBase = 1
403 };
404 enum FaxCompression {
405 FaxCompressionUnknown,
406 FaxCompressionT4_1d,
407 FaxCompressionT4_2d,
408 FaxCompressionT6,
409 };
410 friend ostream & operator<<(ostream & strm, FaxCompression compression);
411 struct Fax {
412 Fax();
413
414 int m_result; // -2=not started, -1=progress, 0=success, >0=ended with error
415 char m_phase; // 'A', 'B', 'D'
416 int m_bitRate; // e.g. 14400, 9600
417 FaxCompression m_compression; // 0=N/A, 1=T.4 1d, 2=T.4 2d, 3=T.6
418 bool m_errorCorrection;
419 int m_txPages;
420 int m_rxPages;
421 int m_totalPages;
422 int m_imageSize; // In bytes
423 int m_resolutionX; // Pixels per inch
424 int m_resolutionY; // Pixels per inch
425 int m_pageWidth;
426 int m_pageHeight;
427 int m_badRows; // Total number of bad rows
428 int m_mostBadRows; // Longest run of bad rows
429 int m_errorCorrectionRetries;
430
431 PString m_stationId; // Remote station identifier
432 PString m_errorText;
433 } m_fax;
434 #endif
435 };
436
437 #endif
438
439
444 class RTP_UserData : public PObject
445 {
446 PCLASSINFO(RTP_UserData, PObject);
447
448 public:
455 virtual void OnTxStatistics(
456 const RTP_Session & session
457 ) const;
458
465 virtual void OnRxStatistics(
466 const RTP_Session & session
467 ) const;
468
469 #if OPAL_VIDEO
470
475 virtual void OnTxIntraFrameRequest(
476 const RTP_Session & session
477 ) const;
478
484 virtual void OnRxIntraFrameRequest(
485 const RTP_Session & session
486 ) const;
487 #endif
488
492 virtual void SessionFailing(
493 RTP_Session & session
494 );
495 };
496
497 class RTP_Encoding;
498
499
502 class RTP_Session : public PObject
503 {
504 PCLASSINFO(RTP_Session, PObject);
505
506 public:
509 struct Params {
510 Params()
511 : id(0)
512 , userData(NULL)
513 , autoDelete(true)
514 , isAudio(false)
515 , remoteIsNAT(false)
516 { }
517
518 PString encoding;
519 unsigned id;
520 RTP_UserData * userData;
521 bool autoDelete;
522 bool isAudio;
523 bool remoteIsNAT;
524 };
525
528 RTP_Session(
529 const Params & options
530 );
531
535 ~RTP_Session();
537
547 void SetJitterBufferSize(
548 unsigned minJitterDelay,
549 unsigned maxJitterDelay,
550 unsigned timeUnits = 0,
551 PINDEX packetSize = 2048
552 );
553
559 unsigned GetJitterBufferSize() const;
560 unsigned GetJitterBufferDelay() const { return GetJitterBufferSize()/GetJitterTimeUnits(); }
561
564 unsigned GetJitterTimeUnits() const { return m_timeUnits; }
565
567 virtual PBoolean ModifyQOS(RTP_QOS * )
568 { return false; }
569
575 virtual PBoolean ReadBufferedData(
576 RTP_DataFrame & frame
577 );
578
584 virtual PBoolean ReadData(
585 RTP_DataFrame & frame
586 ) = 0;
587
590 virtual PBoolean WriteData(
591 RTP_DataFrame & frame
592 ) = 0;
593
597 virtual PBoolean WriteOOBData(
598 RTP_DataFrame & frame,
599 bool rewriteTimeStamp = true
600 );
601
604 virtual PBoolean WriteControl(
605 RTP_ControlFrame & frame
606 ) = 0;
607
610 virtual PBoolean SendReport();
611
614 virtual bool Close(
615 PBoolean reading
616 ) = 0;
617
620 virtual void Reopen(
621 PBoolean isReading
622 ) = 0;
623
626 virtual PString GetLocalHostName() = 0;
627
628 #if OPAL_STATISTICS
629 virtual void GetStatistics(OpalMediaStatistics & statistics, bool receiver) const;
630 #endif
631
632
635 enum SendReceiveStatus {
636 e_ProcessPacket,
637 e_IgnorePacket,
638 e_AbortTransport
639 };
640 virtual SendReceiveStatus OnSendData(RTP_DataFrame & frame);
641 virtual SendReceiveStatus Internal_OnSendData(RTP_DataFrame & frame);
642
643 virtual SendReceiveStatus OnSendControl(RTP_ControlFrame & frame, PINDEX & len);
644 virtual SendReceiveStatus Internal_OnSendControl(RTP_ControlFrame & frame, PINDEX & len);
645
646 virtual SendReceiveStatus OnReceiveData(RTP_DataFrame & frame);
647 virtual SendReceiveStatus Internal_OnReceiveData(RTP_DataFrame & frame);
648
649 virtual SendReceiveStatus OnReceiveControl(RTP_ControlFrame & frame);
650
651 class ReceiverReport : public PObject {
652 PCLASSINFO(ReceiverReport, PObject);
653 public:
654 void PrintOn(ostream &) const;
655
656 DWORD sourceIdentifier;
657 DWORD fractionLost; /* fraction lost since last SR/RR */
658 DWORD totalLost; /* cumulative number of packets lost (signed!) */
659 DWORD lastSequenceNumber; /* extended last sequence number received */
660 DWORD jitter; /* interarrival jitter */
661 PTimeInterval lastTimestamp;/* last SR packet from this source */
662 PTimeInterval delay; /* delay since last SR packet */
663 };
664 PARRAY(ReceiverReportArray, ReceiverReport);
665
666 class SenderReport : public PObject {
667 PCLASSINFO(SenderReport, PObject);
668 public:
669 void PrintOn(ostream &) const;
670
671 DWORD sourceIdentifier;
672 PTime realTimestamp;
673 DWORD rtpTimestamp;
674 DWORD packetsSent;
675 DWORD octetsSent;
676 };
677
678 virtual void OnRxSenderReport(const SenderReport & sender,
679 const ReceiverReportArray & reports);
680 virtual void OnRxReceiverReport(DWORD src,
681 const ReceiverReportArray & reports);
682 virtual void OnReceiverReports(const ReceiverReportArray & reports);
683
684 class SourceDescription : public PObject {
685 PCLASSINFO(SourceDescription, PObject);
686 public:
687 SourceDescription(DWORD src) { sourceIdentifier = src; }
688 void PrintOn(ostream &) const;
689
690 DWORD sourceIdentifier;
691 POrdinalToString items;
692 };
693 PARRAY(SourceDescriptionArray, SourceDescription);
694 virtual void OnRxSourceDescription(const SourceDescriptionArray & descriptions);
695
696 virtual void OnRxGoodbye(const PDWORDArray & sources,
697 const PString & reason);
698
699 virtual void OnRxApplDefined(const PString & type, unsigned subtype, DWORD src,
700 const BYTE * data, PINDEX size);
701
702 #if OPAL_RTCP_XR
703 class ExtendedReport : public PObject {
704 PCLASSINFO(ExtendedReport, PObject);
705 public:
706 void PrintOn(ostream &) const;
707
708 DWORD sourceIdentifier;
709 DWORD lossRate; /* fraction of RTP data packets lost */
710 DWORD discardRate; /* fraction of RTP data packets discarded */
711 DWORD burstDensity; /* fraction of RTP data packets within burst periods */
712 DWORD gapDensity; /* fraction of RTP data packets within inter-burst gaps */
713 DWORD roundTripDelay; /* the most recently calculated round trip time */
714 DWORD RFactor; /* voice quality metric of the call */
715 DWORD mosLQ; /* MOS for listen quality */
716 DWORD mosCQ; /* MOS for conversational quality */
717 DWORD jbNominal; /* current nominal jitter buffer delay, in ms */
718 DWORD jbMaximum; /* current maximum jitter buffer delay, in ms */
719 DWORD jbAbsolute; /* current absolute maximum jitter buffer delay, in ms */
720 };
721 PARRAY(ExtendedReportArray, ExtendedReport);
722
723 virtual void OnRxExtendedReport(DWORD src,
724 const ExtendedReportArray & reports);
725 #endif
726
727
732 unsigned GetSessionID() const { return sessionID; }
733
736 void SetSessionID(unsigned id) { sessionID = id; }
737
740 bool IsAudio() const { return isAudio; }
741
744 void SetAudio(
745 bool aud
746 ) { isAudio = aud; }
747
750 PString GetCanonicalName() const;
751
754 void SetCanonicalName(const PString & name);
755
758 PString GetToolName() const;
759
762 void SetToolName(const PString & name);
763
766 RTP_UserData * GetUserData() const { return userData; }
767
770 void SetUserData(
771 RTP_UserData * data,
772 PBoolean autoDeleteUserData = true
773 );
774
777 DWORD GetSyncSourceOut() const { return syncSourceOut; }
778
781 bool AllowAnySyncSource() const { return allowAnySyncSource; }
782
785 void SetAnySyncSource(
786 bool allow
787 ) { allowAnySyncSource = allow; }
788
791 void SetIgnorePayloadTypeChanges(
792 PBoolean ignore
793 ) { ignorePayloadTypeChanges = ignore; }
794
797 const PTimeInterval & GetReportTimeInterval() { return reportTimeInterval; }
798
801 void SetReportTimeInterval(
802 const PTimeInterval & interval
803 ) { reportTimeInterval = interval; }
804
807 PTimeInterval GetReportTimer()
808 { return reportTimer; }
809
812 unsigned GetTxStatisticsInterval() { return txStatisticsInterval; }
813
816 void SetTxStatisticsInterval(
817 unsigned packets
818 );
819
822 unsigned GetRxStatisticsInterval() { return rxStatisticsInterval; }
823
826 void SetRxStatisticsInterval(
827 unsigned packets
828 );
829
832 void ClearStatistics();
833
836 DWORD GetPacketsSent() const { return packetsSent; }
837
840 DWORD GetOctetsSent() const { return octetsSent; }
841
844 DWORD GetPacketsReceived() const { return packetsReceived; }
845
848 DWORD GetOctetsReceived() const { return octetsReceived; }
849
852 DWORD GetPacketsLost() const { return packetsLost; }
853
857 DWORD GetPacketsLostByRemote() const { return packetsLostByRemote; }
858
861 DWORD GetPacketsOutOfOrder() const { return packetsOutOfOrder; }
862
865 DWORD GetPacketsTooLate() const;
866
869 DWORD GetPacketOverruns() const;
870
875 DWORD GetAverageSendTime() const { return averageSendTime; }
876
881 DWORD GetMarkerRecvCount() const { return markerRecvCount; }
882
887 DWORD GetMarkerSendCount() const { return markerSendCount; }
888
893 DWORD GetMaximumSendTime() const { return maximumSendTime; }
894
899 DWORD GetMinimumSendTime() const { return minimumSendTime; }
900
905 DWORD GetAverageReceiveTime() const { return averageReceiveTime; }
906
911 DWORD GetMaximumReceiveTime() const { return maximumReceiveTime; }
912
917 DWORD GetMinimumReceiveTime() const { return minimumReceiveTime; }
918
919 enum { JitterRoundingGuardBits = 4 };
924 DWORD GetAvgJitterTime() const { return (jitterLevel>>JitterRoundingGuardBits)/GetJitterTimeUnits(); }
925
929 DWORD GetMaxJitterTime() const { return (maximumJitterLevel>>JitterRoundingGuardBits)/GetJitterTimeUnits(); }
930
935 DWORD GetJitterTimeOnRemote() const { return jitterLevelOnRemote/GetJitterTimeUnits(); }
937
938 virtual void SetCloseOnBYE(PBoolean v) { closeOnBye = v; }
939
944 virtual void SendIntraFrameRequest(bool rfc2032, bool pictureLoss);
945
950 virtual void SendTemporalSpatialTradeOff(unsigned tradeOff);
951
952 void SetNextSentSequenceNumber(WORD num) { lastSentSequenceNumber = (WORD)(num-1); }
953
954 virtual PString GetEncoding() const { return m_encoding; }
955 virtual void SetEncoding(const PString & newEncoding);
956
957 DWORD GetSyncSourceIn() const { return syncSourceIn; }
958
959 class EncodingLock
960 {
961 public:
962 EncodingLock(RTP_Session & _session);
963 ~EncodingLock();
964
965 __inline RTP_Encoding * operator->() const { return m_encodingHandler; }
966
967 protected:
968 RTP_Session & session;
969 RTP_Encoding * m_encodingHandler;
970 };
971
972 friend class EncodingLock;
973
974 void SetFailed(bool v)
975 { failed = v; }
976
977 bool HasFailed() const
978 { return failed; }
979
980 typedef PNotifierTemplate<SendReceiveStatus &> FilterNotifier;
981 #define PDECLARE_RTPFilterNotifier(cls, fn) PDECLARE_NOTIFIER2(RTP_DataFrame, cls, fn, RTP_Session::SendReceiveStatus &)
982 #define PCREATE_RTPFilterNotifier(fn) PCREATE_NOTIFIER2(fn, RTP_Session::SendReceiveStatus &)
983
984 void AddFilter(const FilterNotifier & filter);
985
986 #if OPAL_RTCP_XR
987 const RTCP_XR_Metrics & GetMetrics() const { return m_metrics; }
988 #endif
989
990 virtual void SendBYE();
991
992 protected:
993 void AddReceiverReport(RTP_ControlFrame::ReceiverReport & receiver);
994
995 PBoolean InsertReportPacket(RTP_ControlFrame & report);
996
997 #if OPAL_RTCP_XR
998 void InsertExtendedReportPacket(RTP_ControlFrame & report);
999 void OnRxSenderReportToMetrics(const RTP_ControlFrame & frame, PINDEX offset);
1000 #endif
1001
1002 PString m_encoding;
1003 PMutex m_encodingMutex;
1004 RTP_Encoding * m_encodingHandler;
1005
1006 unsigned sessionID;
1007 bool isAudio;
1008 unsigned m_timeUnits;
1009 PString canonicalName;
1010 PString toolName;
1011 RTP_UserData * userData;
1012 PBoolean autoDeleteUserData;
1013
1014 typedef PSafePtr<RTP_JitterBuffer, PSafePtrMultiThreaded> JitterBufferPtr;
1015 JitterBufferPtr m_jitterBuffer;
1016
1017 DWORD syncSourceOut;
1018 DWORD syncSourceIn;
1019 DWORD lastSentTimestamp;
1020 bool allowAnySyncSource;
1021 bool allowOneSyncSourceChange;
1022 PBoolean allowRemoteTransmitAddressChange;
1023 PBoolean allowSequenceChange;
1024 PTimeInterval reportTimeInterval;
1025 unsigned txStatisticsInterval;
1026 unsigned rxStatisticsInterval;
1027 WORD lastSentSequenceNumber;
1028 WORD expectedSequenceNumber;
1029 PTimeInterval lastSentPacketTime;
1030 PTimeInterval lastReceivedPacketTime;
1031 PTime lastSRTimestamp;
1032 PTime lastSRReceiveTime;
1033 PTimeInterval delaySinceLastSR;
1034 WORD lastRRSequenceNumber;
1035 bool resequenceOutOfOrderPackets;
1036 unsigned consecutiveOutOfOrderPackets;
1037 PTimeInterval outOfOrderWaitTime;
1038 PTimeInterval outOfOrderPacketTime;
1039
1040 std::list<RTP_DataFrame> m_outOfOrderPackets;
1041 void SaveOutOfOrderPacket(RTP_DataFrame & frame);
1042
1043 PMutex dataMutex;
1044 DWORD timeStampOffs; // offset between incoming media timestamp and timeStampOut
1045 PBoolean oobTimeStampBaseEstablished; // true if timeStampOffs has been established by media
1046 DWORD oobTimeStampOutBase; // base timestamp value for oob data
1047 PTimeInterval oobTimeStampBase; // base time for oob timestamp
1048
1049 // Statistics
1050 PTime firstPacketSent;
1051 DWORD packetsSent;
1052 DWORD rtcpPacketsSent;
1053 DWORD octetsSent;
1054 PTime firstPacketReceived;
1055 DWORD packetsReceived;
1056 DWORD senderReportsReceived;
1057 DWORD octetsReceived;
1058 DWORD packetsLost;
1059 DWORD packetsLostByRemote;
1060 DWORD packetsOutOfOrder;
1061 DWORD averageSendTime;
1062 DWORD maximumSendTime;
1063 DWORD minimumSendTime;
1064 DWORD averageReceiveTime;
1065 DWORD maximumReceiveTime;
1066 DWORD minimumReceiveTime;
1067 DWORD jitterLevel;
1068 DWORD jitterLevelOnRemote;
1069 DWORD maximumJitterLevel;
1070
1071 DWORD markerSendCount;
1072 DWORD markerRecvCount;
1073
1074 unsigned txStatisticsCount;
1075 unsigned rxStatisticsCount;
1076
1077 #if OPAL_RTCP_XR
1078 // Calculate the VoIP Metrics for RTCP-XR
1079 RTCP_XR_Metrics m_metrics;
1080 #endif
1081
1082 DWORD averageSendTimeAccum;
1083 DWORD maximumSendTimeAccum;
1084 DWORD minimumSendTimeAccum;
1085 DWORD averageReceiveTimeAccum;
1086 DWORD maximumReceiveTimeAccum;
1087 DWORD minimumReceiveTimeAccum;
1088 DWORD packetsLostSinceLastRR;
1089 DWORD lastTransitTime;
1090
1091 RTP_DataFrame::PayloadTypes lastReceivedPayloadType;
1092 PBoolean ignorePayloadTypeChanges;
1093
1094 PMutex reportMutex;
1095 PTimer reportTimer;
1096
1097 PBoolean closeOnBye;
1098 PBoolean byeSent;
1099 bool failed;
1100
1101 list<FilterNotifier> m_filters;
1102 };
1103
1106 class RTP_UDP : public RTP_Session
1107 {
1108 PCLASSINFO(RTP_UDP, RTP_Session);
1109
1110 public:
1115 RTP_UDP(
1116 const Params & options
1117 );
1118
1120 ~RTP_UDP();
1122
1130 virtual PBoolean ReadData(RTP_DataFrame & frame);
1131 virtual PBoolean Internal_ReadData(RTP_DataFrame & frame);
1132
1135 virtual PBoolean WriteData(RTP_DataFrame & frame);
1136 virtual PBoolean Internal_WriteData(RTP_DataFrame & frame);
1137
1141 virtual PBoolean WriteOOBData(RTP_DataFrame & frame, bool setTimeStamp = true);
1142
1145 virtual PBoolean WriteControl(RTP_ControlFrame & frame);
1146
1149 virtual bool Close(
1150 PBoolean reading
1151 );
1152
1155 virtual PString GetLocalHostName();
1157
1160 virtual PBoolean ModifyQOS(RTP_QOS * rtpqos);
1161
1166 virtual PBoolean Open(
1167 PIPSocket::Address localAddress,
1168 WORD portBase,
1169 WORD portMax,
1170 BYTE ipTypeOfService,
1171 PNatMethod * natMethod = NULL,
1172 RTP_QOS * rtpqos = NULL
1173 );
1175
1178 virtual void Reopen(PBoolean isReading);
1180
1185 virtual PIPSocket::Address GetLocalAddress() const { return localAddress; }
1186
1189 virtual void SetLocalAddress(
1190 const PIPSocket::Address & addr
1191 ) { localAddress = addr; }
1192
1195 PIPSocket::Address GetRemoteAddress() const { return remoteAddress; }
1196
1199 virtual WORD GetLocalDataPort() const { return localDataPort; }
1200
1203 virtual WORD GetLocalControlPort() const { return localControlPort; }
1204
1207 virtual WORD GetRemoteDataPort() const { return remoteDataPort; }
1208
1211 virtual WORD GetRemoteControlPort() const { return remoteControlPort; }
1212
1215 virtual PUDPSocket & GetDataSocket() { return *dataSocket; }
1216
1219 virtual PUDPSocket & GetControlSocket() { return *controlSocket; }
1220
1223 virtual PBoolean SetRemoteSocketInfo(
1224 PIPSocket::Address address,
1225 WORD port,
1226 PBoolean isDataPort
1227 );
1228
1231 virtual void ApplyQOS(
1232 const PIPSocket::Address & addr
1233 );
1235
1236 virtual int GetDataSocketHandle() const
1237 { return dataSocket != NULL ? dataSocket->GetHandle() : -1; }
1238
1239 virtual int GetControlSocketHandle() const
1240 { return controlSocket != NULL ? controlSocket->GetHandle() : -1; }
1241
1242 friend class RTP_Encoding;
1243
1244 virtual int WaitForPDU(PUDPSocket & dataSocket, PUDPSocket & controlSocket, const PTimeInterval & timer);
1245 virtual int Internal_WaitForPDU(PUDPSocket & dataSocket, PUDPSocket & controlSocket, const PTimeInterval & timer);
1246
1247 virtual SendReceiveStatus ReadDataPDU(RTP_DataFrame & frame);
1248 virtual SendReceiveStatus Internal_ReadDataPDU(RTP_DataFrame & frame);
1249
1250 virtual SendReceiveStatus OnReadTimeout(RTP_DataFrame & frame);
1251 virtual SendReceiveStatus Internal_OnReadTimeout(RTP_DataFrame & frame);
1252
1253 virtual SendReceiveStatus ReadControlPDU();
1254 virtual SendReceiveStatus ReadDataOrControlPDU(
1255 BYTE * framePtr,
1256 PINDEX frameSize,
1257 PBoolean fromDataChannel
1258 );
1259
1260 virtual bool WriteDataPDU(RTP_DataFrame & frame);
1261 virtual bool WriteDataOrControlPDU(
1262 const BYTE * framePtr,
1263 PINDEX frameSize,
1264 bool toDataChannel
1265 );
1266
1267 virtual void SetEncoding(const PString & newEncoding);
1268
1269
1270 protected:
1271 PIPSocket::Address localAddress;
1272 WORD localDataPort;
1273 WORD localControlPort;
1274
1275 PIPSocket::Address remoteAddress;
1276 WORD remoteDataPort;
1277 WORD remoteControlPort;
1278
1279 PIPSocket::Address remoteTransmitAddress;
1280
1281 PUDPSocket * dataSocket;
1282 PUDPSocket * controlSocket;
1283
1284 bool shutdownRead;
1285 bool shutdownWrite;
1286 bool appliedQOS;
1287 bool remoteIsNAT;
1288 bool localHasNAT;
1289 bool m_firstData;
1290 bool m_firstControl;
1291 int badTransmitCounter;
1292 PTime badTransmitStart;
1293
1294 PTimer timerWriteDataIdle;
1295 PDECLARE_NOTIFIER(PTimer, RTP_UDP, OnWriteDataIdle);
1296 };
1297
1299
1300 class RTP_UDP;
1301
1302 class RTP_Encoding
1303 {
1304 public:
1305 RTP_Encoding();
1306 virtual ~RTP_Encoding();
1307 virtual void ApplyStringOptions(const PStringToString & /*stringOptions*/) {}
1308 virtual void OnStart(RTP_Session & _rtpSession);
1309 virtual void OnFinish();
1310 virtual RTP_Session::SendReceiveStatus OnSendData(RTP_DataFrame & frame);
1311 virtual PBoolean WriteData(RTP_DataFrame & frame, bool oob);
1312 virtual PBoolean WriteDataPDU(RTP_DataFrame & frame);
1313 virtual void OnWriteDataIdle() {}
1314 virtual void SetWriteDataIdleTimer(PTimer &) {}
1315 virtual RTP_Session::SendReceiveStatus OnSendControl(RTP_ControlFrame & frame, PINDEX & len);
1316 virtual RTP_Session::SendReceiveStatus ReadDataPDU(RTP_DataFrame & frame);
1317 virtual RTP_Session::SendReceiveStatus OnReceiveData(RTP_DataFrame & frame);
1318 virtual RTP_Session::SendReceiveStatus OnReadTimeout(RTP_DataFrame & frame);
1319 virtual PBoolean ReadData(RTP_DataFrame & frame);
1320 virtual int WaitForPDU(PUDPSocket & dataSocket, PUDPSocket & controlSocket, const PTimeInterval &);
1321
1322 PMutex mutex;
1323 unsigned refCount;
1324
1325 protected:
1326 RTP_UDP * rtpUDP;
1327 };
1328
1329 PFACTORY_LOAD(RTP_Encoding);
1330
1331
1333
1334 class SecureRTP_UDP : public RTP_UDP
1335 {
1336 PCLASSINFO(SecureRTP_UDP, RTP_UDP);
1337
1338 public:
1343 SecureRTP_UDP(
1344 const Params & options
1345 );
1346
1348 ~SecureRTP_UDP();
1349
1350 virtual void SetSecurityMode(OpalSecurityMode * srtpParms);
1351 virtual OpalSecurityMode * GetSecurityParms() const;
1352
1353 protected:
1354 OpalSecurityMode * securityParms;
1355 };
1356
1357 #endif // OPAL_RTP_RTP_H
1358