# rtp_session.h

Go to the documentation of this file.

    00001 /*
    00002  * rtp_session.h
    00003  *
    00004  * RTP protocol session
    00005  *
    00006  * Open H323 Library
    00007  *
    00008  * Copyright (c) 1998-2012 Equivalence Pty. Ltd.
    00009  *
    00010  * The contents of this file are subject to the Mozilla Public License
    00011  * Version 1.0 (the "License"); you may not use this file except in
    00012  * compliance with the License. You may obtain a copy of the License at
    00013  * http://www.mozilla.org/MPL/
    00014  *
    00015  * Software distributed under the License is distributed on an "AS IS"
    00016  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
    00017  * the License for the specific language governing rights and limitations
    00018  * under the License.
    00019  *
    00020  * The Original Code is Open H323 Library.
    00021  *
    00022  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
    00023  *
    00024  * Portions of this code were written with the assisance of funding from
    00025  * Vovida Networks, Inc. http://www.vovida.com.
    00026  *
    00027  * Contributor(s): ______________________________________.
    00028  *
    00029  * $Revision: 29059 $
    00030  * $Author: rjongbloed $
    00031  * $Date: 2013-01-30 21:12:49 -0600 (Wed, 30 Jan 2013) $
    00032  */
    00033
    00034 #ifndef OPAL_RTP_RTP_SESSION_H
    00035 #define OPAL_RTP_RTP_SESSION_H
    00036
    00037 #ifdef P_USE_PRAGMA
    00038 #pragma interface
    00039 #endif
    00040
    00041 #include <opal/buildopts.h>
    00042
    00043 #include <rtp/rtp.h>
    00044 #include <rtp/jitter.h>
    00045 #include <opal/mediasession.h>
    00046 #include <ptlib/sockets.h>
    00047 #include <ptlib/safecoll.h>
    00048 #include <ptclib/pnat.h>
    00049 #include <ptclib/url.h>
    00050
    00051 #include <list>
    00052
    00053
    00054 class PNatMethod;
    00055 class RTCP_XR_Metrics;
    00056
    00057
    00059
    00062 class OpalRTPSession : public OpalMediaSession
    00063 {
    00064     PCLASSINFO(OpalRTPSession, OpalMediaSession);
    00065   public:
    00066     static const PCaselessString & RTP_AVP();
    00067     static const PCaselessString & RTP_AVPF();
    00068
    00073     OpalRTPSession(const Init & init);
    00074
    00078     ~OpalRTPSession();
    00080
    00083     virtual const PCaselessString & GetSessionType() const { return RTP_AVP(); }
    00084     virtual bool Open(const PString & localInterface, const OpalTransportAddress & remoteAddress, bool isMediaAddress);
    00085     virtual bool IsOpen() const;
    00086     virtual bool Close();
    00087     virtual bool Shutdown(bool reading);
    00088     virtual OpalTransportAddress GetLocalAddress(bool isMediaAddress = true) const;
    00089     virtual OpalTransportAddress GetRemoteAddress(bool isMediaAddress = true) const;
    00090     virtual bool SetRemoteAddress(const OpalTransportAddress & remoteAddress, bool isMediaAddress = true);
    00091
    00092     virtual void AttachTransport(Transport & transport);
    00093     virtual Transport DetachTransport();
    00094
    00095     virtual void SetExternalTransport(const OpalTransportAddressArray & transports);
    00096
    00097     virtual OpalMediaStream * CreateMediaStream(
    00098       const OpalMediaFormat & mediaFormat,
    00099       unsigned sessionID,
    00100       bool isSource
    00101     );
    00103
    00113     void SetJitterBufferSize(
    00114       const OpalJitterBuffer::Init & init
    00115     );
    00116
    00122     unsigned GetJitterBufferSize() const;
    00123     unsigned GetJitterBufferDelay() const { return GetJitterBufferSize()/GetJitterTimeUnits(); }
    00124
    00127     unsigned GetJitterTimeUnits() const { return m_timeUnits; }
    00128
    00133     virtual bool ReadData(
    00134       RTP_DataFrame & frame
    00135     );
    00136
    00139     virtual void FlushData();
    00140
    00143     virtual bool WriteData(
    00144       RTP_DataFrame & frame
    00145     );
    00146
    00150     virtual bool WriteOOBData(
    00151       RTP_DataFrame & frame,
    00152       bool rewriteTimeStamp = true
    00153     );
    00154
    00157     virtual bool WriteControl(
    00158       RTP_ControlFrame & frame
    00159     );
    00160
    00163     virtual void Restart(
    00164       bool isReading
    00165     );
    00166
    00169     virtual PString GetLocalHostName();
    00170
    00171 #if OPAL_STATISTICS
    00172     virtual void GetStatistics(OpalMediaStatistics & statistics, bool receiver) const;
    00173 #endif
    00174
    00175
    00178     enum SendReceiveStatus {
    00179       e_ProcessPacket,
    00180       e_IgnorePacket,
    00181       e_AbortTransport
    00182     };
    00183     virtual SendReceiveStatus OnSendData(RTP_DataFrame & frame);
    00184     virtual SendReceiveStatus OnSendControl(RTP_ControlFrame & frame);
    00185     virtual SendReceiveStatus OnReceiveData(RTP_DataFrame & frame);
    00186     virtual SendReceiveStatus OnReceiveControl(RTP_ControlFrame & frame);
    00187
    00188     class ReceiverReport : public PObject  {
    00189         PCLASSINFO(ReceiverReport, PObject);
    00190       public:
    00191         void PrintOn(ostream &) const;
    00192
    00193         DWORD sourceIdentifier;
    00194         DWORD fractionLost;         /* fraction lost since last SR/RR */
    00195         DWORD totalLost;            /* cumulative number of packets lost (signed!) */
    00196         DWORD lastSequenceNumber;   /* extended last sequence number received */
    00197         DWORD jitter;               /* interarrival jitter */
    00198         PTimeInterval lastTimestamp;/* last SR packet from this source */
    00199         PTimeInterval delay;        /* delay since last SR packet */
    00200     };
    00201     PARRAY(ReceiverReportArray, ReceiverReport);
    00202
    00203     class SenderReport : public PObject  {
    00204         PCLASSINFO(SenderReport, PObject);
    00205       public:
    00206         void PrintOn(ostream &) const;
    00207
    00208         DWORD sourceIdentifier;
    00209         PTime realTimestamp;
    00210         DWORD rtpTimestamp;
    00211         DWORD packetsSent;
    00212         DWORD octetsSent;
    00213     };
    00214
    00215     virtual void OnRxSenderReport(const SenderReport & sender,
    00216                                   const ReceiverReportArray & reports);
    00217     virtual void OnRxReceiverReport(DWORD src,
    00218                                     const ReceiverReportArray & reports);
    00219     virtual void OnReceiverReports(const ReceiverReportArray & reports);
    00220
    00221     class SourceDescription : public PObject  {
    00222         PCLASSINFO(SourceDescription, PObject);
    00223       public:
    00224         SourceDescription(DWORD src) { sourceIdentifier = src; }
    00225         void PrintOn(ostream &) const;
    00226
    00227         DWORD            sourceIdentifier;
    00228         POrdinalToString items;
    00229     };
    00230     PARRAY(SourceDescriptionArray, SourceDescription);
    00231     virtual void OnRxSourceDescription(const SourceDescriptionArray & descriptions);
    00232
    00233     virtual void OnRxGoodbye(const PDWORDArray & sources,
    00234                              const PString & reason);
    00235
    00236     virtual void OnRxApplDefined(const PString & type, unsigned subtype, DWORD src,
    00237                                  const BYTE * data, PINDEX size);
    00238
    00239 #if OPAL_RTCP_XR
    00240     class ExtendedReport : public PObject  {
    00241         PCLASSINFO(ExtendedReport, PObject);
    00242       public:
    00243         void PrintOn(ostream &) const;
    00244
    00245         DWORD sourceIdentifier;
    00246         DWORD lossRate;            /* fraction of RTP data packets lost */
    00247         DWORD discardRate;         /* fraction of RTP data packets discarded */
    00248         DWORD burstDensity;        /* fraction of RTP data packets within burst periods */
    00249         DWORD gapDensity;          /* fraction of RTP data packets within inter-burst gaps */
    00250         DWORD roundTripDelay;  /* the most recently calculated round trip time */
    00251         DWORD RFactor;            /* voice quality metric of the call */
    00252         DWORD mosLQ;               /* MOS for listen quality */
    00253         DWORD mosCQ;               /* MOS for conversational quality */
    00254         DWORD jbNominal;      /* current nominal jitter buffer delay, in ms */
    00255         DWORD jbMaximum;      /* current maximum jitter buffer delay, in ms */
    00256         DWORD jbAbsolute;     /* current absolute maximum jitter buffer delay, in ms */
    00257     };
    00258     PARRAY(ExtendedReportArray, ExtendedReport);
    00259
    00260     virtual void OnRxExtendedReport(
    00261       DWORD src,
    00262       const ExtendedReportArray & reports
    00263     );
    00264
    00265     RTCP_XR_Metrics * GetExtendedMetrics() const { return m_metrics; }
    00266 #endif // OPAL_RTCP_XR
    00267
    00268
    00273     bool IsAudio() const { return m_isAudio; }
    00274
    00277     void SetAudio(
    00278       bool aud
    00279     ) { m_isAudio = aud; }
    00280
    00283     PString GetCanonicalName() const;
    00284
    00287     void SetCanonicalName(const PString & name);
    00288
    00291     PString GetToolName() const;
    00292
    00295     void SetToolName(const PString & name);
    00296
    00299     RTPExtensionHeaders GetExtensionHeaders() const;
    00300
    00303     void SetExtensionHeader(const RTPExtensionHeaders & ext);
    00304
    00307     DWORD GetSyncSourceOut() const { return syncSourceOut; }
    00308
    00311     bool AllowAnySyncSource() const { return allowAnySyncSource; }
    00312
    00315     void SetAnySyncSource(
    00316       bool allow
    00317     ) { allowAnySyncSource = allow; }
    00318
    00321     void SetIgnorePayloadTypeChanges(
    00322       bool ignore
    00323     ) { ignorePayloadTypeChanges = ignore; }
    00324
    00327     const PTimeInterval & GetMaxNoReceiveTime() { return m_maxNoReceiveTime; }
    00328
    00331     void SetMaxNoReceiveTime(
    00332       const PTimeInterval & interval
    00333     )  { m_maxNoReceiveTime = interval; }
    00334
    00337     const PTimeInterval & GetMaxNoTransmitTime() { return m_maxNoTransmitTime; }
    00338
    00341     void SetMaxNoTransmitTime(
    00342       const PTimeInterval & interval
    00343     )  { m_maxNoTransmitTime = interval; }
    00344
    00347     const PTimeInterval & GetReportTimeInterval() { return m_reportTimer.GetResetTime(); }
    00348
    00351     void SetReportTimeInterval(
    00352       const PTimeInterval & interval
    00353     )  { m_reportTimer.RunContinuous(interval); }
    00354
    00357     unsigned GetTxStatisticsInterval() { return txStatisticsInterval; }
    00358
    00361     void SetTxStatisticsInterval(
    00362       unsigned packets
    00363     );
    00364
    00367     unsigned GetRxStatisticsInterval() { return rxStatisticsInterval; }
    00368
    00371     void SetRxStatisticsInterval(
    00372       unsigned packets
    00373     );
    00374
    00377     void ClearStatistics();
    00378
    00381     virtual WORD GetLocalDataPort() const { return m_localDataPort; }
    00382
    00385     virtual WORD GetLocalControlPort() const { return m_localControlPort; }
    00386
    00389     virtual WORD GetRemoteDataPort() const { return m_remoteDataPort; }
    00390
    00393     virtual WORD GetRemoteControlPort() const { return m_remoteControlPort; }
    00394
    00397     virtual PUDPSocket & GetDataSocket() { return *m_dataSocket; }
    00398
    00401     virtual PUDPSocket & GetControlSocket() { return *m_controlSocket; }
    00402
    00405     DWORD GetPacketsSent() const { return packetsSent; }
    00406
    00409     DWORD GetOctetsSent() const { return octetsSent; }
    00410
    00413     DWORD GetPacketsReceived() const { return packetsReceived; }
    00414
    00417     DWORD GetOctetsReceived() const { return octetsReceived; }
    00418
    00421     DWORD GetPacketsLost() const { return packetsLost; }
    00422
    00426     DWORD GetPacketsLostByRemote() const { return packetsLostByRemote; }
    00427
    00430     DWORD GetPacketsOutOfOrder() const { return packetsOutOfOrder; }
    00431
    00434     DWORD GetPacketsTooLate() const;
    00435
    00438     DWORD GetPacketOverruns() const;
    00439
    00444     DWORD GetAverageSendTime() const { return averageSendTime; }
    00445
    00450     DWORD GetMarkerRecvCount() const { return markerRecvCount; }
    00451
    00456     DWORD GetMarkerSendCount() const { return markerSendCount; }
    00457
    00462     DWORD GetMaximumSendTime() const { return maximumSendTime; }
    00463
    00468     DWORD GetMinimumSendTime() const { return minimumSendTime; }
    00469
    00474     DWORD GetAverageReceiveTime() const { return averageReceiveTime; }
    00475
    00480     DWORD GetMaximumReceiveTime() const { return maximumReceiveTime; }
    00481
    00486     DWORD GetMinimumReceiveTime() const { return minimumReceiveTime; }
    00487
    00488     enum { JitterRoundingGuardBits = 4 };
    00493     DWORD GetAvgJitterTime() const { return (jitterLevel>>JitterRoundingGuardBits)/GetJitterTimeUnits(); }
    00494
    00498     DWORD GetMaxJitterTime() const { return (maximumJitterLevel>>JitterRoundingGuardBits)/GetJitterTimeUnits(); }
    00499
    00504     DWORD GetJitterTimeOnRemote() const { return jitterLevelOnRemote/GetJitterTimeUnits(); }
    00506
    00507     virtual void SetCloseOnBYE(bool v)  { m_closeOnBye = v; }
    00508
    00511     virtual void SendFlowControl(
    00512       unsigned maxBitRate,
    00513       unsigned overhead = 0,
    00514       bool notify = false
    00515     );
    00516
    00517 #if OPAL_VIDEO
    00518
    00522     virtual void SendIntraFrameRequest(bool rfc2032, bool pictureLoss);
    00523
    00528     virtual void SendTemporalSpatialTradeOff(unsigned tradeOff);
    00529 #endif
    00530
    00531     void SetNextSentSequenceNumber(WORD num) { lastSentSequenceNumber = (WORD)(num-1); }
    00532
    00533     DWORD GetSyncSourceIn() const { return syncSourceIn; }
    00534
    00535     typedef PNotifierTemplate<SendReceiveStatus &> FilterNotifier;
    00536     #define PDECLARE_RTPFilterNotifier(cls, fn) PDECLARE_NOTIFIER2(RTP_DataFrame, cls, fn, OpalRTPSession::SendReceiveStatus &)
    00537     #define PCREATE_RTPFilterNotifier(fn) PCREATE_NOTIFIER2(fn, OpalRTPSession::SendReceiveStatus &)
    00538
    00539     void AddFilter(const FilterNotifier & filter);
    00540
    00541     virtual void SendBYE();
    00542
    00543   protected:
    00544     ReceiverReportArray BuildReceiverReportArray(const RTP_ControlFrame & frame, PINDEX offset);
    00545     void AddReceiverReport(RTP_ControlFrame::ReceiverReport & receiver);
    00546     bool InsertReportPacket(RTP_ControlFrame & report);
    00547     virtual int WaitForPDU(PUDPSocket & dataSocket, PUDPSocket & controlSocket, const PTimeInterval & timer);
    00548     virtual SendReceiveStatus ReadDataPDU(RTP_DataFrame & frame);
    00549     virtual SendReceiveStatus OnReadTimeout(RTP_DataFrame & frame);
    00550
    00551     virtual bool InternalReadData(RTP_DataFrame & frame);
    00552     virtual SendReceiveStatus ReadControlPDU();
    00553     virtual SendReceiveStatus ReadDataOrControlPDU(
    00554       BYTE * framePtr,
    00555       PINDEX frameSize,
    00556       bool fromDataChannel
    00557     );
    00558     virtual bool HandleUnreachable(PTRACE_PARAM(const char * channelName));
    00559     virtual bool WriteDataOrControlPDU(
    00560       const BYTE * framePtr,
    00561       PINDEX frameSize,
    00562       bool toDataChannel
    00563     );
    00564
    00565
    00566     bool                m_isAudio;
    00567     unsigned            m_timeUnits;
    00568     PString             m_canonicalName;
    00569     PString             m_toolName;
    00570     RTPExtensionHeaders m_extensionHeaders;
    00571     PTimeInterval       m_maxNoReceiveTime;
    00572     PTimeInterval       m_maxNoTransmitTime;
    00573
    00574     DWORD         syncSourceOut;
    00575     DWORD         syncSourceIn;
    00576     DWORD         lastSentTimestamp;
    00577     bool          allowAnySyncSource;
    00578     bool          allowOneSyncSourceChange;
    00579     bool          allowRemoteTransmitAddressChange;
    00580     bool          allowSequenceChange;
    00581     unsigned      txStatisticsInterval;
    00582     unsigned      rxStatisticsInterval;
    00583     WORD          lastSentSequenceNumber;
    00584     WORD          expectedSequenceNumber;
    00585     PTimeInterval lastSentPacketTime;
    00586     PTimeInterval lastReceivedPacketTime;
    00587     PTime         lastSRTimestamp;
    00588     PTime         lastSRReceiveTime;
    00589     PTimeInterval delaySinceLastSR;
    00590     WORD          lastRRSequenceNumber;
    00591     bool          resequenceOutOfOrderPackets;
    00592     unsigned      consecutiveOutOfOrderPackets;
    00593     PTimeInterval outOfOrderWaitTime;
    00594     PTimeInterval outOfOrderPacketTime;
    00595
    00596     std::list<RTP_DataFrame> m_outOfOrderPackets;
    00597     void SaveOutOfOrderPacket(RTP_DataFrame & frame);
    00598
    00599     DWORD         timeStampOffs;               // offset between incoming media timestamp and timeStampOut
    00600     bool          oobTimeStampBaseEstablished; // true if timeStampOffs has been established by media
    00601     DWORD         oobTimeStampOutBase;         // base timestamp value for oob data
    00602     PTimeInterval oobTimeStampBase;            // base time for oob timestamp
    00603
    00604     // Statistics
    00605     PTime firstPacketSent;
    00606     DWORD packetsSent;
    00607     DWORD rtcpPacketsSent;
    00608     DWORD octetsSent;
    00609     PTime firstPacketReceived;
    00610     DWORD packetsReceived;
    00611     DWORD senderReportsReceived;
    00612     DWORD octetsReceived;
    00613     DWORD packetsLost;
    00614     DWORD packetsLostByRemote;
    00615     DWORD packetsOutOfOrder;
    00616     DWORD averageSendTime;
    00617     DWORD maximumSendTime;
    00618     DWORD minimumSendTime;
    00619     DWORD averageReceiveTime;
    00620     DWORD maximumReceiveTime;
    00621     DWORD minimumReceiveTime;
    00622     DWORD jitterLevel;
    00623     DWORD jitterLevelOnRemote;
    00624     DWORD maximumJitterLevel;
    00625
    00626     DWORD m_syncTimestamp;
    00627     PTime m_syncRealTime;
    00628
    00629     DWORD markerSendCount;
    00630     DWORD markerRecvCount;
    00631
    00632     unsigned txStatisticsCount;
    00633     unsigned rxStatisticsCount;
    00634
    00635 #if OPAL_RTCP_XR
    00636     // Calculate the VoIP Metrics for RTCP-XR
    00637     RTCP_XR_Metrics * m_metrics;
    00638     friend class RTCP_XR_Metrics;
    00639 #endif
    00640
    00641     DWORD    averageSendTimeAccum;
    00642     DWORD    maximumSendTimeAccum;
    00643     DWORD    minimumSendTimeAccum;
    00644     DWORD    averageReceiveTimeAccum;
    00645     DWORD    maximumReceiveTimeAccum;
    00646     DWORD    minimumReceiveTimeAccum;
    00647     DWORD    packetsLostSinceLastRR;
    00648     DWORD    lastTransitTime;
    00649     DWORD    m_lastReceivedStatisticTimestamp;
    00650
    00651     RTP_DataFrame::PayloadTypes lastReceivedPayloadType;
    00652     bool ignorePayloadTypeChanges;
    00653
    00654     PMutex m_reportMutex;
    00655     PTimer m_reportTimer;
    00656     PDECLARE_NOTIFIER(PTimer, OpalRTPSession, SendReport);
    00657
    00658     PMutex m_dataMutex;
    00659     bool   m_closeOnBye;
    00660     bool   m_byeSent;
    00661
    00662     list<FilterNotifier> m_filters;
    00663
    00664     PIPSocket::Address m_localAddress;
    00665     WORD               m_localDataPort;
    00666     WORD               m_localControlPort;
    00667
    00668     PIPSocket::Address m_remoteAddress;
    00669     WORD               m_remoteDataPort;
    00670     WORD               m_remoteControlPort;
    00671
    00672     PIPSocket::Address m_remoteTransmitAddress;
    00673
    00674     PUDPSocket * m_dataSocket;
    00675     PUDPSocket * m_controlSocket;
    00676
    00677     bool m_shutdownRead;
    00678     bool m_shutdownWrite;
    00679     bool m_remoteBehindNAT;
    00680     bool m_localHasRestrictedNAT;
    00681     bool m_firstControl;
    00682
    00683     DWORD        m_noTransmitErrors;
    00684     PSimpleTimer m_noTransmitTimer;
    00685
    00686     // Make sure JB is last to make sure it is destroyed first.
    00687     typedef PSafePtr<OpalJitterBuffer, PSafePtrMultiThreaded> JitterBufferPtr;
    00688     JitterBufferPtr m_jitterBuffer;
    00689
    00690   private:
    00691     OpalRTPSession(const OpalRTPSession &);
    00692     void operator=(const OpalRTPSession &) { }
    00693
    00694   friend class RTP_JitterBuffer;
    00695 };
    00696
    00697
    00698 #endif // OPAL_RTP_RTP_H
    00699