# 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: 21035 $
    00030  * $Author: rjongbloed $
    00031  * $Date: 2008-09-17 07:57:58 +0000 (Wed, 17 Sep 2008) $
    00032  */
    00033
    00034 #ifndef __OPAL_RTP_H
    00035 #define __OPAL_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_H
    01158