rtp.h

Go to the documentation of this file.
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: 21283 $
00030  * $Author: rjongbloed $
00031  * $Date: 2008-10-11 07:10:58 +0000 (Sat, 11 Oct 2008) $
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 
00045 class RTP_JitterBuffer;
00046 class PNatMethod;
00047 class OpalSecurityMode;
00048 
00049 #if OPAL_RTP_AGGREGATE
00050 #include <ptclib/sockagg.h>
00051 #else
00052 typedef void * PHandleAggregator;
00053 typedef void * RTP_AggregatedHandle;
00054 #endif
00055 
00057 // 
00058 // class to hold the QoS definitions for an RTP channel
00059 
00060 class RTP_QOS : public PObject
00061 {
00062   PCLASSINFO(RTP_QOS,PObject);
00063   public:
00064     PQoS dataQoS;
00065     PQoS ctrlQoS;
00066 };
00067 
00069 // Real Time Protocol - IETF RFC1889 and RFC1890
00070 
00073 class RTP_DataFrame : public PBYTEArray
00074 {
00075   PCLASSINFO(RTP_DataFrame, PBYTEArray);
00076 
00077   public:
00078     RTP_DataFrame(PINDEX payloadSize = 2048);
00079     RTP_DataFrame(const BYTE * data, PINDEX len, PBoolean dynamic = PTrue);
00080 
00081     enum {
00082       ProtocolVersion = 2,
00083       MinHeaderSize = 12,
00084       // Max safe MTU size (576 bytes as per RFC879) minus IP, UDP an RTP headers
00085       MaxMtuPayloadSize = (576-20-16-12)
00086     };
00087 
00088     enum PayloadTypes {
00089       PCMU,         // G.711 u-Law
00090       FS1016,       // Federal Standard 1016 CELP
00091       G721,         // ADPCM - Subsumed by G.726
00092       G726 = G721,
00093       GSM,          // GSM 06.10
00094       G7231,        // G.723.1 at 6.3kbps or 5.3 kbps
00095       DVI4_8k,      // DVI4 at 8kHz sample rate
00096       DVI4_16k,     // DVI4 at 16kHz sample rate
00097       LPC,          // LPC-10 Linear Predictive CELP
00098       PCMA,         // G.711 A-Law
00099       G722,         // G.722
00100       L16_Stereo,   // 16 bit linear PCM
00101       L16_Mono,     // 16 bit linear PCM
00102       G723,         // G.723
00103       CN,           // Confort Noise
00104       MPA,          // MPEG1 or MPEG2 audio
00105       G728,         // G.728 16kbps CELP
00106       DVI4_11k,     // DVI4 at 11kHz sample rate
00107       DVI4_22k,     // DVI4 at 22kHz sample rate
00108       G729,         // G.729 8kbps
00109       Cisco_CN,     // Cisco systems comfort noise (unofficial)
00110 
00111       CelB = 25,    // Sun Systems Cell-B video
00112       JPEG,         // Motion JPEG
00113       H261 = 31,    // H.261
00114       MPV,          // MPEG1 or MPEG2 video
00115       MP2T,         // MPEG2 transport system
00116       H263,         // H.263
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 
00136     unsigned GetPaddingSize() const;
00137 
00138     PayloadTypes GetPayloadType() const { return (PayloadTypes)(theArray[1]&0x7f); }
00139     void         SetPayloadType(PayloadTypes t);
00140 
00141     WORD GetSequenceNumber() const { return *(PUInt16b *)&theArray[2]; }
00142     void SetSequenceNumber(WORD n) { *(PUInt16b *)&theArray[2] = n; }
00143 
00144     DWORD GetTimestamp() const  { return *(PUInt32b *)&theArray[4]; }
00145     void  SetTimestamp(DWORD t) { *(PUInt32b *)&theArray[4] = t; }
00146 
00147     DWORD GetSyncSource() const  { return *(PUInt32b *)&theArray[8]; }
00148     void  SetSyncSource(DWORD s) { *(PUInt32b *)&theArray[8] = s; }
00149 
00150     PINDEX GetContribSrcCount() const { return theArray[0]&0xf; }
00151     DWORD  GetContribSource(PINDEX idx) const;
00152     void   SetContribSource(PINDEX idx, DWORD src);
00153 
00154     PINDEX GetHeaderSize() const;
00155 
00156     int GetExtensionType() const; // -1 is no extension
00157     void   SetExtensionType(int type);
00158     PINDEX GetExtensionSize() const;
00159     PBoolean   SetExtensionSize(PINDEX sz);
00160     BYTE * GetExtensionPtr() const;
00161 
00162     PINDEX GetPayloadSize() const { return payloadSize - GetPaddingSize(); }
00163     PBoolean   SetPayloadSize(PINDEX sz);
00164     BYTE * GetPayloadPtr()     const { return (BYTE *)(theArray+GetHeaderSize()); }
00165 
00166     virtual void PrintOn(ostream & strm) const;
00167 
00168   protected:
00169     PINDEX payloadSize;
00170 
00171 #if PTRACING
00172     friend ostream & operator<<(ostream & o, PayloadTypes t);
00173 #endif
00174 };
00175 
00176 PLIST(RTP_DataFrameList, RTP_DataFrame);
00177 
00178 
00181 class RTP_ControlFrame : public PBYTEArray
00182 {
00183   PCLASSINFO(RTP_ControlFrame, PBYTEArray);
00184 
00185   public:
00186     RTP_ControlFrame(PINDEX compoundSize = 2048);
00187 
00188     unsigned GetVersion() const { return (BYTE)theArray[compoundOffset]>>6; }
00189 
00190     unsigned GetCount() const { return (BYTE)theArray[compoundOffset]&0x1f; }
00191     void     SetCount(unsigned count);
00192 
00193     enum PayloadTypes {
00194       e_IntraFrameRequest = 192,
00195       e_SenderReport = 200,
00196       e_ReceiverReport,
00197       e_SourceDescription,
00198       e_Goodbye,
00199       e_ApplDefined
00200     };
00201 
00202     unsigned GetPayloadType() const { return (BYTE)theArray[compoundOffset+1]; }
00203     void     SetPayloadType(unsigned t);
00204 
00205     PINDEX GetPayloadSize() const { return 4*(*(PUInt16b *)&theArray[compoundOffset+2]); }
00206     void   SetPayloadSize(PINDEX sz);
00207 
00208     BYTE * GetPayloadPtr() const;
00209 
00210     PBoolean ReadNextPacket();
00211     PBoolean StartNewPacket();
00212     void EndPacket();
00213 
00214     PINDEX GetCompoundSize() const;
00215 
00216     void Reset(PINDEX size);
00217 
00218 #pragma pack(1)
00219     struct ReceiverReport {
00220       PUInt32b ssrc;      /* data source being reported */
00221       BYTE fraction;      /* fraction lost since last SR/RR */
00222       BYTE lost[3];       /* cumulative number of packets lost (signed!) */
00223       PUInt32b last_seq;  /* extended last sequence number received */
00224       PUInt32b jitter;    /* interarrival jitter */
00225       PUInt32b lsr;       /* last SR packet from this source */
00226       PUInt32b dlsr;      /* delay since last SR packet */
00227 
00228       unsigned GetLostPackets() const { return (lost[0]<<16U)+(lost[1]<<8U)+lost[2]; }
00229       void SetLostPackets(unsigned lost);
00230     };
00231 
00232     struct SenderReport {
00233       PUInt32b ntp_sec;   /* NTP timestamp */
00234       PUInt32b ntp_frac;
00235       PUInt32b rtp_ts;    /* RTP timestamp */
00236       PUInt32b psent;     /* packets sent */
00237       PUInt32b osent;     /* octets sent */ 
00238     };
00239 
00240     enum DescriptionTypes {
00241       e_END,
00242       e_CNAME,
00243       e_NAME,
00244       e_EMAIL,
00245       e_PHONE,
00246       e_LOC,
00247       e_TOOL,
00248       e_NOTE,
00249       e_PRIV,
00250       NumDescriptionTypes
00251     };
00252 
00253     struct SourceDescription {
00254       PUInt32b src;       /* first SSRC/CSRC */
00255       struct Item {
00256         BYTE type;        /* type of SDES item (enum DescriptionTypes) */
00257         BYTE length;      /* length of SDES item (in octets) */
00258         char data[1];     /* text, not zero-terminated */
00259 
00260         /* WARNING, SourceDescription may not be big enough to contain length and data, for 
00261            instance, when type == RTP_ControlFrame::e_END.
00262            Be careful whan calling the following function of it may read to over to 
00263            memory allocated*/
00264         unsigned int GetLengthTotal() const {return (unsigned int)(length + 2);} 
00265         const Item * GetNextItem() const { return (const Item *)((char *)this + length + 2); }
00266         Item * GetNextItem() { return (Item *)((char *)this + length + 2); }
00267       } item[1];          /* list of SDES items */
00268     };
00269 
00270     void StartSourceDescription(
00271       DWORD src   
00272     );
00273 
00274     void AddSourceDescriptionItem(
00275       unsigned type,            
00276       const PString & data      
00277     );
00278 #pragma pack()
00279 
00280   protected:
00281     PINDEX compoundOffset;
00282     PINDEX payloadSize;
00283 };
00284 
00285 
00286 class RTP_Session;
00287 
00289 
00290 #if OPAL_STATISTICS
00291 
00294 class OpalMediaStatistics : public PObject
00295 {
00296     PCLASSINFO(OpalMediaStatistics, PObject);
00297   public:
00298     OpalMediaStatistics();
00299 
00300     // General info (typicallly from RTP)
00301     PUInt64  m_totalBytes;
00302     unsigned m_totalPackets;
00303     unsigned m_packetsLost;
00304     unsigned m_packetsOutOfOrder;
00305     unsigned m_packetsTooLate;
00306     unsigned m_packetOverruns;
00307     unsigned m_minimumPacketTime;
00308     unsigned m_averagePacketTime;
00309     unsigned m_maximumPacketTime;
00310 
00311     // Audio
00312     unsigned m_averageJitter;
00313     unsigned m_maximumJitter;
00314 
00315     // Video
00316     unsigned m_totalFrames;
00317     unsigned m_keyFrames;
00318 };
00319 
00320 #endif
00321 
00322 
00327 class RTP_UserData : public PObject
00328 {
00329   PCLASSINFO(RTP_UserData, PObject);
00330 
00331   public:
00338     virtual void OnTxStatistics(
00339       const RTP_Session & session   
00340     ) const;
00341 
00348     virtual void OnRxStatistics(
00349       const RTP_Session & session   
00350     ) const;
00351 
00352 #if OPAL_VIDEO
00353 
00358     virtual void OnTxIntraFrameRequest(
00359       const RTP_Session & session   
00360     ) const;
00361 
00367     virtual void OnRxIntraFrameRequest(
00368       const RTP_Session & session   
00369     ) const;
00370 #endif
00371 
00375     virtual void OnClearCall(
00376       const RTP_Session & session   
00377     );
00378 };
00379 
00380 class RTP_Encoding;
00381 
00382 
00385 class RTP_Session : public PObject
00386 {
00387   PCLASSINFO(RTP_Session, PObject);
00388 
00389   public:
00392     struct Params {
00393       Params()
00394         : id(0)
00395 #if OPAL_RTP_AGGREGATE
00396         , aggregator(NULL)
00397 #endif
00398         , userData(NULL)
00399         , autoDelete(true)
00400         , isAudio(false)
00401         , remoteIsNAT(false)
00402       { }
00403 
00404       PString             encoding;    
00405       unsigned            id;          
00406 #if OPAL_RTP_AGGREGATE
00407       PHandleAggregator * aggregator;  
00408 #endif
00409       RTP_UserData      * userData;    
00410       bool                autoDelete;  
00411       bool                isAudio;     
00412       bool                remoteIsNAT; 
00413     };
00414 
00417     RTP_Session(
00418       const Params & options 
00419     );
00420 
00424     ~RTP_Session();
00426 
00438     void SetJitterBufferSize(
00439       unsigned minJitterDelay, 
00440       unsigned maxJitterDelay, 
00441       unsigned timeUnits = 8,  
00442       PINDEX stackSize = 30000 
00443     );
00444 
00450     unsigned GetJitterBufferSize() const;
00451     
00454     unsigned GetJitterTimeUnits() const;
00455 
00457     virtual PBoolean ModifyQOS(RTP_QOS * )
00458     { return PFalse; }
00459 
00465     virtual PBoolean ReadBufferedData(
00466       RTP_DataFrame & frame   
00467     );
00468 
00474     virtual PBoolean ReadData(
00475       RTP_DataFrame & frame,  
00476       PBoolean loop               
00477     ) = 0;
00478 
00481     virtual PBoolean WriteData(
00482       RTP_DataFrame & frame   
00483     ) = 0;
00484 
00488     virtual PBoolean WriteOOBData(
00489       RTP_DataFrame & frame,
00490       bool rewriteTimeStamp = true
00491     );
00492 
00495     virtual PBoolean WriteControl(
00496       RTP_ControlFrame & frame    
00497     ) = 0;
00498 
00501     virtual PBoolean SendReport();
00502 
00505     virtual void Close(
00506       PBoolean reading    
00507     ) = 0;
00508 
00511     virtual void Reopen(
00512       PBoolean isReading
00513     ) = 0;
00514 
00517     virtual PString GetLocalHostName() = 0;
00518 
00519 #if OPAL_STATISTICS
00520     virtual void GetStatistics(OpalMediaStatistics & statistics, bool receiver) const;
00521 #endif
00522 
00523 
00526     enum SendReceiveStatus {
00527       e_ProcessPacket,
00528       e_IgnorePacket,
00529       e_AbortTransport
00530     };
00531     virtual SendReceiveStatus OnSendData(RTP_DataFrame & frame);
00532     virtual SendReceiveStatus Internal_OnSendData(RTP_DataFrame & frame);
00533 
00534     virtual SendReceiveStatus OnSendControl(RTP_ControlFrame & frame, PINDEX & len);
00535     virtual SendReceiveStatus Internal_OnSendControl(RTP_ControlFrame & frame, PINDEX & len);
00536 
00537     virtual SendReceiveStatus OnReceiveData(RTP_DataFrame & frame);
00538     virtual SendReceiveStatus Internal_OnReceiveData(RTP_DataFrame & frame);
00539 
00540     virtual SendReceiveStatus OnReceiveControl(RTP_ControlFrame & frame);
00541 
00542     class ReceiverReport : public PObject  {
00543         PCLASSINFO(ReceiverReport, PObject);
00544       public:
00545         void PrintOn(ostream &) const;
00546 
00547         DWORD sourceIdentifier;
00548         DWORD fractionLost;         /* fraction lost since last SR/RR */
00549         DWORD totalLost;            /* cumulative number of packets lost (signed!) */
00550         DWORD lastSequenceNumber;   /* extended last sequence number received */
00551         DWORD jitter;               /* interarrival jitter */
00552         PTimeInterval lastTimestamp;/* last SR packet from this source */
00553         PTimeInterval delay;        /* delay since last SR packet */
00554     };
00555     PARRAY(ReceiverReportArray, ReceiverReport);
00556 
00557     class SenderReport : public PObject  {
00558         PCLASSINFO(SenderReport, PObject);
00559       public:
00560         void PrintOn(ostream &) const;
00561 
00562         DWORD sourceIdentifier;
00563         PTime realTimestamp;
00564         DWORD rtpTimestamp;
00565         DWORD packetsSent;
00566         DWORD octetsSent;
00567     };
00568     virtual void OnRxSenderReport(const SenderReport & sender,
00569                                   const ReceiverReportArray & reports);
00570     virtual void OnRxReceiverReport(DWORD src,
00571                                     const ReceiverReportArray & reports);
00572 
00573     class SourceDescription : public PObject  {
00574         PCLASSINFO(SourceDescription, PObject);
00575       public:
00576         SourceDescription(DWORD src) { sourceIdentifier = src; }
00577         void PrintOn(ostream &) const;
00578 
00579         DWORD            sourceIdentifier;
00580         POrdinalToString items;
00581     };
00582     PARRAY(SourceDescriptionArray, SourceDescription);
00583     virtual void OnRxSourceDescription(const SourceDescriptionArray & descriptions);
00584 
00585     virtual void OnRxGoodbye(const PDWORDArray & sources,
00586                              const PString & reason);
00587 
00588     virtual void OnRxApplDefined(const PString & type, unsigned subtype, DWORD src,
00589                                  const BYTE * data, PINDEX size);
00591 
00596     unsigned GetSessionID() const { return sessionID; }
00597 
00600     bool IsAudio() const { return isAudio; }
00601 
00604     void SetAudio(
00605       bool aud    
00606     ) { isAudio = aud; }
00607 
00610     PString GetCanonicalName() const;
00611 
00614     void SetCanonicalName(const PString & name);
00615 
00618     PString GetToolName() const;
00619 
00622     void SetToolName(const PString & name);
00623 
00626     RTP_UserData * GetUserData() const { return userData; }
00627 
00630     void SetUserData(
00631       RTP_UserData * data,            
00632       PBoolean autoDeleteUserData = PTrue  
00633     );
00634 
00637     DWORD GetSyncSourceOut() const { return syncSourceOut; }
00638 
00641     bool AllowAnySyncSource() const { return allowAnySyncSource; }
00642 
00645     void SetAnySyncSource(
00646       bool allow    
00647     ) { allowAnySyncSource = allow; }
00648 
00651     PBoolean WillIgnoreOutOfOrderPackets() const { return ignoreOutOfOrderPackets; }
00652 
00655     void SetIgnoreOutOfOrderPackets(
00656       PBoolean ignore   
00657     ) { ignoreOutOfOrderPackets = ignore; }
00658 
00661     void SetIgnorePayloadTypeChanges(
00662       PBoolean ignore   
00663     ) { ignorePayloadTypeChanges = ignore; }
00664 
00667     const PTimeInterval & GetReportTimeInterval() { return reportTimeInterval; }
00668 
00671     void SetReportTimeInterval(
00672       const PTimeInterval & interval 
00673     )  { reportTimeInterval = interval; }
00674 
00677     PTimeInterval GetReportTimer()
00678     { return reportTimer; }
00679 
00682     unsigned GetTxStatisticsInterval() { return txStatisticsInterval; }
00683 
00686     void SetTxStatisticsInterval(
00687       unsigned packets   
00688     );
00689 
00692     unsigned GetRxStatisticsInterval() { return rxStatisticsInterval; }
00693 
00696     void SetRxStatisticsInterval(
00697       unsigned packets   
00698     );
00699 
00702     DWORD GetPacketsSent() const { return packetsSent; }
00703 
00706     DWORD GetOctetsSent() const { return octetsSent; }
00707 
00710     DWORD GetPacketsReceived() const { return packetsReceived; }
00711 
00714     DWORD GetOctetsReceived() const { return octetsReceived; }
00715 
00718     DWORD GetPacketsLost() const { return packetsLost; }
00719 
00722     DWORD GetPacketsOutOfOrder() const { return packetsOutOfOrder; }
00723 
00726     DWORD GetPacketsTooLate() const;
00727 
00730     DWORD GetPacketOverruns() const;
00731 
00736     DWORD GetAverageSendTime() const { return averageSendTime; }
00737 
00742     DWORD GetMarkerRecvCount() const { return markerRecvCount; }
00743 
00748     DWORD GetMarkerSendCount() const { return markerSendCount; }
00749 
00754     DWORD GetMaximumSendTime() const { return maximumSendTime; }
00755 
00760     DWORD GetMinimumSendTime() const { return minimumSendTime; }
00761 
00766     DWORD GetAverageReceiveTime() const { return averageReceiveTime; }
00767 
00772     DWORD GetMaximumReceiveTime() const { return maximumReceiveTime; }
00773 
00778     DWORD GetMinimumReceiveTime() const { return minimumReceiveTime; }
00779 
00784     DWORD GetAvgJitterTime() const { return jitterLevel>>7; }
00785 
00789     DWORD GetMaxJitterTime() const { return maximumJitterLevel>>7; }
00791 
00794     virtual int GetDataSocketHandle() const
00795     { return -1; }
00796     virtual int GetControlSocketHandle() const
00797     { return -1; }
00799 
00800     virtual void SetCloseOnBYE(PBoolean v)  { closeOnBye = v; }
00801 
00806     virtual void SendIntraFrameRequest();
00807 
00808     void SetNextSentSequenceNumber(WORD num) { lastSentSequenceNumber = (WORD)(num-1); }
00809 
00810     virtual PString GetEncoding() const { return m_encoding; }
00811     virtual void SetEncoding(const PString & newEncoding);
00812 
00813     DWORD GetSyncSourceIn() const { return syncSourceIn; }
00814 
00815     class EncodingLock
00816     {
00817       public:
00818         EncodingLock(RTP_Session & _session);
00819         ~EncodingLock();
00820 
00821         __inline RTP_Encoding * operator->() const { return m_encodingHandler; }
00822 
00823       protected:
00824         RTP_Session  & session;
00825         RTP_Encoding * m_encodingHandler;
00826     };
00827 
00828     friend class EncodingLock; 
00829 
00830   protected:
00831     virtual void SendBYE();
00832     void AddReceiverReport(RTP_ControlFrame::ReceiverReport & receiver);
00833     PBoolean InsertReportPacket(RTP_ControlFrame & report);
00834 
00835     PString             m_encoding;
00836     PMutex              m_encodingMutex;
00837     RTP_Encoding      * m_encodingHandler;
00838 
00839     unsigned           sessionID;
00840     bool               isAudio;
00841     PString            canonicalName;
00842     PString            toolName;
00843     RTP_UserData     * userData;
00844     PBoolean           autoDeleteUserData;
00845     RTP_JitterBuffer * jitter;
00846 
00847     PBoolean      ignoreOutOfOrderPackets;
00848     DWORD         syncSourceOut;
00849     DWORD         syncSourceIn;
00850     DWORD         lastSentTimestamp;
00851     bool          allowAnySyncSource;
00852     bool          allowOneSyncSourceChange;
00853     PBoolean      allowRemoteTransmitAddressChange;
00854     PBoolean      allowSequenceChange;
00855     PTimeInterval reportTimeInterval;
00856     unsigned      txStatisticsInterval;
00857     unsigned      rxStatisticsInterval;
00858     WORD          lastSentSequenceNumber;
00859     WORD          expectedSequenceNumber;
00860     PTimeInterval lastSentPacketTime;
00861     PTimeInterval lastReceivedPacketTime;
00862     WORD          lastRRSequenceNumber;
00863     PINDEX        consecutiveOutOfOrderPackets;
00864 
00865     PMutex        dataMutex;
00866     DWORD         timeStampOffs;               // offset between incoming media timestamp and timeStampOut
00867     PBoolean      oobTimeStampBaseEstablished; // PTrue if timeStampOffs has been established by media
00868     DWORD         oobTimeStampOutBase;         // base timestamp value for oob data
00869     PTimeInterval oobTimeStampBase;            // base time for oob timestamp
00870 
00871     // Statistics
00872     DWORD packetsSent;
00873     DWORD rtcpPacketsSent;
00874     DWORD octetsSent;
00875     DWORD packetsReceived;
00876     DWORD octetsReceived;
00877     DWORD packetsLost;
00878     DWORD packetsOutOfOrder;
00879     DWORD averageSendTime;
00880     DWORD maximumSendTime;
00881     DWORD minimumSendTime;
00882     DWORD averageReceiveTime;
00883     DWORD maximumReceiveTime;
00884     DWORD minimumReceiveTime;
00885     DWORD jitterLevel;
00886     DWORD maximumJitterLevel;
00887 
00888     DWORD markerSendCount;
00889     DWORD markerRecvCount;
00890 
00891     unsigned txStatisticsCount;
00892     unsigned rxStatisticsCount;
00893 
00894     DWORD    averageSendTimeAccum;
00895     DWORD    maximumSendTimeAccum;
00896     DWORD    minimumSendTimeAccum;
00897     DWORD    averageReceiveTimeAccum;
00898     DWORD    maximumReceiveTimeAccum;
00899     DWORD    minimumReceiveTimeAccum;
00900     DWORD    packetsLostSinceLastRR;
00901     DWORD    lastTransitTime;
00902     
00903     RTP_DataFrame::PayloadTypes lastReceivedPayloadType;
00904     PBoolean ignorePayloadTypeChanges;
00905 
00906     PMutex reportMutex;
00907     PTimer reportTimer;
00908 
00909 #if OPAL_RTP_AGGREGATE
00910     PHandleAggregator * aggregator;
00911 #endif
00912 
00913     PBoolean closeOnBye;
00914     PBoolean byeSent;
00915 };
00916 
00919 class RTP_UDP : public RTP_Session
00920 {
00921   PCLASSINFO(RTP_UDP, RTP_Session);
00922 
00923   public:
00928     RTP_UDP(
00929       const Params & options 
00930     );
00931 
00933     ~RTP_UDP();
00935 
00943     virtual PBoolean ReadData(RTP_DataFrame & frame, PBoolean loop);
00944     virtual PBoolean Internal_ReadData(RTP_DataFrame & frame, PBoolean loop);
00945 
00948     virtual PBoolean WriteData(RTP_DataFrame & frame);
00949     virtual PBoolean Internal_WriteData(RTP_DataFrame & frame);
00950 
00954     virtual PBoolean WriteOOBData(RTP_DataFrame & frame, bool setTimeStamp = true);
00955 
00958     virtual PBoolean WriteControl(RTP_ControlFrame & frame);
00959 
00962     virtual void Close(
00963       PBoolean reading    
00964     );
00965 
00968     virtual PString GetLocalHostName();
00970 
00973     virtual PBoolean ModifyQOS(RTP_QOS * rtpqos);
00974 
00979     virtual PBoolean Open(
00980       PIPSocket::Address localAddress,  
00981       WORD portBase,                    
00982       WORD portMax,                     
00983       BYTE ipTypeOfService,             
00984       PNatMethod * natMethod = NULL,    
00985       RTP_QOS * rtpqos = NULL           
00986     );
00988 
00991     virtual void Reopen(PBoolean isReading);
00993 
00998     virtual PIPSocket::Address GetLocalAddress() const { return localAddress; }
00999 
01002     virtual void SetLocalAddress(
01003       const PIPSocket::Address & addr
01004     ) { localAddress = addr; }
01005 
01008     PIPSocket::Address GetRemoteAddress() const { return remoteAddress; }
01009 
01012     virtual WORD GetLocalDataPort() const { return localDataPort; }
01013 
01016     virtual WORD GetLocalControlPort() const { return localControlPort; }
01017 
01020     virtual WORD GetRemoteDataPort() const { return remoteDataPort; }
01021 
01024     virtual WORD GetRemoteControlPort() const { return remoteControlPort; }
01025 
01028     virtual PUDPSocket & GetDataSocket() { return *dataSocket; }
01029 
01032     virtual PUDPSocket & GetControlSocket() { return *controlSocket; }
01033 
01036     virtual PBoolean SetRemoteSocketInfo(
01037       PIPSocket::Address address,   
01038       WORD port,                    
01039       PBoolean isDataPort               
01040     );
01041 
01044     virtual void ApplyQOS(
01045       const PIPSocket::Address & addr
01046     );
01048 
01049     virtual int GetDataSocketHandle() const
01050     { return dataSocket != NULL ? dataSocket->GetHandle() : -1; }
01051 
01052     virtual int GetControlSocketHandle() const
01053     { return controlSocket != NULL ? controlSocket->GetHandle() : -1; }
01054 
01055     friend class RTP_Encoding;
01056 
01057     virtual int WaitForPDU(PUDPSocket & dataSocket, PUDPSocket & controlSocket, const PTimeInterval & timer);
01058     virtual int Internal_WaitForPDU(PUDPSocket & dataSocket, PUDPSocket & controlSocket, const PTimeInterval & timer);
01059 
01060     virtual SendReceiveStatus ReadDataPDU(RTP_DataFrame & frame);
01061     virtual SendReceiveStatus Internal_ReadDataPDU(RTP_DataFrame & frame);
01062 
01063     virtual SendReceiveStatus OnReadTimeout(RTP_DataFrame & frame);
01064     virtual SendReceiveStatus Internal_OnReadTimeout(RTP_DataFrame & frame);
01065 
01066     virtual SendReceiveStatus ReadControlPDU();
01067     virtual SendReceiveStatus ReadDataOrControlPDU(
01068       BYTE * framePtr,
01069       PINDEX frameSize,
01070       PBoolean fromDataChannel
01071     );
01072     
01073     virtual bool WriteDataPDU(RTP_DataFrame & frame);
01074     virtual bool WriteDataOrControlPDU(
01075       const BYTE * framePtr,
01076       PINDEX frameSize,
01077       bool toDataChannel
01078     );
01079 
01080 
01081   protected:
01082     PIPSocket::Address localAddress;
01083     WORD               localDataPort;
01084     WORD               localControlPort;
01085 
01086     PIPSocket::Address remoteAddress;
01087     WORD               remoteDataPort;
01088     WORD               remoteControlPort;
01089 
01090     PIPSocket::Address remoteTransmitAddress;
01091 
01092     PUDPSocket * dataSocket;
01093     PUDPSocket * controlSocket;
01094 
01095     bool shutdownRead;
01096     bool shutdownWrite;
01097     bool appliedQOS;
01098     bool remoteIsNAT;
01099     bool localHasNAT;
01100     bool first;
01101     int  badTransmitCounter;
01102 };
01103 
01105 
01106 class RTP_UDP;
01107 
01108 class RTP_Encoding
01109 {
01110   public:
01111     RTP_Encoding();
01112     virtual ~RTP_Encoding();
01113     virtual void OnStart(RTP_Session & _rtpSession);
01114     virtual void OnFinish();
01115     virtual RTP_Session::SendReceiveStatus OnSendData(RTP_DataFrame & frame);
01116     virtual PBoolean WriteData(RTP_DataFrame & frame);
01117     virtual PBoolean WriteDataPDU(RTP_DataFrame & frame);
01118     virtual RTP_Session::SendReceiveStatus OnSendControl(RTP_ControlFrame & frame, PINDEX & len);
01119     virtual RTP_Session::SendReceiveStatus ReadDataPDU(RTP_DataFrame & frame);
01120     virtual RTP_Session::SendReceiveStatus OnReceiveData(RTP_DataFrame & frame);
01121     virtual RTP_Session::SendReceiveStatus OnReadTimeout(RTP_DataFrame & frame);
01122     virtual PBoolean ReadData(RTP_DataFrame & frame, PBoolean loop);
01123     virtual int WaitForPDU(PUDPSocket & dataSocket, PUDPSocket & controlSocket, const PTimeInterval &);
01124 
01125     PMutex      mutex;
01126     unsigned    refCount;
01127 
01128   protected:
01129     RTP_UDP     * rtpUDP;
01130 };
01131 
01133 
01134 class SecureRTP_UDP : public RTP_UDP
01135 {
01136   PCLASSINFO(SecureRTP_UDP, RTP_UDP);
01137 
01138   public:
01143     SecureRTP_UDP(
01144       const Params & options 
01145     );
01146 
01148     ~SecureRTP_UDP();
01149 
01150     virtual void SetSecurityMode(OpalSecurityMode * srtpParms);  
01151     virtual OpalSecurityMode * GetSecurityParms() const;
01152 
01153   protected:
01154     OpalSecurityMode * securityParms;
01155 };
01156 
01157 #endif // OPAL_RTP_RTP_H
01158 

Generated on Mon Feb 23 02:01:39 2009 for OPAL by  doxygen 1.5.1