OPAL  Version 3.14.3
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: 32454 $
30  * $Author: rjongbloed $
31  * $Date: 2014-08-08 17:38:38 +1000 (Fri, 08 Aug 2014) $
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_config.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 <ptlib/notifier_ext.h>
49 #include <ptclib/pnat.h>
50 #include <ptclib/url.h>
51 
52 #include <list>
53 
54 
55 class OpalRTPEndPoint;
56 class PNatMethod;
57 class PSTUNServer;
58 class RTCP_XR_Metrics;
59 
60 
62 
66 {
67  PCLASSINFO(OpalRTPSession, OpalMediaSession);
68  public:
69  static const PCaselessString & RTP_AVP();
70  static const PCaselessString & RTP_AVPF();
71 
76  OpalRTPSession(const Init & init);
77 
83 
86  virtual const PCaselessString & GetSessionType() const { return RTP_AVP(); }
87  virtual bool Open(const PString & localInterface, const OpalTransportAddress & remoteAddress, bool isMediaAddress);
88  virtual bool IsOpen() const;
89  virtual bool Close();
90  virtual bool Shutdown(bool reading);
91  virtual OpalTransportAddress GetLocalAddress(bool isMediaAddress = true) const;
92  virtual OpalTransportAddress GetRemoteAddress(bool isMediaAddress = true) const;
93  virtual bool SetRemoteAddress(const OpalTransportAddress & remoteAddress, bool isMediaAddress = true);
94 #if OPAL_ICE
95  virtual void SetRemoteUserPass(const PString & user, const PString & pass);
96 #endif
97 
98  virtual void AttachTransport(Transport & transport);
99  virtual Transport DetachTransport();
100 
102  const OpalMediaFormat & mediaFormat,
103  unsigned sessionID,
104  bool isSource
105  );
107 
117  bool SetJitterBufferSize(
118  const OpalJitterBuffer::Init & init
119  );
120 
126  unsigned GetJitterBufferSize() const;
128 
131  unsigned GetJitterTimeUnits() const { return m_timeUnits; }
132 
137  virtual bool ReadData(
138  RTP_DataFrame & frame
139  );
140 
143  virtual bool WriteData(
144  RTP_DataFrame & frame,
145  const PIPSocketAddressAndPort * remote = NULL,
146  bool rewriteHeader = true
149  );
150 
153  void SendReport(bool force);
154 
157  virtual bool WriteControl(
158  RTP_ControlFrame & frame,
159  const PIPSocketAddressAndPort * remote = NULL
160  );
161 
164  virtual void Restart(
165  bool isReading
166  );
167 
170  virtual PString GetLocalHostName();
171 
172 #if OPAL_STATISTICS
173  virtual void GetStatistics(OpalMediaStatistics & statistics, bool receiver) const;
174 #endif
175 
176 
183  };
184  virtual SendReceiveStatus OnSendData(RTP_DataFrame & frame, bool rewriteHeader);
186  virtual SendReceiveStatus OnReceiveData(RTP_DataFrame & frame, PINDEX pduSize);
188 #if OPAL_RTP_FEC
189  virtual SendReceiveStatus OnSendRedundantFrame(RTP_DataFrame & frame);
190  virtual SendReceiveStatus OnSendRedundantData(RTP_DataFrame::PayloadTypes & payloadType, unsigned & timestamp, BYTE * data, PINDEX & size);
191  virtual SendReceiveStatus OnReceiveRedundantFrame(RTP_DataFrame & frame);
192  virtual SendReceiveStatus OnReceiveRedundantData(RTP_DataFrame::PayloadTypes payloadType, unsigned timestamp, const BYTE * data, PINDEX size);
193 #endif
195 
196  class ReceiverReport : public PObject {
197  PCLASSINFO(ReceiverReport, PObject);
198  public:
199 #if PTRACING
200  void PrintOn(ostream &) const;
201 #endif
202 
204  DWORD fractionLost; /* fraction lost since last SR/RR */
205  DWORD totalLost; /* cumulative number of packets lost (signed!) */
206  DWORD lastSequenceNumber; /* extended last sequence number received */
207  DWORD jitter; /* interarrival jitter */
208  PTimeInterval lastTimestamp;/* last SR packet from this source */
209  PTimeInterval delay; /* delay since last SR packet */
210  };
211  PARRAY(ReceiverReportArray, ReceiverReport);
212 
213  class SenderReport : public PObject {
214  PCLASSINFO(SenderReport, PObject);
215  public:
216 #if PTRACING
217  void PrintOn(ostream &) const;
218 #endif
219 
223  DWORD packetsSent;
224  DWORD octetsSent;
225  };
226 
227  virtual void OnRxSenderReport(const SenderReport & sender,
228  const ReceiverReportArray & reports);
229  virtual void OnRxReceiverReport(DWORD src,
230  const ReceiverReportArray & reports);
231  virtual void OnReceiverReports(const ReceiverReportArray & reports);
232 
233  class SourceDescription : public PObject {
234  PCLASSINFO(SourceDescription, PObject);
235  public:
236  SourceDescription(DWORD src) { sourceIdentifier = src; }
237 #if PTRACING
238  void PrintOn(ostream &) const;
239 #endif
240 
242  POrdinalToString items;
243  };
244  PARRAY(SourceDescriptionArray, SourceDescription);
245  virtual void OnRxSourceDescription(const SourceDescriptionArray & descriptions);
246 
247  virtual void OnRxGoodbye(const PDWORDArray & sources,
248  const PString & reason);
249 
250  typedef PNotifierListTemplate<const RTP_ControlFrame::ApplDefinedInfo &> ApplDefinedNotifierList;
251  typedef PNotifierTemplate<const RTP_ControlFrame::ApplDefinedInfo &> ApplDefinedNotifier;
252 
253  virtual void OnRxApplDefined(const RTP_ControlFrame::ApplDefinedInfo & info);
254 
256  {
257  m_applDefinedNotifiers.Add(notifier);
258  }
259 
261  {
262  m_applDefinedNotifiers.Remove(notifier);
263  }
264 
265 #if OPAL_RTCP_XR
266  class ExtendedReport : public PObject {
267  PCLASSINFO(ExtendedReport, PObject);
268  public:
269 #if PTRACING
270  void PrintOn(ostream &) const;
271 #endif
272 
273  DWORD sourceIdentifier;
274  DWORD lossRate; /* fraction of RTP data packets lost */
275  DWORD discardRate; /* fraction of RTP data packets discarded */
276  DWORD burstDensity; /* fraction of RTP data packets within burst periods */
277  DWORD gapDensity; /* fraction of RTP data packets within inter-burst gaps */
278  DWORD roundTripDelay; /* the most recently calculated round trip time */
279  DWORD RFactor; /* voice quality metric of the call */
280  DWORD mosLQ; /* MOS for listen quality */
281  DWORD mosCQ; /* MOS for conversational quality */
282  DWORD jbNominal; /* current nominal jitter buffer delay, in ms */
283  DWORD jbMaximum; /* current maximum jitter buffer delay, in ms */
284  DWORD jbAbsolute; /* current absolute maximum jitter buffer delay, in ms */
285  };
286  PARRAY(ExtendedReportArray, ExtendedReport);
287 
288  virtual void OnRxExtendedReport(
289  DWORD src,
290  const ExtendedReportArray & reports
291  );
292 
293  RTCP_XR_Metrics * GetExtendedMetrics() const { return m_metrics; }
294 #endif // OPAL_RTCP_XR
295 
296 
302  void SetSinglePort(bool v = true) { m_singlePort = v; }
303 
306  bool IsAudio() const { return m_isAudio; }
307 
310  void SetAudio(
311  bool aud
312  ) { m_isAudio = aud; }
313 
314 #if OPAL_RTP_FEC
315 
316  RTP_DataFrame::PayloadTypes GetRedundencyPayloadType() const { return m_redundencyPayloadType; }
317 
319  void SetRedundencyPayloadType(RTP_DataFrame::PayloadTypes pt) { m_redundencyPayloadType = pt; }
320 
322  RTP_DataFrame::PayloadTypes GetUlpFecPayloadType() const { return m_ulpFecPayloadType; }
323 
325  void SetUlpFecPayloadType(RTP_DataFrame::PayloadTypes pt) { m_ulpFecPayloadType = pt; }
326 #endif // OPAL_RTP_FEC
327 
330  PString GetCanonicalName() const;
331 
334  void SetCanonicalName(const PString & name);
335 
338  PString GetGroupId() const;
339 
342  void SetGroupId(const PString & id);
343 
346  PString GetToolName() const;
347 
350  void SetToolName(const PString & name);
351 
355 
358  void SetExtensionHeader(const RTPExtensionHeaders & ext);
359 
362  DWORD GetSyncSourceOut() const { return syncSourceOut; }
363 
366  bool AllowAnySyncSource() const { return allowAnySyncSource; }
367 
371  bool allow
372  ) { allowAnySyncSource = allow; }
373 
377  bool ignore
378  ) { ignorePayloadTypeChanges = ignore; }
379 
382  const PTimeInterval & GetMaxNoReceiveTime() { return m_maxNoReceiveTime; }
383 
387  const PTimeInterval & interval
388  ) { m_maxNoReceiveTime = interval; }
389 
392  const PTimeInterval & GetMaxNoTransmitTime() { return m_maxNoTransmitTime; }
393 
397  const PTimeInterval & interval
398  ) { m_maxNoTransmitTime = interval; }
399 
402  PTimeInterval GetReportTimeInterval() { return m_reportTimer.GetResetTime(); }
403 
407  const PTimeInterval & interval
408  ) { m_reportTimer.RunContinuous(interval); }
409 
413 
417  unsigned packets
418  );
419 
423 
427  unsigned packets
428  );
429 
432  void ClearStatistics();
433 
436  virtual WORD GetLocalDataPort() const { return m_localDataPort; }
437 
440  virtual WORD GetLocalControlPort() const { return m_localControlPort; }
441 
444  virtual WORD GetRemoteDataPort() const { return m_remoteDataPort; }
445 
448  virtual WORD GetRemoteControlPort() const { return m_remoteControlPort; }
449 
452  virtual PUDPSocket & GetDataSocket() { return *m_dataSocket; }
453 
456  virtual PUDPSocket & GetControlSocket() { return *m_controlSocket; }
457 
460  DWORD GetPacketsSent() const { return packetsSent; }
461 
464  DWORD GetOctetsSent() const { return octetsSent; }
465 
468  DWORD GetPacketsReceived() const { return packetsReceived; }
469 
472  DWORD GetOctetsReceived() const { return octetsReceived; }
473 
476  DWORD GetPacketsLost() const { return packetsLost; }
477 
481  DWORD GetPacketsLostByRemote() const { return packetsLostByRemote; }
482 
485  DWORD GetPacketsOutOfOrder() const { return packetsOutOfOrder; }
486 
489  DWORD GetPacketsTooLate() const;
490 
493  DWORD GetPacketOverruns() const;
494 
499  DWORD GetAverageSendTime() const { return averageSendTime; }
500 
505  DWORD GetMarkerRecvCount() const { return markerRecvCount; }
506 
511  DWORD GetMarkerSendCount() const { return markerSendCount; }
512 
517  DWORD GetMaximumSendTime() const { return maximumSendTime; }
518 
523  DWORD GetMinimumSendTime() const { return minimumSendTime; }
524 
529  DWORD GetAverageReceiveTime() const { return averageReceiveTime; }
530 
535  DWORD GetMaximumReceiveTime() const { return maximumReceiveTime; }
536 
541  DWORD GetMinimumReceiveTime() const { return minimumReceiveTime; }
542 
549 
554 
560 
564  DWORD GetRoundTripTime() const { return roundTripTime; }
566 
567  virtual void SetCloseOnBYE(bool v) { m_closeOnBye = v; }
568 
571  virtual void SendFlowControl(
572  unsigned maxBitRate,
573  unsigned overhead = 0,
574  bool notify = false
575  );
576 
577 #if OPAL_VIDEO
578 
582  virtual void SendIntraFrameRequest(bool rfc2032, bool pictureLoss);
583 
588  virtual void SendTemporalSpatialTradeOff(unsigned tradeOff);
589 #endif
590 
591  void SetNextSentSequenceNumber(WORD num) { lastSentSequenceNumber = (WORD)(num-1); }
592 
593  DWORD GetLastSentTimestamp() const { return lastSentTimestamp; }
594  const PTimeInterval & GetLastSentPacketTime() const { return lastSentPacketTime; }
595  DWORD GetSyncSourceIn() const { return syncSourceIn; }
596 
597  typedef PNotifierTemplate<SendReceiveStatus &> FilterNotifier;
598  #define PDECLARE_RTPFilterNotifier(cls, fn) PDECLARE_NOTIFIER2(RTP_DataFrame, cls, fn, OpalRTPSession::SendReceiveStatus &)
599  #define PCREATE_RTPFilterNotifier(fn) PCREATE_NOTIFIER2(fn, OpalRTPSession::SendReceiveStatus &)
600 
601  void AddFilter(const FilterNotifier & filter);
602 
603  virtual void SendBYE();
604 
605  bool SetQoS(const PIPSocket::QoS & qos);
606 
607  protected:
608  ReceiverReportArray BuildReceiverReportArray(const RTP_ControlFrame & frame, PINDEX offset);
613 
614  virtual bool InternalReadData(RTP_DataFrame & frame);
617  BYTE * framePtr,
618  PINDEX & frameSize,
619  bool fromDataChannel
620  );
621  virtual bool HandleUnreachable(PTRACE_PARAM(const char * channelName));
622  virtual bool WriteRawPDU(
623  const BYTE * framePtr,
624  PINDEX frameSize,
625  bool toDataChannel,
626  const PIPSocketAddressAndPort * remote = NULL
627  );
628 
631  bool m_isAudio;
632  unsigned m_timeUnits;
634  PString m_groupId;
635  PString m_toolName;
637  PTimeInterval m_maxNoReceiveTime;
638  PTimeInterval m_maxNoTransmitTime;
639 #if OPAL_RTP_FEC
640  RTP_DataFrame::PayloadTypes m_redundencyPayloadType;
641  RTP_DataFrame::PayloadTypes m_ulpFecPayloadType;
642 #endif
643 
654  PTimeInterval lastSentPacketTime;
655  PTimeInterval lastReceivedPacketTime;
662  PTimeInterval outOfOrderWaitTime;
663  PTimeInterval outOfOrderPacketTime;
666 
667  RTP_DataFrameList m_pendingPackets;
668  void SaveOutOfOrderPacket(RTP_DataFrame & frame);
669 
670  // Statistics
672  DWORD packetsSent;
674  DWORD octetsSent;
679  DWORD packetsLost;
688  DWORD jitterLevel;
692 
695 
698 
701 
702 #if OPAL_RTCP_XR
703  // Calculate the VoIP Metrics for RTCP-XR
704  RTCP_XR_Metrics * m_metrics;
705  friend class RTCP_XR_Metrics;
706 #endif
707 
717 
720 
723  PDECLARE_NOTIFIER(PTimer, OpalRTPSession, TimedSendReport);
724 
725  PMutex m_dataMutex;
726  PMutex m_readMutex;
728  bool m_byeSent;
729 
730  list<FilterNotifier> m_filters;
731 
732  PIPSocket::Address m_localAddress;
735 
736  PIPSocket::Address m_remoteAddress;
739 
740  PIPSocket::QoS m_qos;
741 
742  PUDPSocket * m_dataSocket;
743  PUDPSocket * m_controlSocket;
744 
750 
752  PSimpleTimer m_noTransmitTimer;
753 
754  // Make sure JB is last to make sure it is destroyed first.
755  typedef PSafePtr<OpalJitterBuffer, PSafePtrMultiThreaded> JitterBufferPtr;
757 
759 
760 #if OPAL_ICE
761  PSTUNServer * m_stunServer;
762 #endif
763 
764 #if PTRACING
765  unsigned m_levelTxRR;
766  unsigned m_levelRxSR;
767  unsigned m_levelRxRR;
768  unsigned m_levelRxSDES;
769 #endif
770 
771  private:
773  void operator=(const OpalRTPSession &) { }
774 
775  P_REMOVE_VIRTUAL(int,WaitForPDU(PUDPSocket&,PUDPSocket&,const PTimeInterval&),0);
776  P_REMOVE_VIRTUAL(SendReceiveStatus,ReadDataOrControlPDU(BYTE *,PINDEX,bool),e_AbortTransport);
777  P_REMOVE_VIRTUAL(bool,WriteDataOrControlPDU(const BYTE *,PINDEX,bool),false);
779 
780 
781  friend class RTP_JitterBuffer;
782 };
783 
784 
785 #endif // OPAL_RTP_RTP_H
786