8 * Copyright (c) 1998-2000 Equivalence Pty. Ltd.
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/
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
20 * The Original Code is Open H323 Library.
22 * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
24 * Portions of this code were written with the assisance of funding from
25 * Vovida Networks, Inc. http://www.vovida.com.
27 * Contributor(s): ______________________________________.
30 * Revision 1.60 2006/01/26 03:35:03 shorne
31 * Added more NAT traversal support
33 * Revision 1.59 2006/01/18 07:46:08 csoutheren
34 * Initial version of RTP aggregation (disabled by default)
36 * Revision 1.58 2005/11/30 13:05:01 csoutheren
37 * Changed tags for Doxygen
39 * Revision 1.57 2005/11/21 21:06:23 shorne
42 * Revision 1.56 2005/08/27 02:06:00 csoutheren
43 * Keep track of time first RTP packet is received
45 * Revision 1.55 2005/01/03 14:03:20 csoutheren
46 * Added new configure options and ability to disable/enable modules
48 * Revision 1.54 2005/01/03 06:25:52 csoutheren
49 * Added extensive support for disabling code modules at compile time
51 * Revision 1.53 2004/04/22 12:38:02 rjongbloed
52 * Removed the RTP QoS class if there is no QoS support in build,
53 * thanks Nick Hoath, ISDN Communications Ltd.
55 * Revision 1.52 2004/04/07 05:31:42 csoutheren
56 * Added ability to receive calls from endpoints behind NAT firewalls
58 * Revision 1.51 2003/10/27 06:03:39 csoutheren
59 * Added support for QoS
60 * Thanks to Henry Harrison of AliceStreet
62 * Revision 1.50 2003/10/09 09:47:45 csoutheren
63 * Fixed problem with re-opening RTP half-channels under unusual
64 * circumstances. Thanks to Damien Sandras
66 * Revision 1.49 2003/05/14 13:46:39 rjongbloed
67 * Removed hack of using special payload type for H.263 for a method which
68 * would be less prone to failure in the future.
70 * Revision 1.48 2003/05/02 04:57:43 robertj
71 * Added header extension support to RTP data frame class.
73 * Revision 1.47 2003/05/02 04:21:53 craigs
74 * Added hacked OpalH263 codec
76 * Revision 1.46 2003/02/07 00:30:41 robertj
77 * Changes for bizarre usage of RTP code outside of scope of H.323 specs.
79 * Revision 1.45 2003/02/05 06:32:08 robertj
80 * Fixed non-stun symmetric NAT support recently broken.
82 * Revision 1.44 2003/02/04 07:06:41 robertj
85 * Revision 1.43 2002/11/19 01:48:15 robertj
86 * Allowed get/set of canonical anme and tool name.
88 * Revision 1.42 2002/11/12 22:10:48 robertj
89 * Updated documentation.
91 * Revision 1.41 2002/10/31 00:33:29 robertj
92 * Enhanced jitter buffer system so operates dynamically between minimum and
93 * maximum values. Altered API to assure app writers note the change!
95 * Revision 1.40 2002/09/26 04:01:58 robertj
96 * Fixed calculation of fraction of packets lost in RR, thanks Awais Ali
98 * Revision 1.39 2002/09/16 01:14:15 robertj
99 * Added #define so can select if #pragma interface/implementation is used on
100 * platform basis (eg MacOS) rather than compiler, thanks Robert Monaghan.
102 * Revision 1.38 2002/09/03 05:47:02 robertj
103 * Normalised the multi-include header prevention ifdef/define symbol.
104 * Added copy constructor/operator for session manager.
106 * Revision 1.37 2002/08/05 10:03:47 robertj
107 * Cosmetic changes to normalise the usage of pragma interface/implementation.
109 * Revision 1.36 2002/05/28 02:37:37 robertj
110 * Fixed reading data out of RTCP compound statements.
112 * Revision 1.35 2002/05/02 05:58:24 robertj
113 * Changed the mechanism for sending RTCP reports so that they will continue
114 * to be sent regardless of if there is any actual data traffic.
115 * Added support for compound RTCP statements for sender and receiver reports.
117 * Revision 1.34 2002/02/09 02:33:37 robertj
118 * Improved payload type docuemntation and added Cisco CN.
120 * Revision 1.33 2002/01/22 07:08:26 robertj
121 * Added IllegalPayloadType enum as need marker for none set
122 * and MaxPayloadType is a legal value.
124 * Revision 1.32 2001/11/09 05:39:54 craigs
125 * Added initial T.38 support thanks to Adam Lazur
127 * Revision 1.31 2001/09/11 00:21:21 robertj
128 * Fixed missing stack sizes in endpoint for cleaner thread and jitter thread.
130 * Revision 1.30 2001/07/06 06:32:22 robertj
131 * Added flag and checks for RTP data having specific SSRC.
132 * Changed transmitter IP address check so is based on first received
133 * PDU instead of expecting it to come from the host we are sending to.
135 * Revision 1.29 2001/06/04 11:37:48 robertj
136 * Added thread safe enumeration functions of RTP sessions.
137 * Added member access functions to UDP based RTP sessions.
139 * Revision 1.28 2001/04/24 06:15:50 robertj
140 * Added work around for strange Cisco bug which suddenly starts sending
141 * RTP packets beginning at a difference sequence number base.
143 * Revision 1.27 2001/04/02 23:58:23 robertj
144 * Added jitter calculation to RTP session.
145 * Added trace of statistics.
147 * Revision 1.26 2001/02/09 05:16:24 robertj
148 * Added #pragma interface for GNU C++.
150 * Revision 1.25 2000/12/18 08:58:30 craigs
151 * Added ability set ports
153 * Revision 1.24 2000/09/25 01:44:31 robertj
154 * Fixed possible race condition on shutdown of RTP session with jitter buffer.
156 * Revision 1.23 2000/09/21 02:06:06 craigs
157 * Added handling for endpoints that return conformant, but useless, RTP address
160 * Revision 1.22 2000/05/23 12:57:28 robertj
161 * Added ability to change IP Type Of Service code from applications.
163 * Revision 1.21 2000/05/18 11:53:34 robertj
164 * Changes to support doc++ documentation generation.
166 * Revision 1.20 2000/05/04 11:49:21 robertj
167 * Added Packets Too Late statistics, requiring major rearrangement of jitter buffer code.
169 * Revision 1.19 2000/05/02 04:32:25 robertj
170 * Fixed copyright notice comment.
172 * Revision 1.18 2000/05/01 01:01:24 robertj
173 * Added flag for what to do with out of orer packets (use if jitter, don't if not).
175 * Revision 1.17 2000/04/30 03:55:18 robertj
176 * Improved the RTCP messages, epecially reports
178 * Revision 1.16 2000/04/10 17:39:21 robertj
179 * Fixed debug output of RTP payload types to allow for unknown numbers.
181 * Revision 1.15 2000/04/05 03:17:31 robertj
182 * Added more RTP statistics gathering and H.245 round trip delay calculation.
184 * Revision 1.14 2000/03/23 02:55:18 robertj
185 * Added sending of SDES control packets.
187 * Revision 1.13 2000/03/20 20:54:04 robertj
188 * Fixed problem with being able to reopen for reading an RTP_Session (Cisco compatibilty)
190 * Revision 1.12 2000/02/29 13:00:13 robertj
191 * Added extra statistic display for RTP packets out of order.
193 * Revision 1.11 1999/12/30 09:14:31 robertj
194 * Changed payload type functions to use enum.
196 * Revision 1.10 1999/12/23 23:02:35 robertj
197 * File reorganision for separating RTP from H.323 and creation of LID for VPB support.
199 * Revision 1.9 1999/11/20 05:35:57 robertj
200 * Fixed possibly I/O block in RTP read loops.
202 * Revision 1.8 1999/11/19 09:17:15 robertj
203 * Fixed problems with aycnhronous shut down of logical channels.
205 * Revision 1.7 1999/11/14 11:41:18 robertj
206 * Added access functions to RTP statistics.
208 * Revision 1.6 1999/09/08 04:05:48 robertj
209 * Added support for video capabilities & codec, still needs the actual codec itself!
211 * Revision 1.5 1999/08/31 12:34:18 robertj
212 * Added gatekeeper support.
214 * Revision 1.4 1999/07/13 09:53:24 robertj
215 * Fixed some problems with jitter buffer and added more debugging.
217 * Revision 1.3 1999/07/09 06:09:49 robertj
218 * Major implementation. An ENORMOUS amount of stuff added everywhere.
220 * Revision 1.2 1999/06/22 13:49:40 robertj
221 * Added GSM support and further RTP protocol enhancements.
223 * Revision 1.1 1999/06/14 06:12:25 robertj
224 * Changes for using RTP sessions correctly in H323 Logical Channel context
235 #include <openh323buildopts.h>
236 #include <ptlib/sockets.h>
238 class RTP_JitterBuffer;
239 class PHandleAggregator;
245 ///////////////////////////////////////////////////////////////////////////////
247 // class to hold the QoS definitions for an RTP channel
251 class RTP_QOS : public PObject
253 PCLASSINFO(RTP_QOS,PObject);
265 ///////////////////////////////////////////////////////////////////////////////
266 // Real Time Protocol - IETF RFC1889 and RFC1890
268 /**An RTP data frame encapsulation.
270 class RTP_DataFrame : public PBYTEArray
272 PCLASSINFO(RTP_DataFrame, PBYTEArray);
275 RTP_DataFrame(PINDEX payloadSize = 2048);
284 FS1016, // Federal Standard 1016 CELP
285 G721, // ADPCM - Subsumed by G.726
288 G7231, // G.723.1 at 6.3kbps or 5.3 kbps
289 DVI4_8k, // DVI4 at 8kHz sample rate
290 DVI4_16k, // DVI4 at 16kHz sample rate
291 LPC, // LPC-10 Linear Predictive CELP
294 L16_Stereo, // 16 bit linear PCM
295 L16_Mono, // 16 bit linear PCM
298 MPA, // MPEG1 or MPEG2 audio
299 G728, // G.728 16kbps CELP
300 DVI4_11k, // DVI4 at 11kHz sample rate
301 DVI4_22k, // DVI4 at 22kHz sample rate
303 Cisco_CN, // Cisco systems comfort noise (unofficial)
305 CelB = 25, // Sun Systems Cell-B video
308 MPV, // MPEG1 or MPEG2 video
309 MP2T, // MPEG2 transport system
312 LastKnownPayloadType,
315 MaxPayloadType = 127,
319 unsigned GetVersion() const { return (theArray[0]>>6)&3; }
321 BOOL GetExtension() const { return (theArray[0]&0x10) != 0; }
322 void SetExtension(BOOL ext);
324 BOOL GetMarker() const { return (theArray[1]&0x80) != 0; }
325 void SetMarker(BOOL m);
327 PayloadTypes GetPayloadType() const { return (PayloadTypes)(theArray[1]&0x7f); }
328 void SetPayloadType(PayloadTypes t);
330 WORD GetSequenceNumber() const { return *(PUInt16b *)&theArray[2]; }
331 void SetSequenceNumber(WORD n) { *(PUInt16b *)&theArray[2] = n; }
333 DWORD GetTimestamp() const { return *(PUInt32b *)&theArray[4]; }
334 void SetTimestamp(DWORD t) { *(PUInt32b *)&theArray[4] = t; }
336 DWORD GetSyncSource() const { return *(PUInt32b *)&theArray[8]; }
337 void SetSyncSource(DWORD s) { *(PUInt32b *)&theArray[8] = s; }
339 PINDEX GetContribSrcCount() const { return theArray[0]&0xf; }
340 DWORD GetContribSource(PINDEX idx) const;
341 void SetContribSource(PINDEX idx, DWORD src);
343 PINDEX GetHeaderSize() const;
345 int GetExtensionType() const; // -1 is no extension
346 void SetExtensionType(int type);
347 PINDEX GetExtensionSize() const;
348 BOOL SetExtensionSize(PINDEX sz);
349 BYTE * GetExtensionPtr() const;
351 PINDEX GetPayloadSize() const { return payloadSize; }
352 BOOL SetPayloadSize(PINDEX sz);
353 BYTE * GetPayloadPtr() const { return (BYTE *)(theArray+GetHeaderSize()); }
359 friend ostream & operator<<(ostream & o, PayloadTypes t);
363 PLIST(RTP_DataFrameList, RTP_DataFrame);
366 /**An RTP control frame encapsulation.
368 class RTP_ControlFrame : public PBYTEArray
370 PCLASSINFO(RTP_ControlFrame, PBYTEArray);
373 RTP_ControlFrame(PINDEX compoundSize = 2048);
375 unsigned GetVersion() const { return (BYTE)theArray[compoundOffset]>>6; }
377 unsigned GetCount() const { return (BYTE)theArray[compoundOffset]&0x1f; }
378 void SetCount(unsigned count);
381 e_SenderReport = 200,
388 unsigned GetPayloadType() const { return (BYTE)theArray[compoundOffset+1]; }
389 void SetPayloadType(unsigned t);
391 PINDEX GetPayloadSize() const { return 4*(*(PUInt16b *)&theArray[compoundOffset+2]); }
392 void SetPayloadSize(PINDEX sz);
394 BYTE * GetPayloadPtr() const { return (BYTE *)(theArray+compoundOffset+4); }
396 BOOL ReadNextCompound();
397 BOOL WriteNextCompound();
399 PINDEX GetCompoundSize() const { return compoundSize; }
402 struct ReceiverReport {
403 PUInt32b ssrc; /* data source being reported */
404 BYTE fraction; /* fraction lost since last SR/RR */
405 BYTE lost[3]; /* cumulative number of packets lost (signed!) */
406 PUInt32b last_seq; /* extended last sequence number received */
407 PUInt32b jitter; /* interarrival jitter */
408 PUInt32b lsr; /* last SR packet from this source */
409 PUInt32b dlsr; /* delay since last SR packet */
411 unsigned GetLostPackets() const { return (lost[0]<<16U)+(lost[1]<<8U)+lost[2]; }
412 void SetLostPackets(unsigned lost);
415 struct SenderReport {
416 PUInt32b ssrc; /* source this RTCP packet refers to */
417 PUInt32b ntp_sec; /* NTP timestamp */
419 PUInt32b rtp_ts; /* RTP timestamp */
420 PUInt32b psent; /* packets sent */
421 PUInt32b osent; /* octets sent */
424 enum DescriptionTypes {
437 struct SourceDescription {
438 PUInt32b src; /* first SSRC/CSRC */
440 BYTE type; /* type of SDES item (enum DescriptionTypes) */
441 BYTE length; /* length of SDES item (in octets) */
442 char data[1]; /* text, not zero-terminated */
444 const Item * GetNextItem() const { return (const Item *)((char *)this + length + 2); }
445 Item * GetNextItem() { return (Item *)((char *)this + length + 2); }
446 } item[1]; /* list of SDES items */
449 SourceDescription & AddSourceDescription(
450 DWORD src ///< SSRC/CSRC identifier
453 SourceDescription::Item & AddSourceDescriptionItem(
454 SourceDescription & sdes, ///< SDES record to add item to
455 unsigned type, ///< Description type
456 const PString & data ///< Data for description
461 PINDEX compoundOffset;
468 /**This class is the base for user data that may be attached to the RTP_session
469 allowing callbacks for statistics and progress monitoring to be passed to an
470 arbitrary object that an RTP consumer may require.
472 class RTP_UserData : public PObject
474 PCLASSINFO(RTP_UserData, PObject);
477 /**Callback from the RTP session for transmit statistics monitoring.
478 This is called every RTP_Session::txStatisticsInterval packets on the
479 transmitter indicating that the statistics have been updated.
481 The default behaviour does nothing.
483 virtual void OnTxStatistics(
484 const RTP_Session & session ///< Session with statistics
487 /**Callback from the RTP session for receive statistics monitoring.
488 This is called every RTP_Session::receiverReportInterval packets on the
489 receiver indicating that the statistics have been updated.
491 The default behaviour does nothing.
493 virtual void OnRxStatistics(
494 const RTP_Session & session ///< Session with statistics
499 /**This class is for encpsulating the IETF Real Time Protocol interface.
501 class RTP_Session : public PObject
503 PCLASSINFO(RTP_Session, PObject);
507 DefaultAudioSessionID = 1,
508 DefaultVideoSessionID = 2,
509 DefaultFaxSessionID = 3
512 /**@name Construction */
514 /**Create a new RTP session.
517 #ifdef H323_RTP_AGGREGATE
518 PHandleAggregator * aggregator, ///< RTP aggregator
520 unsigned id, ///< Session ID for RTP channel
521 RTP_UserData * userData = NULL ///< Optional data for session.
525 This deletes the userData field.
530 /**@name Operations */
532 /**Sets the size of the jitter buffer to be used by this RTP session.
533 A session default to not having any jitter buffer enabled for reading
534 and the ReadBufferedData() function simply calls ReadData(). Once a
535 jitter buffer has been created it cannot be removed, though its size
538 If the jitterDelay paramter is zero, it destroys the jitter buffer
539 attached to this RTP session.
541 void SetJitterBufferSize(
542 unsigned minJitterDelay, ///< Minimum jitter buffer delay in RTP timestamp units
543 unsigned maxJitterDelay, ///< Maximum jitter buffer delay in RTP timestamp units
544 PINDEX stackSize = 30000 ///< Stack size for jitter thread
547 /**Get current size of the jitter buffer.
548 This returns the currently used jitter buffer delay in RTP timestamp
549 units. It will be some value between the minimum and maximum set in
550 the SetJitterBufferSize() function.
552 unsigned GetJitterBufferSize() const;
554 /**Modifies the QOS specifications for this RTP session*/
555 virtual BOOL ModifyQOS(RTP_QOS * )
558 /**Read a data frame from the RTP channel.
559 This function will conditionally read data from eth jitter buffer or
560 directly if there is no jitter buffer enabled. An application should
561 generally use this in preference to directly calling ReadData().
563 BOOL ReadBufferedData(
564 DWORD timestamp, ///< Timestamp to read from buffer.
565 RTP_DataFrame & frame ///< Frame read from the RTP session
568 /**Read a data frame from the RTP channel.
569 Any control frames received are dispatched to callbacks and are not
570 returned by this function. It will block until a data frame is
571 available or an error occurs.
573 virtual BOOL ReadData(
574 RTP_DataFrame & frame, ///< Frame read from the RTP session
575 BOOL loop ///< If TRUE, loop as long as data is available, if FALSE, only process once
578 /**Write a data frame from the RTP channel.
580 virtual BOOL WriteData(
581 RTP_DataFrame & frame ///< Frame to write to the RTP session
584 /**Write a control frame from the RTP channel.
586 virtual BOOL WriteControl(
587 RTP_ControlFrame & frame ///< Frame to write to the RTP session
590 /**Write the RTCP reports.
592 virtual BOOL SendReport();
594 /**Close down the RTP session.
597 BOOL reading ///< Closing the read side of the session
600 /**Get the local host name as used in SDES packes.
602 virtual PString GetLocalHostName() = 0;
605 /**@name Call back functions */
607 enum SendReceiveStatus {
612 virtual SendReceiveStatus OnSendData(RTP_DataFrame & frame);
613 virtual SendReceiveStatus OnReceiveData(const RTP_DataFrame & frame);
614 virtual SendReceiveStatus OnReceiveControl(RTP_ControlFrame & frame);
616 class ReceiverReport : public PObject {
617 PCLASSINFO(ReceiverReport, PObject);
619 void PrintOn(ostream &) const;
621 DWORD sourceIdentifier;
622 DWORD fractionLost; /* fraction lost since last SR/RR */
623 DWORD totalLost; /* cumulative number of packets lost (signed!) */
624 DWORD lastSequenceNumber; /* extended last sequence number received */
625 DWORD jitter; /* interarrival jitter */
626 PTimeInterval lastTimestamp;/* last SR packet from this source */
627 PTimeInterval delay; /* delay since last SR packet */
629 PARRAY(ReceiverReportArray, ReceiverReport);
631 class SenderReport : public PObject {
632 PCLASSINFO(SenderReport, PObject);
634 void PrintOn(ostream &) const;
636 DWORD sourceIdentifier;
642 virtual void OnRxSenderReport(const SenderReport & sender,
643 const ReceiverReportArray & reports);
644 virtual void OnRxReceiverReport(DWORD src,
645 const ReceiverReportArray & reports);
647 class SourceDescription : public PObject {
648 PCLASSINFO(SourceDescription, PObject);
650 SourceDescription(DWORD src) { sourceIdentifier = src; }
651 void PrintOn(ostream &) const;
653 DWORD sourceIdentifier;
654 POrdinalToString items;
656 PARRAY(SourceDescriptionArray, SourceDescription);
657 virtual void OnRxSourceDescription(const SourceDescriptionArray & descriptions);
659 virtual void OnRxGoodbye(const PDWORDArray & sources,
660 const PString & reason);
662 virtual void OnRxApplDefined(const PString & type, unsigned subtype, DWORD src,
663 const BYTE * data, PINDEX size);
666 /**@name Member variable access */
668 /**Get the ID for the RTP session.
670 unsigned GetSessionID() const { return sessionID; }
672 /**Get the canonical name for the RTP session.
674 PString GetCanonicalName() const;
676 /**Set the canonical name for the RTP session.
678 void SetCanonicalName(const PString & name);
680 /**Get the tool name for the RTP session.
682 PString GetToolName() const;
684 /**Set the tool name for the RTP session.
686 void SetToolName(const PString & name);
688 /**Get the user data for the session.
690 RTP_UserData * GetUserData() const { return userData; }
692 /**Set the user data for the session.
695 RTP_UserData * data ///< New user data to be used
698 /**Get the source output identifier.
700 DWORD GetSyncSourceOut() const { return syncSourceOut; }
702 /**Increment reference count for RTP session.
704 void IncrementReference() { referenceCount++; }
706 /**Decrement reference count for RTP session.
708 BOOL DecrementReference() { return --referenceCount == 0; }
710 /**Indicate if will ignore all but first received SSRC value.
712 BOOL WillIgnoreOtherSources() const { return ignoreOtherSources; }
714 /**Indicate if will ignore all but first received SSRC value.
716 void SetIgnoreOtherSources(
717 BOOL ignore ///< Flag for ignore other SSRC values
718 ) { ignoreOtherSources = ignore; }
720 /**Indicate if will ignore out of order packets.
722 BOOL WillIgnoreOutOfOrderPackets() const { return ignoreOutOfOrderPackets; }
724 /**Indicate if will ignore out of order packets.
726 void SetIgnoreOutOfOrderPackets(
727 BOOL ignore ///< Flag for ignore out of order packets
728 ) { ignoreOutOfOrderPackets = ignore; }
730 /**Get the time interval for sending RTCP reports in the session.
732 const PTimeInterval & GetReportTimeInterval() { return reportTimeInterval; }
734 /**Set the time interval for sending RTCP reports in the session.
736 void SetReportTimeInterval(
737 const PTimeInterval & interval ///< New time interval for reports.
738 ) { reportTimeInterval = interval; }
740 /**Get the current report timer
742 PTimeInterval GetReportTimer()
743 { return reportTimer; }
745 /**Get the interval for transmitter statistics in the session.
747 unsigned GetTxStatisticsInterval() { return txStatisticsInterval; }
749 /**Set the interval for transmitter statistics in the session.
751 void SetTxStatisticsInterval(
752 unsigned packets ///< Number of packets between callbacks
755 /**Get the interval for receiver statistics in the session.
757 unsigned GetRxStatisticsInterval() { return rxStatisticsInterval; }
759 /**Set the interval for receiver statistics in the session.
761 void SetRxStatisticsInterval(
762 unsigned packets ///< Number of packets between callbacks
765 /**Get total number of packets sent in session.
767 DWORD GetPacketsSent() const { return packetsSent; }
769 /**Get total number of octets sent in session.
771 DWORD GetOctetsSent() const { return octetsSent; }
773 /**Get total number of packets received in session.
775 DWORD GetPacketsReceived() const { return packetsReceived; }
777 /**Get total number of octets received in session.
779 DWORD GetOctetsReceived() const { return octetsReceived; }
781 /**Get total number received packets lost in session.
783 DWORD GetPacketsLost() const { return packetsLost; }
785 /**Get total number of packets received out of order in session.
787 DWORD GetPacketsOutOfOrder() const { return packetsOutOfOrder; }
789 /**Get total number received packets too late to go into jitter buffer.
791 DWORD GetPacketsTooLate() const;
793 /**Get average time between sent packets.
794 This is averaged over the last txStatisticsInterval packets and is in
797 DWORD GetAverageSendTime() const { return averageSendTime; }
799 /**Get maximum time between sent packets.
800 This is over the last txStatisticsInterval packets and is in
803 DWORD GetMaximumSendTime() const { return maximumSendTime; }
805 /**Get minimum time between sent packets.
806 This is over the last txStatisticsInterval packets and is in
809 DWORD GetMinimumSendTime() const { return minimumSendTime; }
811 /**Get average time between received packets.
812 This is averaged over the last rxStatisticsInterval packets and is in
815 DWORD GetAverageReceiveTime() const { return averageReceiveTime; }
817 /**Get maximum time between received packets.
818 This is over the last rxStatisticsInterval packets and is in
821 DWORD GetMaximumReceiveTime() const { return maximumReceiveTime; }
823 /**Get minimum time between received packets.
824 This is over the last rxStatisticsInterval packets and is in
827 DWORD GetMinimumReceiveTime() const { return minimumReceiveTime; }
829 /**Get averaged jitter time for received packets.
830 This is the calculated statistical variance of the interarrival
831 time of received packets in milliseconds.
833 DWORD GetAvgJitterTime() const { return jitterLevel>>7; }
835 /**Get averaged jitter time for received packets.
836 This is the maximum value of jitterLevel for the session.
838 DWORD GetMaxJitterTime() const { return maximumJitterLevel>>7; }
841 * return the timestamp at which the first packet of RTP data was received
843 PTime GetFirstDataReceivedTime() const { return firstDataReceivedTime; }
846 /**@name Functions added to RTP aggregator */
848 virtual int GetDataSocketHandle() const
850 virtual int GetControlSocketHandle() const
855 void AddReceiverReport(RTP_ControlFrame::ReceiverReport & receiver);
858 PString canonicalName;
860 unsigned referenceCount;
861 RTP_UserData * userData;
863 #ifndef NO_H323_AUDIO_CODECS
864 RTP_JitterBuffer * jitter;
867 BOOL ignoreOtherSources;
868 BOOL ignoreOutOfOrderPackets;
871 PTimeInterval reportTimeInterval;
872 unsigned txStatisticsInterval;
873 unsigned rxStatisticsInterval;
874 WORD lastSentSequenceNumber;
875 WORD expectedSequenceNumber;
876 DWORD lastSentTimestamp;
877 PTimeInterval lastSentPacketTime;
878 PTimeInterval lastReceivedPacketTime;
879 WORD lastRRSequenceNumber;
880 PINDEX consecutiveOutOfOrderPackets;
885 DWORD packetsReceived;
886 DWORD octetsReceived;
888 DWORD packetsOutOfOrder;
889 DWORD averageSendTime;
890 DWORD maximumSendTime;
891 DWORD minimumSendTime;
892 DWORD averageReceiveTime;
893 DWORD maximumReceiveTime;
894 DWORD minimumReceiveTime;
896 DWORD maximumJitterLevel;
898 unsigned txStatisticsCount;
899 unsigned rxStatisticsCount;
901 DWORD averageSendTimeAccum;
902 DWORD maximumSendTimeAccum;
903 DWORD minimumSendTimeAccum;
904 DWORD averageReceiveTimeAccum;
905 DWORD maximumReceiveTimeAccum;
906 DWORD minimumReceiveTimeAccum;
907 DWORD packetsLostSinceLastRR;
908 DWORD lastTransitTime;
909 PTime firstDataReceivedTime;
914 #ifdef H323_RTP_AGGREGATE
915 PHandleAggregator * aggregator;
920 /**This class is for encpsulating the IETF Real Time Protocol interface.
922 class RTP_SessionManager : public PObject
924 PCLASSINFO(RTP_SessionManager, PObject);
927 /**@name Construction */
929 /**Construct new session manager database.
931 RTP_SessionManager();
932 RTP_SessionManager(const RTP_SessionManager & sm);
933 RTP_SessionManager & operator=(const RTP_SessionManager & sm);
937 /**@name Operations */
939 /**Use an RTP session for the specified ID.
941 If this function returns a non-null value, then the ReleaseSession()
942 function MUST be called or the session is never deleted for the
943 lifetime of the session manager.
945 If there is no session of the specified ID, then you MUST call the
946 AddSession() function with a new RTP_Session. The mutex flag is left
947 locked in this case. The AddSession() expects the mutex to be locked
948 and unlocks it automatically.
950 RTP_Session * UseSession(
951 unsigned sessionID ///< Session ID to use.
954 /**Add an RTP session for the specified ID.
956 This function MUST be called only after the UseSession() function has
957 returned NULL. The mutex flag is left locked in that case. This
958 function expects the mutex to be locked and unlocks it automatically.
961 RTP_Session * session ///< Session to add.
964 /**Release the session. If the session ID is not being used any more any
965 clients via the UseSession() function, then the session is deleted.
968 unsigned sessionID ///< Session ID to release.
971 /**Get a session for the specified ID.
972 Unlike UseSession, this does not increment the usage count on the
973 session so may be used to just gain a pointer to an RTP session.
975 RTP_Session * GetSession(
976 unsigned sessionID /// Session ID to get.
979 /**Begin an enumeration of the RTP sessions.
980 This function acquires the mutex for the sessions database and returns
981 the first element in it.
984 RTP_Session * session;
985 for (session = rtpSessions.First(); session != NULL; session = rtpSessions.Next()) {
986 if (session->Something()) {
992 Note that the Exit() function must be called if the enumeration is
993 stopped prior to Next() returning NULL.
995 RTP_Session * First();
997 /**Get the next session in the enumeration.
998 The session database remains locked until this function returns NULL.
1000 Note that the Exit() function must be called if the enumeration is
1001 stopped prior to Next() returning NULL.
1003 RTP_Session * Next();
1005 /**Exit the enumeration of RTP sessions.
1006 If the enumeration is desired to be exited before Next() returns NULL
1007 this this must be called to unlock the session database.
1009 Note that you should NOT call Exit() if Next() HAS returned NULL, or
1010 race conditions can result.
1017 PDICTIONARY(SessionDict, POrdinalKey, RTP_Session);
1018 SessionDict sessions;
1020 PINDEX enumerationIndex;
1025 /**This class is for the IETF Real Time Protocol interface on UDP/IP.
1027 class RTP_UDP : public RTP_Session
1029 PCLASSINFO(RTP_UDP, RTP_Session);
1032 /**@name Construction */
1034 /**Create a new RTP channel.
1037 #ifdef H323_RTP_AGGREGATE
1038 PHandleAggregator * aggregator, ///< RTP aggregator
1040 unsigned id, ///< Session ID for RTP channel
1041 BOOL remoteIsNat = FALSE ///< If TRUE, we have hints the remote endpoint is behind a NAT
1048 /**@name Overrides from class RTP_Session */
1050 /**Read a data frame from the RTP channel.
1051 Any control frames received are dispatched to callbacks and are not
1052 returned by this function. It will block until a data frame is
1053 available or an error occurs.
1055 virtual BOOL ReadData(RTP_DataFrame & frame, BOOL loop);
1057 /**Write a data frame from the RTP channel.
1059 virtual BOOL WriteData(RTP_DataFrame & frame);
1061 /**Write a control frame from the RTP channel.
1063 virtual BOOL WriteControl(RTP_ControlFrame & frame);
1065 /**Close down the RTP session.
1068 BOOL reading ///< Closing the read side of the session
1071 /**Get the session description name.
1073 virtual PString GetLocalHostName();
1076 /**@name QoS Settings */
1078 /**Change the QoS settings
1080 virtual BOOL ModifyQOS(RTP_QOS * rtpqos);
1082 /** Enable QOS on Call Basis
1084 virtual void EnableGQoS();
1087 /** Get the QOS settings
1093 /**@name New functions for class */
1095 /**Open the UDP ports for the RTP session.
1098 PIPSocket::Address localAddress, ///< Local interface to bind to
1099 WORD portBase, ///< Base of ports to search
1100 WORD portMax, ///< end of ports to search (inclusive)
1101 BYTE ipTypeOfService, ///< Type of Service byte
1103 PNatMethod * meth = NULL, ///* Nat Method to use to create sockets (or NULL if no Method)
1105 void * = NULL, ///< STUN server to use createing sockets (or NULL if no STUN)
1107 RTP_QOS * rtpqos = NULL ///< QOS spec (or NULL if no QoS)
1111 /**Reopens an existing session in the given direction.
1113 void Reopen(BOOL isReading);
1116 /**@name Member variable access */
1118 /**Get local address of session.
1120 PIPSocket::Address GetLocalAddress() const { return localAddress; }
1122 /**Set local address of session.
1124 void SetLocalAddress(
1125 const PIPSocket::Address & addr
1126 ) { localAddress = addr; }
1128 /**Get remote address of session.
1130 PIPSocket::Address GetRemoteAddress() const { return remoteAddress; }
1132 /**Get local data port of session.
1134 WORD GetLocalDataPort() const { return localDataPort; }
1136 /**Get local control port of session.
1138 WORD GetLocalControlPort() const { return localControlPort; }
1140 /**Get remote data port of session.
1142 WORD GetRemoteDataPort() const { return remoteDataPort; }
1144 /**Get remote control port of session.
1146 WORD GetRemoteControlPort() const { return remoteControlPort; }
1148 /**Get data UDP socket of session.
1150 PUDPSocket & GetDataSocket() { return *dataSocket; }
1152 /**Get control UDP socket of session.
1154 PUDPSocket & GetControlSocket() { return *controlSocket; }
1156 /**Set the remote address and port information for session.
1158 BOOL SetRemoteSocketInfo(
1159 PIPSocket::Address address, ///< Address of remote
1160 WORD port, ///< Port on remote
1161 BOOL isDataPort ///< Flag for data or control channel
1164 /**Apply QOS - requires address to connect the socket on Windows platforms
1167 const PIPSocket::Address & addr
1171 int GetDataSocketHandle() const
1172 { return dataSocket != NULL ? dataSocket->GetHandle() : -1; }
1174 int GetControlSocketHandle() const
1175 { return controlSocket != NULL ? controlSocket->GetHandle() : -1; }
1178 SendReceiveStatus ReadDataPDU(RTP_DataFrame & frame);
1179 SendReceiveStatus ReadControlPDU();
1180 SendReceiveStatus ReadDataOrControlPDU(
1181 PUDPSocket & socket,
1183 BOOL fromDataChannel
1186 PIPSocket::Address localAddress;
1188 WORD localControlPort;
1190 PIPSocket::Address remoteAddress;
1191 WORD remoteDataPort;
1192 WORD remoteControlPort;
1194 PIPSocket::Address remoteTransmitAddress;
1199 PUDPSocket * dataSocket;
1200 PUDPSocket * controlSocket;
1209 #endif // __OPAL_RTP_H
1212 /////////////////////////////////////////////////////////////////////////////