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: 27942 $
00030  * $Author: rjongbloed $
00031  * $Date: 2012-06-29 21:44:01 -0500 (Fri, 29 Jun 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 <ptclib/url.h>
00044 
00045 #include <set>
00046 
00047 
00049 // Real Time Protocol - IETF RFC1889 and RFC1890
00050 
00053 class RTP_DataFrame : public PBYTEArray
00054 {
00055   PCLASSINFO(RTP_DataFrame, PBYTEArray);
00056 
00057   public:
00058     RTP_DataFrame(PINDEX payloadSize = 0, PINDEX bufferSize = 0);
00059     RTP_DataFrame(const BYTE * data, PINDEX len, bool dynamic = true);
00060 
00061     enum {
00062       ProtocolVersion = 2,
00063       MinHeaderSize = 12,
00064       // Max safe MTU size (576 bytes as per RFC879) minus IP, UDP an RTP headers
00065       MaxMtuPayloadSize = (576-20-16-12)
00066     };
00067 
00068     enum PayloadTypes {
00069       PCMU,         // G.711 u-Law
00070       FS1016,       // Federal Standard 1016 CELP
00071       G721,         // ADPCM - Subsumed by G.726
00072       G726 = G721,
00073       GSM,          // GSM 06.10
00074       G7231,        // G.723.1 at 6.3kbps or 5.3 kbps
00075       DVI4_8k,      // DVI4 at 8kHz sample rate
00076       DVI4_16k,     // DVI4 at 16kHz sample rate
00077       LPC,          // LPC-10 Linear Predictive CELP
00078       PCMA,         // G.711 A-Law
00079       G722,         // G.722
00080       L16_Stereo,   // 16 bit linear PCM
00081       L16_Mono,     // 16 bit linear PCM
00082       G723,         // G.723
00083       CN,           // Confort Noise
00084       MPA,          // MPEG1 or MPEG2 audio
00085       G728,         // G.728 16kbps CELP
00086       DVI4_11k,     // DVI4 at 11kHz sample rate
00087       DVI4_22k,     // DVI4 at 22kHz sample rate
00088       G729,         // G.729 8kbps
00089       Cisco_CN,     // Cisco systems comfort noise (unofficial)
00090 
00091       CelB = 25,    // Sun Systems Cell-B video
00092       JPEG,         // Motion JPEG
00093       H261 = 31,    // H.261
00094       MPV,          // MPEG1 or MPEG2 video
00095       MP2T,         // MPEG2 transport system
00096       H263,         // H.263
00097 
00098       T38 = 38,     // T.38 (internal)
00099 
00100       LastKnownPayloadType,
00101 
00102       DynamicBase = 96,
00103       MaxPayloadType = 127,
00104       IllegalPayloadType
00105     };
00106 
00107     unsigned GetVersion() const { return (theArray[0]>>6)&3; }
00108 
00109     bool GetExtension() const   { return (theArray[0]&0x10) != 0; }
00110     void SetExtension(bool ext);
00111 
00112     bool GetMarker() const { return (theArray[1]&0x80) != 0; }
00113     void SetMarker(bool m);
00114 
00115     bool GetPadding() const { return (theArray[0]&0x20) != 0; }
00116     void SetPadding(bool v)  { if (v) theArray[0] |= 0x20; else theArray[0] &= 0xdf; }
00117     BYTE * GetPaddingPtr() const { return (BYTE *)(theArray+m_headerSize+m_payloadSize); }
00118 
00119     PINDEX GetPaddingSize() const { return m_paddingSize; }
00120     bool   SetPaddingSize(PINDEX sz);
00121 
00122     PayloadTypes GetPayloadType() const { return (PayloadTypes)(theArray[1]&0x7f); }
00123     void         SetPayloadType(PayloadTypes t);
00124 
00125     WORD GetSequenceNumber() const { return *(PUInt16b *)&theArray[2]; }
00126     void SetSequenceNumber(WORD n) { *(PUInt16b *)&theArray[2] = n; }
00127 
00128     DWORD GetTimestamp() const  { return *(PUInt32b *)&theArray[4]; }
00129     void  SetTimestamp(DWORD t) { *(PUInt32b *)&theArray[4] = t; }
00130 
00131     DWORD GetSyncSource() const  { return *(PUInt32b *)&theArray[8]; }
00132     void  SetSyncSource(DWORD s) { *(PUInt32b *)&theArray[8] = s; }
00133 
00134     PINDEX GetContribSrcCount() const { return theArray[0]&0xf; }
00135     DWORD  GetContribSource(PINDEX idx) const;
00136     void   SetContribSource(PINDEX idx, DWORD src);
00137 
00138     PINDEX GetHeaderSize() const { return m_headerSize; }
00139 
00140     void CopyHeader(const RTP_DataFrame & other);
00141 
00148     BYTE * GetHeaderExtension(
00149       unsigned & id,      
00150       PINDEX & length,    
00151       int idx = -1        
00152     ) const;
00153 
00155     enum HeaderExtensionType {
00156       RFC3550,
00157       RFC5285_OneByte,
00158       RFC5285_TwoByte
00159     };
00160 
00164     BYTE * GetHeaderExtension(
00165       HeaderExtensionType type, 
00166       unsigned id,              
00167       PINDEX & length           
00168     ) const;
00169 
00176     bool SetHeaderExtension(
00177       unsigned id,        
00178       PINDEX length,      
00179       const BYTE * data,  
00180       HeaderExtensionType type 
00181     );
00182 
00183     PINDEX GetExtensionSizeDWORDs() const;      // get the number of 32 bit words in the extension (excluding the header).
00184     bool   SetExtensionSizeDWORDs(PINDEX sz);   // set the number of 32 bit words in the extension (excluding the header)
00185 
00186     PINDEX GetPayloadSize() const { return m_payloadSize; }
00187     bool   SetPayloadSize(PINDEX sz);
00188     BYTE * GetPayloadPtr()     const { return (BYTE *)(theArray+m_headerSize); }
00189 
00190     virtual PObject * Clone() const { return new RTP_DataFrame(*this); }
00191     virtual void PrintOn(ostream & strm) const;
00192 
00193     // Note this sets the whole packet length, and calculates the various
00194     // sub-section sizes: header payload and padding.
00195     bool SetPacketSize(PINDEX sz);
00196 
00199     PTime GetAbsoluteTime() const { return m_absoluteTime; }
00200 
00203     void SetAbsoluteTime() { m_absoluteTime.SetCurrentTime(); }
00204     void SetAbsoluteTime(const PTime & t) { m_absoluteTime = t; }
00205 
00210     unsigned GetDiscontinuity() const { return m_discontinuity; }
00211 
00212     void SetDiscontinuity(unsigned lost) { m_discontinuity = lost; }
00213 
00214   protected:
00215     PINDEX   m_headerSize;
00216     PINDEX   m_payloadSize;
00217     PINDEX   m_paddingSize;
00218     PTime    m_absoluteTime;
00219     unsigned m_discontinuity;
00220 
00221 #if PTRACING
00222     friend ostream & operator<<(ostream & o, PayloadTypes t);
00223 #endif
00224 };
00225 
00226 PLIST(RTP_DataFrameList, RTP_DataFrame);
00227 
00228 
00231 class RTP_ControlFrame : public PBYTEArray
00232 {
00233   PCLASSINFO(RTP_ControlFrame, PBYTEArray);
00234 
00235   public:
00236     RTP_ControlFrame(PINDEX compoundSize = 2048);
00237 
00238     unsigned GetVersion() const { return (BYTE)theArray[compoundOffset]>>6; }
00239 
00240     unsigned GetCount() const { return (BYTE)theArray[compoundOffset]&0x1f; }
00241     void     SetCount(unsigned count);
00242 
00243     enum PayloadTypes {
00244       e_IntraFrameRequest       = 192,
00245       e_SenderReport            = 200,
00246       e_ReceiverReport          = 201,
00247       e_SourceDescription       = 202,
00248       e_Goodbye                 = 203,
00249       e_ApplDefined             = 204,
00250       e_TransportLayerFeedBack  = 205, // RFC4585
00251       e_PayloadSpecificFeedBack = 206,
00252       e_ExtendedReport          = 207  // RFC3611
00253     };
00254 
00255     unsigned GetPayloadType() const { return (BYTE)theArray[compoundOffset+1]; }
00256     void     SetPayloadType(unsigned t);
00257 
00258     PINDEX GetPayloadSize() const { return 4*(*(PUInt16b *)&theArray[compoundOffset+2]); }
00259     void   SetPayloadSize(PINDEX sz);
00260 
00261     BYTE * GetPayloadPtr() const;
00262 
00263     bool ReadNextPacket();
00264     bool StartNewPacket();
00265     void EndPacket();
00266 
00267     PINDEX GetCompoundSize() const;
00268 
00269     void Reset(PINDEX size);
00270 
00271 #pragma pack(1)
00272     struct ReceiverReport {
00273       PUInt32b ssrc;      /* data source being reported */
00274       BYTE fraction;      /* fraction lost since last SR/RR */
00275       BYTE lost[3];       /* cumulative number of packets lost (signed!) */
00276       PUInt32b last_seq;  /* extended last sequence number received */
00277       PUInt32b jitter;    /* interarrival jitter */
00278       PUInt32b lsr;       /* last SR packet from this source */
00279       PUInt32b dlsr;      /* delay since last SR packet */
00280 
00281       unsigned GetLostPackets() const { return (lost[0]<<16U)+(lost[1]<<8U)+lost[2]; }
00282       void SetLostPackets(unsigned lost);
00283     };
00284 
00285     struct SenderReport {
00286       PUInt32b ntp_sec;   /* NTP timestamp */
00287       PUInt32b ntp_frac;
00288       PUInt32b rtp_ts;    /* RTP timestamp */
00289       PUInt32b psent;     /* packets sent */
00290       PUInt32b osent;     /* octets sent */ 
00291     };
00292 
00293     struct ExtendedReport {
00294       /* VoIP Metrics Report Block */
00295       BYTE bt;                     /* block type */
00296       BYTE type_specific;          /* determined by the block definition */
00297       PUInt16b length;             /* length of the report block */
00298       PUInt32b ssrc;               /* data source being reported */
00299       BYTE loss_rate;              /* fraction of RTP data packets lost */ 
00300       BYTE discard_rate;           /* fraction of RTP data packets discarded */
00301       BYTE burst_density;          /* fraction of RTP data packets within burst periods */
00302       BYTE gap_density;            /* fraction of RTP data packets within inter-burst gaps */
00303       PUInt16b burst_duration;     /* the mean duration, in ms, of burst periods */
00304       PUInt16b gap_duration;       /* the mean duration, in ms, of gap periods */
00305       PUInt16b round_trip_delay;   /* the most recently calculated round trip time */    
00306       PUInt16b end_system_delay;   /* the most recently estimates end system delay */
00307       BYTE signal_level;           /* voice signal level related to 0 dBm */
00308       BYTE noise_level;            /* ratio of the silent background level to 0 dBm */
00309       BYTE rerl;                   /* residual echo return loss */
00310       BYTE gmin;                   /* gap threshold */
00311       BYTE r_factor;               /* voice quality metric of the call */
00312       BYTE ext_r_factor;           /* external R factor */
00313       BYTE mos_lq;                 /* MOS for listen quality */
00314       BYTE mos_cq;                 /* MOS for conversational quality */
00315       BYTE rx_config;              /* receiver configuration byte */
00316       BYTE reserved;               /* reserved for future definition */
00317       PUInt16b jb_nominal;         /* current nominal jitter buffer delay, in ms */ 
00318       PUInt16b jb_maximum;         /* current maximum jitter buffer delay, in ms */
00319       PUInt16b jb_absolute;        /* current absolute maximum jitter buffer delay, in ms */
00320     };
00321 
00322     enum DescriptionTypes {
00323       e_END,
00324       e_CNAME,
00325       e_NAME,
00326       e_EMAIL,
00327       e_PHONE,
00328       e_LOC,
00329       e_TOOL,
00330       e_NOTE,
00331       e_PRIV,
00332       NumDescriptionTypes
00333     };
00334 
00335     struct SourceDescription {
00336       PUInt32b src;       /* first SSRC/CSRC */
00337       struct Item {
00338         BYTE type;        /* type of SDES item (enum DescriptionTypes) */
00339         BYTE length;      /* length of SDES item (in octets) */
00340         char data[1];     /* text, not zero-terminated */
00341 
00342         /* WARNING, SourceDescription may not be big enough to contain length and data, for 
00343            instance, when type == RTP_ControlFrame::e_END.
00344            Be careful whan calling the following function of it may read to over to 
00345            memory allocated*/
00346         unsigned int GetLengthTotal() const {return (unsigned int)(length + 2);} 
00347         const Item * GetNextItem() const { return (const Item *)((char *)this + length + 2); }
00348         Item * GetNextItem() { return (Item *)((char *)this + length + 2); }
00349       } item[1];          /* list of SDES items */
00350     };
00351 
00352     void StartSourceDescription(
00353       DWORD src   
00354     );
00355 
00356     void AddSourceDescriptionItem(
00357       unsigned type,            
00358       const PString & data      
00359     );
00360 
00361     // RFC4585 Feedback Message Type (FMT)
00362     unsigned GetFbType() const { return (BYTE)theArray[compoundOffset]&0x1f; }
00363     void     SetFbType(unsigned type, PINDEX fciSize);
00364 
00365     enum TransportLayerFbTypes {
00366       e_TransportNACK = 1,
00367       e_TMMBR = 3,
00368       e_TMMBN
00369     };
00370 
00371     enum PayloadSpecificFbTypes {
00372       e_PictureLossIndication = 1,
00373       e_SliceLostIndication,
00374       e_ReferencePictureSelectionIndication,
00375       e_FullIntraRequest,                     //RFC5104
00376       e_TemporalSpatialTradeOffRequest,
00377       e_TemporalSpatialTradeOffNotification,
00378       e_VideoBackChannelMessage,
00379       e_ApplicationLayerFbMessage = 15
00380     };
00381 
00382     struct FbFCI {
00383       PUInt32b senderSSRC;  /* data source of sender of message */
00384       PUInt32b mediaSSRC;   /* data source of media */
00385     };
00386 
00387     struct FbFIR {
00388       FbFCI    fci;
00389       PUInt32b requestSSRC;
00390       BYTE     sequenceNUmber;
00391     };
00392 
00393     struct FbTSTO {
00394       FbFCI    fci;
00395       PUInt32b requestSSRC;
00396       BYTE     sequenceNUmber;
00397       BYTE     reserver[2];
00398       BYTE     tradeOff;
00399     };
00400 
00401     // Same for request (e_TMMBR) and notification (e_TMMBN)
00402     struct FbTMMB {
00403       FbFCI    fci;
00404       PUInt32b requestSSRC;
00405       PUInt32b bitRateAndOverhead; // Various bit fields
00406 
00407       unsigned GetBitRate() const;
00408       unsigned GetOverhead() const { return bitRateAndOverhead & 0x1ff; }
00409     };
00410 
00411 #pragma pack()
00412 
00413   protected:
00414     PINDEX compoundOffset;
00415     PINDEX payloadSize;
00416 };
00417 
00418 
00420 
00423 class RTPExtensionHeaderInfo : public PObject
00424 {
00425     PCLASSINFO(RTPExtensionHeaderInfo, PObject);
00426   public:
00427     unsigned m_id;
00428 
00429     enum Direction {
00430       Undefined = -1,
00431       Inactive,
00432       RecvOnly,
00433       SendOnly,
00434       SendRecv
00435     } m_direction;
00436 
00437     PURL m_uri;
00438 
00439     PString m_attributes;
00440 
00441     RTPExtensionHeaderInfo();
00442     virtual Comparison Compare(const PObject & other) const;
00443 
00444 #if OPAL_SIP
00445     bool ParseSDP(const PString & param);
00446     void OutputSDP(ostream & strm) const;
00447 #endif
00448 };
00449 
00450 typedef std::set<RTPExtensionHeaderInfo> RTPExtensionHeaders;
00451 
00452 
00453 #endif // OPAL_RTP_RTP_H
00454 

Generated on 21 Jun 2013 for OPAL by  doxygen 1.4.7