# 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