OPAL  Version 3.10.4
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: 26716 $
30  * $Author: rjongbloed $
31  * $Date: 2011-11-30 17:51:43 -0600 (Wed, 30 Nov 2011) $
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 <ptlib/sockets.h>
44 #include <ptlib/safecoll.h>
45 
46 #include <list>
47 
48 #include <rtp/metrics.h>
49 
50 class RTP_JitterBuffer;
51 class PNatMethod;
52 class OpalSecurityMode;
53 
55 //
56 // class to hold the QoS definitions for an RTP channel
57 
58 class RTP_QOS : public PObject
59 {
60  PCLASSINFO(RTP_QOS,PObject);
61  public:
62  PQoS dataQoS;
63  PQoS ctrlQoS;
64 };
65 
67 // Real Time Protocol - IETF RFC1889 and RFC1890
68 
71 class RTP_DataFrame : public PBYTEArray
72 {
73  PCLASSINFO(RTP_DataFrame, PBYTEArray);
74 
75  public:
76  RTP_DataFrame(PINDEX payloadSize = 0, PINDEX bufferSize = 0);
77  RTP_DataFrame(const BYTE * data, PINDEX len, PBoolean dynamic = true);
78 
79  enum {
82  // Max safe MTU size (576 bytes as per RFC879) minus IP, UDP an RTP headers
83  MaxMtuPayloadSize = (576-20-16-12)
84  };
85 
86  enum PayloadTypes {
87  PCMU, // G.711 u-Law
88  FS1016, // Federal Standard 1016 CELP
89  G721, // ADPCM - Subsumed by G.726
91  GSM, // GSM 06.10
92  G7231, // G.723.1 at 6.3kbps or 5.3 kbps
93  DVI4_8k, // DVI4 at 8kHz sample rate
94  DVI4_16k, // DVI4 at 16kHz sample rate
95  LPC, // LPC-10 Linear Predictive CELP
96  PCMA, // G.711 A-Law
97  G722, // G.722
98  L16_Stereo, // 16 bit linear PCM
99  L16_Mono, // 16 bit linear PCM
100  G723, // G.723
101  CN, // Confort Noise
102  MPA, // MPEG1 or MPEG2 audio
103  G728, // G.728 16kbps CELP
104  DVI4_11k, // DVI4 at 11kHz sample rate
105  DVI4_22k, // DVI4 at 22kHz sample rate
106  G729, // G.729 8kbps
107  Cisco_CN, // Cisco systems comfort noise (unofficial)
108 
109  CelB = 25, // Sun Systems Cell-B video
110  JPEG, // Motion JPEG
111  H261 = 31, // H.261
112  MPV, // MPEG1 or MPEG2 video
113  MP2T, // MPEG2 transport system
114  H263, // H.263
115 
116  T38 = 38, // T.38 (internal)
117 
119 
123  };
124 
125  unsigned GetVersion() const { return (theArray[0]>>6)&3; }
126 
127  PBoolean GetExtension() const { return (theArray[0]&0x10) != 0; }
128  void SetExtension(PBoolean ext);
129 
130  PBoolean GetMarker() const { return (theArray[1]&0x80) != 0; }
131  void SetMarker(PBoolean m);
132 
133  bool GetPadding() const { return (theArray[0]&0x20) != 0; }
134  void SetPadding(bool v) { if (v) theArray[0] |= 0x20; else theArray[0] &= 0xdf; }
135  BYTE * GetPaddingPtr() const { return (BYTE *)(theArray+m_headerSize+m_payloadSize); }
136 
137  unsigned GetPaddingSize() const { return m_paddingSize; }
138  bool SetPaddingSize(PINDEX sz);
139 
140  PayloadTypes GetPayloadType() const { return (PayloadTypes)(theArray[1]&0x7f); }
142 
143  WORD GetSequenceNumber() const { return *(PUInt16b *)&theArray[2]; }
144  void SetSequenceNumber(WORD n) { *(PUInt16b *)&theArray[2] = n; }
145 
146  DWORD GetTimestamp() const { return *(PUInt32b *)&theArray[4]; }
147  void SetTimestamp(DWORD t) { *(PUInt32b *)&theArray[4] = t; }
148 
149  DWORD GetSyncSource() const { return *(PUInt32b *)&theArray[8]; }
150  void SetSyncSource(DWORD s) { *(PUInt32b *)&theArray[8] = s; }
151 
152  PINDEX GetContribSrcCount() const { return theArray[0]&0xf; }
153  DWORD GetContribSource(PINDEX idx) const;
154  void SetContribSource(PINDEX idx, DWORD src);
155 
156  PINDEX GetHeaderSize() const { return m_headerSize; }
157 
158  int GetExtensionType() const; // -1 is no extension
159  void SetExtensionType(int type);
160  PINDEX GetExtensionSizeDWORDs() const; // get the number of 32 bit words in the extension (excluding the header).
161  bool SetExtensionSizeDWORDs(PINDEX sz); // set the number of 32 bit words in the extension (excluding the header)
162  BYTE * GetExtensionPtr() const;
163 
164  PINDEX GetPayloadSize() const { return m_payloadSize; }
165  bool SetPayloadSize(PINDEX sz);
166  BYTE * GetPayloadPtr() const { return (BYTE *)(theArray+m_headerSize); }
167 
168  virtual PObject * Clone() const { return new RTP_DataFrame(*this); }
169  virtual void PrintOn(ostream & strm) const;
170 
171  // Note this sets the whole packet length, and calculates the various
172  // sub-section sizes: header payload and padding.
173  bool SetPacketSize(PINDEX sz);
174 
175  protected:
176  PINDEX m_headerSize;
179 
180 #if PTRACING
181  friend ostream & operator<<(ostream & o, PayloadTypes t);
182 #endif
183 };
184 
185 PLIST(RTP_DataFrameList, RTP_DataFrame);
186 
187 
190 class RTP_ControlFrame : public PBYTEArray
191 {
192  PCLASSINFO(RTP_ControlFrame, PBYTEArray);
193 
194  public:
195  RTP_ControlFrame(PINDEX compoundSize = 2048);
196 
197  unsigned GetVersion() const { return (BYTE)theArray[compoundOffset]>>6; }
198 
199  unsigned GetCount() const { return (BYTE)theArray[compoundOffset]&0x1f; }
200  void SetCount(unsigned count);
201 
203  e_IntraFrameRequest = 192,
204  e_SenderReport = 200,
205  e_ReceiverReport = 201,
206  e_SourceDescription = 202,
207  e_Goodbye = 203,
208  e_ApplDefined = 204,
209  e_TransportLayerFeedBack = 205, // RFC4585
210  e_PayloadSpecificFeedBack = 206,
211  e_ExtendedReport = 207 // RFC3611
212  };
213 
214  unsigned GetPayloadType() const { return (BYTE)theArray[compoundOffset+1]; }
215  void SetPayloadType(unsigned t);
216 
217  PINDEX GetPayloadSize() const { return 4*(*(PUInt16b *)&theArray[compoundOffset+2]); }
218  void SetPayloadSize(PINDEX sz);
219 
220  BYTE * GetPayloadPtr() const;
221 
222  PBoolean ReadNextPacket();
223  PBoolean StartNewPacket();
224  void EndPacket();
225 
226  PINDEX GetCompoundSize() const;
227 
228  void Reset(PINDEX size);
229 
230 #pragma pack(1)
231  struct ReceiverReport {
232  PUInt32b ssrc; /* data source being reported */
233  BYTE fraction; /* fraction lost since last SR/RR */
234  BYTE lost[3]; /* cumulative number of packets lost (signed!) */
235  PUInt32b last_seq; /* extended last sequence number received */
236  PUInt32b jitter; /* interarrival jitter */
237  PUInt32b lsr; /* last SR packet from this source */
238  PUInt32b dlsr; /* delay since last SR packet */
239 
240  unsigned GetLostPackets() const { return (lost[0]<<16U)+(lost[1]<<8U)+lost[2]; }
241  void SetLostPackets(unsigned lost);
242  };
243 
244  struct SenderReport {
245  PUInt32b ntp_sec; /* NTP timestamp */
246  PUInt32b ntp_frac;
247  PUInt32b rtp_ts; /* RTP timestamp */
248  PUInt32b psent; /* packets sent */
249  PUInt32b osent; /* octets sent */
250  };
251 
252  struct ExtendedReport {
253  /* VoIP Metrics Report Block */
254  BYTE bt; /* block type */
255  BYTE type_specific; /* determined by the block definition */
256  PUInt16b length; /* length of the report block */
257  PUInt32b ssrc; /* data source being reported */
258  BYTE loss_rate; /* fraction of RTP data packets lost */
259  BYTE discard_rate; /* fraction of RTP data packets discarded */
260  BYTE burst_density; /* fraction of RTP data packets within burst periods */
261  BYTE gap_density; /* fraction of RTP data packets within inter-burst gaps */
262  PUInt16b burst_duration; /* the mean duration, in ms, of burst periods */
263  PUInt16b gap_duration; /* the mean duration, in ms, of gap periods */
264  PUInt16b round_trip_delay; /* the most recently calculated round trip time */
265  PUInt16b end_system_delay; /* the most recently estimates end system delay */
266  BYTE signal_level; /* voice signal level related to 0 dBm */
267  BYTE noise_level; /* ratio of the silent background level to 0 dBm */
268  BYTE rerl; /* residual echo return loss */
269  BYTE gmin; /* gap threshold */
270  BYTE r_factor; /* voice quality metric of the call */
271  BYTE ext_r_factor; /* external R factor */
272  BYTE mos_lq; /* MOS for listen quality */
273  BYTE mos_cq; /* MOS for conversational quality */
274  BYTE rx_config; /* receiver configuration byte */
275  BYTE reserved; /* reserved for future definition */
276  PUInt16b jb_nominal; /* current nominal jitter buffer delay, in ms */
277  PUInt16b jb_maximum; /* current maximum jitter buffer delay, in ms */
278  PUInt16b jb_absolute; /* current absolute maximum jitter buffer delay, in ms */
279  };
280 
291  NumDescriptionTypes
292  };
293 
295  PUInt32b src; /* first SSRC/CSRC */
296  struct Item {
297  BYTE type; /* type of SDES item (enum DescriptionTypes) */
298  BYTE length; /* length of SDES item (in octets) */
299  char data[1]; /* text, not zero-terminated */
300 
301  /* WARNING, SourceDescription may not be big enough to contain length and data, for
302  instance, when type == RTP_ControlFrame::e_END.
303  Be careful whan calling the following function of it may read to over to
304  memory allocated*/
305  unsigned int GetLengthTotal() const {return (unsigned int)(length + 2);}
306  const Item * GetNextItem() const { return (const Item *)((char *)this + length + 2); }
307  Item * GetNextItem() { return (Item *)((char *)this + length + 2); }
308  } item[1]; /* list of SDES items */
309  };
310 
311  void StartSourceDescription(
312  DWORD src
313  );
314 
315  void AddSourceDescriptionItem(
316  unsigned type,
317  const PString & data
318  );
319 
320  // RFC4585 Feedback Message Type (FMT)
321  unsigned GetFbType() const { return (BYTE)theArray[compoundOffset]&0x1f; }
322  void SetFbType(unsigned type, PINDEX fciSize);
323 
325  e_PictureLossIndication = 1,
332  e_ApplicationLayerFbMessage = 15
333  };
334 
335  struct FbFCI {
336  PUInt32b senderSSRC; /* data source of sender of message */
337  PUInt32b mediaSSRC; /* data source of media */
338  };
339 
340  struct FbFIR {
342  PUInt32b requestSSRC;
344  };
345 
346  struct FbTSTO {
348  PUInt32b requestSSRC;
350  BYTE reserver[2];
351  BYTE tradeOff;
352  };
353 
354 #pragma pack()
355 
356  protected:
358  PINDEX payloadSize;
359 };
360 
361 
362 class RTP_Session;
363 
365 
366 #if OPAL_STATISTICS
367 
370 class OpalMediaStatistics : public PObject
371 {
372  PCLASSINFO(OpalMediaStatistics, PObject);
373  public:
375 
376  // General info (typicallly from RTP)
377  PUInt64 m_totalBytes;
378  unsigned m_totalPackets;
379  unsigned m_packetsLost;
386 
387  // Audio
388  unsigned m_averageJitter;
389  unsigned m_maximumJitter;
391 
392  // Video
393  unsigned m_totalFrames;
394  unsigned m_keyFrames;
395 
396  // Fax
397 #if OPAL_FAX
398  enum {
399  FaxNotStarted = -2,
400  FaxInProgress = -1,
401  FaxSuccessful = 0,
402  FaxErrorBase = 1
403  };
409  };
410  friend ostream & operator<<(ostream & strm, FaxCompression compression);
411  struct Fax {
412  Fax();
413 
414  int m_result; // -2=not started, -1=progress, 0=success, >0=ended with error
415  char m_phase; // 'A', 'B', 'D'
416  int m_bitRate; // e.g. 14400, 9600
417  FaxCompression m_compression; // 0=N/A, 1=T.4 1d, 2=T.4 2d, 3=T.6
422  int m_imageSize; // In bytes
423  int m_resolutionX; // Pixels per inch
424  int m_resolutionY; // Pixels per inch
427  int m_badRows; // Total number of bad rows
428  int m_mostBadRows; // Longest run of bad rows
430 
431  PString m_stationId; // Remote station identifier
432  PString m_errorText;
433  } m_fax;
434 #endif
435 };
436 
437 #endif
438 
439 
444 class RTP_UserData : public PObject
445 {
446  PCLASSINFO(RTP_UserData, PObject);
447 
448  public:
455  virtual void OnTxStatistics(
456  const RTP_Session & session
457  ) const;
458 
465  virtual void OnRxStatistics(
466  const RTP_Session & session
467  ) const;
468 
469 #if OPAL_VIDEO
470 
475  virtual void OnTxIntraFrameRequest(
476  const RTP_Session & session
477  ) const;
478 
484  virtual void OnRxIntraFrameRequest(
485  const RTP_Session & session
486  ) const;
487 #endif
488 
492  virtual void SessionFailing(
493  RTP_Session & session
494  );
495 };
496 
497 class RTP_Encoding;
498 
499 
502 class RTP_Session : public PObject
503 {
504  PCLASSINFO(RTP_Session, PObject);
505 
506  public:
509  struct Params {
511  : id(0)
512  , userData(NULL)
513  , autoDelete(true)
514  , isAudio(false)
515  , remoteIsNAT(false)
516  { }
517 
518  PString encoding;
519  unsigned id;
521  bool autoDelete;
522  bool isAudio;
523  bool remoteIsNAT;
524  };
525 
528  RTP_Session(
529  const Params & options
530  );
531 
535  ~RTP_Session();
537 
547  void SetJitterBufferSize(
548  unsigned minJitterDelay,
549  unsigned maxJitterDelay,
550  unsigned timeUnits = 0,
551  PINDEX packetSize = 2048
552  );
553 
559  unsigned GetJitterBufferSize() const;
560  unsigned GetJitterBufferDelay() const { return GetJitterBufferSize()/GetJitterTimeUnits(); }
561 
564  unsigned GetJitterTimeUnits() const { return m_timeUnits; }
565 
567  virtual PBoolean ModifyQOS(RTP_QOS * )
568  { return false; }
569 
575  virtual PBoolean ReadBufferedData(
576  RTP_DataFrame & frame
577  );
578 
584  virtual PBoolean ReadData(
585  RTP_DataFrame & frame
586  ) = 0;
587 
590  virtual PBoolean WriteData(
591  RTP_DataFrame & frame
592  ) = 0;
593 
597  virtual PBoolean WriteOOBData(
598  RTP_DataFrame & frame,
599  bool rewriteTimeStamp = true
600  );
601 
604  virtual PBoolean WriteControl(
605  RTP_ControlFrame & frame
606  ) = 0;
607 
610  virtual PBoolean SendReport();
611 
614  virtual bool Close(
615  PBoolean reading
616  ) = 0;
617 
620  virtual void Reopen(
621  PBoolean isReading
622  ) = 0;
623 
626  virtual PString GetLocalHostName() = 0;
627 
628 #if OPAL_STATISTICS
629  virtual void GetStatistics(OpalMediaStatistics & statistics, bool receiver) const;
630 #endif
631 
632 
638  e_AbortTransport
639  };
640  virtual SendReceiveStatus OnSendData(RTP_DataFrame & frame);
641  virtual SendReceiveStatus Internal_OnSendData(RTP_DataFrame & frame);
642 
643  virtual SendReceiveStatus OnSendControl(RTP_ControlFrame & frame, PINDEX & len);
644  virtual SendReceiveStatus Internal_OnSendControl(RTP_ControlFrame & frame, PINDEX & len);
645 
646  virtual SendReceiveStatus OnReceiveData(RTP_DataFrame & frame);
647  virtual SendReceiveStatus Internal_OnReceiveData(RTP_DataFrame & frame);
648 
649  virtual SendReceiveStatus OnReceiveControl(RTP_ControlFrame & frame);
650 
651  class ReceiverReport : public PObject {
652  PCLASSINFO(ReceiverReport, PObject);
653  public:
654  void PrintOn(ostream &) const;
655 
657  DWORD fractionLost; /* fraction lost since last SR/RR */
658  DWORD totalLost; /* cumulative number of packets lost (signed!) */
659  DWORD lastSequenceNumber; /* extended last sequence number received */
660  DWORD jitter; /* interarrival jitter */
661  PTimeInterval lastTimestamp;/* last SR packet from this source */
662  PTimeInterval delay; /* delay since last SR packet */
663  };
664  PARRAY(ReceiverReportArray, ReceiverReport);
665 
666  class SenderReport : public PObject {
667  PCLASSINFO(SenderReport, PObject);
668  public:
669  void PrintOn(ostream &) const;
670 
674  DWORD packetsSent;
675  DWORD octetsSent;
676  };
677 
678  virtual void OnRxSenderReport(const SenderReport & sender,
679  const ReceiverReportArray & reports);
680  virtual void OnRxReceiverReport(DWORD src,
681  const ReceiverReportArray & reports);
682  virtual void OnReceiverReports(const ReceiverReportArray & reports);
683 
684  class SourceDescription : public PObject {
685  PCLASSINFO(SourceDescription, PObject);
686  public:
687  SourceDescription(DWORD src) { sourceIdentifier = src; }
688  void PrintOn(ostream &) const;
689 
691  POrdinalToString items;
692  };
693  PARRAY(SourceDescriptionArray, SourceDescription);
694  virtual void OnRxSourceDescription(const SourceDescriptionArray & descriptions);
695 
696  virtual void OnRxGoodbye(const PDWORDArray & sources,
697  const PString & reason);
698 
699  virtual void OnRxApplDefined(const PString & type, unsigned subtype, DWORD src,
700  const BYTE * data, PINDEX size);
701 
702 #if OPAL_RTCP_XR
703  class ExtendedReport : public PObject {
704  PCLASSINFO(ExtendedReport, PObject);
705  public:
706  void PrintOn(ostream &) const;
707 
708  DWORD sourceIdentifier;
709  DWORD lossRate; /* fraction of RTP data packets lost */
710  DWORD discardRate; /* fraction of RTP data packets discarded */
711  DWORD burstDensity; /* fraction of RTP data packets within burst periods */
712  DWORD gapDensity; /* fraction of RTP data packets within inter-burst gaps */
713  DWORD roundTripDelay; /* the most recently calculated round trip time */
714  DWORD RFactor; /* voice quality metric of the call */
715  DWORD mosLQ; /* MOS for listen quality */
716  DWORD mosCQ; /* MOS for conversational quality */
717  DWORD jbNominal; /* current nominal jitter buffer delay, in ms */
718  DWORD jbMaximum; /* current maximum jitter buffer delay, in ms */
719  DWORD jbAbsolute; /* current absolute maximum jitter buffer delay, in ms */
720  };
721  PARRAY(ExtendedReportArray, ExtendedReport);
722 
723  virtual void OnRxExtendedReport(DWORD src,
724  const ExtendedReportArray & reports);
725 #endif
726 
727 
732  unsigned GetSessionID() const { return sessionID; }
733 
736  void SetSessionID(unsigned id) { sessionID = id; }
737 
740  bool IsAudio() const { return isAudio; }
741 
744  void SetAudio(
745  bool aud
746  ) { isAudio = aud; }
747 
750  PString GetCanonicalName() const;
751 
754  void SetCanonicalName(const PString & name);
755 
758  PString GetToolName() const;
759 
762  void SetToolName(const PString & name);
763 
766  RTP_UserData * GetUserData() const { return userData; }
767 
770  void SetUserData(
771  RTP_UserData * data,
772  PBoolean autoDeleteUserData = true
773  );
774 
777  DWORD GetSyncSourceOut() const { return syncSourceOut; }
778 
781  bool AllowAnySyncSource() const { return allowAnySyncSource; }
782 
785  void SetAnySyncSource(
786  bool allow
787  ) { allowAnySyncSource = allow; }
788 
791  void SetIgnorePayloadTypeChanges(
792  PBoolean ignore
793  ) { ignorePayloadTypeChanges = ignore; }
794 
797  const PTimeInterval & GetReportTimeInterval() { return reportTimeInterval; }
798 
801  void SetReportTimeInterval(
802  const PTimeInterval & interval
803  ) { reportTimeInterval = interval; }
804 
807  PTimeInterval GetReportTimer()
808  { return reportTimer; }
809 
812  unsigned GetTxStatisticsInterval() { return txStatisticsInterval; }
813 
816  void SetTxStatisticsInterval(
817  unsigned packets
818  );
819 
822  unsigned GetRxStatisticsInterval() { return rxStatisticsInterval; }
823 
826  void SetRxStatisticsInterval(
827  unsigned packets
828  );
829 
832  void ClearStatistics();
833 
836  DWORD GetPacketsSent() const { return packetsSent; }
837 
840  DWORD GetOctetsSent() const { return octetsSent; }
841 
844  DWORD GetPacketsReceived() const { return packetsReceived; }
845 
848  DWORD GetOctetsReceived() const { return octetsReceived; }
849 
852  DWORD GetPacketsLost() const { return packetsLost; }
853 
857  DWORD GetPacketsLostByRemote() const { return packetsLostByRemote; }
858 
861  DWORD GetPacketsOutOfOrder() const { return packetsOutOfOrder; }
862 
865  DWORD GetPacketsTooLate() const;
866 
869  DWORD GetPacketOverruns() const;
870 
875  DWORD GetAverageSendTime() const { return averageSendTime; }
876 
881  DWORD GetMarkerRecvCount() const { return markerRecvCount; }
882 
887  DWORD GetMarkerSendCount() const { return markerSendCount; }
888 
893  DWORD GetMaximumSendTime() const { return maximumSendTime; }
894 
899  DWORD GetMinimumSendTime() const { return minimumSendTime; }
900 
905  DWORD GetAverageReceiveTime() const { return averageReceiveTime; }
906 
911  DWORD GetMaximumReceiveTime() const { return maximumReceiveTime; }
912 
917  DWORD GetMinimumReceiveTime() const { return minimumReceiveTime; }
918 
919  enum { JitterRoundingGuardBits = 4 };
924  DWORD GetAvgJitterTime() const { return (jitterLevel>>JitterRoundingGuardBits)/GetJitterTimeUnits(); }
925 
929  DWORD GetMaxJitterTime() const { return (maximumJitterLevel>>JitterRoundingGuardBits)/GetJitterTimeUnits(); }
930 
935  DWORD GetJitterTimeOnRemote() const { return jitterLevelOnRemote/GetJitterTimeUnits(); }
937 
938  virtual void SetCloseOnBYE(PBoolean v) { closeOnBye = v; }
939 
944  virtual void SendIntraFrameRequest(bool rfc2032, bool pictureLoss);
945 
950  virtual void SendTemporalSpatialTradeOff(unsigned tradeOff);
951 
952  void SetNextSentSequenceNumber(WORD num) { lastSentSequenceNumber = (WORD)(num-1); }
953 
954  virtual PString GetEncoding() const { return m_encoding; }
955  virtual void SetEncoding(const PString & newEncoding);
956 
957  DWORD GetSyncSourceIn() const { return syncSourceIn; }
958 
960  {
961  public:
962  EncodingLock(RTP_Session & _session);
963  ~EncodingLock();
964 
965  __inline RTP_Encoding * operator->() const { return m_encodingHandler; }
966 
967  protected:
970  };
971 
972  friend class EncodingLock;
973 
974  void SetFailed(bool v)
975  { failed = v; }
976 
977  bool HasFailed() const
978  { return failed; }
979 
980  typedef PNotifierTemplate<SendReceiveStatus &> FilterNotifier;
981  #define PDECLARE_RTPFilterNotifier(cls, fn) PDECLARE_NOTIFIER2(RTP_DataFrame, cls, fn, RTP_Session::SendReceiveStatus &)
982  #define PCREATE_RTPFilterNotifier(fn) PCREATE_NOTIFIER2(fn, RTP_Session::SendReceiveStatus &)
983 
984  void AddFilter(const FilterNotifier & filter);
985 
986 #if OPAL_RTCP_XR
987  const RTCP_XR_Metrics & GetMetrics() const { return m_metrics; }
988 #endif
989 
990  virtual void SendBYE();
991 
992  protected:
993  void AddReceiverReport(RTP_ControlFrame::ReceiverReport & receiver);
994 
995  PBoolean InsertReportPacket(RTP_ControlFrame & report);
996 
997 #if OPAL_RTCP_XR
998  void InsertExtendedReportPacket(RTP_ControlFrame & report);
999  void OnRxSenderReportToMetrics(const RTP_ControlFrame & frame, PINDEX offset);
1000 #endif
1001 
1002  PString m_encoding;
1005 
1006  unsigned sessionID;
1007  bool isAudio;
1008  unsigned m_timeUnits;
1009  PString canonicalName;
1010  PString toolName;
1013 
1014  typedef PSafePtr<RTP_JitterBuffer, PSafePtrMultiThreaded> JitterBufferPtr;
1016 
1024  PTimeInterval reportTimeInterval;
1029  PTimeInterval lastSentPacketTime;
1030  PTimeInterval lastReceivedPacketTime;
1033  PTimeInterval delaySinceLastSR;
1037  PTimeInterval outOfOrderWaitTime;
1038  PTimeInterval outOfOrderPacketTime;
1039 
1040  std::list<RTP_DataFrame> m_outOfOrderPackets;
1041  void SaveOutOfOrderPacket(RTP_DataFrame & frame);
1042 
1043  PMutex dataMutex;
1044  DWORD timeStampOffs; // offset between incoming media timestamp and timeStampOut
1045  PBoolean oobTimeStampBaseEstablished; // true if timeStampOffs has been established by media
1046  DWORD oobTimeStampOutBase; // base timestamp value for oob data
1047  PTimeInterval oobTimeStampBase; // base time for oob timestamp
1048 
1049  // Statistics
1053  DWORD octetsSent;
1070 
1073 
1076 
1077 #if OPAL_RTCP_XR
1078  // Calculate the VoIP Metrics for RTCP-XR
1079  RTCP_XR_Metrics m_metrics;
1080 #endif
1081 
1090 
1093 
1094  PMutex reportMutex;
1095  PTimer reportTimer;
1096 
1097  PBoolean closeOnBye;
1098  PBoolean byeSent;
1099  bool failed;
1100 
1101  list<FilterNotifier> m_filters;
1102 };
1103 
1106 class RTP_UDP : public RTP_Session
1107 {
1108  PCLASSINFO(RTP_UDP, RTP_Session);
1109 
1110  public:
1115  RTP_UDP(
1116  const Params & options
1117  );
1118 
1120  ~RTP_UDP();
1122 
1130  virtual PBoolean ReadData(RTP_DataFrame & frame);
1131  virtual PBoolean Internal_ReadData(RTP_DataFrame & frame);
1132 
1135  virtual PBoolean WriteData(RTP_DataFrame & frame);
1136  virtual PBoolean Internal_WriteData(RTP_DataFrame & frame);
1137 
1141  virtual PBoolean WriteOOBData(RTP_DataFrame & frame, bool setTimeStamp = true);
1142 
1145  virtual PBoolean WriteControl(RTP_ControlFrame & frame);
1146 
1149  virtual bool Close(
1150  PBoolean reading
1151  );
1152 
1155  virtual PString GetLocalHostName();
1157 
1160  virtual PBoolean ModifyQOS(RTP_QOS * rtpqos);
1161 
1166  virtual PBoolean Open(
1167  PIPSocket::Address localAddress,
1168  WORD portBase,
1169  WORD portMax,
1170  BYTE ipTypeOfService,
1171  PNatMethod * natMethod = NULL,
1172  RTP_QOS * rtpqos = NULL
1173  );
1175 
1178  virtual void Reopen(PBoolean isReading);
1180 
1185  virtual PIPSocket::Address GetLocalAddress() const { return localAddress; }
1186 
1189  virtual void SetLocalAddress(
1190  const PIPSocket::Address & addr
1191  ) { localAddress = addr; }
1192 
1195  PIPSocket::Address GetRemoteAddress() const { return remoteAddress; }
1196 
1199  virtual WORD GetLocalDataPort() const { return localDataPort; }
1200 
1203  virtual WORD GetLocalControlPort() const { return localControlPort; }
1204 
1207  virtual WORD GetRemoteDataPort() const { return remoteDataPort; }
1208 
1211  virtual WORD GetRemoteControlPort() const { return remoteControlPort; }
1212 
1215  virtual PUDPSocket & GetDataSocket() { return *dataSocket; }
1216 
1219  virtual PUDPSocket & GetControlSocket() { return *controlSocket; }
1220 
1223  virtual PBoolean SetRemoteSocketInfo(
1224  PIPSocket::Address address,
1225  WORD port,
1226  PBoolean isDataPort
1227  );
1228 
1231  virtual void ApplyQOS(
1232  const PIPSocket::Address & addr
1233  );
1235 
1236  virtual int GetDataSocketHandle() const
1237  { return dataSocket != NULL ? dataSocket->GetHandle() : -1; }
1238 
1239  virtual int GetControlSocketHandle() const
1240  { return controlSocket != NULL ? controlSocket->GetHandle() : -1; }
1241 
1242  friend class RTP_Encoding;
1243 
1244  virtual int WaitForPDU(PUDPSocket & dataSocket, PUDPSocket & controlSocket, const PTimeInterval & timer);
1245  virtual int Internal_WaitForPDU(PUDPSocket & dataSocket, PUDPSocket & controlSocket, const PTimeInterval & timer);
1246 
1247  virtual SendReceiveStatus ReadDataPDU(RTP_DataFrame & frame);
1248  virtual SendReceiveStatus Internal_ReadDataPDU(RTP_DataFrame & frame);
1249 
1251  virtual SendReceiveStatus Internal_OnReadTimeout(RTP_DataFrame & frame);
1252 
1253  virtual SendReceiveStatus ReadControlPDU();
1254  virtual SendReceiveStatus ReadDataOrControlPDU(
1255  BYTE * framePtr,
1256  PINDEX frameSize,
1257  PBoolean fromDataChannel
1258  );
1259 
1260  virtual bool WriteDataPDU(RTP_DataFrame & frame);
1261  virtual bool WriteDataOrControlPDU(
1262  const BYTE * framePtr,
1263  PINDEX frameSize,
1264  bool toDataChannel
1265  );
1266 
1267  virtual void SetEncoding(const PString & newEncoding);
1268 
1269 
1270  protected:
1271  PIPSocket::Address localAddress;
1274 
1275  PIPSocket::Address remoteAddress;
1278 
1279  PIPSocket::Address remoteTransmitAddress;
1280 
1281  PUDPSocket * dataSocket;
1282  PUDPSocket * controlSocket;
1283 
1293 
1295  PDECLARE_NOTIFIER(PTimer, RTP_UDP, OnWriteDataIdle);
1296 };
1297 
1299 
1300 class RTP_UDP;
1301 
1303 {
1304  public:
1305  RTP_Encoding();
1306  virtual ~RTP_Encoding();
1307  virtual void ApplyStringOptions(const PStringToString & /*stringOptions*/) {}
1308  virtual void OnStart(RTP_Session & _rtpSession);
1309  virtual void OnFinish();
1310  virtual RTP_Session::SendReceiveStatus OnSendData(RTP_DataFrame & frame);
1311  virtual PBoolean WriteData(RTP_DataFrame & frame, bool oob);
1312  virtual PBoolean WriteDataPDU(RTP_DataFrame & frame);
1313  virtual void OnWriteDataIdle() {}
1314  virtual void SetWriteDataIdleTimer(PTimer &) {}
1315  virtual RTP_Session::SendReceiveStatus OnSendControl(RTP_ControlFrame & frame, PINDEX & len);
1316  virtual RTP_Session::SendReceiveStatus ReadDataPDU(RTP_DataFrame & frame);
1317  virtual RTP_Session::SendReceiveStatus OnReceiveData(RTP_DataFrame & frame);
1318  virtual RTP_Session::SendReceiveStatus OnReadTimeout(RTP_DataFrame & frame);
1319  virtual PBoolean ReadData(RTP_DataFrame & frame);
1320  virtual int WaitForPDU(PUDPSocket & dataSocket, PUDPSocket & controlSocket, const PTimeInterval &);
1321 
1322  PMutex mutex;
1323  unsigned refCount;
1324 
1325  protected:
1327 };
1328 
1330 
1331 
1333 
1334 class SecureRTP_UDP : public RTP_UDP
1335 {
1336  PCLASSINFO(SecureRTP_UDP, RTP_UDP);
1337 
1338  public:
1343  SecureRTP_UDP(
1344  const Params & options
1345  );
1346 
1348  ~SecureRTP_UDP();
1349 
1350  virtual void SetSecurityMode(OpalSecurityMode * srtpParms);
1351  virtual OpalSecurityMode * GetSecurityParms() const;
1352 
1353  protected:
1355 };
1356 
1357 #endif // OPAL_RTP_RTP_H
1358