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