OPAL  Version 3.12.5
rtp_session.h
Go to the documentation of this file.
1 /*
2  * rtp_session.h
3  *
4  * RTP protocol session
5  *
6  * Open H323 Library
7  *
8  * Copyright (c) 1998-2012 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: 29059 $
30  * $Author: rjongbloed $
31  * $Date: 2013-01-30 21:12:49 -0600 (Wed, 30 Jan 2013) $
32  */
33 
34 #ifndef OPAL_RTP_RTP_SESSION_H
35 #define OPAL_RTP_RTP_SESSION_H
36 
37 #ifdef P_USE_PRAGMA
38 #pragma interface
39 #endif
40 
41 #include <opal/buildopts.h>
42 
43 #include <rtp/rtp.h>
44 #include <rtp/jitter.h>
45 #include <opal/mediasession.h>
46 #include <ptlib/sockets.h>
47 #include <ptlib/safecoll.h>
48 #include <ptclib/pnat.h>
49 #include <ptclib/url.h>
50 
51 #include <list>
52 
53 
54 class PNatMethod;
55 class RTCP_XR_Metrics;
56 
57 
59 
63 {
64  PCLASSINFO(OpalRTPSession, OpalMediaSession);
65  public:
66  static const PCaselessString & RTP_AVP();
67  static const PCaselessString & RTP_AVPF();
68 
73  OpalRTPSession(const Init & init);
74 
80 
83  virtual const PCaselessString & GetSessionType() const { return RTP_AVP(); }
84  virtual bool Open(const PString & localInterface, const OpalTransportAddress & remoteAddress, bool isMediaAddress);
85  virtual bool IsOpen() const;
86  virtual bool Close();
87  virtual bool Shutdown(bool reading);
88  virtual OpalTransportAddress GetLocalAddress(bool isMediaAddress = true) const;
89  virtual OpalTransportAddress GetRemoteAddress(bool isMediaAddress = true) const;
90  virtual bool SetRemoteAddress(const OpalTransportAddress & remoteAddress, bool isMediaAddress = true);
91 
92  virtual void AttachTransport(Transport & transport);
93  virtual Transport DetachTransport();
94 
95  virtual void SetExternalTransport(const OpalTransportAddressArray & transports);
96 
98  const OpalMediaFormat & mediaFormat,
99  unsigned sessionID,
100  bool isSource
101  );
103 
113  void SetJitterBufferSize(
114  const OpalJitterBuffer::Init & init
115  );
116 
122  unsigned GetJitterBufferSize() const;
124 
127  unsigned GetJitterTimeUnits() const { return m_timeUnits; }
128 
133  virtual bool ReadData(
134  RTP_DataFrame & frame
135  );
136 
139  virtual void FlushData();
140 
143  virtual bool WriteData(
144  RTP_DataFrame & frame
145  );
146 
150  virtual bool WriteOOBData(
151  RTP_DataFrame & frame,
152  bool rewriteTimeStamp = true
153  );
154 
157  virtual bool WriteControl(
158  RTP_ControlFrame & frame
159  );
160 
163  virtual void Restart(
164  bool isReading
165  );
166 
169  virtual PString GetLocalHostName();
170 
171 #if OPAL_STATISTICS
172  virtual void GetStatistics(OpalMediaStatistics & statistics, bool receiver) const;
173 #endif
174 
175 
182  };
183  virtual SendReceiveStatus OnSendData(RTP_DataFrame & frame);
187 
188  class ReceiverReport : public PObject {
189  PCLASSINFO(ReceiverReport, PObject);
190  public:
191  void PrintOn(ostream &) const;
192 
194  DWORD fractionLost; /* fraction lost since last SR/RR */
195  DWORD totalLost; /* cumulative number of packets lost (signed!) */
196  DWORD lastSequenceNumber; /* extended last sequence number received */
197  DWORD jitter; /* interarrival jitter */
198  PTimeInterval lastTimestamp;/* last SR packet from this source */
199  PTimeInterval delay; /* delay since last SR packet */
200  };
201  PARRAY(ReceiverReportArray, ReceiverReport);
202 
203  class SenderReport : public PObject {
204  PCLASSINFO(SenderReport, PObject);
205  public:
206  void PrintOn(ostream &) const;
207 
211  DWORD packetsSent;
212  DWORD octetsSent;
213  };
214 
215  virtual void OnRxSenderReport(const SenderReport & sender,
216  const ReceiverReportArray & reports);
217  virtual void OnRxReceiverReport(DWORD src,
218  const ReceiverReportArray & reports);
219  virtual void OnReceiverReports(const ReceiverReportArray & reports);
220 
221  class SourceDescription : public PObject {
222  PCLASSINFO(SourceDescription, PObject);
223  public:
224  SourceDescription(DWORD src) { sourceIdentifier = src; }
225  void PrintOn(ostream &) const;
226 
228  POrdinalToString items;
229  };
230  PARRAY(SourceDescriptionArray, SourceDescription);
231  virtual void OnRxSourceDescription(const SourceDescriptionArray & descriptions);
232 
233  virtual void OnRxGoodbye(const PDWORDArray & sources,
234  const PString & reason);
235 
236  virtual void OnRxApplDefined(const PString & type, unsigned subtype, DWORD src,
237  const BYTE * data, PINDEX size);
238 
239 #if OPAL_RTCP_XR
240  class ExtendedReport : public PObject {
241  PCLASSINFO(ExtendedReport, PObject);
242  public:
243  void PrintOn(ostream &) const;
244 
245  DWORD sourceIdentifier;
246  DWORD lossRate; /* fraction of RTP data packets lost */
247  DWORD discardRate; /* fraction of RTP data packets discarded */
248  DWORD burstDensity; /* fraction of RTP data packets within burst periods */
249  DWORD gapDensity; /* fraction of RTP data packets within inter-burst gaps */
250  DWORD roundTripDelay; /* the most recently calculated round trip time */
251  DWORD RFactor; /* voice quality metric of the call */
252  DWORD mosLQ; /* MOS for listen quality */
253  DWORD mosCQ; /* MOS for conversational quality */
254  DWORD jbNominal; /* current nominal jitter buffer delay, in ms */
255  DWORD jbMaximum; /* current maximum jitter buffer delay, in ms */
256  DWORD jbAbsolute; /* current absolute maximum jitter buffer delay, in ms */
257  };
258  PARRAY(ExtendedReportArray, ExtendedReport);
259 
260  virtual void OnRxExtendedReport(
261  DWORD src,
262  const ExtendedReportArray & reports
263  );
264 
265  RTCP_XR_Metrics * GetExtendedMetrics() const { return m_metrics; }
266 #endif // OPAL_RTCP_XR
267 
268 
273  bool IsAudio() const { return m_isAudio; }
274 
277  void SetAudio(
278  bool aud
279  ) { m_isAudio = aud; }
280 
283  PString GetCanonicalName() const;
284 
287  void SetCanonicalName(const PString & name);
288 
291  PString GetToolName() const;
292 
295  void SetToolName(const PString & name);
296 
300 
303  void SetExtensionHeader(const RTPExtensionHeaders & ext);
304 
307  DWORD GetSyncSourceOut() const { return syncSourceOut; }
308 
311  bool AllowAnySyncSource() const { return allowAnySyncSource; }
312 
316  bool allow
317  ) { allowAnySyncSource = allow; }
318 
322  bool ignore
323  ) { ignorePayloadTypeChanges = ignore; }
324 
327  const PTimeInterval & GetMaxNoReceiveTime() { return m_maxNoReceiveTime; }
328 
332  const PTimeInterval & interval
333  ) { m_maxNoReceiveTime = interval; }
334 
337  const PTimeInterval & GetMaxNoTransmitTime() { return m_maxNoTransmitTime; }
338 
342  const PTimeInterval & interval
343  ) { m_maxNoTransmitTime = interval; }
344 
347  const PTimeInterval & GetReportTimeInterval() { return m_reportTimer.GetResetTime(); }
348 
352  const PTimeInterval & interval
353  ) { m_reportTimer.RunContinuous(interval); }
354 
358 
362  unsigned packets
363  );
364 
368 
372  unsigned packets
373  );
374 
377  void ClearStatistics();
378 
381  virtual WORD GetLocalDataPort() const { return m_localDataPort; }
382 
385  virtual WORD GetLocalControlPort() const { return m_localControlPort; }
386 
389  virtual WORD GetRemoteDataPort() const { return m_remoteDataPort; }
390 
393  virtual WORD GetRemoteControlPort() const { return m_remoteControlPort; }
394 
397  virtual PUDPSocket & GetDataSocket() { return *m_dataSocket; }
398 
401  virtual PUDPSocket & GetControlSocket() { return *m_controlSocket; }
402 
405  DWORD GetPacketsSent() const { return packetsSent; }
406 
409  DWORD GetOctetsSent() const { return octetsSent; }
410 
413  DWORD GetPacketsReceived() const { return packetsReceived; }
414 
417  DWORD GetOctetsReceived() const { return octetsReceived; }
418 
421  DWORD GetPacketsLost() const { return packetsLost; }
422 
426  DWORD GetPacketsLostByRemote() const { return packetsLostByRemote; }
427 
430  DWORD GetPacketsOutOfOrder() const { return packetsOutOfOrder; }
431 
434  DWORD GetPacketsTooLate() const;
435 
438  DWORD GetPacketOverruns() const;
439 
444  DWORD GetAverageSendTime() const { return averageSendTime; }
445 
450  DWORD GetMarkerRecvCount() const { return markerRecvCount; }
451 
456  DWORD GetMarkerSendCount() const { return markerSendCount; }
457 
462  DWORD GetMaximumSendTime() const { return maximumSendTime; }
463 
468  DWORD GetMinimumSendTime() const { return minimumSendTime; }
469 
474  DWORD GetAverageReceiveTime() const { return averageReceiveTime; }
475 
480  DWORD GetMaximumReceiveTime() const { return maximumReceiveTime; }
481 
486  DWORD GetMinimumReceiveTime() const { return minimumReceiveTime; }
487 
494 
499 
506 
507  virtual void SetCloseOnBYE(bool v) { m_closeOnBye = v; }
508 
511  virtual void SendFlowControl(
512  unsigned maxBitRate,
513  unsigned overhead = 0,
514  bool notify = false
515  );
516 
517 #if OPAL_VIDEO
518 
522  virtual void SendIntraFrameRequest(bool rfc2032, bool pictureLoss);
523 
528  virtual void SendTemporalSpatialTradeOff(unsigned tradeOff);
529 #endif
530 
531  void SetNextSentSequenceNumber(WORD num) { lastSentSequenceNumber = (WORD)(num-1); }
532 
533  DWORD GetSyncSourceIn() const { return syncSourceIn; }
534 
535  typedef PNotifierTemplate<SendReceiveStatus &> FilterNotifier;
536  #define PDECLARE_RTPFilterNotifier(cls, fn) PDECLARE_NOTIFIER2(RTP_DataFrame, cls, fn, OpalRTPSession::SendReceiveStatus &)
537  #define PCREATE_RTPFilterNotifier(fn) PCREATE_NOTIFIER2(fn, OpalRTPSession::SendReceiveStatus &)
538 
539  void AddFilter(const FilterNotifier & filter);
540 
541  virtual void SendBYE();
542 
543  protected:
544  ReceiverReportArray BuildReceiverReportArray(const RTP_ControlFrame & frame, PINDEX offset);
546  bool InsertReportPacket(RTP_ControlFrame & report);
547  virtual int WaitForPDU(PUDPSocket & dataSocket, PUDPSocket & controlSocket, const PTimeInterval & timer);
550 
551  virtual bool InternalReadData(RTP_DataFrame & frame);
554  BYTE * framePtr,
555  PINDEX frameSize,
556  bool fromDataChannel
557  );
558  virtual bool HandleUnreachable(PTRACE_PARAM(const char * channelName));
559  virtual bool WriteDataOrControlPDU(
560  const BYTE * framePtr,
561  PINDEX frameSize,
562  bool toDataChannel
563  );
564 
565 
566  bool m_isAudio;
567  unsigned m_timeUnits;
569  PString m_toolName;
571  PTimeInterval m_maxNoReceiveTime;
572  PTimeInterval m_maxNoTransmitTime;
573 
585  PTimeInterval lastSentPacketTime;
586  PTimeInterval lastReceivedPacketTime;
589  PTimeInterval delaySinceLastSR;
593  PTimeInterval outOfOrderWaitTime;
594  PTimeInterval outOfOrderPacketTime;
595 
596  std::list<RTP_DataFrame> m_outOfOrderPackets;
597  void SaveOutOfOrderPacket(RTP_DataFrame & frame);
598 
599  DWORD timeStampOffs; // offset between incoming media timestamp and timeStampOut
600  bool oobTimeStampBaseEstablished; // true if timeStampOffs has been established by media
601  DWORD oobTimeStampOutBase; // base timestamp value for oob data
602  PTimeInterval oobTimeStampBase; // base time for oob timestamp
603 
604  // Statistics
606  DWORD packetsSent;
608  DWORD octetsSent;
613  DWORD packetsLost;
622  DWORD jitterLevel;
625 
628 
631 
634 
635 #if OPAL_RTCP_XR
636  // Calculate the VoIP Metrics for RTCP-XR
637  RTCP_XR_Metrics * m_metrics;
638  friend class RTCP_XR_Metrics;
639 #endif
640 
650 
653 
656  PDECLARE_NOTIFIER(PTimer, OpalRTPSession, SendReport);
657 
658  PMutex m_dataMutex;
660  bool m_byeSent;
661 
662  list<FilterNotifier> m_filters;
663 
664  PIPSocket::Address m_localAddress;
667 
668  PIPSocket::Address m_remoteAddress;
671 
672  PIPSocket::Address m_remoteTransmitAddress;
673 
674  PUDPSocket * m_dataSocket;
675  PUDPSocket * m_controlSocket;
676 
682 
684  PSimpleTimer m_noTransmitTimer;
685 
686  // Make sure JB is last to make sure it is destroyed first.
687  typedef PSafePtr<OpalJitterBuffer, PSafePtrMultiThreaded> JitterBufferPtr;
689 
690  private:
692  void operator=(const OpalRTPSession &) { }
693 
694  friend class RTP_JitterBuffer;
695 };
696 
697 
698 #endif // OPAL_RTP_RTP_H
699