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 

Generated on 21 Jun 2013 for OPAL by  doxygen 1.4.7