# 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: 27699 $
    00030  * $Author: rjongbloed $
    00031  * $Date: 2012-05-24 20:35:37 -0500 (Thu, 24 May 2012) $
    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
    00049 class RTP_JitterBuffer;
    00050 class PNatMethod;
    00051 class OpalSecurityMode;
    00052 class RTCP_XR_Metrics;
    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 void FlushData();
    00591
    00594     virtual PBoolean WriteData(
    00595       RTP_DataFrame & frame
    00596     ) = 0;
    00597
    00601     virtual PBoolean WriteOOBData(
    00602       RTP_DataFrame & frame,
    00603       bool rewriteTimeStamp = true
    00604     );
    00605
    00608     virtual PBoolean WriteControl(
    00609       RTP_ControlFrame & frame
    00610     ) = 0;
    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(
    00724       DWORD src,
    00725       const ExtendedReportArray & reports
    00726     );
    00727
    00728     RTCP_XR_Metrics * GetExtendedMetrics() const { return m_metrics; }
    00729 #endif // OPAL_RTCP_XR
    00730
    00731
    00736     unsigned GetSessionID() const { return sessionID; }
    00737
    00740     void SetSessionID(unsigned id) { sessionID = id; }
    00741
    00744     bool IsAudio() const { return isAudio; }
    00745
    00748     void SetAudio(
    00749       bool aud
    00750     ) { isAudio = aud; }
    00751
    00754     PString GetCanonicalName() const;
    00755
    00758     void SetCanonicalName(const PString & name);
    00759
    00762     PString GetToolName() const;
    00763
    00766     void SetToolName(const PString & name);
    00767
    00770     RTP_UserData * GetUserData() const { return userData; }
    00771
    00774     void SetUserData(
    00775       RTP_UserData * data,
    00776       PBoolean autoDeleteUserData = true
    00777     );
    00778
    00781     DWORD GetSyncSourceOut() const { return syncSourceOut; }
    00782
    00785     bool AllowAnySyncSource() const { return allowAnySyncSource; }
    00786
    00789     void SetAnySyncSource(
    00790       bool allow
    00791     ) { allowAnySyncSource = allow; }
    00792
    00795     void SetIgnorePayloadTypeChanges(
    00796       PBoolean ignore
    00797     ) { ignorePayloadTypeChanges = ignore; }
    00798
    00801     const PTimeInterval & GetReportTimeInterval() { return m_reportTimer.GetResetTime(); }
    00802
    00805     void SetReportTimeInterval(
    00806       const PTimeInterval & interval
    00807     )  { m_reportTimer.RunContinuous(interval); }
    00808
    00811     unsigned GetTxStatisticsInterval() { return txStatisticsInterval; }
    00812
    00815     void SetTxStatisticsInterval(
    00816       unsigned packets
    00817     );
    00818
    00821     unsigned GetRxStatisticsInterval() { return rxStatisticsInterval; }
    00822
    00825     void SetRxStatisticsInterval(
    00826       unsigned packets
    00827     );
    00828
    00831     void ClearStatistics();
    00832
    00835     DWORD GetPacketsSent() const { return packetsSent; }
    00836
    00839     DWORD GetOctetsSent() const { return octetsSent; }
    00840
    00843     DWORD GetPacketsReceived() const { return packetsReceived; }
    00844
    00847     DWORD GetOctetsReceived() const { return octetsReceived; }
    00848
    00851     DWORD GetPacketsLost() const { return packetsLost; }
    00852
    00856     DWORD GetPacketsLostByRemote() const { return packetsLostByRemote; }
    00857
    00860     DWORD GetPacketsOutOfOrder() const { return packetsOutOfOrder; }
    00861
    00864     DWORD GetPacketsTooLate() const;
    00865
    00868     DWORD GetPacketOverruns() const;
    00869
    00874     DWORD GetAverageSendTime() const { return averageSendTime; }
    00875
    00880     DWORD GetMarkerRecvCount() const { return markerRecvCount; }
    00881
    00886     DWORD GetMarkerSendCount() const { return markerSendCount; }
    00887
    00892     DWORD GetMaximumSendTime() const { return maximumSendTime; }
    00893
    00898     DWORD GetMinimumSendTime() const { return minimumSendTime; }
    00899
    00904     DWORD GetAverageReceiveTime() const { return averageReceiveTime; }
    00905
    00910     DWORD GetMaximumReceiveTime() const { return maximumReceiveTime; }
    00911
    00916     DWORD GetMinimumReceiveTime() const { return minimumReceiveTime; }
    00917
    00918     enum { JitterRoundingGuardBits = 4 };
    00923     DWORD GetAvgJitterTime() const { return (jitterLevel>>JitterRoundingGuardBits)/GetJitterTimeUnits(); }
    00924
    00928     DWORD GetMaxJitterTime() const { return (maximumJitterLevel>>JitterRoundingGuardBits)/GetJitterTimeUnits(); }
    00929
    00934     DWORD GetJitterTimeOnRemote() const { return jitterLevelOnRemote/GetJitterTimeUnits(); }
    00936
    00937     virtual void SetCloseOnBYE(PBoolean v)  { closeOnBye = v; }
    00938
    00943     virtual void SendIntraFrameRequest(bool rfc2032, bool pictureLoss);
    00944
    00949     virtual void SendTemporalSpatialTradeOff(unsigned tradeOff);
    00950
    00951     void SetNextSentSequenceNumber(WORD num) { lastSentSequenceNumber = (WORD)(num-1); }
    00952
    00953     virtual PString GetEncoding() const { return m_encoding; }
    00954     virtual void SetEncoding(const PString & newEncoding);
    00955
    00956     DWORD GetSyncSourceIn() const { return syncSourceIn; }
    00957
    00958     class EncodingLock
    00959     {
    00960       public:
    00961         EncodingLock(RTP_Session & _session);
    00962         ~EncodingLock();
    00963
    00964         __inline RTP_Encoding * operator->() const { return m_encodingHandler; }
    00965
    00966       protected:
    00967         RTP_Session  & session;
    00968         RTP_Encoding * m_encodingHandler;
    00969     };
    00970
    00971     friend class EncodingLock;
    00972
    00973     void SetFailed(bool v)
    00974     { failed = v; }
    00975
    00976     bool HasFailed() const
    00977     { return failed; }
    00978
    00979     typedef PNotifierTemplate<SendReceiveStatus &> FilterNotifier;
    00980     #define PDECLARE_RTPFilterNotifier(cls, fn) PDECLARE_NOTIFIER2(RTP_DataFrame, cls, fn, RTP_Session::SendReceiveStatus &)
    00981     #define PCREATE_RTPFilterNotifier(fn) PCREATE_NOTIFIER2(fn, RTP_Session::SendReceiveStatus &)
    00982
    00983     void AddFilter(const FilterNotifier & filter);
    00984
    00985     virtual void SendBYE();
    00986
    00987   protected:
    00988     RTP_Session::ReceiverReportArray BuildReceiverReportArray(const RTP_ControlFrame & frame, PINDEX offset);
    00989     void AddReceiverReport(RTP_ControlFrame::ReceiverReport & receiver);
    00990
    00991     PBoolean InsertReportPacket(RTP_ControlFrame & report);
    00992
    00993     PString             m_encoding;
    00994     PMutex              m_encodingMutex;
    00995     RTP_Encoding      * m_encodingHandler;
    00996
    00997     unsigned           sessionID;
    00998     bool               isAudio;
    00999     unsigned           m_timeUnits;
    01000     PString            canonicalName;
    01001     PString            toolName;
    01002     RTP_UserData     * userData;
    01003     PBoolean           autoDeleteUserData;
    01004
    01005     typedef PSafePtr<RTP_JitterBuffer, PSafePtrMultiThreaded> JitterBufferPtr;
    01006     JitterBufferPtr m_jitterBuffer;
    01007
    01008     DWORD         syncSourceOut;
    01009     DWORD         syncSourceIn;
    01010     DWORD         lastSentTimestamp;
    01011     bool          allowAnySyncSource;
    01012     bool          allowOneSyncSourceChange;
    01013     PBoolean      allowRemoteTransmitAddressChange;
    01014     PBoolean      allowSequenceChange;
    01015     unsigned      txStatisticsInterval;
    01016     unsigned      rxStatisticsInterval;
    01017     WORD          lastSentSequenceNumber;
    01018     WORD          expectedSequenceNumber;
    01019     PTimeInterval lastSentPacketTime;
    01020     PTimeInterval lastReceivedPacketTime;
    01021     PTime         lastSRTimestamp;
    01022     PTime         lastSRReceiveTime;
    01023     PTimeInterval delaySinceLastSR;
    01024     WORD          lastRRSequenceNumber;
    01025     bool          resequenceOutOfOrderPackets;
    01026     unsigned      consecutiveOutOfOrderPackets;
    01027     PTimeInterval outOfOrderWaitTime;
    01028     PTimeInterval outOfOrderPacketTime;
    01029
    01030     std::list<RTP_DataFrame> m_outOfOrderPackets;
    01031     void SaveOutOfOrderPacket(RTP_DataFrame & frame);
    01032
    01033     PMutex        dataMutex;
    01034     DWORD         timeStampOffs;               // offset between incoming media timestamp and timeStampOut
    01035     PBoolean      oobTimeStampBaseEstablished; // true if timeStampOffs has been established by media
    01036     DWORD         oobTimeStampOutBase;         // base timestamp value for oob data
    01037     PTimeInterval oobTimeStampBase;            // base time for oob timestamp
    01038
    01039     // Statistics
    01040     PTime firstPacketSent;
    01041     DWORD packetsSent;
    01042     DWORD rtcpPacketsSent;
    01043     DWORD octetsSent;
    01044     PTime firstPacketReceived;
    01045     DWORD packetsReceived;
    01046     DWORD senderReportsReceived;
    01047     DWORD octetsReceived;
    01048     DWORD packetsLost;
    01049     DWORD packetsLostByRemote;
    01050     DWORD packetsOutOfOrder;
    01051     DWORD averageSendTime;
    01052     DWORD maximumSendTime;
    01053     DWORD minimumSendTime;
    01054     DWORD averageReceiveTime;
    01055     DWORD maximumReceiveTime;
    01056     DWORD minimumReceiveTime;
    01057     DWORD jitterLevel;
    01058     DWORD jitterLevelOnRemote;
    01059     DWORD maximumJitterLevel;
    01060
    01061     DWORD markerSendCount;
    01062     DWORD markerRecvCount;
    01063
    01064     unsigned txStatisticsCount;
    01065     unsigned rxStatisticsCount;
    01066
    01067 #if OPAL_RTCP_XR
    01068     // Calculate the VoIP Metrics for RTCP-XR
    01069     RTCP_XR_Metrics * m_metrics;
    01070     friend class RTCP_XR_Metrics;
    01071 #endif
    01072
    01073     DWORD    averageSendTimeAccum;
    01074     DWORD    maximumSendTimeAccum;
    01075     DWORD    minimumSendTimeAccum;
    01076     DWORD    averageReceiveTimeAccum;
    01077     DWORD    maximumReceiveTimeAccum;
    01078     DWORD    minimumReceiveTimeAccum;
    01079     DWORD    packetsLostSinceLastRR;
    01080     DWORD    lastTransitTime;
    01081
    01082     RTP_DataFrame::PayloadTypes lastReceivedPayloadType;
    01083     PBoolean ignorePayloadTypeChanges;
    01084
    01085     PMutex m_reportMutex;
    01086     PTimer m_reportTimer;
    01087     PDECLARE_NOTIFIER(PTimer, RTP_Session, SendReport);
    01088
    01089     PBoolean closeOnBye;
    01090     PBoolean byeSent;
    01091     bool                failed;
    01092
    01093     list<FilterNotifier> m_filters;
    01094 };
    01095
    01098 class RTP_UDP : public RTP_Session
    01099 {
    01100   PCLASSINFO(RTP_UDP, RTP_Session);
    01101
    01102   public:
    01107     RTP_UDP(
    01108       const Params & options
    01109     );
    01110
    01112     ~RTP_UDP();
    01114
    01122     virtual PBoolean ReadData(RTP_DataFrame & frame);
    01123     virtual PBoolean Internal_ReadData(RTP_DataFrame & frame);
    01124
    01127     virtual void FlushData();
    01128
    01131     virtual PBoolean WriteData(RTP_DataFrame & frame);
    01132     virtual PBoolean Internal_WriteData(RTP_DataFrame & frame);
    01133
    01137     virtual PBoolean WriteOOBData(RTP_DataFrame & frame, bool setTimeStamp = true);
    01138
    01141     virtual PBoolean WriteControl(RTP_ControlFrame & frame);
    01142
    01145     virtual bool Close(
    01146       PBoolean reading
    01147     );
    01148
    01151     virtual PString GetLocalHostName();
    01153
    01156     virtual PBoolean ModifyQOS(RTP_QOS * rtpqos);
    01157
    01162     virtual PBoolean Open(
    01163       PIPSocket::Address localAddress,
    01164       WORD portBase,
    01165       WORD portMax,
    01166       BYTE ipTypeOfService,
    01167       PNatMethod * natMethod = NULL,
    01168       RTP_QOS * rtpqos = NULL
    01169     );
    01171
    01174     virtual void Reopen(PBoolean isReading);
    01176
    01181     virtual PIPSocket::Address GetLocalAddress() const { return localAddress; }
    01182
    01185     virtual void SetLocalAddress(
    01186       const PIPSocket::Address & addr
    01187     ) { localAddress = addr; }
    01188
    01191     PIPSocket::Address GetRemoteAddress() const { return remoteAddress; }
    01192
    01195     virtual WORD GetLocalDataPort() const { return localDataPort; }
    01196
    01199     virtual WORD GetLocalControlPort() const { return localControlPort; }
    01200
    01203     virtual WORD GetRemoteDataPort() const { return remoteDataPort; }
    01204
    01207     virtual WORD GetRemoteControlPort() const { return remoteControlPort; }
    01208
    01211     virtual PUDPSocket & GetDataSocket() { return *dataSocket; }
    01212
    01215     virtual PUDPSocket & GetControlSocket() { return *controlSocket; }
    01216
    01219     virtual PBoolean SetRemoteSocketInfo(
    01220       PIPSocket::Address address,
    01221       WORD port,
    01222       PBoolean isDataPort
    01223     );
    01224
    01227     virtual void ApplyQOS(
    01228       const PIPSocket::Address & addr
    01229     );
    01231
    01232     virtual int GetDataSocketHandle() const
    01233     { return dataSocket != NULL ? dataSocket->GetHandle() : -1; }
    01234
    01235     virtual int GetControlSocketHandle() const
    01236     { return controlSocket != NULL ? controlSocket->GetHandle() : -1; }
    01237
    01238     friend class RTP_Encoding;
    01239
    01240     virtual int WaitForPDU(PUDPSocket & dataSocket, PUDPSocket & controlSocket, const PTimeInterval & timer);
    01241     virtual int Internal_WaitForPDU(PUDPSocket & dataSocket, PUDPSocket & controlSocket, const PTimeInterval & timer);
    01242
    01243     virtual SendReceiveStatus ReadDataPDU(RTP_DataFrame & frame);
    01244     virtual SendReceiveStatus Internal_ReadDataPDU(RTP_DataFrame & frame);
    01245
    01246     virtual SendReceiveStatus OnReadTimeout(RTP_DataFrame & frame);
    01247     virtual SendReceiveStatus Internal_OnReadTimeout(RTP_DataFrame & frame);
    01248
    01249     virtual SendReceiveStatus ReadControlPDU();
    01250     virtual SendReceiveStatus ReadDataOrControlPDU(
    01251       BYTE * framePtr,
    01252       PINDEX frameSize,
    01253       PBoolean fromDataChannel
    01254     );
    01255
    01256     virtual bool WriteDataPDU(RTP_DataFrame & frame);
    01257     virtual bool WriteDataOrControlPDU(
    01258       const BYTE * framePtr,
    01259       PINDEX frameSize,
    01260       bool toDataChannel
    01261     );
    01262
    01263     virtual void SetEncoding(const PString & newEncoding);
    01264
    01265
    01266   protected:
    01267     PIPSocket::Address localAddress;
    01268     WORD               localDataPort;
    01269     WORD               localControlPort;
    01270
    01271     PIPSocket::Address remoteAddress;
    01272     WORD               remoteDataPort;
    01273     WORD               remoteControlPort;
    01274
    01275     PIPSocket::Address remoteTransmitAddress;
    01276
    01277     PUDPSocket * dataSocket;
    01278     PUDPSocket * controlSocket;
    01279
    01280     bool shutdownRead;
    01281     bool shutdownWrite;
    01282     bool appliedQOS;
    01283     bool remoteIsNAT;
    01284     bool localHasNAT;
    01285     bool m_firstControl;
    01286     int  badTransmitCounter;
    01287     PTime badTransmitStart;
    01288
    01289     PTimer timerWriteDataIdle;
    01290     PDECLARE_NOTIFIER(PTimer,  RTP_UDP, OnWriteDataIdle);
    01291 };
    01292
    01294
    01295 class RTP_UDP;
    01296
    01297 class RTP_Encoding
    01298 {
    01299   public:
    01300     RTP_Encoding();
    01301     virtual ~RTP_Encoding();
    01302     virtual void ApplyStringOptions(const PStringToString & /*stringOptions*/) {}
    01303     virtual void OnStart(RTP_Session & _rtpSession);
    01304     virtual void OnFinish();
    01305     virtual RTP_Session::SendReceiveStatus OnSendData(RTP_DataFrame & frame);
    01306     virtual PBoolean WriteData(RTP_DataFrame & frame, bool oob);
    01307     virtual PBoolean WriteDataPDU(RTP_DataFrame & frame);
    01308     virtual void OnWriteDataIdle() {}
    01309     virtual void SetWriteDataIdleTimer(PTimer &) {}
    01310     virtual RTP_Session::SendReceiveStatus OnSendControl(RTP_ControlFrame & frame, PINDEX & len);
    01311     virtual RTP_Session::SendReceiveStatus ReadDataPDU(RTP_DataFrame & frame);
    01312     virtual RTP_Session::SendReceiveStatus OnReceiveData(RTP_DataFrame & frame);
    01313     virtual RTP_Session::SendReceiveStatus OnReadTimeout(RTP_DataFrame & frame);
    01314     virtual PBoolean ReadData(RTP_DataFrame & frame);
    01315     virtual int WaitForPDU(PUDPSocket & dataSocket, PUDPSocket & controlSocket, const PTimeInterval &);
    01316
    01317     PMutex      mutex;
    01318     unsigned    refCount;
    01319
    01320   protected:
    01321     RTP_UDP     * rtpUDP;
    01322 };
    01323
    01324 PFACTORY_LOAD(RTP_Encoding);
    01325
    01326
    01328
    01329 class SecureRTP_UDP : public RTP_UDP
    01330 {
    01331   PCLASSINFO(SecureRTP_UDP, RTP_UDP);
    01332
    01333   public:
    01338     SecureRTP_UDP(
    01339       const Params & options
    01340     );
    01341
    01343     ~SecureRTP_UDP();
    01344
    01345     virtual void SetSecurityMode(OpalSecurityMode * srtpParms);
    01346     virtual OpalSecurityMode * GetSecurityParms() const;
    01347
    01348   protected:
    01349     OpalSecurityMode * securityParms;
    01350 };
    01351
    01352 #endif // OPAL_RTP_RTP_H
    01353