00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
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;
00195 DWORD totalLost;
00196 DWORD lastSequenceNumber;
00197 DWORD jitter;
00198 PTimeInterval lastTimestamp;
00199 PTimeInterval delay;
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;
00247 DWORD discardRate;
00248 DWORD burstDensity;
00249 DWORD gapDensity;
00250 DWORD roundTripDelay;
00251 DWORD RFactor;
00252 DWORD mosLQ;
00253 DWORD mosCQ;
00254 DWORD jbNominal;
00255 DWORD jbMaximum;
00256 DWORD jbAbsolute;
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;
00600 bool oobTimeStampBaseEstablished;
00601 DWORD oobTimeStampOutBase;
00602 PTimeInterval oobTimeStampBase;
00603
00604
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
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
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