OPAL  Version 3.12.5
rtp.h
Go to the documentation of this file.
1 /*
2  * rtp.h
3  *
4  * RTP protocol handler
5  *
6  * Open H323 Library
7  *
8  * Copyright (c) 1998-2001 Equivalence Pty. Ltd.
9  *
10  * The contents of this file are subject to the Mozilla Public License
11  * Version 1.0 (the "License"); you may not use this file except in
12  * compliance with the License. You may obtain a copy of the License at
13  * http://www.mozilla.org/MPL/
14  *
15  * Software distributed under the License is distributed on an "AS IS"
16  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
17  * the License for the specific language governing rights and limitations
18  * under the License.
19  *
20  * The Original Code is Open H323 Library.
21  *
22  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
23  *
24  * Portions of this code were written with the assisance of funding from
25  * Vovida Networks, Inc. http://www.vovida.com.
26  *
27  * Contributor(s): ______________________________________.
28  *
29  * $Revision: 27942 $
30  * $Author: rjongbloed $
31  * $Date: 2012-06-29 21:44:01 -0500 (Fri, 29 Jun 2012) $
32  */
33 
34 #ifndef OPAL_RTP_RTP_H
35 #define OPAL_RTP_RTP_H
36 
37 #ifdef P_USE_PRAGMA
38 #pragma interface
39 #endif
40 
41 #include <opal/buildopts.h>
42 
43 #include <ptclib/url.h>
44 
45 #include <set>
46 
47 
49 // Real Time Protocol - IETF RFC1889 and RFC1890
50 
53 class RTP_DataFrame : public PBYTEArray
54 {
55  PCLASSINFO(RTP_DataFrame, PBYTEArray);
56 
57  public:
58  RTP_DataFrame(PINDEX payloadSize = 0, PINDEX bufferSize = 0);
59  RTP_DataFrame(const BYTE * data, PINDEX len, bool dynamic = true);
60 
61  enum {
64  // Max safe MTU size (576 bytes as per RFC879) minus IP, UDP an RTP headers
65  MaxMtuPayloadSize = (576-20-16-12)
66  };
67 
68  enum PayloadTypes {
69  PCMU, // G.711 u-Law
70  FS1016, // Federal Standard 1016 CELP
71  G721, // ADPCM - Subsumed by G.726
73  GSM, // GSM 06.10
74  G7231, // G.723.1 at 6.3kbps or 5.3 kbps
75  DVI4_8k, // DVI4 at 8kHz sample rate
76  DVI4_16k, // DVI4 at 16kHz sample rate
77  LPC, // LPC-10 Linear Predictive CELP
78  PCMA, // G.711 A-Law
79  G722, // G.722
80  L16_Stereo, // 16 bit linear PCM
81  L16_Mono, // 16 bit linear PCM
82  G723, // G.723
83  CN, // Confort Noise
84  MPA, // MPEG1 or MPEG2 audio
85  G728, // G.728 16kbps CELP
86  DVI4_11k, // DVI4 at 11kHz sample rate
87  DVI4_22k, // DVI4 at 22kHz sample rate
88  G729, // G.729 8kbps
89  Cisco_CN, // Cisco systems comfort noise (unofficial)
90 
91  CelB = 25, // Sun Systems Cell-B video
92  JPEG, // Motion JPEG
93  H261 = 31, // H.261
94  MPV, // MPEG1 or MPEG2 video
95  MP2T, // MPEG2 transport system
96  H263, // H.263
97 
98  T38 = 38, // T.38 (internal)
99 
101 
105  };
106 
107  unsigned GetVersion() const { return (theArray[0]>>6)&3; }
108 
109  bool GetExtension() const { return (theArray[0]&0x10) != 0; }
110  void SetExtension(bool ext);
111 
112  bool GetMarker() const { return (theArray[1]&0x80) != 0; }
113  void SetMarker(bool m);
114 
115  bool GetPadding() const { return (theArray[0]&0x20) != 0; }
116  void SetPadding(bool v) { if (v) theArray[0] |= 0x20; else theArray[0] &= 0xdf; }
117  BYTE * GetPaddingPtr() const { return (BYTE *)(theArray+m_headerSize+m_payloadSize); }
118 
119  PINDEX GetPaddingSize() const { return m_paddingSize; }
120  bool SetPaddingSize(PINDEX sz);
121 
122  PayloadTypes GetPayloadType() const { return (PayloadTypes)(theArray[1]&0x7f); }
124 
125  WORD GetSequenceNumber() const { return *(PUInt16b *)&theArray[2]; }
126  void SetSequenceNumber(WORD n) { *(PUInt16b *)&theArray[2] = n; }
127 
128  DWORD GetTimestamp() const { return *(PUInt32b *)&theArray[4]; }
129  void SetTimestamp(DWORD t) { *(PUInt32b *)&theArray[4] = t; }
130 
131  DWORD GetSyncSource() const { return *(PUInt32b *)&theArray[8]; }
132  void SetSyncSource(DWORD s) { *(PUInt32b *)&theArray[8] = s; }
133 
134  PINDEX GetContribSrcCount() const { return theArray[0]&0xf; }
135  DWORD GetContribSource(PINDEX idx) const;
136  void SetContribSource(PINDEX idx, DWORD src);
137 
138  PINDEX GetHeaderSize() const { return m_headerSize; }
139 
140  void CopyHeader(const RTP_DataFrame & other);
141 
148  BYTE * GetHeaderExtension(
149  unsigned & id,
150  PINDEX & length,
151  int idx = -1
152  ) const;
153 
159  };
160 
164  BYTE * GetHeaderExtension(
165  HeaderExtensionType type,
166  unsigned id,
167  PINDEX & length
168  ) const;
169 
176  bool SetHeaderExtension(
177  unsigned id,
178  PINDEX length,
179  const BYTE * data,
180  HeaderExtensionType type
181  );
182 
183  PINDEX GetExtensionSizeDWORDs() const; // get the number of 32 bit words in the extension (excluding the header).
184  bool SetExtensionSizeDWORDs(PINDEX sz); // set the number of 32 bit words in the extension (excluding the header)
185 
186  PINDEX GetPayloadSize() const { return m_payloadSize; }
187  bool SetPayloadSize(PINDEX sz);
188  BYTE * GetPayloadPtr() const { return (BYTE *)(theArray+m_headerSize); }
189 
190  virtual PObject * Clone() const { return new RTP_DataFrame(*this); }
191  virtual void PrintOn(ostream & strm) const;
192 
193  // Note this sets the whole packet length, and calculates the various
194  // sub-section sizes: header payload and padding.
195  bool SetPacketSize(PINDEX sz);
196 
199  PTime GetAbsoluteTime() const { return m_absoluteTime; }
200 
203  void SetAbsoluteTime() { m_absoluteTime.SetCurrentTime(); }
204  void SetAbsoluteTime(const PTime & t) { m_absoluteTime = t; }
205 
210  unsigned GetDiscontinuity() const { return m_discontinuity; }
211 
212  void SetDiscontinuity(unsigned lost) { m_discontinuity = lost; }
213 
214  protected:
215  PINDEX m_headerSize;
219  unsigned m_discontinuity;
220 
221 #if PTRACING
222  friend ostream & operator<<(ostream & o, PayloadTypes t);
223 #endif
224 };
225 
226 PLIST(RTP_DataFrameList, RTP_DataFrame);
227 
228 
231 class RTP_ControlFrame : public PBYTEArray
232 {
233  PCLASSINFO(RTP_ControlFrame, PBYTEArray);
234 
235  public:
236  RTP_ControlFrame(PINDEX compoundSize = 2048);
237 
238  unsigned GetVersion() const { return (BYTE)theArray[compoundOffset]>>6; }
239 
240  unsigned GetCount() const { return (BYTE)theArray[compoundOffset]&0x1f; }
241  void SetCount(unsigned count);
242 
244  e_IntraFrameRequest = 192,
245  e_SenderReport = 200,
246  e_ReceiverReport = 201,
247  e_SourceDescription = 202,
248  e_Goodbye = 203,
249  e_ApplDefined = 204,
250  e_TransportLayerFeedBack = 205, // RFC4585
251  e_PayloadSpecificFeedBack = 206,
252  e_ExtendedReport = 207 // RFC3611
253  };
254 
255  unsigned GetPayloadType() const { return (BYTE)theArray[compoundOffset+1]; }
256  void SetPayloadType(unsigned t);
257 
258  PINDEX GetPayloadSize() const { return 4*(*(PUInt16b *)&theArray[compoundOffset+2]); }
259  void SetPayloadSize(PINDEX sz);
260 
261  BYTE * GetPayloadPtr() const;
262 
263  bool ReadNextPacket();
264  bool StartNewPacket();
265  void EndPacket();
266 
267  PINDEX GetCompoundSize() const;
268 
269  void Reset(PINDEX size);
270 
271 #pragma pack(1)
272  struct ReceiverReport {
273  PUInt32b ssrc; /* data source being reported */
274  BYTE fraction; /* fraction lost since last SR/RR */
275  BYTE lost[3]; /* cumulative number of packets lost (signed!) */
276  PUInt32b last_seq; /* extended last sequence number received */
277  PUInt32b jitter; /* interarrival jitter */
278  PUInt32b lsr; /* last SR packet from this source */
279  PUInt32b dlsr; /* delay since last SR packet */
280 
281  unsigned GetLostPackets() const { return (lost[0]<<16U)+(lost[1]<<8U)+lost[2]; }
282  void SetLostPackets(unsigned lost);
283  };
284 
285  struct SenderReport {
286  PUInt32b ntp_sec; /* NTP timestamp */
287  PUInt32b ntp_frac;
288  PUInt32b rtp_ts; /* RTP timestamp */
289  PUInt32b psent; /* packets sent */
290  PUInt32b osent; /* octets sent */
291  };
292 
293  struct ExtendedReport {
294  /* VoIP Metrics Report Block */
295  BYTE bt; /* block type */
296  BYTE type_specific; /* determined by the block definition */
297  PUInt16b length; /* length of the report block */
298  PUInt32b ssrc; /* data source being reported */
299  BYTE loss_rate; /* fraction of RTP data packets lost */
300  BYTE discard_rate; /* fraction of RTP data packets discarded */
301  BYTE burst_density; /* fraction of RTP data packets within burst periods */
302  BYTE gap_density; /* fraction of RTP data packets within inter-burst gaps */
303  PUInt16b burst_duration; /* the mean duration, in ms, of burst periods */
304  PUInt16b gap_duration; /* the mean duration, in ms, of gap periods */
305  PUInt16b round_trip_delay; /* the most recently calculated round trip time */
306  PUInt16b end_system_delay; /* the most recently estimates end system delay */
307  BYTE signal_level; /* voice signal level related to 0 dBm */
308  BYTE noise_level; /* ratio of the silent background level to 0 dBm */
309  BYTE rerl; /* residual echo return loss */
310  BYTE gmin; /* gap threshold */
311  BYTE r_factor; /* voice quality metric of the call */
312  BYTE ext_r_factor; /* external R factor */
313  BYTE mos_lq; /* MOS for listen quality */
314  BYTE mos_cq; /* MOS for conversational quality */
315  BYTE rx_config; /* receiver configuration byte */
316  BYTE reserved; /* reserved for future definition */
317  PUInt16b jb_nominal; /* current nominal jitter buffer delay, in ms */
318  PUInt16b jb_maximum; /* current maximum jitter buffer delay, in ms */
319  PUInt16b jb_absolute; /* current absolute maximum jitter buffer delay, in ms */
320  };
321 
332  NumDescriptionTypes
333  };
334 
336  PUInt32b src; /* first SSRC/CSRC */
337  struct Item {
338  BYTE type; /* type of SDES item (enum DescriptionTypes) */
339  BYTE length; /* length of SDES item (in octets) */
340  char data[1]; /* text, not zero-terminated */
341 
342  /* WARNING, SourceDescription may not be big enough to contain length and data, for
343  instance, when type == RTP_ControlFrame::e_END.
344  Be careful whan calling the following function of it may read to over to
345  memory allocated*/
346  unsigned int GetLengthTotal() const {return (unsigned int)(length + 2);}
347  const Item * GetNextItem() const { return (const Item *)((char *)this + length + 2); }
348  Item * GetNextItem() { return (Item *)((char *)this + length + 2); }
349  } item[1]; /* list of SDES items */
350  };
351 
352  void StartSourceDescription(
353  DWORD src
354  );
355 
356  void AddSourceDescriptionItem(
357  unsigned type,
358  const PString & data
359  );
360 
361  // RFC4585 Feedback Message Type (FMT)
362  unsigned GetFbType() const { return (BYTE)theArray[compoundOffset]&0x1f; }
363  void SetFbType(unsigned type, PINDEX fciSize);
364 
366  e_TransportNACK = 1,
367  e_TMMBR = 3,
368  e_TMMBN
369  };
370 
372  e_PictureLossIndication = 1,
379  e_ApplicationLayerFbMessage = 15
380  };
381 
382  struct FbFCI {
383  PUInt32b senderSSRC; /* data source of sender of message */
384  PUInt32b mediaSSRC; /* data source of media */
385  };
386 
387  struct FbFIR {
389  PUInt32b requestSSRC;
391  };
392 
393  struct FbTSTO {
395  PUInt32b requestSSRC;
397  BYTE reserver[2];
398  BYTE tradeOff;
399  };
400 
401  // Same for request (e_TMMBR) and notification (e_TMMBN)
402  struct FbTMMB {
404  PUInt32b requestSSRC;
405  PUInt32b bitRateAndOverhead; // Various bit fields
406 
407  unsigned GetBitRate() const;
408  unsigned GetOverhead() const { return bitRateAndOverhead & 0x1ff; }
409  };
410 
411 #pragma pack()
412 
413  protected:
415  PINDEX payloadSize;
416 };
417 
418 
420 
423 class RTPExtensionHeaderInfo : public PObject
424 {
425  PCLASSINFO(RTPExtensionHeaderInfo, PObject);
426  public:
427  unsigned m_id;
428 
429  enum Direction {
430  Undefined = -1,
434  SendRecv
435  } m_direction;
436 
437  PURL m_uri;
438 
439  PString m_attributes;
440 
442  virtual Comparison Compare(const PObject & other) const;
443 
444 #if OPAL_SIP
445  bool ParseSDP(const PString & param);
446  void OutputSDP(ostream & strm) const;
447 #endif
448 };
449 
450 typedef std::set<RTPExtensionHeaderInfo> RTPExtensionHeaders;
451 
452 
453 #endif // OPAL_RTP_RTP_H
454