OPAL Version 3.10.2
|
00001 /* 00002 * rtp.h 00003 * 00004 * RTP protocol handler 00005 * 00006 * Open H323 Library 00007 * 00008 * Copyright (c) 1998-2001 Equivalence Pty. Ltd. 00009 * 00010 * The contents of this file are subject to the Mozilla Public License 00011 * Version 1.0 (the "License"); you may not use this file except in 00012 * compliance with the License. You may obtain a copy of the License at 00013 * http://www.mozilla.org/MPL/ 00014 * 00015 * Software distributed under the License is distributed on an "AS IS" 00016 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 00017 * the License for the specific language governing rights and limitations 00018 * under the License. 00019 * 00020 * The Original Code is Open H323 Library. 00021 * 00022 * The Initial Developer of the Original Code is Equivalence Pty. Ltd. 00023 * 00024 * Portions of this code were written with the assisance of funding from 00025 * Vovida Networks, Inc. http://www.vovida.com. 00026 * 00027 * Contributor(s): ______________________________________. 00028 * 00029 * $Revision: 26293 $ 00030 * $Author: rjongbloed $ 00031 * $Date: 2011-08-08 21:25:33 -0500 (Mon, 08 Aug 2011) $ 00032 */ 00033 00034 #ifndef OPAL_RTP_RTP_H 00035 #define OPAL_RTP_RTP_H 00036 00037 #ifdef P_USE_PRAGMA 00038 #pragma interface 00039 #endif 00040 00041 #include <opal/buildopts.h> 00042 00043 #include <ptlib/sockets.h> 00044 #include <ptlib/safecoll.h> 00045 00046 #include <list> 00047 00048 #include <rtp/metrics.h> 00049 00050 class RTP_JitterBuffer; 00051 class PNatMethod; 00052 class OpalSecurityMode; 00053 00055 // 00056 // class to hold the QoS definitions for an RTP channel 00057 00058 class RTP_QOS : public PObject 00059 { 00060 PCLASSINFO(RTP_QOS,PObject); 00061 public: 00062 PQoS dataQoS; 00063 PQoS ctrlQoS; 00064 }; 00065 00067 // Real Time Protocol - IETF RFC1889 and RFC1890 00068 00071 class RTP_DataFrame : public PBYTEArray 00072 { 00073 PCLASSINFO(RTP_DataFrame, PBYTEArray); 00074 00075 public: 00076 RTP_DataFrame(PINDEX payloadSize = 0, PINDEX bufferSize = 0); 00077 RTP_DataFrame(const BYTE * data, PINDEX len, PBoolean dynamic = true); 00078 00079 enum { 00080 ProtocolVersion = 2, 00081 MinHeaderSize = 12, 00082 // Max safe MTU size (576 bytes as per RFC879) minus IP, UDP an RTP headers 00083 MaxMtuPayloadSize = (576-20-16-12) 00084 }; 00085 00086 enum PayloadTypes { 00087 PCMU, // G.711 u-Law 00088 FS1016, // Federal Standard 1016 CELP 00089 G721, // ADPCM - Subsumed by G.726 00090 G726 = G721, 00091 GSM, // GSM 06.10 00092 G7231, // G.723.1 at 6.3kbps or 5.3 kbps 00093 DVI4_8k, // DVI4 at 8kHz sample rate 00094 DVI4_16k, // DVI4 at 16kHz sample rate 00095 LPC, // LPC-10 Linear Predictive CELP 00096 PCMA, // G.711 A-Law 00097 G722, // G.722 00098 L16_Stereo, // 16 bit linear PCM 00099 L16_Mono, // 16 bit linear PCM 00100 G723, // G.723 00101 CN, // Confort Noise 00102 MPA, // MPEG1 or MPEG2 audio 00103 G728, // G.728 16kbps CELP 00104 DVI4_11k, // DVI4 at 11kHz sample rate 00105 DVI4_22k, // DVI4 at 22kHz sample rate 00106 G729, // G.729 8kbps 00107 Cisco_CN, // Cisco systems comfort noise (unofficial) 00108 00109 CelB = 25, // Sun Systems Cell-B video 00110 JPEG, // Motion JPEG 00111 H261 = 31, // H.261 00112 MPV, // MPEG1 or MPEG2 video 00113 MP2T, // MPEG2 transport system 00114 H263, // H.263 00115 00116 T38 = 38, // T.38 (internal) 00117 00118 LastKnownPayloadType, 00119 00120 DynamicBase = 96, 00121 MaxPayloadType = 127, 00122 IllegalPayloadType 00123 }; 00124 00125 unsigned GetVersion() const { return (theArray[0]>>6)&3; } 00126 00127 PBoolean GetExtension() const { return (theArray[0]&0x10) != 0; } 00128 void SetExtension(PBoolean ext); 00129 00130 PBoolean GetMarker() const { return (theArray[1]&0x80) != 0; } 00131 void SetMarker(PBoolean m); 00132 00133 bool GetPadding() const { return (theArray[0]&0x20) != 0; } 00134 void SetPadding(bool v) { if (v) theArray[0] |= 0x20; else theArray[0] &= 0xdf; } 00135 BYTE * GetPaddingPtr() const { return (BYTE *)(theArray+m_headerSize+m_payloadSize); } 00136 00137 unsigned GetPaddingSize() const { return m_paddingSize; } 00138 bool SetPaddingSize(PINDEX sz); 00139 00140 PayloadTypes GetPayloadType() const { return (PayloadTypes)(theArray[1]&0x7f); } 00141 void SetPayloadType(PayloadTypes t); 00142 00143 WORD GetSequenceNumber() const { return *(PUInt16b *)&theArray[2]; } 00144 void SetSequenceNumber(WORD n) { *(PUInt16b *)&theArray[2] = n; } 00145 00146 DWORD GetTimestamp() const { return *(PUInt32b *)&theArray[4]; } 00147 void SetTimestamp(DWORD t) { *(PUInt32b *)&theArray[4] = t; } 00148 00149 DWORD GetSyncSource() const { return *(PUInt32b *)&theArray[8]; } 00150 void SetSyncSource(DWORD s) { *(PUInt32b *)&theArray[8] = s; } 00151 00152 PINDEX GetContribSrcCount() const { return theArray[0]&0xf; } 00153 DWORD GetContribSource(PINDEX idx) const; 00154 void SetContribSource(PINDEX idx, DWORD src); 00155 00156 PINDEX GetHeaderSize() const { return m_headerSize; } 00157 00158 int GetExtensionType() const; // -1 is no extension 00159 void SetExtensionType(int type); 00160 PINDEX GetExtensionSizeDWORDs() const; // get the number of 32 bit words in the extension (excluding the header). 00161 bool SetExtensionSizeDWORDs(PINDEX sz); // set the number of 32 bit words in the extension (excluding the header) 00162 BYTE * GetExtensionPtr() const; 00163 00164 PINDEX GetPayloadSize() const { return m_payloadSize; } 00165 bool SetPayloadSize(PINDEX sz); 00166 BYTE * GetPayloadPtr() const { return (BYTE *)(theArray+m_headerSize); } 00167 00168 virtual PObject * Clone() const { return new RTP_DataFrame(*this); } 00169 virtual void PrintOn(ostream & strm) const; 00170 00171 // Note this sets the whole packet length, and calculates the various 00172 // sub-section sizes: header payload and padding. 00173 bool SetPacketSize(PINDEX sz); 00174 00175 protected: 00176 PINDEX m_headerSize; 00177 PINDEX m_payloadSize; 00178 PINDEX m_paddingSize; 00179 00180 #if PTRACING 00181 friend ostream & operator<<(ostream & o, PayloadTypes t); 00182 #endif 00183 }; 00184 00185 PLIST(RTP_DataFrameList, RTP_DataFrame); 00186 00187 00190 class RTP_ControlFrame : public PBYTEArray 00191 { 00192 PCLASSINFO(RTP_ControlFrame, PBYTEArray); 00193 00194 public: 00195 RTP_ControlFrame(PINDEX compoundSize = 2048); 00196 00197 unsigned GetVersion() const { return (BYTE)theArray[compoundOffset]>>6; } 00198 00199 unsigned GetCount() const { return (BYTE)theArray[compoundOffset]&0x1f; } 00200 void SetCount(unsigned count); 00201 00202 enum PayloadTypes { 00203 e_IntraFrameRequest = 192, 00204 e_SenderReport = 200, 00205 e_ReceiverReport = 201, 00206 e_SourceDescription = 202, 00207 e_Goodbye = 203, 00208 e_ApplDefined = 204, 00209 e_TransportLayerFeedBack = 205, // RFC4585 00210 e_PayloadSpecificFeedBack = 206, 00211 e_ExtendedReport = 207 // RFC3611 00212 }; 00213 00214 unsigned GetPayloadType() const { return (BYTE)theArray[compoundOffset+1]; } 00215 void SetPayloadType(unsigned t); 00216 00217 PINDEX GetPayloadSize() const { return 4*(*(PUInt16b *)&theArray[compoundOffset+2]); } 00218 void SetPayloadSize(PINDEX sz); 00219 00220 BYTE * GetPayloadPtr() const; 00221 00222 PBoolean ReadNextPacket(); 00223 PBoolean StartNewPacket(); 00224 void EndPacket(); 00225 00226 PINDEX GetCompoundSize() const; 00227 00228 void Reset(PINDEX size); 00229 00230 #pragma pack(1) 00231 struct ReceiverReport { 00232 PUInt32b ssrc; /* data source being reported */ 00233 BYTE fraction; /* fraction lost since last SR/RR */ 00234 BYTE lost[3]; /* cumulative number of packets lost (signed!) */ 00235 PUInt32b last_seq; /* extended last sequence number received */ 00236 PUInt32b jitter; /* interarrival jitter */ 00237 PUInt32b lsr; /* last SR packet from this source */ 00238 PUInt32b dlsr; /* delay since last SR packet */ 00239 00240 unsigned GetLostPackets() const { return (lost[0]<<16U)+(lost[1]<<8U)+lost[2]; } 00241 void SetLostPackets(unsigned lost); 00242 }; 00243 00244 struct SenderReport { 00245 PUInt32b ntp_sec; /* NTP timestamp */ 00246 PUInt32b ntp_frac; 00247 PUInt32b rtp_ts; /* RTP timestamp */ 00248 PUInt32b psent; /* packets sent */ 00249 PUInt32b osent; /* octets sent */ 00250 }; 00251 00252 struct ExtendedReport { 00253 /* VoIP Metrics Report Block */ 00254 BYTE bt; /* block type */ 00255 BYTE type_specific; /* determined by the block definition */ 00256 PUInt16b length; /* length of the report block */ 00257 PUInt32b ssrc; /* data source being reported */ 00258 BYTE loss_rate; /* fraction of RTP data packets lost */ 00259 BYTE discard_rate; /* fraction of RTP data packets discarded */ 00260 BYTE burst_density; /* fraction of RTP data packets within burst periods */ 00261 BYTE gap_density; /* fraction of RTP data packets within inter-burst gaps */ 00262 PUInt16b burst_duration; /* the mean duration, in ms, of burst periods */ 00263 PUInt16b gap_duration; /* the mean duration, in ms, of gap periods */ 00264 PUInt16b round_trip_delay; /* the most recently calculated round trip time */ 00265 PUInt16b end_system_delay; /* the most recently estimates end system delay */ 00266 BYTE signal_level; /* voice signal level related to 0 dBm */ 00267 BYTE noise_level; /* ratio of the silent background level to 0 dBm */ 00268 BYTE rerl; /* residual echo return loss */ 00269 BYTE gmin; /* gap threshold */ 00270 BYTE r_factor; /* voice quality metric of the call */ 00271 BYTE ext_r_factor; /* external R factor */ 00272 BYTE mos_lq; /* MOS for listen quality */ 00273 BYTE mos_cq; /* MOS for conversational quality */ 00274 BYTE rx_config; /* receiver configuration byte */ 00275 BYTE reserved; /* reserved for future definition */ 00276 PUInt16b jb_nominal; /* current nominal jitter buffer delay, in ms */ 00277 PUInt16b jb_maximum; /* current maximum jitter buffer delay, in ms */ 00278 PUInt16b jb_absolute; /* current absolute maximum jitter buffer delay, in ms */ 00279 }; 00280 00281 enum DescriptionTypes { 00282 e_END, 00283 e_CNAME, 00284 e_NAME, 00285 e_EMAIL, 00286 e_PHONE, 00287 e_LOC, 00288 e_TOOL, 00289 e_NOTE, 00290 e_PRIV, 00291 NumDescriptionTypes 00292 }; 00293 00294 struct SourceDescription { 00295 PUInt32b src; /* first SSRC/CSRC */ 00296 struct Item { 00297 BYTE type; /* type of SDES item (enum DescriptionTypes) */ 00298 BYTE length; /* length of SDES item (in octets) */ 00299 char data[1]; /* text, not zero-terminated */ 00300 00301 /* WARNING, SourceDescription may not be big enough to contain length and data, for 00302 instance, when type == RTP_ControlFrame::e_END. 00303 Be careful whan calling the following function of it may read to over to 00304 memory allocated*/ 00305 unsigned int GetLengthTotal() const {return (unsigned int)(length + 2);} 00306 const Item * GetNextItem() const { return (const Item *)((char *)this + length + 2); } 00307 Item * GetNextItem() { return (Item *)((char *)this + length + 2); } 00308 } item[1]; /* list of SDES items */ 00309 }; 00310 00311 void StartSourceDescription( 00312 DWORD src 00313 ); 00314 00315 void AddSourceDescriptionItem( 00316 unsigned type, 00317 const PString & data 00318 ); 00319 00320 // RFC4585 Feedback Message Type (FMT) 00321 unsigned GetFbType() const { return (BYTE)theArray[compoundOffset]&0x1f; } 00322 void SetFbType(unsigned type, PINDEX fciSize); 00323 00324 enum PayloadSpecificFbTypes { 00325 e_PictureLossIndication = 1, 00326 e_SliceLostIndication, 00327 e_ReferencePictureSelectionIndication, 00328 e_FullIntraRequest, //RFC5104 00329 e_TemporalSpatialTradeOffRequest, 00330 e_TemporalSpatialTradeOffNotification, 00331 e_VideoBackChannelMessage, 00332 e_ApplicationLayerFbMessage = 15 00333 }; 00334 00335 struct FbFCI { 00336 PUInt32b senderSSRC; /* data source of sender of message */ 00337 PUInt32b mediaSSRC; /* data source of media */ 00338 }; 00339 00340 struct FbFIR { 00341 FbFCI fci; 00342 PUInt32b requestSSRC; 00343 BYTE sequenceNUmber; 00344 }; 00345 00346 struct FbTSTO { 00347 FbFCI fci; 00348 PUInt32b requestSSRC; 00349 BYTE sequenceNUmber; 00350 BYTE reserver[2]; 00351 BYTE tradeOff; 00352 }; 00353 00354 #pragma pack() 00355 00356 protected: 00357 PINDEX compoundOffset; 00358 PINDEX payloadSize; 00359 }; 00360 00361 00362 class RTP_Session; 00363 00365 00366 #if OPAL_STATISTICS 00367 00370 class OpalMediaStatistics : public PObject 00371 { 00372 PCLASSINFO(OpalMediaStatistics, PObject); 00373 public: 00374 OpalMediaStatistics(); 00375 00376 // General info (typicallly from RTP) 00377 PUInt64 m_totalBytes; 00378 unsigned m_totalPackets; 00379 unsigned m_packetsLost; 00380 unsigned m_packetsOutOfOrder; 00381 unsigned m_packetsTooLate; 00382 unsigned m_packetOverruns; 00383 unsigned m_minimumPacketTime; 00384 unsigned m_averagePacketTime; 00385 unsigned m_maximumPacketTime; 00386 00387 // Audio 00388 unsigned m_averageJitter; 00389 unsigned m_maximumJitter; 00390 unsigned m_jitterBufferDelay; 00391 00392 // Video 00393 unsigned m_totalFrames; 00394 unsigned m_keyFrames; 00395 00396 // Fax 00397 #if OPAL_FAX 00398 enum { 00399 FaxNotStarted = -2, 00400 FaxInProgress = -1, 00401 FaxSuccessful = 0, 00402 FaxErrorBase = 1 00403 }; 00404 enum FaxCompression { 00405 FaxCompressionUnknown, 00406 FaxCompressionT4_1d, 00407 FaxCompressionT4_2d, 00408 FaxCompressionT6, 00409 }; 00410 friend ostream & operator<<(ostream & strm, FaxCompression compression); 00411 struct Fax { 00412 Fax(); 00413 00414 int m_result; // -2=not started, -1=progress, 0=success, >0=ended with error 00415 char m_phase; // 'A', 'B', 'D' 00416 int m_bitRate; // e.g. 14400, 9600 00417 FaxCompression m_compression; // 0=N/A, 1=T.4 1d, 2=T.4 2d, 3=T.6 00418 bool m_errorCorrection; 00419 int m_txPages; 00420 int m_rxPages; 00421 int m_totalPages; 00422 int m_imageSize; // In bytes 00423 int m_resolutionX; // Pixels per inch 00424 int m_resolutionY; // Pixels per inch 00425 int m_pageWidth; 00426 int m_pageHeight; 00427 int m_badRows; // Total number of bad rows 00428 int m_mostBadRows; // Longest run of bad rows 00429 int m_errorCorrectionRetries; 00430 00431 PString m_stationId; // Remote station identifier 00432 PString m_errorText; 00433 } m_fax; 00434 #endif 00435 }; 00436 00437 #endif 00438 00439 00444 class RTP_UserData : public PObject 00445 { 00446 PCLASSINFO(RTP_UserData, PObject); 00447 00448 public: 00455 virtual void OnTxStatistics( 00456 const RTP_Session & session 00457 ) const; 00458 00465 virtual void OnRxStatistics( 00466 const RTP_Session & session 00467 ) const; 00468 00469 #if OPAL_VIDEO 00470 00475 virtual void OnTxIntraFrameRequest( 00476 const RTP_Session & session 00477 ) const; 00478 00484 virtual void OnRxIntraFrameRequest( 00485 const RTP_Session & session 00486 ) const; 00487 #endif 00488 00492 virtual void SessionFailing( 00493 RTP_Session & session 00494 ); 00495 }; 00496 00497 class RTP_Encoding; 00498 00499 00502 class RTP_Session : public PObject 00503 { 00504 PCLASSINFO(RTP_Session, PObject); 00505 00506 public: 00509 struct Params { 00510 Params() 00511 : id(0) 00512 , userData(NULL) 00513 , autoDelete(true) 00514 , isAudio(false) 00515 , remoteIsNAT(false) 00516 { } 00517 00518 PString encoding; 00519 unsigned id; 00520 RTP_UserData * userData; 00521 bool autoDelete; 00522 bool isAudio; 00523 bool remoteIsNAT; 00524 }; 00525 00528 RTP_Session( 00529 const Params & options 00530 ); 00531 00535 ~RTP_Session(); 00537 00547 void SetJitterBufferSize( 00548 unsigned minJitterDelay, 00549 unsigned maxJitterDelay, 00550 unsigned timeUnits = 0, 00551 PINDEX packetSize = 2048 00552 ); 00553 00559 unsigned GetJitterBufferSize() const; 00560 unsigned GetJitterBufferDelay() const { return GetJitterBufferSize()/GetJitterTimeUnits(); } 00561 00564 unsigned GetJitterTimeUnits() const { return m_timeUnits; } 00565 00567 virtual PBoolean ModifyQOS(RTP_QOS * ) 00568 { return false; } 00569 00575 virtual PBoolean ReadBufferedData( 00576 RTP_DataFrame & frame 00577 ); 00578 00584 virtual PBoolean ReadData( 00585 RTP_DataFrame & frame 00586 ) = 0; 00587 00590 virtual PBoolean WriteData( 00591 RTP_DataFrame & frame 00592 ) = 0; 00593 00597 virtual PBoolean WriteOOBData( 00598 RTP_DataFrame & frame, 00599 bool rewriteTimeStamp = true 00600 ); 00601 00604 virtual PBoolean WriteControl( 00605 RTP_ControlFrame & frame 00606 ) = 0; 00607 00610 virtual PBoolean SendReport(); 00611 00614 virtual bool Close( 00615 PBoolean reading 00616 ) = 0; 00617 00620 virtual void Reopen( 00621 PBoolean isReading 00622 ) = 0; 00623 00626 virtual PString GetLocalHostName() = 0; 00627 00628 #if OPAL_STATISTICS 00629 virtual void GetStatistics(OpalMediaStatistics & statistics, bool receiver) const; 00630 #endif 00631 00632 00635 enum SendReceiveStatus { 00636 e_ProcessPacket, 00637 e_IgnorePacket, 00638 e_AbortTransport 00639 }; 00640 virtual SendReceiveStatus OnSendData(RTP_DataFrame & frame); 00641 virtual SendReceiveStatus Internal_OnSendData(RTP_DataFrame & frame); 00642 00643 virtual SendReceiveStatus OnSendControl(RTP_ControlFrame & frame, PINDEX & len); 00644 virtual SendReceiveStatus Internal_OnSendControl(RTP_ControlFrame & frame, PINDEX & len); 00645 00646 virtual SendReceiveStatus OnReceiveData(RTP_DataFrame & frame); 00647 virtual SendReceiveStatus Internal_OnReceiveData(RTP_DataFrame & frame); 00648 00649 virtual SendReceiveStatus OnReceiveControl(RTP_ControlFrame & frame); 00650 00651 class ReceiverReport : public PObject { 00652 PCLASSINFO(ReceiverReport, PObject); 00653 public: 00654 void PrintOn(ostream &) const; 00655 00656 DWORD sourceIdentifier; 00657 DWORD fractionLost; /* fraction lost since last SR/RR */ 00658 DWORD totalLost; /* cumulative number of packets lost (signed!) */ 00659 DWORD lastSequenceNumber; /* extended last sequence number received */ 00660 DWORD jitter; /* interarrival jitter */ 00661 PTimeInterval lastTimestamp;/* last SR packet from this source */ 00662 PTimeInterval delay; /* delay since last SR packet */ 00663 }; 00664 PARRAY(ReceiverReportArray, ReceiverReport); 00665 00666 class SenderReport : public PObject { 00667 PCLASSINFO(SenderReport, PObject); 00668 public: 00669 void PrintOn(ostream &) const; 00670 00671 DWORD sourceIdentifier; 00672 PTime realTimestamp; 00673 DWORD rtpTimestamp; 00674 DWORD packetsSent; 00675 DWORD octetsSent; 00676 }; 00677 00678 virtual void OnRxSenderReport(const SenderReport & sender, 00679 const ReceiverReportArray & reports); 00680 virtual void OnRxReceiverReport(DWORD src, 00681 const ReceiverReportArray & reports); 00682 virtual void OnReceiverReports(const ReceiverReportArray & reports); 00683 00684 class SourceDescription : public PObject { 00685 PCLASSINFO(SourceDescription, PObject); 00686 public: 00687 SourceDescription(DWORD src) { sourceIdentifier = src; } 00688 void PrintOn(ostream &) const; 00689 00690 DWORD sourceIdentifier; 00691 POrdinalToString items; 00692 }; 00693 PARRAY(SourceDescriptionArray, SourceDescription); 00694 virtual void OnRxSourceDescription(const SourceDescriptionArray & descriptions); 00695 00696 virtual void OnRxGoodbye(const PDWORDArray & sources, 00697 const PString & reason); 00698 00699 virtual void OnRxApplDefined(const PString & type, unsigned subtype, DWORD src, 00700 const BYTE * data, PINDEX size); 00701 00702 #if OPAL_RTCP_XR 00703 class ExtendedReport : public PObject { 00704 PCLASSINFO(ExtendedReport, PObject); 00705 public: 00706 void PrintOn(ostream &) const; 00707 00708 DWORD sourceIdentifier; 00709 DWORD lossRate; /* fraction of RTP data packets lost */ 00710 DWORD discardRate; /* fraction of RTP data packets discarded */ 00711 DWORD burstDensity; /* fraction of RTP data packets within burst periods */ 00712 DWORD gapDensity; /* fraction of RTP data packets within inter-burst gaps */ 00713 DWORD roundTripDelay; /* the most recently calculated round trip time */ 00714 DWORD RFactor; /* voice quality metric of the call */ 00715 DWORD mosLQ; /* MOS for listen quality */ 00716 DWORD mosCQ; /* MOS for conversational quality */ 00717 DWORD jbNominal; /* current nominal jitter buffer delay, in ms */ 00718 DWORD jbMaximum; /* current maximum jitter buffer delay, in ms */ 00719 DWORD jbAbsolute; /* current absolute maximum jitter buffer delay, in ms */ 00720 }; 00721 PARRAY(ExtendedReportArray, ExtendedReport); 00722 00723 virtual void OnRxExtendedReport(DWORD src, 00724 const ExtendedReportArray & reports); 00725 #endif 00726 00727 00732 unsigned GetSessionID() const { return sessionID; } 00733 00736 void SetSessionID(unsigned id) { sessionID = id; } 00737 00740 bool IsAudio() const { return isAudio; } 00741 00744 void SetAudio( 00745 bool aud 00746 ) { isAudio = aud; } 00747 00750 PString GetCanonicalName() const; 00751 00754 void SetCanonicalName(const PString & name); 00755 00758 PString GetToolName() const; 00759 00762 void SetToolName(const PString & name); 00763 00766 RTP_UserData * GetUserData() const { return userData; } 00767 00770 void SetUserData( 00771 RTP_UserData * data, 00772 PBoolean autoDeleteUserData = true 00773 ); 00774 00777 DWORD GetSyncSourceOut() const { return syncSourceOut; } 00778 00781 bool AllowAnySyncSource() const { return allowAnySyncSource; } 00782 00785 void SetAnySyncSource( 00786 bool allow 00787 ) { allowAnySyncSource = allow; } 00788 00791 void SetIgnorePayloadTypeChanges( 00792 PBoolean ignore 00793 ) { ignorePayloadTypeChanges = ignore; } 00794 00797 const PTimeInterval & GetReportTimeInterval() { return reportTimeInterval; } 00798 00801 void SetReportTimeInterval( 00802 const PTimeInterval & interval 00803 ) { reportTimeInterval = interval; } 00804 00807 PTimeInterval GetReportTimer() 00808 { return reportTimer; } 00809 00812 unsigned GetTxStatisticsInterval() { return txStatisticsInterval; } 00813 00816 void SetTxStatisticsInterval( 00817 unsigned packets 00818 ); 00819 00822 unsigned GetRxStatisticsInterval() { return rxStatisticsInterval; } 00823 00826 void SetRxStatisticsInterval( 00827 unsigned packets 00828 ); 00829 00832 void ClearStatistics(); 00833 00836 DWORD GetPacketsSent() const { return packetsSent; } 00837 00840 DWORD GetOctetsSent() const { return octetsSent; } 00841 00844 DWORD GetPacketsReceived() const { return packetsReceived; } 00845 00848 DWORD GetOctetsReceived() const { return octetsReceived; } 00849 00852 DWORD GetPacketsLost() const { return packetsLost; } 00853 00857 DWORD GetPacketsLostByRemote() const { return packetsLostByRemote; } 00858 00861 DWORD GetPacketsOutOfOrder() const { return packetsOutOfOrder; } 00862 00865 DWORD GetPacketsTooLate() const; 00866 00869 DWORD GetPacketOverruns() const; 00870 00875 DWORD GetAverageSendTime() const { return averageSendTime; } 00876 00881 DWORD GetMarkerRecvCount() const { return markerRecvCount; } 00882 00887 DWORD GetMarkerSendCount() const { return markerSendCount; } 00888 00893 DWORD GetMaximumSendTime() const { return maximumSendTime; } 00894 00899 DWORD GetMinimumSendTime() const { return minimumSendTime; } 00900 00905 DWORD GetAverageReceiveTime() const { return averageReceiveTime; } 00906 00911 DWORD GetMaximumReceiveTime() const { return maximumReceiveTime; } 00912 00917 DWORD GetMinimumReceiveTime() const { return minimumReceiveTime; } 00918 00919 enum { JitterRoundingGuardBits = 4 }; 00924 DWORD GetAvgJitterTime() const { return (jitterLevel>>JitterRoundingGuardBits)/GetJitterTimeUnits(); } 00925 00929 DWORD GetMaxJitterTime() const { return (maximumJitterLevel>>JitterRoundingGuardBits)/GetJitterTimeUnits(); } 00930 00935 DWORD GetJitterTimeOnRemote() const { return jitterLevelOnRemote/GetJitterTimeUnits(); } 00937 00938 virtual void SetCloseOnBYE(PBoolean v) { closeOnBye = v; } 00939 00944 virtual void SendIntraFrameRequest(bool rfc2032, bool pictureLoss); 00945 00950 virtual void SendTemporalSpatialTradeOff(unsigned tradeOff); 00951 00952 void SetNextSentSequenceNumber(WORD num) { lastSentSequenceNumber = (WORD)(num-1); } 00953 00954 virtual PString GetEncoding() const { return m_encoding; } 00955 virtual void SetEncoding(const PString & newEncoding); 00956 00957 DWORD GetSyncSourceIn() const { return syncSourceIn; } 00958 00959 class EncodingLock 00960 { 00961 public: 00962 EncodingLock(RTP_Session & _session); 00963 ~EncodingLock(); 00964 00965 __inline RTP_Encoding * operator->() const { return m_encodingHandler; } 00966 00967 protected: 00968 RTP_Session & session; 00969 RTP_Encoding * m_encodingHandler; 00970 }; 00971 00972 friend class EncodingLock; 00973 00974 void SetFailed(bool v) 00975 { failed = v; } 00976 00977 bool HasFailed() const 00978 { return failed; } 00979 00980 typedef PNotifierTemplate<SendReceiveStatus &> FilterNotifier; 00981 #define PDECLARE_RTPFilterNotifier(cls, fn) PDECLARE_NOTIFIER2(RTP_DataFrame, cls, fn, RTP_Session::SendReceiveStatus &) 00982 #define PCREATE_RTPFilterNotifier(fn) PCREATE_NOTIFIER2(fn, RTP_Session::SendReceiveStatus &) 00983 00984 void AddFilter(const FilterNotifier & filter); 00985 00986 #if OPAL_RTCP_XR 00987 const RTCP_XR_Metrics & GetMetrics() const { return m_metrics; } 00988 #endif 00989 00990 virtual void SendBYE(); 00991 00992 protected: 00993 void AddReceiverReport(RTP_ControlFrame::ReceiverReport & receiver); 00994 00995 PBoolean InsertReportPacket(RTP_ControlFrame & report); 00996 00997 #if OPAL_RTCP_XR 00998 void InsertExtendedReportPacket(RTP_ControlFrame & report); 00999 void OnRxSenderReportToMetrics(const RTP_ControlFrame & frame, PINDEX offset); 01000 #endif 01001 01002 PString m_encoding; 01003 PMutex m_encodingMutex; 01004 RTP_Encoding * m_encodingHandler; 01005 01006 unsigned sessionID; 01007 bool isAudio; 01008 unsigned m_timeUnits; 01009 PString canonicalName; 01010 PString toolName; 01011 RTP_UserData * userData; 01012 PBoolean autoDeleteUserData; 01013 01014 typedef PSafePtr<RTP_JitterBuffer, PSafePtrMultiThreaded> JitterBufferPtr; 01015 JitterBufferPtr m_jitterBuffer; 01016 01017 DWORD syncSourceOut; 01018 DWORD syncSourceIn; 01019 DWORD lastSentTimestamp; 01020 bool allowAnySyncSource; 01021 bool allowOneSyncSourceChange; 01022 PBoolean allowRemoteTransmitAddressChange; 01023 PBoolean allowSequenceChange; 01024 PTimeInterval reportTimeInterval; 01025 unsigned txStatisticsInterval; 01026 unsigned rxStatisticsInterval; 01027 WORD lastSentSequenceNumber; 01028 WORD expectedSequenceNumber; 01029 PTimeInterval lastSentPacketTime; 01030 PTimeInterval lastReceivedPacketTime; 01031 PTime lastSRTimestamp; 01032 PTime lastSRReceiveTime; 01033 PTimeInterval delaySinceLastSR; 01034 WORD lastRRSequenceNumber; 01035 bool resequenceOutOfOrderPackets; 01036 unsigned consecutiveOutOfOrderPackets; 01037 PTimeInterval outOfOrderPacketTime; 01038 01039 std::list<RTP_DataFrame> m_outOfOrderPackets; 01040 void SaveOutOfOrderPacket(RTP_DataFrame & frame); 01041 01042 PMutex dataMutex; 01043 DWORD timeStampOffs; // offset between incoming media timestamp and timeStampOut 01044 PBoolean oobTimeStampBaseEstablished; // true if timeStampOffs has been established by media 01045 DWORD oobTimeStampOutBase; // base timestamp value for oob data 01046 PTimeInterval oobTimeStampBase; // base time for oob timestamp 01047 01048 // Statistics 01049 PTime firstPacketSent; 01050 DWORD packetsSent; 01051 DWORD rtcpPacketsSent; 01052 DWORD octetsSent; 01053 PTime firstPacketReceived; 01054 DWORD packetsReceived; 01055 DWORD senderReportsReceived; 01056 DWORD octetsReceived; 01057 DWORD packetsLost; 01058 DWORD packetsLostByRemote; 01059 DWORD packetsOutOfOrder; 01060 DWORD averageSendTime; 01061 DWORD maximumSendTime; 01062 DWORD minimumSendTime; 01063 DWORD averageReceiveTime; 01064 DWORD maximumReceiveTime; 01065 DWORD minimumReceiveTime; 01066 DWORD jitterLevel; 01067 DWORD jitterLevelOnRemote; 01068 DWORD maximumJitterLevel; 01069 01070 DWORD markerSendCount; 01071 DWORD markerRecvCount; 01072 01073 unsigned txStatisticsCount; 01074 unsigned rxStatisticsCount; 01075 01076 #if OPAL_RTCP_XR 01077 // Calculate the VoIP Metrics for RTCP-XR 01078 RTCP_XR_Metrics m_metrics; 01079 #endif 01080 01081 DWORD averageSendTimeAccum; 01082 DWORD maximumSendTimeAccum; 01083 DWORD minimumSendTimeAccum; 01084 DWORD averageReceiveTimeAccum; 01085 DWORD maximumReceiveTimeAccum; 01086 DWORD minimumReceiveTimeAccum; 01087 DWORD packetsLostSinceLastRR; 01088 DWORD lastTransitTime; 01089 01090 RTP_DataFrame::PayloadTypes lastReceivedPayloadType; 01091 PBoolean ignorePayloadTypeChanges; 01092 01093 PMutex reportMutex; 01094 PTimer reportTimer; 01095 01096 PBoolean closeOnBye; 01097 PBoolean byeSent; 01098 bool failed; 01099 01100 list<FilterNotifier> m_filters; 01101 }; 01102 01105 class RTP_UDP : public RTP_Session 01106 { 01107 PCLASSINFO(RTP_UDP, RTP_Session); 01108 01109 public: 01114 RTP_UDP( 01115 const Params & options 01116 ); 01117 01119 ~RTP_UDP(); 01121 01129 virtual PBoolean ReadData(RTP_DataFrame & frame); 01130 virtual PBoolean Internal_ReadData(RTP_DataFrame & frame); 01131 01134 virtual PBoolean WriteData(RTP_DataFrame & frame); 01135 virtual PBoolean Internal_WriteData(RTP_DataFrame & frame); 01136 01140 virtual PBoolean WriteOOBData(RTP_DataFrame & frame, bool setTimeStamp = true); 01141 01144 virtual PBoolean WriteControl(RTP_ControlFrame & frame); 01145 01148 virtual bool Close( 01149 PBoolean reading 01150 ); 01151 01154 virtual PString GetLocalHostName(); 01156 01159 virtual PBoolean ModifyQOS(RTP_QOS * rtpqos); 01160 01165 virtual PBoolean Open( 01166 PIPSocket::Address localAddress, 01167 WORD portBase, 01168 WORD portMax, 01169 BYTE ipTypeOfService, 01170 PNatMethod * natMethod = NULL, 01171 RTP_QOS * rtpqos = NULL 01172 ); 01174 01177 virtual void Reopen(PBoolean isReading); 01179 01184 virtual PIPSocket::Address GetLocalAddress() const { return localAddress; } 01185 01188 virtual void SetLocalAddress( 01189 const PIPSocket::Address & addr 01190 ) { localAddress = addr; } 01191 01194 PIPSocket::Address GetRemoteAddress() const { return remoteAddress; } 01195 01198 virtual WORD GetLocalDataPort() const { return localDataPort; } 01199 01202 virtual WORD GetLocalControlPort() const { return localControlPort; } 01203 01206 virtual WORD GetRemoteDataPort() const { return remoteDataPort; } 01207 01210 virtual WORD GetRemoteControlPort() const { return remoteControlPort; } 01211 01214 virtual PUDPSocket & GetDataSocket() { return *dataSocket; } 01215 01218 virtual PUDPSocket & GetControlSocket() { return *controlSocket; } 01219 01222 virtual PBoolean SetRemoteSocketInfo( 01223 PIPSocket::Address address, 01224 WORD port, 01225 PBoolean isDataPort 01226 ); 01227 01230 virtual void ApplyQOS( 01231 const PIPSocket::Address & addr 01232 ); 01234 01235 virtual int GetDataSocketHandle() const 01236 { return dataSocket != NULL ? dataSocket->GetHandle() : -1; } 01237 01238 virtual int GetControlSocketHandle() const 01239 { return controlSocket != NULL ? controlSocket->GetHandle() : -1; } 01240 01241 friend class RTP_Encoding; 01242 01243 virtual int WaitForPDU(PUDPSocket & dataSocket, PUDPSocket & controlSocket, const PTimeInterval & timer); 01244 virtual int Internal_WaitForPDU(PUDPSocket & dataSocket, PUDPSocket & controlSocket, const PTimeInterval & timer); 01245 01246 virtual SendReceiveStatus ReadDataPDU(RTP_DataFrame & frame); 01247 virtual SendReceiveStatus Internal_ReadDataPDU(RTP_DataFrame & frame); 01248 01249 virtual SendReceiveStatus OnReadTimeout(RTP_DataFrame & frame); 01250 virtual SendReceiveStatus Internal_OnReadTimeout(RTP_DataFrame & frame); 01251 01252 virtual SendReceiveStatus ReadControlPDU(); 01253 virtual SendReceiveStatus ReadDataOrControlPDU( 01254 BYTE * framePtr, 01255 PINDEX frameSize, 01256 PBoolean fromDataChannel 01257 ); 01258 01259 virtual bool WriteDataPDU(RTP_DataFrame & frame); 01260 virtual bool WriteDataOrControlPDU( 01261 const BYTE * framePtr, 01262 PINDEX frameSize, 01263 bool toDataChannel 01264 ); 01265 01266 virtual void SetEncoding(const PString & newEncoding); 01267 01268 01269 protected: 01270 PIPSocket::Address localAddress; 01271 WORD localDataPort; 01272 WORD localControlPort; 01273 01274 PIPSocket::Address remoteAddress; 01275 WORD remoteDataPort; 01276 WORD remoteControlPort; 01277 01278 PIPSocket::Address remoteTransmitAddress; 01279 01280 PUDPSocket * dataSocket; 01281 PUDPSocket * controlSocket; 01282 01283 bool shutdownRead; 01284 bool shutdownWrite; 01285 bool appliedQOS; 01286 bool remoteIsNAT; 01287 bool localHasNAT; 01288 bool m_firstData; 01289 bool m_firstControl; 01290 int badTransmitCounter; 01291 PTime badTransmitStart; 01292 01293 PTimer timerWriteDataIdle; 01294 PDECLARE_NOTIFIER(PTimer, RTP_UDP, OnWriteDataIdle); 01295 }; 01296 01298 01299 class RTP_UDP; 01300 01301 class RTP_Encoding 01302 { 01303 public: 01304 RTP_Encoding(); 01305 virtual ~RTP_Encoding(); 01306 virtual void ApplyStringOptions(const PStringToString & /*stringOptions*/) {} 01307 virtual void OnStart(RTP_Session & _rtpSession); 01308 virtual void OnFinish(); 01309 virtual RTP_Session::SendReceiveStatus OnSendData(RTP_DataFrame & frame); 01310 virtual PBoolean WriteData(RTP_DataFrame & frame, bool oob); 01311 virtual PBoolean WriteDataPDU(RTP_DataFrame & frame); 01312 virtual void OnWriteDataIdle() {} 01313 virtual void SetWriteDataIdleTimer(PTimer &) {} 01314 virtual RTP_Session::SendReceiveStatus OnSendControl(RTP_ControlFrame & frame, PINDEX & len); 01315 virtual RTP_Session::SendReceiveStatus ReadDataPDU(RTP_DataFrame & frame); 01316 virtual RTP_Session::SendReceiveStatus OnReceiveData(RTP_DataFrame & frame); 01317 virtual RTP_Session::SendReceiveStatus OnReadTimeout(RTP_DataFrame & frame); 01318 virtual PBoolean ReadData(RTP_DataFrame & frame); 01319 virtual int WaitForPDU(PUDPSocket & dataSocket, PUDPSocket & controlSocket, const PTimeInterval &); 01320 01321 PMutex mutex; 01322 unsigned refCount; 01323 01324 protected: 01325 RTP_UDP * rtpUDP; 01326 }; 01327 01328 PFACTORY_LOAD(RTP_Encoding); 01329 01330 01332 01333 class SecureRTP_UDP : public RTP_UDP 01334 { 01335 PCLASSINFO(SecureRTP_UDP, RTP_UDP); 01336 01337 public: 01342 SecureRTP_UDP( 01343 const Params & options 01344 ); 01345 01347 ~SecureRTP_UDP(); 01348 01349 virtual void SetSecurityMode(OpalSecurityMode * srtpParms); 01350 virtual OpalSecurityMode * GetSecurityParms() const; 01351 01352 protected: 01353 OpalSecurityMode * securityParms; 01354 }; 01355 01356 #endif // OPAL_RTP_RTP_H 01357