OPAL  Version 3.12.9
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: 31007 $
30  * $Author: rjongbloed $
31  * $Date: 2013-11-29 12:10:28 +1100 (Fri, 29 Nov 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  bool 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 bool WriteData(
140  RTP_DataFrame & frame
141  );
142 
146  virtual bool WriteOOBData(
147  RTP_DataFrame & frame,
148  bool rewriteTimeStamp = true
149  );
150 
153  virtual bool WriteControl(
154  RTP_ControlFrame & frame
155  );
156 
159  virtual void Restart(
160  bool isReading
161  );
162 
165  virtual PString GetLocalHostName();
166 
167 #if OPAL_STATISTICS
168  virtual void GetStatistics(OpalMediaStatistics & statistics, bool receiver) const;
169 #endif
170 
171 
178  };
179  virtual SendReceiveStatus OnSendData(RTP_DataFrame & frame);
183 
184  class ReceiverReport : public PObject {
185  PCLASSINFO(ReceiverReport, PObject);
186  public:
187  void PrintOn(ostream &) const;
188 
190  DWORD fractionLost; /* fraction lost since last SR/RR */
191  DWORD totalLost; /* cumulative number of packets lost (signed!) */
192  DWORD lastSequenceNumber; /* extended last sequence number received */
193  DWORD jitter; /* interarrival jitter */
194  PTimeInterval lastTimestamp;/* last SR packet from this source */
195  PTimeInterval delay; /* delay since last SR packet */
196  };
197  PARRAY(ReceiverReportArray, ReceiverReport);
198 
199  class SenderReport : public PObject {
200  PCLASSINFO(SenderReport, PObject);
201  public:
202  void PrintOn(ostream &) const;
203 
207  DWORD packetsSent;
208  DWORD octetsSent;
209  };
210 
211  virtual void OnRxSenderReport(const SenderReport & sender,
212  const ReceiverReportArray & reports);
213  virtual void OnRxReceiverReport(DWORD src,
214  const ReceiverReportArray & reports);
215  virtual void OnReceiverReports(const ReceiverReportArray & reports);
216 
217  class SourceDescription : public PObject {
218  PCLASSINFO(SourceDescription, PObject);
219  public:
220  SourceDescription(DWORD src) { sourceIdentifier = src; }
221  void PrintOn(ostream &) const;
222 
224  POrdinalToString items;
225  };
226  PARRAY(SourceDescriptionArray, SourceDescription);
227  virtual void OnRxSourceDescription(const SourceDescriptionArray & descriptions);
228 
229  virtual void OnRxGoodbye(const PDWORDArray & sources,
230  const PString & reason);
231 
232  virtual void OnRxApplDefined(const PString & type, unsigned subtype, DWORD src,
233  const BYTE * data, PINDEX size);
234 
235 #if OPAL_RTCP_XR
236  class ExtendedReport : public PObject {
237  PCLASSINFO(ExtendedReport, PObject);
238  public:
239  void PrintOn(ostream &) const;
240 
241  DWORD sourceIdentifier;
242  DWORD lossRate; /* fraction of RTP data packets lost */
243  DWORD discardRate; /* fraction of RTP data packets discarded */
244  DWORD burstDensity; /* fraction of RTP data packets within burst periods */
245  DWORD gapDensity; /* fraction of RTP data packets within inter-burst gaps */
246  DWORD roundTripDelay; /* the most recently calculated round trip time */
247  DWORD RFactor; /* voice quality metric of the call */
248  DWORD mosLQ; /* MOS for listen quality */
249  DWORD mosCQ; /* MOS for conversational quality */
250  DWORD jbNominal; /* current nominal jitter buffer delay, in ms */
251  DWORD jbMaximum; /* current maximum jitter buffer delay, in ms */
252  DWORD jbAbsolute; /* current absolute maximum jitter buffer delay, in ms */
253  };
254  PARRAY(ExtendedReportArray, ExtendedReport);
255 
256  virtual void OnRxExtendedReport(
257  DWORD src,
258  const ExtendedReportArray & reports
259  );
260 
261  RTCP_XR_Metrics * GetExtendedMetrics() const { return m_metrics; }
262 #endif // OPAL_RTCP_XR
263 
264 
269  bool IsAudio() const { return m_isAudio; }
270 
273  void SetAudio(
274  bool aud
275  ) { m_isAudio = aud; }
276 
279  PString GetCanonicalName() const;
280 
283  void SetCanonicalName(const PString & name);
284 
287  PString GetToolName() const;
288 
291  void SetToolName(const PString & name);
292 
296 
299  void SetExtensionHeader(const RTPExtensionHeaders & ext);
300 
303  DWORD GetSyncSourceOut() const { return syncSourceOut; }
304 
307  bool AllowAnySyncSource() const { return allowAnySyncSource; }
308 
312  bool allow
313  ) { allowAnySyncSource = allow; }
314 
318  bool ignore
319  ) { ignorePayloadTypeChanges = ignore; }
320 
323  const PTimeInterval & GetMaxNoReceiveTime() { return m_maxNoReceiveTime; }
324 
328  const PTimeInterval & interval
329  ) { m_maxNoReceiveTime = interval; }
330 
333  const PTimeInterval & GetMaxNoTransmitTime() { return m_maxNoTransmitTime; }
334 
338  const PTimeInterval & interval
339  ) { m_maxNoTransmitTime = interval; }
340 
343  const PTimeInterval & GetReportTimeInterval() { return m_reportTimer.GetResetTime(); }
344 
348  const PTimeInterval & interval
349  ) { m_reportTimer.RunContinuous(interval); }
350 
354 
358  unsigned packets
359  );
360 
364 
368  unsigned packets
369  );
370 
373  void ClearStatistics();
374 
377  virtual WORD GetLocalDataPort() const { return m_localDataPort; }
378 
381  virtual WORD GetLocalControlPort() const { return m_localControlPort; }
382 
385  virtual WORD GetRemoteDataPort() const { return m_remoteDataPort; }
386 
389  virtual WORD GetRemoteControlPort() const { return m_remoteControlPort; }
390 
393  virtual PUDPSocket & GetDataSocket() { return *m_dataSocket; }
394 
397  virtual PUDPSocket & GetControlSocket() { return *m_controlSocket; }
398 
401  DWORD GetPacketsSent() const { return packetsSent; }
402 
405  DWORD GetOctetsSent() const { return octetsSent; }
406 
409  DWORD GetPacketsReceived() const { return packetsReceived; }
410 
413  DWORD GetOctetsReceived() const { return octetsReceived; }
414 
417  DWORD GetPacketsLost() const { return packetsLost; }
418 
422  DWORD GetPacketsLostByRemote() const { return packetsLostByRemote; }
423 
426  DWORD GetPacketsOutOfOrder() const { return packetsOutOfOrder; }
427 
430  DWORD GetPacketsTooLate() const;
431 
434  DWORD GetPacketOverruns() const;
435 
440  DWORD GetAverageSendTime() const { return averageSendTime; }
441 
446  DWORD GetMarkerRecvCount() const { return markerRecvCount; }
447 
452  DWORD GetMarkerSendCount() const { return markerSendCount; }
453 
458  DWORD GetMaximumSendTime() const { return maximumSendTime; }
459 
464  DWORD GetMinimumSendTime() const { return minimumSendTime; }
465 
470  DWORD GetAverageReceiveTime() const { return averageReceiveTime; }
471 
476  DWORD GetMaximumReceiveTime() const { return maximumReceiveTime; }
477 
482  DWORD GetMinimumReceiveTime() const { return minimumReceiveTime; }
483 
490 
495 
502 
503  virtual void SetCloseOnBYE(bool v) { m_closeOnBye = v; }
504 
507  virtual void SendFlowControl(
508  unsigned maxBitRate,
509  unsigned overhead = 0,
510  bool notify = false
511  );
512 
513 #if OPAL_VIDEO
514 
518  virtual void SendIntraFrameRequest(bool rfc2032, bool pictureLoss);
519 
524  virtual void SendTemporalSpatialTradeOff(unsigned tradeOff);
525 #endif
526 
527  void SetNextSentSequenceNumber(WORD num) { lastSentSequenceNumber = (WORD)(num-1); }
528 
529  DWORD GetSyncSourceIn() const { return syncSourceIn; }
530 
531  typedef PNotifierTemplate<SendReceiveStatus &> FilterNotifier;
532  #define PDECLARE_RTPFilterNotifier(cls, fn) PDECLARE_NOTIFIER2(RTP_DataFrame, cls, fn, OpalRTPSession::SendReceiveStatus &)
533  #define PCREATE_RTPFilterNotifier(fn) PCREATE_NOTIFIER2(fn, OpalRTPSession::SendReceiveStatus &)
534 
535  void AddFilter(const FilterNotifier & filter);
536 
537  virtual void SendBYE();
538 
539  protected:
540  ReceiverReportArray BuildReceiverReportArray(const RTP_ControlFrame & frame, PINDEX offset);
542  bool InsertReportPacket(RTP_ControlFrame & report);
543  virtual int WaitForPDU(PUDPSocket & dataSocket, PUDPSocket & controlSocket, const PTimeInterval & timer);
546 
547  virtual bool InternalReadData(RTP_DataFrame & frame);
550  BYTE * framePtr,
551  PINDEX frameSize,
552  bool fromDataChannel
553  );
554  virtual bool HandleUnreachable(PTRACE_PARAM(const char * channelName));
555  virtual bool WriteDataOrControlPDU(
556  const BYTE * framePtr,
557  PINDEX frameSize,
558  bool toDataChannel
559  );
560 
561 
562  bool m_isAudio;
563  unsigned m_timeUnits;
565  PString m_toolName;
567  PTimeInterval m_maxNoReceiveTime;
568  PTimeInterval m_maxNoTransmitTime;
569 
581  PTimeInterval lastSentPacketTime;
582  PTimeInterval lastReceivedPacketTime;
585  PTimeInterval delaySinceLastSR;
589  PTimeInterval outOfOrderWaitTime;
590  PTimeInterval outOfOrderPacketTime;
593 
594  std::list<RTP_DataFrame> m_outOfOrderPackets;
595  void SaveOutOfOrderPacket(RTP_DataFrame & frame);
596 
597  DWORD timeStampOffs; // offset between incoming media timestamp and timeStampOut
598  bool oobTimeStampBaseEstablished; // true if timeStampOffs has been established by media
599  DWORD oobTimeStampOutBase; // base timestamp value for oob data
600  PTimeInterval oobTimeStampBase; // base time for oob timestamp
601 
602  // Statistics
604  DWORD packetsSent;
606  DWORD octetsSent;
611  DWORD packetsLost;
620  DWORD jitterLevel;
623 
626 
629 
632 
633 #if OPAL_RTCP_XR
634  // Calculate the VoIP Metrics for RTCP-XR
635  RTCP_XR_Metrics * m_metrics;
636  friend class RTCP_XR_Metrics;
637 #endif
638 
648 
651 
654  PDECLARE_NOTIFIER(PTimer, OpalRTPSession, SendReport);
655 
656  PMutex m_dataMutex;
657  PMutex m_readMutex;
659  bool m_byeSent;
660 
661  list<FilterNotifier> m_filters;
662 
663  PIPSocket::Address m_localAddress;
666 
667  PIPSocket::Address m_remoteAddress;
670 
671  PIPSocket::Address m_remoteTransmitAddress;
672 
673  PUDPSocket * m_dataSocket;
674  PUDPSocket * m_controlSocket;
675 
681 
683  PSimpleTimer m_noTransmitTimer;
684 
685  // Make sure JB is last to make sure it is destroyed first.
686  typedef PSafePtr<OpalJitterBuffer, PSafePtrMultiThreaded> JitterBufferPtr;
688 
689  private:
691  void operator=(const OpalRTPSession &) { }
692 
693  friend class RTP_JitterBuffer;
694 };
695 
696 
697 #endif // OPAL_RTP_RTP_H
698