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
00035
00036
00037
00038
00039
00040
00047 #ifndef __CCXX_RTP_H__
00048 #define __CCXX_RTP_H__
00049
00050 #ifndef __CCXX_SOCKET_H__
00051 #include <cc++/socket.h>
00052 #endif
00053
00054 #ifdef __NAMESPACES__
00055 namespace ost {
00056 #endif
00057
00058
00059 const uint8 RTP_VERSION = 2;
00060
00061
00062 typedef uint32 microtimeout_t;
00063
00064
00065 typedef uint32 nanotimeout_t;
00066
00067 struct RTCPPacket;
00068 struct SenderInfo;
00069 struct ReceiverInfo;
00070
00083 typedef enum
00084 {
00085 RTP_PAYLOAD_PCMU = 0,
00086 RTP_PAYLOAD_1016,
00087 RTP_PAYLOAD_G726,
00088 RTP_PAYLOAD_GSM,
00089 RTP_PAYLOAD_G723,
00090 RTP_PAYLOAD_DVI4_8000,
00091 RTP_PAYLOAD_DVI4_16000,
00092 RTP_PAYLOAD_LPC,
00093 RTP_PAYLOAD_PCMA,
00094 RTP_PAYLOAD_G722,
00095 RTP_PAYLOAD_L16_DUAL,
00096 RTP_PAYLOAD_L16_MONO,
00097 RTP_PAYLOAD_QCELP,
00098 RTP_PAYLOAD_MPA = 14,
00099 RTP_PAYLOAD_G728,
00100 RTP_PAYLOAD_DVI4_11025,
00101 RTP_PAYLOAD_DVI4_22050,
00102 RTP_PAYLOAD_G729,
00103 RTP_PAYLOAD_CELB = 25,
00104 RTP_PAYLOAD_JPEG,
00105 RTP_PAYLOAD_NV = 28,
00106 RTP_PAYLOAD_H261 = 31,
00107 RTP_PAYLOAD_MPV,
00108 RTP_PAYLOAD_MP2T,
00109 RTP_PAYLOAD_H263,
00110 RTP_PAYLOAD_INVALID = 128,
00111
00112 RTP_PAYLOAD_G726_40,
00113 RTP_PAYLOAD_G726_24,
00114 RTP_PAYLOAD_G726_16,
00115 RTP_PAYLOAD_G729D,
00116 RTP_PAYLOAD_G729E,
00117 RTP_PAYLOAD_GSM_EFR,
00118 RTP_PAYLOAD_L8,
00119 RTP_PAYLOAD_RED,
00120 RTP_PAYLOAD_VDVI,
00121 RTP_PAYLOAD_BT656,
00122 RTP_PAYLOAD_H263_1998,
00123 RTP_PAYLOAD_MP1S,
00124 RTP_PAYLOAD_MP2P,
00125 RTP_PAYLOAD_BMPEG,
00126 RTP_PAYLOAD_EMPTY
00127 } rtp_payload_t;
00128
00134 typedef enum
00135 {
00136 RTCP_TYPE_SR = 200,
00137 RTCP_TYPE_RR,
00138 RTCP_TYPE_SDES,
00139 RTCP_TYPE_BYE,
00140 RTCP_TYPE_APP
00141 } rtcp_type_t;
00142
00150 typedef enum
00151 {
00152 RTCP_SDES_ITEM_END = 0,
00153 RTCP_SDES_ITEM_CNAME,
00154 RTCP_SDES_ITEM_NAME,
00155 RTCP_SDES_ITEM_EMAIL,
00156 RTCP_SDES_ITEM_PHONE,
00157 RTCP_SDES_ITEM_LOC,
00158 RTCP_SDES_ITEM_TOOL,
00159 RTCP_SDES_ITEM_NOTE,
00160 RTCP_SDES_ITEM_PRIV,
00161 RTCP_SDES_ITEM_H323_CADDR,
00162 } sdes_item_type_t;
00163
00182 typedef enum
00183 {
00184 BEST_EFFORT_SERVICE,
00185 ENHANCED_SERVICE
00186 } type_of_service_t;
00187
00196 typedef enum
00197 {
00198 RTP_PURGE_SEND,
00199 RTP_PURGE_RECV,
00200 RTP_PURGE_BOTH
00201 } rtp_purge_t;
00202
00203 typedef enum {
00204 CAST_MCAST,
00205 CAST_UCAST
00206 } rtp_cast_t;
00207
00208 class CCXX_CLASS_EXPORT IncomingRTPPkt;
00209 class CCXX_CLASS_EXPORT OutgoingRTPPkt;
00210 class CCXX_CLASS_EXPORT RTPQueue;
00211 class CCXX_CLASS_EXPORT QueueRTCPManager;
00212 class CCXX_CLASS_EXPORT RTPSource;
00213
00226 class CCXX_CLASS_EXPORT RTPData
00227 {
00228
00229 public:
00233 RTPData(const RTPData& origin);
00234
00241 RTPData&
00242 operator=(const RTPData& source);
00243
00244 inline const unsigned char*
00245 getData() const
00246 { return datablock->data; };
00247
00248 inline size_t
00249 getSize() const
00250 { return datablock->size; };
00251
00252 inline rtp_payload_t
00253 getPayloadType() const
00254 { return datablock->pt; }
00255
00256 protected:
00257
00258 RTPData(IncomingRTPPkt& packet);
00259
00260 ~RTPData();
00261
00262 private:
00263
00264 struct dataCounter {
00265 uint16 count;
00266 const unsigned char* data;
00267 const size_t size;
00268 rtp_payload_t pt;
00269 dataCounter(const unsigned char* data, size_t size, rtp_payload_t pt);
00270 ~dataCounter();
00271 };
00272
00273 mutable dataCounter* datablock;
00274
00275
00276
00277
00278 RTPSource* src;
00279
00280 friend RTPQueue;
00281 };
00282
00298 class CCXX_CLASS_EXPORT RTPSource
00299 {
00300
00301 public:
00302 uint32 getID() const
00303 { return ssrc; };
00304
00310 uint32
00311 getRate() const;
00312
00326 inline void
00327 setKitchenSize(microtimeout_t s)
00328 { kitchensize = ((s / 1000) * getRate() / 1000); };
00329
00335 inline microtimeout_t
00336 getKitchenDuration() const
00337 { return (((kitchensize * 1000) / getRate())* 1000); };
00338
00339 inline uint32
00340 getKitchenSize() const
00341 { return kitchensize; };
00342
00351 inline microtimeout_t
00352 getCurrentKitchenDuration()
00353 { return (((currentkitchen * 1000) / getRate())* 1000); };
00354
00355 inline microtimeout_t
00356 getCurrentKitchenSize()
00357 { return currentkitchen;};
00358
00359 const char* const
00360 getSDESItem(sdes_item_type_t type) const;
00361
00362 inline const char* const
00363 getCNAME() const
00364 { return getSDESItem(RTCP_SDES_ITEM_CNAME); };
00365
00366 inline const char* const
00367 getNAME() const
00368 { return getSDESItem(RTCP_SDES_ITEM_NAME); };
00369
00370 inline const char* const
00371 getEMAIL() const
00372 { return getSDESItem(RTCP_SDES_ITEM_EMAIL); };
00373
00374 inline const char* const
00375 getPHONE() const
00376 { return getSDESItem(RTCP_SDES_ITEM_PHONE); };
00377
00378 inline const char* const
00379 getLOC() const
00380 { return getSDESItem(RTCP_SDES_ITEM_LOC); };
00381
00382 inline const char* const
00383 getTOOL() const
00384 { return getSDESItem(RTCP_SDES_ITEM_TOOL); };
00385
00386 inline const char* const
00387 getNOTE() const
00388 { return getSDESItem(RTCP_SDES_ITEM_NOTE); };
00389
00390 inline const char* const
00391 getPRIV() const
00392 { return getSDESItem(RTCP_SDES_ITEM_PRIV); };
00393
00394 inline const char* const
00395 getH323_CADDR() const
00396 { return getSDESItem(RTCP_SDES_ITEM_H323_CADDR); };
00397
00401 inline bool
00402 isSender() const
00403 { return active_sender; };
00404
00405 bool isValid() const
00406 { return valid; };
00407
00408 inline bool
00409 operator==(const RTPSource &rhs) const
00410 { return (this == &rhs); }
00411
00412 inline bool
00413 operator!=(const RTPSource &rhs) const
00414 { return !(*this == rhs); }
00415
00419 RTPSource(uint32 ssrc);
00420
00424 ~RTPSource();
00425
00429 RTPSource(const RTPSource& origin);
00430
00431 RTPSource&
00432 operator=(const RTPSource &origin);
00433
00434 protected:
00435
00436 private:
00444 inline void
00445 setCurrentKitchenSize(uint32 s)
00446 { currentkitchen = s; };
00447
00451 void endSource();
00452
00453 void
00454 setSDESItem(sdes_item_type_t item, const char* const value);
00455
00464 void
00465 recordReception(IncomingRTPPkt& p);
00466
00476 void
00477 recordInsertion(IncomingRTPPkt& p);
00478
00486 void
00487 recordExtraction(IncomingRTPPkt& p);
00488
00492 inline void
00493 setSender(bool active)
00494 { active_sender = active; };
00495
00501 inline void
00502 setInitialTimestamp(uint32 ts)
00503 { initial_timestamp = ts; }
00504
00513 inline uint32
00514 getInitialTimestamp()
00515 {return initial_timestamp; }
00516
00523 inline uint16
00524 getExpectedSeqNum()
00525 { return expectedseqnum; }
00526
00533 inline void
00534 setExpectedSeqNum(uint16 n)
00535 { expectedseqnum = n; }
00536
00537
00538
00539 uint32 ssrc;
00540
00541 uint32 initial_timestamp;
00542
00543 uint32 packet_count;
00544
00545 struct timeval last_time;
00546
00547
00548 uint32 kitchensize;
00549
00550
00551 uint32 currentkitchen;
00552
00553 uint16 expectedseqnum;
00554
00555
00556
00557 bool valid;
00558
00559 bool active_sender;
00560
00561
00562
00563 RTPSource* prev, * next;
00564
00565 IncomingRTPPkt* first, * last;
00566
00567 RTPSource* nextcollis;
00568
00569 static const char* const unknown;
00570
00571 SenderInfo* sender_info;
00572
00573 static const SenderInfo* dummySI;
00574
00575 ReceiverInfo* receiver_info;
00576
00577 static const ReceiverInfo* dummyRB;
00578
00579 char **sdes_items;
00580
00581 friend class MembershipControl;
00582 friend RTPQueue;
00583 friend QueueRTCPManager;
00584 friend IncomingRTPPkt;
00585 };
00586
00587
00588 class CCXX_CLASS_EXPORT Members
00589 {
00590 public:
00591
00592 Members() :
00593 members(static_cast<uint32>(-1)),
00594 active_senders(0)
00595 { };
00600 inline void
00601 increaseMembersCount()
00602 { members++; };
00603
00608 inline void
00609 decreaseMembersCount()
00610 { members--; };
00611
00612 inline void
00613 setMembersCount(uint32 n)
00614 { members = n; };
00615
00616 inline void
00617 increaseSendersCount()
00618 { active_senders++; };
00619
00620 inline void
00621 decreaseSendersCount()
00622 { active_senders--; };
00623
00624 inline void
00625 setSendersCount(uint32 n)
00626 { active_senders = n; };
00627
00628
00633 inline uint32
00634 membersCount() const
00635 { return members; };
00636
00637 inline uint32
00638 sendersCount() const
00639 { return active_senders; };
00640
00641
00642
00643 uint32 members;
00644
00645 uint32 active_senders;
00646 };
00647
00672 class CCXX_CLASS_EXPORT MembershipControl : public Members
00673 {
00674 public:
00683 inline const RTPSource&
00684 getSource(uint32 ssrc) const
00685 { return const_cast<MembershipControl*>(this)->getSourceBySSRC(ssrc,false); }
00686
00695 inline const RTPSource&
00696 getOrCreateSource(uint32 ssrc)
00697 { return getSourceBySSRC(ssrc,true); }
00698
00699 protected:
00705 RTPSource&
00706 addNewSource(uint32 ssrc);
00707
00721 MembershipControl(uint32 initial_size = 7);
00722
00728 virtual
00729 ~MembershipControl();
00730
00735 void
00736 endMembers();
00737
00747 RTPSource&
00748 getSourceBySSRC(uint32 ssrc, bool create = false);
00749
00757 bool
00758 removeSource(uint32 ssrc);
00759
00760 const RTPSource&
00761 NullSource() const
00762 { return dummysource; };
00763
00764
00765 const static RTPSource dummysource;
00766
00767 private:
00768
00769 MembershipControl(const MembershipControl &o);
00770
00771 MembershipControl&
00772 operator=(const MembershipControl &o);
00773
00774
00775 uint32 SOURCE_BUCKETS;
00776 RTPSource** sources;
00777
00778 RTPSource* first, * last;
00779 };
00780
00806 class CCXX_CLASS_EXPORT RTPQueue : protected Thread, protected MembershipControl
00807 {
00808 public:
00814 inline const RTPSource&
00815 getLocalInfo() const
00816 { return *localsrc; };
00817
00824 bool
00825 isWaiting(const RTPSource &src = dummysource) const;
00826
00835 bool
00836 isCookedWaiting(void) const;
00837
00843 bool
00844 isSending(void) const;
00845
00860 void
00861 putPacket(uint32 stamp, rtp_payload_t payload, unsigned char* data = NULL, size_t len = 0, bool mark = false);
00862
00921 const RTPData&
00922 getCookedPacket(const RTPSource &src = dummysource);
00923
00930 uint32
00931 getFirstTimestamp(const RTPSource &src = dummysource);
00932
00939 uint16
00940 getFirstSequence(const RTPSource &src = dummysource);
00941
00949 const RTPData&
00950 getPacket(uint32 stamp, const RTPSource &src = dummysource);
00951
00963 size_t
00964 getPacket(uint32 stamp, unsigned char* data, size_t max,
00965 const RTPSource &src = dummysource);
00966
00974 rtp_payload_t
00975 getPayloadType(uint32 timestamp, const RTPSource &src = dummysource);
00976
01038 uint32
01039 getCurrentTimestamp(rtp_payload_t pt) const;
01040
01049 uint32
01050 getTimestampIncrement(size_t packet_size) const;
01051
01059 void
01060 setSessionBandwidth(uint32 bw)
01061 { sessionbw = bw; };
01062
01075 uint32
01076 getRate(rtp_payload_t pt = RTP_PAYLOAD_EMPTY) const;
01077
01084 rtp_payload_t
01085 getPayloadType(const RTPSource& src) const;
01086
01095 inline const RTPSource&
01096 getSource(uint32 ssrc) const
01097 { return MembershipControl::getSource(htonl(ssrc)); };
01098
01111 inline void
01112 setTypeOfService(type_of_service_t tos)
01113 { type_of_service = tos; }
01114
01125 size_t
01126 setPartial(uint32 timestamp, unsigned char* data, size_t offset, size_t max);
01127
01139 size_t
01140 getPartial(uint32 timestamp, unsigned char* data, size_t offset, size_t max);
01141
01147 inline bool
01148 isActive(void) const
01149 { return active; };
01150
01157 inline void
01158 setTimeout(microtimeout_t t)
01159 { timeout = t;};
01160
01169 inline void
01170 setExpired(microtimeout_t t)
01171 { expired = t;};
01172
01196 void
01197 setGlobalKitchenDuration(microtimeout_t t);
01198
01199 void
01200 setGlobalKitchenSize(uint32 s);
01201
01210 inline microtimeout_t
01211 getGlobalKitchenDuration() const
01212 { return (((kitchensize * 1000) / getRate())*1000); };
01213
01228 inline void
01229 setEndToEndDelay(microtimeout_t t)
01230 { e2edelay = t; };
01231
01237 inline void
01238 setSegmentSize(size_t size)
01239 {segment = size;};
01240
01251 inline bool
01252 isComplete(void)
01253 {return complete;};
01254
01263 inline bool
01264 isMarked(void)
01265 {return marked;};
01266
01270 inline void
01271 setTimeclock(void)
01272 {timeclock.setTimer();};
01273
01279 inline timeout_t
01280 getTimeclock(void)
01281 {return timeclock.getElapsed();};
01282
01288 inline uint32
01289 RTPSendCount() const
01290 { return sendcount;};
01291
01298 inline uint32
01299 RTPOctetCount() const
01300 { return octetcount;};
01301
01302 protected:
01303
01311 RTPQueue(int pri, uint32 size = 7);
01312
01329 RTPQueue(uint32 ssrc, int pri, uint32 size = 7);
01330
01334 virtual
01335 ~RTPQueue();
01336
01343 virtual inline void
01344 RTCPService(microtimeout_t& wait)
01345 { return; };
01346
01350 virtual void
01351 Bye(const char* const reason)
01352 { return; }
01353
01357 virtual void timerTick(void)
01358 { return; };
01359
01369 microtimeout_t
01370 getTimeout(void);
01371
01379 virtual bool
01380 isPendingData(microtimeout_t timeout) = 0;
01381
01388 void Purge(rtp_purge_t flag);
01389
01396 size_t
01397 sendPacket(void);
01398
01408 virtual size_t
01409 writeData(const unsigned char* const packet, size_t len) = 0;
01410
01417 size_t
01418 recvPacket(void);
01419
01429 virtual size_t
01430 readData(unsigned char* buffer, size_t len) = 0;
01431
01440 virtual bool
01441 gotPacket(IncomingRTPPkt* packet)
01442 { return true; }
01443
01449 virtual void expireSend(OutgoingRTPPkt *packet)
01450 {return;};
01451
01458 virtual void expireRecv(IncomingRTPPkt *packet)
01459 {return ;};
01460
01470 IncomingRTPPkt*
01471 getWaiting(uint32 timestamp, const RTPSource &src = dummysource);
01472
01476 void
01477 endQueue();
01478
01482 void Final()
01483 { delete this; };
01484
01485
01486 volatile bool active;
01487
01488 RTPSource* localsrc;
01489
01490 struct timeval initial_time;
01491 uint32 current_rate;
01492
01493 uint32 initial_timestamp;
01494
01495 private:
01496 friend IncomingRTPPkt;
01497
01498 RTPQueue(const RTPQueue &o);
01499
01500 RTPQueue&
01501 operator=(const RTPQueue &o);
01502
01508 void
01509 initQueue(uint32 localssrc);
01510
01514 void
01515 Run(void);
01516
01517
01523 void
01524 RTPService(microtimeout_t& wait);
01525
01534 void
01535 insertRecvPacket(IncomingRTPPkt *packet);
01536
01537 type_of_service_t type_of_service;
01538 uint32 sessionbw;
01539 rtp_cast_t sessioncast;
01540
01541
01542 static const size_t RECVBUFFER_SIZE = 8192;
01543
01544 uint32 sendcount;
01545
01546 uint32 octetcount;
01547
01548
01549 OutgoingRTPPkt* sendfirst, * sendlast;
01550 IncomingRTPPkt* recvfirst, * recvlast;
01551 mutable Mutex sendlock, recvlock;
01552
01553 uint16 sendseq;
01554
01555 uint32 sendsources[16];
01556
01557 unsigned sendcc;
01558
01559 unsigned segment;
01560
01561 bool marked;
01562
01563 bool complete;
01564
01565 TimerPort timeclock;
01566
01567
01568
01569 struct timeval overflow_time;
01570
01571
01572 microtimeout_t timeout;
01573
01574 microtimeout_t expired;
01575
01576
01577
01578 microtimeout_t e2edelay;
01579
01580
01581 uint32 kitchensize;
01582
01583
01584
01585
01586 static uint32 payload_rate[96];
01587 };
01588
01608 class CCXX_CLASS_EXPORT QueueRTCPManager : public RTPQueue
01609 {
01610 public:
01628 virtual void
01629 setControlBandwidth(float fraction)
01630 { controlbw = fraction; };
01631
01645 virtual void
01646 setSendersControlFraction(float fraction)
01647 { sendcontrolbw = fraction; recvcontrolbw = 1 - fraction;};
01648
01654 inline uint32
01655 RTCPSendCount() const
01656 { return ctrlsendcount; }
01657
01662 void inline
01663 setNAME(const char* const name)
01664 { localsrc->setSDESItem(RTCP_SDES_ITEM_NAME,name); };
01665
01666 void inline
01667 setEMAIL(const char* const email)
01668 { localsrc->setSDESItem(RTCP_SDES_ITEM_EMAIL,email); };
01669
01670 void inline setPHONE(const char* const phone)
01671 { localsrc->setSDESItem(RTCP_SDES_ITEM_PHONE,phone); };
01672
01673 void inline
01674 setLOC(const char* const loc)
01675 { localsrc->setSDESItem(RTCP_SDES_ITEM_LOC,loc); };
01676
01677 void inline
01678 setTOOL(const char* const tool)
01679 { localsrc->setSDESItem(RTCP_SDES_ITEM_TOOL,tool); };
01680
01681 void inline
01682 setNOTE(const char* const note)
01683 { localsrc->setSDESItem(RTCP_SDES_ITEM_NOTE,note); };
01684
01685 void inline
01686 setPRIV(const char* const priv)
01687 { localsrc->setSDESItem(RTCP_SDES_ITEM_PRIV,priv); };
01688
01689 void inline
01690 setH323_CADDR(const char* const h323ca)
01691 { localsrc->setSDESItem(RTCP_SDES_ITEM_H323_CADDR,h323ca); };
01692
01693 protected:
01694 QueueRTCPManager(int pri);
01695
01696 virtual
01697 ~QueueRTCPManager();
01698
01699 void
01700 endQueueRTCPManager();
01701
01707 void
01708 RTCPService(microtimeout_t& wait);
01709
01717 void
01718 Bye(const char* const reason = NULL);
01719
01723 void
01724 gotHello(const char* sdes)
01725 { return; }
01726
01730 void
01731 gotGoodbye(void)
01732 { return; }
01733
01737 void
01738 handleSSRCCollision();
01739
01752 virtual timeval
01753 computeRTCPInterval();
01754
01755 private:
01756 QueueRTCPManager(const QueueRTCPManager &o);
01757
01758 QueueRTCPManager&
01759 operator=(const QueueRTCPManager &o);
01760
01764 void
01765 setSDESItem(sdes_item_type_t type, const char *const value);
01766
01771 void
01772 findCNAME();
01773
01778 void
01779 updateAvgRTCPSize(uint16 len);
01780
01786 void
01787 ReverseReconsideration();
01788
01793 bool
01794 TimerReconsideration();
01795
01803 void
01804 TimeOutSSRCs();
01805
01810 bool
01811 getSDES_APP(RTCPPacket &pkt, uint16 &pointer, uint16 len);
01812
01822 bool
01823 getBYE(RTCPPacket &pkt, uint16 &pointer, uint16 len);
01824
01828 void
01829 getOnlyBye();
01830
01842 inline virtual uint16
01843 networkHeaderSize()
01844 { return 20; }
01845
01857 inline virtual uint16
01858 transportHeaderSize()
01859 { return 8; }
01860
01866 size_t
01867 sendControl(void);
01868
01878 void
01879 recvControl(void);
01880
01887 bool
01888 packReportBlock(uint16& len);
01889
01905 bool
01906 tryAnotherRR(RTCPPacket*& pkt, uint16& len, uint16& blocks);
01907
01914 void
01915 packSDES(uint16& len);
01916
01917 size_t
01918 sendBYE(const char* const reason);
01919
01924 virtual size_t
01925 writeControl(const unsigned char* const buffer, size_t len) = 0;
01926
01931 virtual size_t
01932 readControl(unsigned char* buffer, size_t len) = 0;
01933
01939 virtual bool
01940 isPendingControl(microtimeout_t timeout) = 0;
01941
01950 bool
01951 RTCPHeaderCheck(size_t len);
01952
01953
01954
01955 uint16 pathMTU;
01956
01957
01958
01959 unsigned char* rtcpsend_buffer;
01960
01961
01962
01963 unsigned char* rtcprecv_buffer;
01964
01965
01966 bool rtcp_active;
01967
01968 float controlbw, sendcontrolbw, recvcontrolbw;
01969
01970 uint32 ctrlsendcount;
01971
01972
01973
01974 uint16 lower_headers_size;
01975
01976 timeval rtcp_tp, rtcp_tc, rtcp_tn;
01977 uint32 rtcp_pmembers;
01978 uint32 rtcp_bw;
01979 bool rtcp_we_sent;
01980 uint16 rtcp_avg_size;
01981 bool rtcp_initial;
01982
01983 timeval rtcp_last_check;
01984
01985 timeval rtcp_check_interval;
01986
01987 timeval rtcp_next_check;
01988
01989
01990 uint32 last_sendcount;
01991
01992 uint32 prev_nvalid_sources;
01993 timeval rtcp_calculated_interval;
01994
01995
01996 size_t CNAME_len;
01997
01998
01999
02000
02001
02002 uint32 nprevalid_srcs;
02003
02004 uint32 nvalid_srcs;
02005
02006 uint32 npredeleted_srcs;
02007
02008 uint32 ndeleted_srcs;
02009
02010 microtimeout_t rtcp_min_interval;
02011
02012
02013 const static uint32 NTP_EPOCH_OFFSET = static_cast<uint32>(2208992400u);
02014
02015
02016 #if __BYTE_ORDER == __BIG_ENDIAN
02017 static const uint16 RTCP_VALID_MASK = (0xc000 | 0x2000 | 0xfe);
02018 static const uint16 RTCP_VALID_VALUE = ((RTP_VERSION << 14) |
02019 RTCP_TYPE_SR);
02020 #else
02021 static const uint16 RTCP_VALID_MASK = (0x00c0 | 0x0020 | 0xfe00);
02022 static const uint16 RTCP_VALID_VALUE = ((RTP_VERSION << 6) |
02023 (RTCP_TYPE_SR << 8));
02024 #endif
02025 static const uint16 TIMEOUT_MULTIPLIER = 5;
02026 static const double RECONSIDERATION_COMPENSATION = 2.718281828 - 1.5;
02027 };
02028
02041 class CCXX_CLASS_EXPORT UDPIPv4Socket: protected UDPSocket
02042 {
02043 public:
02050 UDPIPv4Socket(const InetAddress& ia, tpport_t port) :
02051 UDPSocket(ia, port)
02052 { };
02053
02057 ~UDPIPv4Socket()
02058 { };
02059
02066 sockerror_t
02067 Connect(const InetAddress& ia, tpport_t port);
02068
02072 inline bool
02073 isPendingPacket(microtimeout_t timeout)
02074 { return isPending(SOCKET_PENDING_INPUT, timeout/1000);};
02075
02079 inline size_t
02080 writePacket(const unsigned char* const buffer, size_t len)
02081 {return ::send(so, buffer, len, MSG_DONTWAIT);};
02082
02086 inline size_t
02087 readPacket(unsigned char *buffer, size_t len)
02088 {return ::read(so, buffer, len);};
02089
02093 inline sockerror_t
02094 setMulticast(bool enable)
02095 { return setMulticast(enable); };
02096
02103 inline sockerror_t
02104 joinGroup(const InetMcastAddress& ia)
02105 { return Join(ia); };
02106
02113 inline sockerror_t
02114 leaveGroup(const InetMcastAddress& ia)
02115 { return Drop(ia); };
02116
02123 inline sockerror_t
02124 setMcastTTL(uint8 ttl)
02125 { setTimeToLive(ttl); };
02126
02130 void
02131 endSocket()
02132 { UDPSocket::endSocket(); };
02133 };
02134
02147 template <typename serviceQueue, typename dataSocket, typename controlSocket>
02148 class __EXPORT T_RTPSocket : public serviceQueue
02149 {
02150 public:
02156 T_RTPSocket(const InetAddress& ia, tpport_t port = 5004, int pri = 0) :
02157 serviceQueue(pri)
02158 {
02159 base = even_port(port);
02160 dso = new dataSocket(ia,even_port(port));
02161 cso = new controlSocket(ia,odd_port(port + 1));
02162 };
02163
02169 T_RTPSocket(const InetMcastAddress& bind, tpport_t port = 5004, int pri = 0)
02170 {
02171 base = even_port(port);
02172 dso = new dataSocket(ia,even_port(port));
02173 cso = new controlSocket(ia,odd_port(port + 1));
02174 };
02175
02179 ~T_RTPSocket()
02180 { endSocket(); };
02181
02187 inline sockerror_t
02188 Connect(const InetHostAddress& ia, tpport_t port = 0)
02189 { return connect(ia,port); };
02190
02196 inline sockerror_t
02197 Connect(const InetMcastAddress& ia, tpport_t port = 0)
02198 { return connect(ia,port); };
02199
02206 inline sockerror_t
02207 joinGroup(const InetMcastAddress& ia, tpport_t port = 0)
02208 {
02209 sockerror_t error = dso->setMulticast(true);
02210 if ( error ) return error;
02211 error = dso->joinGroup(ia);
02212 if ( error ) return error;
02213 error = cso->setMulticast(true);
02214 if ( error ) {
02215 dso->leaveGroup(ia);
02216 return error;
02217 }
02218 error = cso->joinGroup(ia);
02219 if ( error ) {
02220 dso->leaveGroup(ia);
02221 return error;
02222 }
02223 return Connect(ia,port);
02224 };
02225
02232 inline sockerror_t
02233 leaveGroup(const InetMcastAddress& ia)
02234 {
02235 sockerror_t error = dso->setMulticast(true);
02236 if ( error ) return error;
02237 error = dso->leaveGroup(ia);
02238 if ( error ) return error;
02239 error = cso->setMulticast(true);
02240 if ( error ) return errror;
02241 return cso->leaveGroup(ia);
02242 };
02243
02250 inline sockerror_t
02251 setMcastTTL(uint8 ttl)
02252 {
02253 sockerror_t error = dso->setMulticast(true);
02254 if ( error ) return error;
02255 error = dso->setTimeToLive(ttl);
02256 if ( error ) return error;
02257 error = cso->setMulticast(true);
02258 if ( error ) return error;
02259 return cso->setTimeToLive(ttl);
02260 };
02261
02262 protected:
02266 inline bool
02267 isPendingData(microtimeout_t timeout)
02268 { return dso->isPendingPacket(timeout); };
02269
02274 inline size_t
02275 readData(unsigned char* buffer, size_t len)
02276 { return dso->readPacket(buffer, len); };
02277
02282 inline size_t
02283 writeData(const unsigned char* const buffer, size_t len)
02284 { return dso->writePacket(buffer, len); };
02285
02290 inline bool
02291 isPendingControl(microtimeout_t timeout)
02292 { return cso->isPendingPacket(timeout); };
02293
02299 inline size_t
02300 readControl(unsigned char *buffer, size_t len)
02301 { return cso->readPacket(buffer,len); };
02302
02308 inline size_t
02309 writeControl(const unsigned char* const buffer, size_t len)
02310 { return cso->writePacket(buffer,len); };
02311
02312 inline void
02313 endSocket()
02314 { dso->endSocket(); cso->endSocket(); };
02315
02316 private:
02325 sockerror_t
02326 connect(const InetAddress& ia, tpport_t port = 0)
02327 {
02328 sockerror_t error;
02329 if ( !port )
02330 port = base;
02331 if ( active )
02332 active = false;
02333
02334 error = dso->Connect(ia, even_port(port));
02335 if ( error )
02336 return error;
02337 error = cso->Connect(ia, odd_port(port + 1));
02338 if ( error )
02339 return error;
02340
02341 active = true;
02342 Start();
02343 return SOCKET_SUCCESS;
02344 };
02345
02353 inline tpport_t
02354 odd_port(tpport_t port)
02355 { return (port & 0x01)? (port) : (port - 1); };
02356
02364 inline tpport_t
02365 even_port(tpport_t port)
02366 { return (port & 0x01)? (port - 1) : (port); };
02367
02368 tpport_t base;
02369 dataSocket* dso;
02370 controlSocket* cso;
02371 };
02372
02379 typedef T_RTPSocket<QueueRTCPManager,UDPIPv4Socket,UDPIPv4Socket> RTPSocket;
02380
02391 class CCXX_CLASS_EXPORT RTPDuplex : public RTPQueue, protected UDPReceive, public UDPTransmit
02392 {
02393
02394 public:
02395
02402 RTPDuplex(const InetAddress &bind, tpport_t local, tpport_t remote, int pri);
02403
02407 virtual
02408 ~RTPDuplex();
02409
02416 sockerror_t
02417 Connect(const InetHostAddress &host, tpport_t port = 0);
02418
02419 protected:
02420
02425 bool
02426 isPendingData(microtimeout_t timeout)
02427 { return isPendingReceive(timeout); }
02428
02434 size_t
02435 writeData(const unsigned char *const buffer, size_t len)
02436 { return Transmit((const char *)buffer, len); }
02437
02443 size_t
02444 readData(unsigned char *buffer, size_t len)
02445 { return Receive(buffer, len); }
02446
02450 RTPSource &getPeer();
02451
02452 private:
02453
02454 tpport_t base;
02455 };
02456
02457 #ifdef __NAMESPACES__
02458 };
02459 #endif
02460
02461 #endif //__CCXX_RTP_H__
02462