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 CCXX_NAMESPACES
00055 namespace ost {
00056 #endif
00057
00058
00059 const uint8 CCRTP_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
00192 typedef enum
00193 {
00194 RTPSOURCE_STATE_PREVALID,
00195 RTPSOURCE_STATE_VALID,
00196 RTPSOURCE_STATE_SAYINGBYE
00197 } rtpsource_state_t;
00198
00207 typedef enum
00208 {
00209 RTP_PURGE_SEND,
00210 RTP_PURGE_RECV,
00211 RTP_PURGE_BOTH
00212 } rtp_purge_t;
00213
00214 typedef enum {
00215 CAST_MCAST,
00216 CAST_UCAST
00217 } rtp_cast_t;
00218
00219 class CCXX_CLASS_EXPORT IncomingRTPPkt;
00220 class CCXX_CLASS_EXPORT OutgoingRTPPkt;
00221 class CCXX_CLASS_EXPORT RTPQueue;
00222 class CCXX_CLASS_EXPORT QueueRTCPManager;
00223 class CCXX_CLASS_EXPORT RTPSource;
00224
00237 class CCXX_CLASS_EXPORT RTPData
00238 {
00239
00240 public:
00244 RTPData(const RTPData& origin);
00245
00252 RTPData&
00253 operator=(const RTPData& source);
00254
00255 inline const unsigned char*
00256 getData() const
00257 { return datablock->data; };
00258
00259 inline size_t
00260 getSize() const
00261 { return datablock->size; };
00262
00263 inline rtp_payload_t
00264 getPayloadType() const
00265 { return datablock->pt; }
00266
00267 protected:
00268
00269 RTPData(IncomingRTPPkt& packet);
00270
00271 ~RTPData();
00272
00273 private:
00274
00275 struct dataCounter {
00276 uint16 count;
00277 const unsigned char* data;
00278 const size_t size;
00279 rtp_payload_t pt;
00280 dataCounter(const unsigned char* data, size_t size, rtp_payload_t pt);
00281 ~dataCounter();
00282 };
00283
00284 mutable dataCounter* datablock;
00285
00286
00287
00288
00289 RTPSource* src;
00290
00291 friend RTPQueue;
00292 };
00293
00310 class CCXX_CLASS_EXPORT RTPSource
00311 {
00312 public:
00313 bool getHello();
00314 bool getGoodbye();
00315
00316 uint32 getID() const
00317 { return ssrc; };
00318
00324 uint32
00325 getRate() const;
00326
00340 inline void
00341 setKitchenSize(microtimeout_t s)
00342 { kitchensize = ((s / 1000) * getRate() / 1000); };
00343
00349 inline microtimeout_t
00350 getKitchenDuration() const
00351 { return (((kitchensize * 1000) / getRate())* 1000); };
00352
00353 inline uint32
00354 getKitchenSize() const
00355 { return kitchensize; };
00356
00365 inline microtimeout_t
00366 getCurrentKitchenDuration()
00367 { return (((currentkitchen * 1000) / getRate())* 1000); };
00368
00369 inline microtimeout_t
00370 getCurrentKitchenSize()
00371 { return currentkitchen;};
00372
00373 const char* const
00374 getSDESItem(sdes_item_type_t type) const;
00375
00376 inline const char* const
00377 getCNAME() const
00378 { return getSDESItem(RTCP_SDES_ITEM_CNAME); };
00379
00380 inline const char* const
00381 getNAME() const
00382 { return getSDESItem(RTCP_SDES_ITEM_NAME); };
00383
00384 inline const char* const
00385 getEMAIL() const
00386 { return getSDESItem(RTCP_SDES_ITEM_EMAIL); };
00387
00388 inline const char* const
00389 getPHONE() const
00390 { return getSDESItem(RTCP_SDES_ITEM_PHONE); };
00391
00392 inline const char* const
00393 getLOC() const
00394 { return getSDESItem(RTCP_SDES_ITEM_LOC); };
00395
00396 inline const char* const
00397 getTOOL() const
00398 { return getSDESItem(RTCP_SDES_ITEM_TOOL); };
00399
00400 inline const char* const
00401 getNOTE() const
00402 { return getSDESItem(RTCP_SDES_ITEM_NOTE); };
00403
00404 inline const char* const
00405 getPRIV() const
00406 { return getSDESItem(RTCP_SDES_ITEM_PRIV); };
00407
00408 inline const char* const
00409 getH323_CADDR() const
00410 { return getSDESItem(RTCP_SDES_ITEM_H323_CADDR); };
00411
00415 inline bool
00416 isSender() const
00417 { return active_sender; };
00418
00419 bool isValid() const
00420 { return valid; };
00421
00422 inline bool
00423 operator==(const RTPSource &rhs) const
00424 { return (this == &rhs); }
00425
00426 inline bool
00427 operator!=(const RTPSource &rhs) const
00428 { return !(*this == rhs); }
00429
00433 RTPSource(uint32 ssrc);
00434
00438 ~RTPSource();
00439
00443 RTPSource(const RTPSource& origin);
00444
00445 RTPSource&
00446 operator=(const RTPSource &origin);
00447
00448 protected:
00449
00450 private:
00458 inline void
00459 setCurrentKitchenSize(uint32 s)
00460 { currentkitchen = s; };
00461
00465 void endSource();
00466
00467 void
00468 setSDESItem(sdes_item_type_t item, const char* const value);
00469
00478 void
00479 recordReception(IncomingRTPPkt& p);
00480
00490 void
00491 recordInsertion(IncomingRTPPkt& p);
00492
00500 void
00501 recordExtraction(IncomingRTPPkt& p);
00502
00506 inline void
00507 setSender(bool active)
00508 { active_sender = active; };
00509
00515 inline void
00516 setInitialTimestamp(uint32 ts)
00517 { initial_timestamp = ts; }
00518
00527 inline uint32
00528 getInitialTimestamp()
00529 {return initial_timestamp; }
00530
00537 inline uint16
00538 getExpectedSeqNum()
00539 { return expectedseqnum; }
00540
00547 inline void
00548 setExpectedSeqNum(uint16 n)
00549 { expectedseqnum = n; }
00550
00551 inline void
00552 setState(rtpsource_state_t st)
00553 { state = st; }
00554
00555
00556
00557 uint32 ssrc;
00558
00559 rtpsource_state_t state;
00560
00561 uint32 initial_timestamp;
00562
00563 uint32 packet_count;
00564
00565 struct timeval last_time;
00566
00567
00568 uint32 kitchensize;
00569
00570
00571 uint32 currentkitchen;
00572
00573 uint16 expectedseqnum;
00574
00575
00576
00577 bool flag;
00578
00579
00580
00581 bool valid;
00582
00583 bool active_sender;
00584
00585
00586
00587 RTPSource* prev, * next;
00588
00589 IncomingRTPPkt* first, * last;
00590
00591 RTPSource* nextcollis;
00592
00593 static const char* const unknown;
00594
00595 SenderInfo* sender_info;
00596
00597 static const SenderInfo* dummySI;
00598
00599 ReceiverInfo* receiver_info;
00600
00601 static const ReceiverInfo* dummyRB;
00602
00603 char **sdes_items;
00604
00605
00606 friend class MembershipControl;
00607 friend RTPQueue;
00608 friend QueueRTCPManager;
00609 friend IncomingRTPPkt;
00610 };
00611
00612
00613 class CCXX_CLASS_EXPORT Members
00614 {
00615 public:
00616
00617 Members() :
00618 members(static_cast<uint32>(-1)),
00619
00620 active_senders(0)
00621 { };
00622
00627 inline void
00628 increaseMembersCount()
00629 { members++; };
00630
00635 inline void
00636 decreaseMembersCount()
00637 { members--; };
00638
00639 inline void
00640 setMembersCount(uint32 n)
00641 { members = n; };
00642
00643 inline void
00644 increaseSendersCount()
00645 { active_senders++; };
00646
00647 inline void
00648 decreaseSendersCount()
00649 { active_senders--; };
00650
00651 inline void
00652 setSendersCount(uint32 n)
00653 { active_senders = n; };
00654
00659 inline uint32
00660 membersCount() const
00661 { return members; };
00662
00663 inline uint32
00664 sendersCount() const
00665 { return active_senders; };
00666
00667
00668
00669 uint32 members;
00670
00671 uint32 active_senders;
00672 };
00673
00698 class CCXX_CLASS_EXPORT MembershipControl : public Members
00699 {
00700 public:
00709 inline const RTPSource&
00710 getSource(uint32 ssrc) const
00711 { return const_cast<MembershipControl*>(this)->getSourceBySSRC(ssrc,false); }
00712
00721 inline const RTPSource&
00722 getOrCreateSource(uint32 ssrc)
00723 { return getSourceBySSRC(ssrc,true); }
00724
00725 protected:
00731 RTPSource&
00732 addNewSource(uint32 ssrc);
00733
00747 MembershipControl(uint32 initial_size = 7);
00748
00754 virtual
00755 ~MembershipControl();
00756
00761 void
00762 endMembers();
00763
00773 RTPSource&
00774 getSourceBySSRC(uint32 ssrc, bool create = false);
00775
00786 bool
00787 BYESource(uint32 ssrc);
00788
00796 bool
00797 removeSource(uint32 ssrc);
00798
00799 const RTPSource&
00800 NullSource() const
00801 { return dummysource; };
00802
00803
00804 const static RTPSource dummysource;
00805
00806 const RTPSource&
00807 getFirstPlayer();
00808
00809 const RTPSource&
00810 getLastPlayer();
00811
00812 const RTPSource&
00813 getNextPlayer();
00814
00815 const RTPSource&
00816 getCurrentPlayer();
00817
00818 private:
00819
00820 MembershipControl(const MembershipControl &o);
00821
00822 MembershipControl&
00823 operator=(const MembershipControl &o);
00824
00825
00826 uint32 SOURCE_BUCKETS;
00827 RTPSource** sources;
00828
00829 RTPSource* first, * last;
00830 mutable Mutex playerslock;
00831 };
00832
00858 class CCXX_CLASS_EXPORT RTPQueue : protected Thread, protected MembershipControl
00859 {
00860 public:
00864 inline void Start(void)
00865 {Thread::Start();};
00866
00872 inline const RTPSource&
00873 getLocalInfo() const
00874 { return *localsrc; };
00875
00882 bool
00883 isWaiting(const RTPSource &src = dummysource) const;
00884
00893 bool
00894 isCookedWaiting(void) const;
00895
00901 bool
00902 isSending(void) const;
00903
00918 void
00919 putPacket(uint32 stamp, rtp_payload_t payload, const unsigned char* data = NULL, size_t len = 0, bool mark = false);
00920
00979 const RTPData&
00980 getCookedPacket(const RTPSource &src = dummysource);
00981
00988 uint32
00989 getFirstTimestamp(const RTPSource &src = dummysource);
00990
00997 uint16
00998 getFirstSequence(const RTPSource &src = dummysource);
00999
01007 const RTPData&
01008 getPacket(uint32 stamp, const RTPSource &src = dummysource);
01009
01021 size_t
01022 getPacket(uint32 stamp, unsigned char* data, size_t max,
01023 const RTPSource &src = dummysource);
01024
01032 rtp_payload_t
01033 getPayloadType(uint32 timestamp, const RTPSource &src = dummysource);
01034
01096 uint32
01097 getCurrentTimestamp(rtp_payload_t pt) const;
01098
01107 uint32
01108 getTimestampIncrement(size_t packet_size) const;
01109
01117 void
01118 setSessionBandwidth(uint32 bw)
01119 { sessionbw = bw; };
01120
01133 uint32
01134 getRate(rtp_payload_t pt = RTP_PAYLOAD_EMPTY) const;
01135
01142 rtp_payload_t
01143 getPayloadType(const RTPSource& src) const;
01144
01153 inline const RTPSource&
01154 getSource(uint32 ssrc) const
01155 { return MembershipControl::getSource(htonl(ssrc)); };
01156
01169 inline void
01170 setTypeOfService(type_of_service_t tos)
01171 { type_of_service = tos; }
01172
01183 size_t
01184 setPartial(uint32 timestamp, unsigned char* data, size_t offset, size_t max);
01185
01197 size_t
01198 getPartial(uint32 timestamp, unsigned char* data, size_t offset, size_t max);
01199
01205 inline bool
01206 isActive(void) const
01207 { return active; };
01208
01215 inline void
01216 setTimeout(microtimeout_t t)
01217 { timeout = t;};
01218
01227 inline void
01228 setExpired(microtimeout_t t)
01229 { expired = t;};
01230
01254 void
01255 setGlobalKitchenDuration(microtimeout_t t);
01256
01257 void
01258 setGlobalKitchenSize(uint32 s);
01259
01268 inline microtimeout_t
01269 getGlobalKitchenDuration() const
01270 { return (((kitchensize * 1000) / getRate())*1000); };
01271
01286 inline void
01287 setEndToEndDelay(microtimeout_t t)
01288 { e2edelay = t; };
01289
01295 inline void
01296 setSegmentSize(size_t size)
01297 {segment = size;};
01298
01309 inline bool
01310 isComplete()
01311 { return complete; };
01312
01321 inline bool
01322 isMarked(void)
01323 {return marked;};
01324
01328 inline void
01329 setTimeclock(void)
01330 {timeclock.setTimer();};
01331
01337 inline timeout_t
01338 getTimeclock(void)
01339 {return timeclock.getElapsed();};
01340
01346 inline uint32
01347 RTPSendCount() const
01348 { return sendcount;};
01349
01356 inline uint32
01357 RTPOctetCount() const
01358 { return octetcount;};
01359
01360 protected:
01361
01369 RTPQueue(int pri, uint32 size = 7);
01370
01387 RTPQueue(uint32 ssrc, int pri, uint32 size = 7);
01388
01392 virtual
01393 ~RTPQueue();
01394
01401 virtual inline void
01402 RTCPService(microtimeout_t& wait)
01403 { return; };
01404
01408 virtual void
01409 Bye(const char* const reason)
01410 { return; }
01411
01415 virtual void timerTick(void)
01416 { return; };
01417
01427 microtimeout_t
01428 getTimeout(void);
01429
01437 virtual bool
01438 isPendingData(microtimeout_t timeout) = 0;
01439
01446 void Purge(rtp_purge_t flag);
01447
01454 size_t
01455 sendPacket(void);
01456
01466 virtual size_t
01467 writeData(const unsigned char* const packet, size_t len) = 0;
01468
01475 size_t
01476 recvPacket(void);
01477
01487 virtual size_t
01488 readData(unsigned char* buffer, size_t len) = 0;
01489
01498 virtual bool
01499 gotPacket(IncomingRTPPkt* packet)
01500 { return true; }
01501
01507 virtual void expireSend(OutgoingRTPPkt *packet)
01508 {return;};
01509
01516 virtual void expireRecv(IncomingRTPPkt *packet)
01517 {return ;};
01518
01528 IncomingRTPPkt*
01529 getWaiting(uint32 timestamp, const RTPSource &src = dummysource);
01530
01534 void
01535 endQueue();
01536
01540 void Final()
01541 { delete this; };
01542
01543
01544 volatile bool active;
01545
01546 RTPSource* localsrc;
01547
01548 struct timeval initial_time;
01549 uint32 current_rate;
01550
01551 uint32 initial_timestamp;
01552
01553 private:
01554 friend IncomingRTPPkt;
01555
01556 RTPQueue(const RTPQueue &o);
01557
01558 RTPQueue&
01559 operator=(const RTPQueue &o);
01560
01566 void
01567 initQueue(uint32 localssrc);
01568
01572 void
01573 Run(void);
01574
01575
01581 void
01582 RTPService(microtimeout_t& wait);
01583
01592 void
01593 insertRecvPacket(IncomingRTPPkt *packet);
01594
01595 type_of_service_t type_of_service;
01596 uint32 sessionbw;
01597 rtp_cast_t sessioncast;
01598
01599
01600 static const size_t RECVBUFFER_SIZE = 8192;
01601
01602 uint32 sendcount;
01603
01604 uint32 octetcount;
01605
01606
01607 OutgoingRTPPkt* sendfirst, * sendlast;
01608 IncomingRTPPkt* recvfirst, * recvlast;
01609 mutable Mutex sendlock, recvlock;
01610
01611 uint16 sendseq;
01612
01613 uint32 sendsources[16];
01614
01615 uint16 sendcc;
01616
01617 unsigned segment;
01618
01619 bool marked;
01620
01621 bool complete;
01622
01623 TimerPort timeclock;
01624
01625
01626
01627 struct timeval overflow_time;
01628
01629
01630 microtimeout_t timeout;
01631
01632 microtimeout_t expired;
01633
01634
01635
01636 microtimeout_t e2edelay;
01637
01638
01639 uint32 kitchensize;
01640
01641
01642
01643
01644 static uint32 payload_rate[96];
01645 };
01646
01666 class CCXX_CLASS_EXPORT QueueRTCPManager : public RTPQueue
01667 {
01668 public:
01686 virtual void
01687 setControlBandwidth(float fraction)
01688 { controlbw = fraction; };
01689
01703 virtual void
01704 setSendersControlFraction(float fraction)
01705 { sendcontrolbw = fraction; recvcontrolbw = 1 - fraction;};
01706
01712 inline uint32
01713 RTCPSendCount() const
01714 { return ctrlsendcount; }
01715
01720 void inline
01721 setNAME(const char* const name)
01722 { localsrc->setSDESItem(RTCP_SDES_ITEM_NAME,name); };
01723
01724 void inline
01725 setEMAIL(const char* const email)
01726 { localsrc->setSDESItem(RTCP_SDES_ITEM_EMAIL,email); };
01727
01728 void inline setPHONE(const char* const phone)
01729 { localsrc->setSDESItem(RTCP_SDES_ITEM_PHONE,phone); };
01730
01731 void inline
01732 setLOC(const char* const loc)
01733 { localsrc->setSDESItem(RTCP_SDES_ITEM_LOC,loc); };
01734
01735 void inline
01736 setTOOL(const char* const tool)
01737 { localsrc->setSDESItem(RTCP_SDES_ITEM_TOOL,tool); };
01738
01739 void inline
01740 setNOTE(const char* const note)
01741 { localsrc->setSDESItem(RTCP_SDES_ITEM_NOTE,note); };
01742
01743 void inline
01744 setPRIV(const char* const priv)
01745 { localsrc->setSDESItem(RTCP_SDES_ITEM_PRIV,priv); };
01746
01747 void inline
01748 setH323_CADDR(const char* const h323ca)
01749 { localsrc->setSDESItem(RTCP_SDES_ITEM_H323_CADDR,h323ca); };
01750
01751 protected:
01752 QueueRTCPManager(int pri);
01753
01754 virtual
01755 ~QueueRTCPManager();
01756
01757 void
01758 endQueueRTCPManager();
01759
01765 void
01766 RTCPService(microtimeout_t& wait);
01767
01775 void
01776 Bye(const char* const reason = NULL);
01777
01781 virtual void
01782 gotHello(RTPSource &src)
01783 { return; }
01784
01791 virtual void
01792 gotGoodbye(RTPSource &src, char *reason)
01793 { return; }
01794
01798 void
01799 handleSSRCCollision();
01800
01813 virtual timeval
01814 computeRTCPInterval();
01815
01820 inline void
01821 setPrevMembersCount(uint32 count)
01822 { rtcp_pmembers = count; };
01823
01828 inline uint32
01829 PrevMembersCount() const
01830 { return rtcp_pmembers; };
01831
01832 private:
01833 QueueRTCPManager(const QueueRTCPManager &o);
01834
01835 QueueRTCPManager&
01836 operator=(const QueueRTCPManager &o);
01837
01841 void
01842 setSDESItem(sdes_item_type_t type, const char *const value);
01843
01848 void
01849 findCNAME();
01850
01855 void
01856 updateAvgRTCPSize(size_t len);
01857
01863 void
01864 ReverseReconsideration();
01865
01870 bool
01871 TimerReconsideration();
01872
01880 void
01881 TimeOutSSRCs();
01882
01887 bool
01888 getSDES_APP(RTCPPacket &pkt, uint32 &pointer, size_t len);
01889
01902 bool
01903 getBYE(RTCPPacket &pkt, uint32 &pointer, size_t len);
01904
01908 void
01909 getOnlyBye();
01910
01922 inline virtual uint16
01923 networkHeaderSize()
01924 { return 20; }
01925
01937 inline virtual uint16
01938 transportHeaderSize()
01939 { return 8; }
01940
01946 size_t
01947 sendControl(void);
01948
01958 void
01959 recvControl(void);
01960
01967 bool
01968 packReportBlock(uint16& len);
01969
01985 bool
01986 tryAnotherRR(RTCPPacket*& pkt, uint16& len, uint16& blocks);
01987
01994 void
01995 packSDES(uint16& len);
01996
01997 size_t
01998 sendBYE(const char* const reason);
01999
02004 virtual size_t
02005 writeControl(const unsigned char* const buffer, size_t len) = 0;
02006
02011 virtual size_t
02012 readControl(unsigned char* buffer, size_t len) = 0;
02013
02019 virtual bool
02020 isPendingControl(microtimeout_t timeout) = 0;
02021
02030 bool
02031 RTCPHeaderCheck(size_t len);
02032
02033
02034
02035 uint16 pathMTU;
02036
02037
02038
02039 unsigned char* rtcpsend_buffer;
02040
02041
02042
02043 unsigned char* rtcprecv_buffer;
02044
02045
02046 bool rtcp_active;
02047
02048 float controlbw, sendcontrolbw, recvcontrolbw;
02049
02050 uint32 ctrlsendcount;
02051
02052
02053
02054 uint16 lower_headers_size;
02055
02056 timeval rtcp_tp, rtcp_tc, rtcp_tn;
02057 uint32 rtcp_pmembers;
02058 uint32 rtcp_bw;
02059 bool rtcp_we_sent;
02060 uint16 rtcp_avg_size;
02061 bool rtcp_initial;
02062
02063 timeval rtcp_last_check;
02064
02065 timeval rtcp_check_interval;
02066
02067 timeval rtcp_next_check;
02068
02069
02070 uint32 last_sendcount;
02071
02072 uint32 prev_nvalid_sources;
02073 timeval rtcp_calculated_interval;
02074
02075
02076 size_t CNAME_len;
02077
02078
02079
02080
02081
02082 uint32 nprevalid_srcs;
02083
02084 uint32 nvalid_srcs;
02085
02086 uint32 npredeleted_srcs;
02087
02088 uint32 ndeleted_srcs;
02089
02090 microtimeout_t rtcp_min_interval;
02091
02092
02093 const static uint32 NTP_EPOCH_OFFSET = static_cast<uint32>(2208992400u);
02094
02095
02096 #if __BYTE_ORDER == __BIG_ENDIAN
02097 static const uint16 RTCP_VALID_MASK;
02098 static const uint16 RTCP_VALID_VALUE;
02099 #else
02100 static const uint16 RTCP_VALID_MASK;
02101 static const uint16 RTCP_VALID_VALUE;
02102 #endif
02103 static const uint16 TIMEOUT_MULTIPLIER;
02104 static const double RECONSIDERATION_COMPENSATION;
02105 };
02106
02122 class CCXX_CLASS_EXPORT UDPIPv4Socket: private UDPReceive, private UDPTransmit
02123 {
02124 public:
02131 UDPIPv4Socket(const InetAddress& ia, tpport_t port) :
02132 UDPReceive(ia, port), UDPTransmit()
02133 { };
02134
02138 ~UDPIPv4Socket()
02139 { };
02140
02147 sockerror_t
02148 Connect(const InetHostAddress& ia, tpport_t port)
02149 { return UDPTransmit::Connect(ia,port); };
02150
02157 sockerror_t
02158 Connect(const InetMcastAddress& ia, tpport_t port)
02159 { return UDPTransmit::Connect(ia,port); };
02160
02164 inline bool
02165 isPendingPacket(microtimeout_t timeout)
02166 { return UDPReceive::isInputReady(timeout/1000); };
02167
02171 inline size_t
02172 writePacket(const unsigned char* const buffer, size_t len)
02173 { return UDPTransmit::Transmit((const char* const)buffer,len); };
02174
02178 inline size_t
02179 readPacket(unsigned char *buffer, size_t len)
02180 { return UDPReceive::Receive(buffer,len); };
02181
02185 inline sockerror_t
02186 setMulticast(bool enable)
02187 {
02188 sockerror_t error = UDPReceive::setMulticast(enable);
02189 if (error) return error;
02190 else return UDPTransmit::setMulticast(enable);
02191 };
02192
02199 inline sockerror_t
02200 joinGroup(const InetMcastAddress& ia)
02201 { return UDPReceive::Join(ia); };
02202
02209 inline sockerror_t
02210 leaveGroup(const InetMcastAddress& ia)
02211 { return UDPReceive::Drop(ia); };
02212
02219 inline sockerror_t
02220 setMcastTTL(uint8 ttl)
02221 { return UDPTransmit::setTimeToLive(ttl); };
02222
02226 void
02227 endSocket()
02228 { UDPTransmit::endTransmitter(); UDPReceive::endReceiver(); };
02229 };
02230
02243 template <typename serviceQueue, typename dataSocket, typename controlSocket>
02244 class CCXX_CLASS_EXPORT T_RTPSocket : public serviceQueue
02245 {
02246 public:
02252 T_RTPSocket(const InetHostAddress& ia, tpport_t port = 5004, int pri = 0) :
02253 serviceQueue(pri)
02254 {
02255 base = even_port(port);
02256 dso = new dataSocket(ia,even_port(port));
02257 cso = new controlSocket(ia,odd_port(port + 1));
02258 };
02259
02265 T_RTPSocket(const InetMcastAddress& ia, tpport_t port = 5004, int pri = 0):
02266 serviceQueue(pri)
02267
02268 {
02269 base = even_port(port);
02270 dso = new dataSocket(ia,even_port(port));
02271 cso = new controlSocket(ia,odd_port(port + 1));
02272 };
02273
02277 virtual
02278 ~T_RTPSocket()
02279 { endSocket(); };
02280
02289 inline sockerror_t
02290 Connect(const InetHostAddress& ia, tpport_t port = 0)
02291 {
02292 sockerror_t error;
02293 if ( !port )
02294 port = base;
02295 if ( active )
02296 active = false;
02297
02298 error = dso->Connect(ia, even_port(port));
02299 if ( error )
02300 return error;
02301 error = cso->Connect(ia, odd_port(port + 1));
02302 if ( error )
02303 return error;
02304
02305 active = true;
02306 Start();
02307 return SOCKET_SUCCESS;
02308 };
02309
02315 inline sockerror_t
02316 Connect(const InetMcastAddress& ia, tpport_t port = 0)
02317 {
02318 sockerror_t error = dso->setMulticast(true);
02319 if (error)
02320 return error;
02321 error = cso->setMulticast(true);
02322 if (error)
02323 return error;
02324
02325 if ( !port )
02326 port = base;
02327 if ( active )
02328 active = false;
02329
02330 error = dso->Connect(ia, even_port(port));
02331 if ( error )
02332 return error;
02333 error = cso->Connect(ia, odd_port(port + 1));
02334 if ( error )
02335 return error;
02336
02337 active = true;
02338 Start();
02339 return SOCKET_SUCCESS;
02340 };
02341
02348 inline sockerror_t
02349 joinGroup(const InetMcastAddress& ia, tpport_t port = 0)
02350 {
02351 sockerror_t error = dso->setMulticast(true);
02352 if ( error ) return error;
02353 error = dso->joinGroup(ia);
02354 if ( error ) return error;
02355 error = cso->setMulticast(true);
02356 if ( error ) {
02357 dso->leaveGroup(ia);
02358 return error;
02359 }
02360 error = cso->joinGroup(ia);
02361 if ( error ) {
02362 dso->leaveGroup(ia);
02363 return error;
02364 }
02365 return Connect(ia,port);
02366 };
02367
02374 inline sockerror_t
02375 leaveGroup(const InetMcastAddress& ia)
02376 {
02377 sockerror_t error = dso->setMulticast(false);
02378 if ( error ) return error;
02379 error = dso->leaveGroup(ia);
02380 if ( error ) return error;
02381 error = cso->setMulticast(false);
02382 if ( error ) return errror;
02383 return cso->leaveGroup(ia);
02384 };
02385
02392 inline sockerror_t
02393 setMcastTTL(uint8 ttl)
02394 {
02395 sockerror_t error = dso->setMulticast(true);
02396 if ( error ) return error;
02397 error = dso->setTimeToLive(ttl);
02398 if ( error ) return error;
02399 error = cso->setMulticast(true);
02400 if ( error ) return error;
02401 return cso->setTimeToLive(ttl);
02402 };
02403
02404 protected:
02408 inline bool
02409 isPendingData(microtimeout_t timeout)
02410 { return dso->isPendingPacket(timeout); };
02411
02416 inline size_t
02417 readData(unsigned char* buffer, size_t len)
02418 { return dso->readPacket(buffer, len); };
02419
02424 inline size_t
02425 writeData(const unsigned char* const buffer, size_t len)
02426 { return dso->writePacket(buffer, len); };
02427
02432 inline bool
02433 isPendingControl(microtimeout_t timeout)
02434 { return cso->isPendingPacket(timeout); };
02435
02441 inline size_t
02442 readControl(unsigned char *buffer, size_t len)
02443 { return cso->readPacket(buffer,len); };
02444
02450 inline size_t
02451 writeControl(const unsigned char* const buffer, size_t len)
02452 { return cso->writePacket(buffer,len); };
02453
02454 inline void
02455 endSocket()
02456 { dso->endSocket(); cso->endSocket(); };
02457
02458 private:
02466 inline tpport_t
02467 odd_port(tpport_t port)
02468 { return (port & 0x01)? (port) : (port - 1); };
02469
02477 inline tpport_t
02478 even_port(tpport_t port)
02479 { return (port & 0x01)? (port - 1) : (port); };
02480
02481 tpport_t base;
02482 dataSocket* dso;
02483 controlSocket* cso;
02484 };
02485
02492 typedef T_RTPSocket<QueueRTCPManager,UDPIPv4Socket,UDPIPv4Socket> RTPSocket;
02493
02504 class CCXX_CLASS_EXPORT RTPDuplex : public RTPQueue, protected UDPReceive, public UDPTransmit
02505 {
02506
02507 public:
02508
02515 RTPDuplex(const InetAddress &bind, tpport_t local, tpport_t remote, int pri);
02516
02520 virtual
02521 ~RTPDuplex();
02522
02529 sockerror_t
02530 Connect(const InetHostAddress &host, tpport_t port = 0);
02531
02532 protected:
02533
02538 bool
02539 isPendingData(microtimeout_t timeout)
02540 { return isPendingReceive(timeout); }
02541
02547 size_t
02548 writeData(const unsigned char *const buffer, size_t len)
02549 { return Transmit((const char *)buffer, len); }
02550
02556 size_t
02557 readData(unsigned char *buffer, size_t len)
02558 { return Receive(buffer, len); }
02559
02563 RTPSource &getPeer();
02564
02565 private:
02566
02567 tpport_t base;
02568 };
02569
02570 #ifdef CCXX_NAMESPACES
02571 };
02572 #endif
02573
02574 #endif //__CCXX_RTP_H__
02575