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_H
00035 #define OPAL_RTP_RTP_H
00036
00037 #ifdef P_USE_PRAGMA
00038 #pragma interface
00039 #endif
00040
00041 #include <opal/buildopts.h>
00042
00043 #include <ptlib/sockets.h>
00044 #include <ptlib/safecoll.h>
00045
00046 #include <list>
00047
00048
00049 class RTP_JitterBuffer;
00050 class PNatMethod;
00051 class OpalSecurityMode;
00052
00054
00055
00056
00057 class RTP_QOS : public PObject
00058 {
00059 PCLASSINFO(RTP_QOS,PObject);
00060 public:
00061 PQoS dataQoS;
00062 PQoS ctrlQoS;
00063 };
00064
00066
00067
00070 class RTP_DataFrame : public PBYTEArray
00071 {
00072 PCLASSINFO(RTP_DataFrame, PBYTEArray);
00073
00074 public:
00075 RTP_DataFrame(PINDEX payloadSize = 0, PINDEX bufferSize = 0);
00076 RTP_DataFrame(const BYTE * data, PINDEX len, PBoolean dynamic = true);
00077
00078 enum {
00079 ProtocolVersion = 2,
00080 MinHeaderSize = 12,
00081
00082 MaxMtuPayloadSize = (576-20-16-12)
00083 };
00084
00085 enum PayloadTypes {
00086 PCMU,
00087 FS1016,
00088 G721,
00089 G726 = G721,
00090 GSM,
00091 G7231,
00092 DVI4_8k,
00093 DVI4_16k,
00094 LPC,
00095 PCMA,
00096 G722,
00097 L16_Stereo,
00098 L16_Mono,
00099 G723,
00100 CN,
00101 MPA,
00102 G728,
00103 DVI4_11k,
00104 DVI4_22k,
00105 G729,
00106 Cisco_CN,
00107
00108 CelB = 25,
00109 JPEG,
00110 H261 = 31,
00111 MPV,
00112 MP2T,
00113 H263,
00114
00115 T38 = 38,
00116
00117 LastKnownPayloadType,
00118
00119 DynamicBase = 96,
00120 MaxPayloadType = 127,
00121 IllegalPayloadType
00122 };
00123
00124 unsigned GetVersion() const { return (theArray[0]>>6)&3; }
00125
00126 PBoolean GetExtension() const { return (theArray[0]&0x10) != 0; }
00127 void SetExtension(PBoolean ext);
00128
00129 PBoolean GetMarker() const { return (theArray[1]&0x80) != 0; }
00130 void SetMarker(PBoolean m);
00131
00132 bool GetPadding() const { return (theArray[0]&0x20) != 0; }
00133 void SetPadding(bool v) { if (v) theArray[0] |= 0x20; else theArray[0] &= 0xdf; }
00134 BYTE * GetPaddingPtr() const { return (BYTE *)(theArray+m_headerSize+m_payloadSize); }
00135
00136 unsigned GetPaddingSize() const { return m_paddingSize; }
00137 bool SetPaddingSize(PINDEX sz);
00138
00139 PayloadTypes GetPayloadType() const { return (PayloadTypes)(theArray[1]&0x7f); }
00140 void SetPayloadType(PayloadTypes t);
00141
00142 WORD GetSequenceNumber() const { return *(PUInt16b *)&theArray[2]; }
00143 void SetSequenceNumber(WORD n) { *(PUInt16b *)&theArray[2] = n; }
00144
00145 DWORD GetTimestamp() const { return *(PUInt32b *)&theArray[4]; }
00146 void SetTimestamp(DWORD t) { *(PUInt32b *)&theArray[4] = t; }
00147
00148 DWORD GetSyncSource() const { return *(PUInt32b *)&theArray[8]; }
00149 void SetSyncSource(DWORD s) { *(PUInt32b *)&theArray[8] = s; }
00150
00151 PINDEX GetContribSrcCount() const { return theArray[0]&0xf; }
00152 DWORD GetContribSource(PINDEX idx) const;
00153 void SetContribSource(PINDEX idx, DWORD src);
00154
00155 PINDEX GetHeaderSize() const { return m_headerSize; }
00156
00157 int GetExtensionType() const;
00158 void SetExtensionType(int type);
00159 PINDEX GetExtensionSizeDWORDs() const;
00160 bool SetExtensionSizeDWORDs(PINDEX sz);
00161 BYTE * GetExtensionPtr() const;
00162
00163 PINDEX GetPayloadSize() const { return m_payloadSize; }
00164 bool SetPayloadSize(PINDEX sz);
00165 BYTE * GetPayloadPtr() const { return (BYTE *)(theArray+m_headerSize); }
00166
00167 virtual PObject * Clone() const { return new RTP_DataFrame(*this); }
00168 virtual void PrintOn(ostream & strm) const;
00169
00170
00171
00172 bool SetPacketSize(PINDEX sz);
00173
00174 protected:
00175 PINDEX m_headerSize;
00176 PINDEX m_payloadSize;
00177 PINDEX m_paddingSize;
00178
00179 #if PTRACING
00180 friend ostream & operator<<(ostream & o, PayloadTypes t);
00181 #endif
00182 };
00183
00184 PLIST(RTP_DataFrameList, RTP_DataFrame);
00185
00186
00189 class RTP_ControlFrame : public PBYTEArray
00190 {
00191 PCLASSINFO(RTP_ControlFrame, PBYTEArray);
00192
00193 public:
00194 RTP_ControlFrame(PINDEX compoundSize = 2048);
00195
00196 unsigned GetVersion() const { return (BYTE)theArray[compoundOffset]>>6; }
00197
00198 unsigned GetCount() const { return (BYTE)theArray[compoundOffset]&0x1f; }
00199 void SetCount(unsigned count);
00200
00201 enum PayloadTypes {
00202 e_IntraFrameRequest = 192,
00203 e_SenderReport = 200,
00204 e_ReceiverReport,
00205 e_SourceDescription,
00206 e_Goodbye,
00207 e_ApplDefined,
00208 e_TransportLayerFeedBack,
00209 e_PayloadSpecificFeedBack
00210 };
00211
00212 unsigned GetPayloadType() const { return (BYTE)theArray[compoundOffset+1]; }
00213 void SetPayloadType(unsigned t);
00214
00215 PINDEX GetPayloadSize() const { return 4*(*(PUInt16b *)&theArray[compoundOffset+2]); }
00216 void SetPayloadSize(PINDEX sz);
00217
00218 BYTE * GetPayloadPtr() const;
00219
00220 PBoolean ReadNextPacket();
00221 PBoolean StartNewPacket();
00222 void EndPacket();
00223
00224 PINDEX GetCompoundSize() const;
00225
00226 void Reset(PINDEX size);
00227
00228 #pragma pack(1)
00229 struct ReceiverReport {
00230 PUInt32b ssrc;
00231 BYTE fraction;
00232 BYTE lost[3];
00233 PUInt32b last_seq;
00234 PUInt32b jitter;
00235 PUInt32b lsr;
00236 PUInt32b dlsr;
00237
00238 unsigned GetLostPackets() const { return (lost[0]<<16U)+(lost[1]<<8U)+lost[2]; }
00239 void SetLostPackets(unsigned lost);
00240 };
00241
00242 struct SenderReport {
00243 PUInt32b ntp_sec;
00244 PUInt32b ntp_frac;
00245 PUInt32b rtp_ts;
00246 PUInt32b psent;
00247 PUInt32b osent;
00248 };
00249
00250 enum DescriptionTypes {
00251 e_END,
00252 e_CNAME,
00253 e_NAME,
00254 e_EMAIL,
00255 e_PHONE,
00256 e_LOC,
00257 e_TOOL,
00258 e_NOTE,
00259 e_PRIV,
00260 NumDescriptionTypes
00261 };
00262
00263 struct SourceDescription {
00264 PUInt32b src;
00265 struct Item {
00266 BYTE type;
00267 BYTE length;
00268 char data[1];
00269
00270
00271
00272
00273
00274 unsigned int GetLengthTotal() const {return (unsigned int)(length + 2);}
00275 const Item * GetNextItem() const { return (const Item *)((char *)this + length + 2); }
00276 Item * GetNextItem() { return (Item *)((char *)this + length + 2); }
00277 } item[1];
00278 };
00279
00280 void StartSourceDescription(
00281 DWORD src
00282 );
00283
00284 void AddSourceDescriptionItem(
00285 unsigned type,
00286 const PString & data
00287 );
00288
00289
00290 unsigned GetFbType() const { return (BYTE)theArray[compoundOffset]&0x1f; }
00291 void SetFbType(unsigned type, PINDEX fciSize);
00292
00293 enum PayloadSpecificFbTypes {
00294 e_PictureLossIndication = 1,
00295 e_SliceLostIndication,
00296 e_ReferencePictureSelectionIndication,
00297 e_FullIntraRequest,
00298 e_TemporalSpatialTradeOffRequest,
00299 e_TemporalSpatialTradeOffNotification,
00300 e_VideoBackChannelMessage,
00301 e_ApplicationLayerFbMessage = 15
00302 };
00303
00304 struct FbFCI {
00305 PUInt32b senderSSRC;
00306 PUInt32b mediaSSRC;
00307 };
00308
00309 struct FbFIR {
00310 FbFCI fci;
00311 PUInt32b requestSSRC;
00312 BYTE sequenceNUmber;
00313 };
00314
00315 struct FbTSTO {
00316 FbFCI fci;
00317 PUInt32b requestSSRC;
00318 BYTE sequenceNUmber;
00319 BYTE reserver[2];
00320 BYTE tradeOff;
00321 };
00322
00323 #pragma pack()
00324
00325 protected:
00326 PINDEX compoundOffset;
00327 PINDEX payloadSize;
00328 };
00329
00330
00331 class RTP_Session;
00332
00334
00335 #if OPAL_STATISTICS
00336
00339 class OpalMediaStatistics : public PObject
00340 {
00341 PCLASSINFO(OpalMediaStatistics, PObject);
00342 public:
00343 OpalMediaStatistics();
00344
00345
00346 PUInt64 m_totalBytes;
00347 unsigned m_totalPackets;
00348 unsigned m_packetsLost;
00349 unsigned m_packetsOutOfOrder;
00350 unsigned m_packetsTooLate;
00351 unsigned m_packetOverruns;
00352 unsigned m_minimumPacketTime;
00353 unsigned m_averagePacketTime;
00354 unsigned m_maximumPacketTime;
00355
00356
00357 unsigned m_averageJitter;
00358 unsigned m_maximumJitter;
00359
00360
00361 unsigned m_totalFrames;
00362 unsigned m_keyFrames;
00363
00364
00365 #if OPAL_FAX
00366 enum {
00367 FaxNotStarted = -2,
00368 FaxInProgress = -1,
00369 FaxSuccessful = 0,
00370 FaxErrorBase = 1
00371 };
00372 struct Fax {
00373 Fax();
00374
00375 int m_result;
00376 int m_bitRate;
00377 int m_compression;
00378 bool m_errorCorrection;
00379 int m_txPages;
00380 int m_rxPages;
00381 int m_totalPages;
00382 int m_imageSize;
00383 int m_resolutionX;
00384 int m_resolutionY;
00385 int m_pageWidth;
00386 int m_pageHeight;
00387 int m_badRows;
00388 int m_mostBadRows;
00389 int m_errorCorrectionRetries;
00390
00391 PString m_errorText;
00392 } m_fax;
00393 #endif
00394 };
00395
00396 #endif
00397
00398
00403 class RTP_UserData : public PObject
00404 {
00405 PCLASSINFO(RTP_UserData, PObject);
00406
00407 public:
00414 virtual void OnTxStatistics(
00415 const RTP_Session & session
00416 ) const;
00417
00424 virtual void OnRxStatistics(
00425 const RTP_Session & session
00426 ) const;
00427
00428 #if OPAL_VIDEO
00429
00434 virtual void OnTxIntraFrameRequest(
00435 const RTP_Session & session
00436 ) const;
00437
00443 virtual void OnRxIntraFrameRequest(
00444 const RTP_Session & session
00445 ) const;
00446 #endif
00447
00451 virtual void SessionFailing(
00452 RTP_Session & session
00453 );
00454 };
00455
00456 class RTP_Encoding;
00457
00458
00461 class RTP_Session : public PObject
00462 {
00463 PCLASSINFO(RTP_Session, PObject);
00464
00465 public:
00468 struct Params {
00469 Params()
00470 : id(0)
00471 , userData(NULL)
00472 , autoDelete(true)
00473 , isAudio(false)
00474 , remoteIsNAT(false)
00475 { }
00476
00477 PString encoding;
00478 unsigned id;
00479 RTP_UserData * userData;
00480 bool autoDelete;
00481 bool isAudio;
00482 bool remoteIsNAT;
00483 };
00484
00487 RTP_Session(
00488 const Params & options
00489 );
00490
00494 ~RTP_Session();
00496
00506 void SetJitterBufferSize(
00507 unsigned minJitterDelay,
00508 unsigned maxJitterDelay,
00509 unsigned timeUnits = 0,
00510 PINDEX packetSize = 2048
00511 );
00512
00518 unsigned GetJitterBufferSize() const;
00519
00522 unsigned GetJitterTimeUnits() const { return m_timeUnits; }
00523
00525 virtual PBoolean ModifyQOS(RTP_QOS * )
00526 { return false; }
00527
00533 virtual PBoolean ReadBufferedData(
00534 RTP_DataFrame & frame
00535 );
00536
00542 virtual PBoolean ReadData(
00543 RTP_DataFrame & frame
00544 ) = 0;
00545
00548 virtual PBoolean WriteData(
00549 RTP_DataFrame & frame
00550 ) = 0;
00551
00555 virtual PBoolean WriteOOBData(
00556 RTP_DataFrame & frame,
00557 bool rewriteTimeStamp = true
00558 );
00559
00562 virtual PBoolean WriteControl(
00563 RTP_ControlFrame & frame
00564 ) = 0;
00565
00568 virtual PBoolean SendReport();
00569
00572 virtual bool Close(
00573 PBoolean reading
00574 ) = 0;
00575
00578 virtual void Reopen(
00579 PBoolean isReading
00580 ) = 0;
00581
00584 virtual PString GetLocalHostName() = 0;
00585
00586 #if OPAL_STATISTICS
00587 virtual void GetStatistics(OpalMediaStatistics & statistics, bool receiver) const;
00588 #endif
00589
00590
00593 enum SendReceiveStatus {
00594 e_ProcessPacket,
00595 e_IgnorePacket,
00596 e_AbortTransport
00597 };
00598 virtual SendReceiveStatus OnSendData(RTP_DataFrame & frame);
00599 virtual SendReceiveStatus Internal_OnSendData(RTP_DataFrame & frame);
00600
00601 virtual SendReceiveStatus OnSendControl(RTP_ControlFrame & frame, PINDEX & len);
00602 virtual SendReceiveStatus Internal_OnSendControl(RTP_ControlFrame & frame, PINDEX & len);
00603
00604 virtual SendReceiveStatus OnReceiveData(RTP_DataFrame & frame);
00605 virtual SendReceiveStatus Internal_OnReceiveData(RTP_DataFrame & frame);
00606
00607 virtual SendReceiveStatus OnReceiveControl(RTP_ControlFrame & frame);
00608
00609 class ReceiverReport : public PObject {
00610 PCLASSINFO(ReceiverReport, PObject);
00611 public:
00612 void PrintOn(ostream &) const;
00613
00614 DWORD sourceIdentifier;
00615 DWORD fractionLost;
00616 DWORD totalLost;
00617 DWORD lastSequenceNumber;
00618 DWORD jitter;
00619 PTimeInterval lastTimestamp;
00620 PTimeInterval delay;
00621 };
00622 PARRAY(ReceiverReportArray, ReceiverReport);
00623
00624 class SenderReport : public PObject {
00625 PCLASSINFO(SenderReport, PObject);
00626 public:
00627 void PrintOn(ostream &) const;
00628
00629 DWORD sourceIdentifier;
00630 PTime realTimestamp;
00631 DWORD rtpTimestamp;
00632 DWORD packetsSent;
00633 DWORD octetsSent;
00634 };
00635 virtual void OnRxSenderReport(const SenderReport & sender,
00636 const ReceiverReportArray & reports);
00637 virtual void OnRxReceiverReport(DWORD src,
00638 const ReceiverReportArray & reports);
00639 virtual void OnReceiverReports(const ReceiverReportArray & reports);
00640
00641 class SourceDescription : public PObject {
00642 PCLASSINFO(SourceDescription, PObject);
00643 public:
00644 SourceDescription(DWORD src) { sourceIdentifier = src; }
00645 void PrintOn(ostream &) const;
00646
00647 DWORD sourceIdentifier;
00648 POrdinalToString items;
00649 };
00650 PARRAY(SourceDescriptionArray, SourceDescription);
00651 virtual void OnRxSourceDescription(const SourceDescriptionArray & descriptions);
00652
00653 virtual void OnRxGoodbye(const PDWORDArray & sources,
00654 const PString & reason);
00655
00656 virtual void OnRxApplDefined(const PString & type, unsigned subtype, DWORD src,
00657 const BYTE * data, PINDEX size);
00659
00664 unsigned GetSessionID() const { return sessionID; }
00665
00668 void SetSessionID(unsigned id) { sessionID = id; }
00669
00672 bool IsAudio() const { return isAudio; }
00673
00676 void SetAudio(
00677 bool aud
00678 ) { isAudio = aud; }
00679
00682 PString GetCanonicalName() const;
00683
00686 void SetCanonicalName(const PString & name);
00687
00690 PString GetToolName() const;
00691
00694 void SetToolName(const PString & name);
00695
00698 RTP_UserData * GetUserData() const { return userData; }
00699
00702 void SetUserData(
00703 RTP_UserData * data,
00704 PBoolean autoDeleteUserData = true
00705 );
00706
00709 DWORD GetSyncSourceOut() const { return syncSourceOut; }
00710
00713 bool AllowAnySyncSource() const { return allowAnySyncSource; }
00714
00717 void SetAnySyncSource(
00718 bool allow
00719 ) { allowAnySyncSource = allow; }
00720
00723 void SetIgnorePayloadTypeChanges(
00724 PBoolean ignore
00725 ) { ignorePayloadTypeChanges = ignore; }
00726
00729 const PTimeInterval & GetReportTimeInterval() { return reportTimeInterval; }
00730
00733 void SetReportTimeInterval(
00734 const PTimeInterval & interval
00735 ) { reportTimeInterval = interval; }
00736
00739 PTimeInterval GetReportTimer()
00740 { return reportTimer; }
00741
00744 unsigned GetTxStatisticsInterval() { return txStatisticsInterval; }
00745
00748 void SetTxStatisticsInterval(
00749 unsigned packets
00750 );
00751
00754 unsigned GetRxStatisticsInterval() { return rxStatisticsInterval; }
00755
00758 void SetRxStatisticsInterval(
00759 unsigned packets
00760 );
00761
00764 void ClearStatistics();
00765
00768 DWORD GetPacketsSent() const { return packetsSent; }
00769
00772 DWORD GetOctetsSent() const { return octetsSent; }
00773
00776 DWORD GetPacketsReceived() const { return packetsReceived; }
00777
00780 DWORD GetOctetsReceived() const { return octetsReceived; }
00781
00784 DWORD GetPacketsLost() const { return packetsLost; }
00785
00789 DWORD GetPacketsLostByRemote() const { return packetsLostByRemote; }
00790
00793 DWORD GetPacketsOutOfOrder() const { return packetsOutOfOrder; }
00794
00797 DWORD GetPacketsTooLate() const;
00798
00801 DWORD GetPacketOverruns() const;
00802
00807 DWORD GetAverageSendTime() const { return averageSendTime; }
00808
00813 DWORD GetMarkerRecvCount() const { return markerRecvCount; }
00814
00819 DWORD GetMarkerSendCount() const { return markerSendCount; }
00820
00825 DWORD GetMaximumSendTime() const { return maximumSendTime; }
00826
00831 DWORD GetMinimumSendTime() const { return minimumSendTime; }
00832
00837 DWORD GetAverageReceiveTime() const { return averageReceiveTime; }
00838
00843 DWORD GetMaximumReceiveTime() const { return maximumReceiveTime; }
00844
00849 DWORD GetMinimumReceiveTime() const { return minimumReceiveTime; }
00850
00851 enum { JitterRoundingGuardBits = 4 };
00856 DWORD GetAvgJitterTime() const { return (jitterLevel>>JitterRoundingGuardBits)/GetJitterTimeUnits(); }
00857
00861 DWORD GetMaxJitterTime() const { return (maximumJitterLevel>>JitterRoundingGuardBits)/GetJitterTimeUnits(); }
00862
00867 DWORD GetJitterTimeOnRemote() const { return jitterLevelOnRemote/GetJitterTimeUnits(); }
00869
00870 virtual void SetCloseOnBYE(PBoolean v) { closeOnBye = v; }
00871
00876 virtual void SendIntraFrameRequest(bool rfc2032, bool pictureLoss);
00877
00882 virtual void SendTemporalSpatialTradeOff(unsigned tradeOff);
00883
00884 void SetNextSentSequenceNumber(WORD num) { lastSentSequenceNumber = (WORD)(num-1); }
00885
00886 virtual PString GetEncoding() const { return m_encoding; }
00887 virtual void SetEncoding(const PString & newEncoding);
00888
00889 DWORD GetSyncSourceIn() const { return syncSourceIn; }
00890
00891 class EncodingLock
00892 {
00893 public:
00894 EncodingLock(RTP_Session & _session);
00895 ~EncodingLock();
00896
00897 __inline RTP_Encoding * operator->() const { return m_encodingHandler; }
00898
00899 protected:
00900 RTP_Session & session;
00901 RTP_Encoding * m_encodingHandler;
00902 };
00903
00904 friend class EncodingLock;
00905
00906 void SetFailed(bool v)
00907 { failed = v; }
00908
00909 bool HasFailed() const
00910 { return failed; }
00911
00912 void AddFilter(const PNotifier & filter);
00913
00914 protected:
00915 virtual void SendBYE();
00916 void AddReceiverReport(RTP_ControlFrame::ReceiverReport & receiver);
00917 PBoolean InsertReportPacket(RTP_ControlFrame & report);
00918
00919 PString m_encoding;
00920 PMutex m_encodingMutex;
00921 RTP_Encoding * m_encodingHandler;
00922
00923 unsigned sessionID;
00924 bool isAudio;
00925 unsigned m_timeUnits;
00926 PString canonicalName;
00927 PString toolName;
00928 RTP_UserData * userData;
00929 PBoolean autoDeleteUserData;
00930
00931 typedef PSafePtr<RTP_JitterBuffer, PSafePtrMultiThreaded> JitterBufferPtr;
00932 JitterBufferPtr m_jitterBuffer;
00933
00934 DWORD syncSourceOut;
00935 DWORD syncSourceIn;
00936 DWORD lastSentTimestamp;
00937 bool allowAnySyncSource;
00938 bool allowOneSyncSourceChange;
00939 PBoolean allowRemoteTransmitAddressChange;
00940 PBoolean allowSequenceChange;
00941 PTimeInterval reportTimeInterval;
00942 unsigned txStatisticsInterval;
00943 unsigned rxStatisticsInterval;
00944 WORD lastSentSequenceNumber;
00945 WORD expectedSequenceNumber;
00946 PTimeInterval lastSentPacketTime;
00947 PTimeInterval lastReceivedPacketTime;
00948 WORD lastRRSequenceNumber;
00949 bool resequenceOutOfOrderPackets;
00950 unsigned consecutiveOutOfOrderPackets;
00951 PTimeInterval outOfOrderPacketTime;
00952
00953 std::list<RTP_DataFrame> m_outOfOrderPackets;
00954 void SaveOutOfOrderPacket(RTP_DataFrame & frame);
00955
00956 PMutex dataMutex;
00957 DWORD timeStampOffs;
00958 PBoolean oobTimeStampBaseEstablished;
00959 DWORD oobTimeStampOutBase;
00960 PTimeInterval oobTimeStampBase;
00961
00962
00963 DWORD packetsSent;
00964 DWORD rtcpPacketsSent;
00965 DWORD octetsSent;
00966 DWORD packetsReceived;
00967 DWORD octetsReceived;
00968 DWORD packetsLost;
00969 DWORD packetsLostByRemote;
00970 DWORD packetsOutOfOrder;
00971 DWORD averageSendTime;
00972 DWORD maximumSendTime;
00973 DWORD minimumSendTime;
00974 DWORD averageReceiveTime;
00975 DWORD maximumReceiveTime;
00976 DWORD minimumReceiveTime;
00977 DWORD jitterLevel;
00978 DWORD jitterLevelOnRemote;
00979 DWORD maximumJitterLevel;
00980
00981 DWORD markerSendCount;
00982 DWORD markerRecvCount;
00983
00984 unsigned txStatisticsCount;
00985 unsigned rxStatisticsCount;
00986
00987 DWORD averageSendTimeAccum;
00988 DWORD maximumSendTimeAccum;
00989 DWORD minimumSendTimeAccum;
00990 DWORD averageReceiveTimeAccum;
00991 DWORD maximumReceiveTimeAccum;
00992 DWORD minimumReceiveTimeAccum;
00993 DWORD packetsLostSinceLastRR;
00994 DWORD lastTransitTime;
00995
00996 RTP_DataFrame::PayloadTypes lastReceivedPayloadType;
00997 PBoolean ignorePayloadTypeChanges;
00998
00999 PMutex reportMutex;
01000 PTimer reportTimer;
01001
01002 PBoolean closeOnBye;
01003 PBoolean byeSent;
01004 bool failed;
01005
01006 class Filter : public PObject {
01007 PCLASSINFO(Filter, PObject);
01008 public:
01009 Filter(const PNotifier & n) : notifier(n) { }
01010 PNotifier notifier;
01011 };
01012 PList<Filter> filters;
01013 };
01014
01017 class RTP_UDP : public RTP_Session
01018 {
01019 PCLASSINFO(RTP_UDP, RTP_Session);
01020
01021 public:
01026 RTP_UDP(
01027 const Params & options
01028 );
01029
01031 ~RTP_UDP();
01033
01041 virtual PBoolean ReadData(RTP_DataFrame & frame);
01042 virtual PBoolean Internal_ReadData(RTP_DataFrame & frame);
01043
01046 virtual PBoolean WriteData(RTP_DataFrame & frame);
01047 virtual PBoolean Internal_WriteData(RTP_DataFrame & frame);
01048
01052 virtual PBoolean WriteOOBData(RTP_DataFrame & frame, bool setTimeStamp = true);
01053
01056 virtual PBoolean WriteControl(RTP_ControlFrame & frame);
01057
01060 virtual bool Close(
01061 PBoolean reading
01062 );
01063
01066 virtual PString GetLocalHostName();
01068
01071 virtual PBoolean ModifyQOS(RTP_QOS * rtpqos);
01072
01077 virtual PBoolean Open(
01078 PIPSocket::Address localAddress,
01079 WORD portBase,
01080 WORD portMax,
01081 BYTE ipTypeOfService,
01082 PNatMethod * natMethod = NULL,
01083 RTP_QOS * rtpqos = NULL
01084 );
01086
01089 virtual void Reopen(PBoolean isReading);
01091
01096 virtual PIPSocket::Address GetLocalAddress() const { return localAddress; }
01097
01100 virtual void SetLocalAddress(
01101 const PIPSocket::Address & addr
01102 ) { localAddress = addr; }
01103
01106 PIPSocket::Address GetRemoteAddress() const { return remoteAddress; }
01107
01110 virtual WORD GetLocalDataPort() const { return localDataPort; }
01111
01114 virtual WORD GetLocalControlPort() const { return localControlPort; }
01115
01118 virtual WORD GetRemoteDataPort() const { return remoteDataPort; }
01119
01122 virtual WORD GetRemoteControlPort() const { return remoteControlPort; }
01123
01126 virtual PUDPSocket & GetDataSocket() { return *dataSocket; }
01127
01130 virtual PUDPSocket & GetControlSocket() { return *controlSocket; }
01131
01134 virtual PBoolean SetRemoteSocketInfo(
01135 PIPSocket::Address address,
01136 WORD port,
01137 PBoolean isDataPort
01138 );
01139
01142 virtual void ApplyQOS(
01143 const PIPSocket::Address & addr
01144 );
01146
01147 virtual int GetDataSocketHandle() const
01148 { return dataSocket != NULL ? dataSocket->GetHandle() : -1; }
01149
01150 virtual int GetControlSocketHandle() const
01151 { return controlSocket != NULL ? controlSocket->GetHandle() : -1; }
01152
01153 friend class RTP_Encoding;
01154
01155 virtual int WaitForPDU(PUDPSocket & dataSocket, PUDPSocket & controlSocket, const PTimeInterval & timer);
01156 virtual int Internal_WaitForPDU(PUDPSocket & dataSocket, PUDPSocket & controlSocket, const PTimeInterval & timer);
01157
01158 virtual SendReceiveStatus ReadDataPDU(RTP_DataFrame & frame);
01159 virtual SendReceiveStatus Internal_ReadDataPDU(RTP_DataFrame & frame);
01160
01161 virtual SendReceiveStatus OnReadTimeout(RTP_DataFrame & frame);
01162 virtual SendReceiveStatus Internal_OnReadTimeout(RTP_DataFrame & frame);
01163
01164 virtual SendReceiveStatus ReadControlPDU();
01165 virtual SendReceiveStatus ReadDataOrControlPDU(
01166 BYTE * framePtr,
01167 PINDEX frameSize,
01168 PBoolean fromDataChannel
01169 );
01170
01171 virtual bool WriteDataPDU(RTP_DataFrame & frame);
01172 virtual bool WriteDataOrControlPDU(
01173 const BYTE * framePtr,
01174 PINDEX frameSize,
01175 bool toDataChannel
01176 );
01177
01178 virtual void SetEncoding(const PString & newEncoding);
01179
01180
01181 protected:
01182 PIPSocket::Address localAddress;
01183 WORD localDataPort;
01184 WORD localControlPort;
01185
01186 PIPSocket::Address remoteAddress;
01187 WORD remoteDataPort;
01188 WORD remoteControlPort;
01189
01190 PIPSocket::Address remoteTransmitAddress;
01191
01192 PUDPSocket * dataSocket;
01193 PUDPSocket * controlSocket;
01194
01195 bool shutdownRead;
01196 bool shutdownWrite;
01197 bool appliedQOS;
01198 bool remoteIsNAT;
01199 bool localHasNAT;
01200 bool first;
01201 int badTransmitCounter;
01202 PTime badTransmitStart;
01203
01204 PTimer timerWriteDataIdle;
01205 PDECLARE_NOTIFIER(PTimer, RTP_UDP, OnWriteDataIdle);
01206 };
01207
01209
01210 class RTP_UDP;
01211
01212 class RTP_Encoding
01213 {
01214 public:
01215 RTP_Encoding();
01216 virtual ~RTP_Encoding();
01217 virtual void ApplyStringOptions(const PStringToString & ) {}
01218 virtual void OnStart(RTP_Session & _rtpSession);
01219 virtual void OnFinish();
01220 virtual RTP_Session::SendReceiveStatus OnSendData(RTP_DataFrame & frame);
01221 virtual PBoolean WriteData(RTP_DataFrame & frame, bool oob);
01222 virtual PBoolean WriteDataPDU(RTP_DataFrame & frame);
01223 virtual void OnWriteDataIdle() {}
01224 virtual void SetWriteDataIdleTimer(PTimer &) {}
01225 virtual RTP_Session::SendReceiveStatus OnSendControl(RTP_ControlFrame & frame, PINDEX & len);
01226 virtual RTP_Session::SendReceiveStatus ReadDataPDU(RTP_DataFrame & frame);
01227 virtual RTP_Session::SendReceiveStatus OnReceiveData(RTP_DataFrame & frame);
01228 virtual RTP_Session::SendReceiveStatus OnReadTimeout(RTP_DataFrame & frame);
01229 virtual PBoolean ReadData(RTP_DataFrame & frame);
01230 virtual int WaitForPDU(PUDPSocket & dataSocket, PUDPSocket & controlSocket, const PTimeInterval &);
01231
01232 PMutex mutex;
01233 unsigned refCount;
01234
01235 protected:
01236 RTP_UDP * rtpUDP;
01237 };
01238
01239 PFACTORY_LOAD(RTP_Encoding);
01240
01241
01243
01244 class SecureRTP_UDP : public RTP_UDP
01245 {
01246 PCLASSINFO(SecureRTP_UDP, RTP_UDP);
01247
01248 public:
01253 SecureRTP_UDP(
01254 const Params & options
01255 );
01256
01258 ~SecureRTP_UDP();
01259
01260 virtual void SetSecurityMode(OpalSecurityMode * srtpParms);
01261 virtual OpalSecurityMode * GetSecurityParms() const;
01262
01263 protected:
01264 OpalSecurityMode * securityParms;
01265 };
01266
01267 #endif // OPAL_RTP_RTP_H
01268