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 #ifndef CCXX_RTP_RTPPKT_H_
00039 #define CCXX_RTP_RTPPKT_H_
00040
00041 #include <ccrtp/base.h>
00042 #include <ccrtp/formats.h>
00043
00044 #ifdef CCXX_NAMESPACES
00045 namespace ost {
00046 #endif
00047
00071 class __EXPORT RTPPacket
00072 {
00073 private:
00074 struct RTPFixedHeader;
00075 struct RTPHeaderExt;
00076
00077 public:
00090 RTPPacket(const unsigned char* const block, size_t len,
00091 bool duplicate = false);
00092
00104 RTPPacket(size_t hdrlen, size_t plen, uint8 paddinglen);
00105
00112 inline uint32
00113 getHeaderSize() const
00114 { return hdrSize; }
00115
00119 inline const uint8* const
00120 getPayload() const
00121 { return (uint8*)(buffer + getHeaderSize()); }
00122
00126 inline uint32
00127 getPayloadSize() const
00128 { return payloadSize; }
00129
00133 inline PayloadType
00134 getPayloadType() const
00135 { return static_cast<PayloadType>(getHeader()->payload); }
00136
00140 inline uint16
00141 getSeqNum() const
00142 { return cachedSeqNum; }
00143
00147 inline uint32
00148 getTimestamp() const
00149 { return cachedTimestamp; }
00150
00154 inline uint8
00155 getProtocolVersion() const
00156 { return getHeader()->version; }
00157
00162 inline bool
00163 isPadded() const
00164 { return getHeader()->padding; }
00165
00172 inline uint8
00173 getPaddingSize() const
00174 { return buffer[total - 1]; }
00175
00182 inline bool
00183 isMarked() const
00184 { return getHeader()->marker; }
00185
00191 inline bool
00192 isExtended() const
00193 { return getHeader()->extension; }
00194
00199 inline uint16
00200 getCSRCsCount() const
00201 { return getHeader()->cc; }
00202
00210 inline const uint32*
00211 getCSRCs() const
00212 { return static_cast<const uint32*>(&(getHeader()->sources[1])); }
00213
00226 inline uint16
00227 getHdrExtUndefined() const
00228 { return (isExtended()? getHeaderExt()->undefined : 0); }
00229
00241 inline uint32
00242 getHdrExtSize() const
00243 { return (isExtended()?
00244 (static_cast<uint32>(getHeaderExt()->length) << 2) :
00245 0); }
00246
00253 inline const unsigned char*
00254 getHdrExtContent() const
00255 { return (isExtended() ?
00256 (reinterpret_cast<const unsigned char*>(getHeaderExt()) +
00257 sizeof(RTPHeaderExt)) :
00258 NULL); }
00259
00266 inline const unsigned char* const
00267 getRawPacket() const
00268 { return buffer; }
00269
00276 inline uint32
00277 getRawPacketSize() const
00278 { return total; };
00279
00280 inline size_t
00281 getSizeOfFixedHeader() const
00282 { return sizeof(RTPFixedHeader); }
00283
00284 protected:
00288 inline virtual ~RTPPacket()
00289 { endPacket(); };
00290
00294 void
00295 endPacket();
00296
00302 inline RTPFixedHeader*
00303 getHeader() const
00304 { return reinterpret_cast<RTPFixedHeader*>(buffer); }
00305
00306 inline void
00307 setExtension(bool e)
00308 { getHeader()->extension = e; }
00309
00317 inline const RTPHeaderExt*
00318 getHeaderExt() const
00319 {
00320 uint32 fixsize = sizeof(RTPFixedHeader) + (getHeader()->cc << 2);
00321 return (reinterpret_cast<RTPHeaderExt*>(buffer + fixsize));
00322 }
00323
00329 inline uint32
00330 getRawTimestamp() const
00331 { return ntohl(getHeader()->timestamp); };
00332
00333 inline void
00334 setbuffer(const void* src, size_t len, size_t pos)
00335 { memcpy(buffer + pos,src,len); }
00336
00338 uint16 cachedSeqNum;
00340 uint32 cachedTimestamp;
00341
00342 private:
00344 unsigned char* buffer;
00346 uint32 hdrSize;
00348 uint32 payloadSize;
00350 uint32 total;
00352 bool duplicated;
00353
00354 #pragma pack(1)
00355
00365 struct RTPFixedHeader
00366 {
00367 #if __BYTE_ORDER == __BIG_ENDIAN
00368
00369 unsigned char version:2;
00370 unsigned char padding:1;
00371 unsigned char extension:1;
00372 unsigned char cc:4;
00373 unsigned char marker:1;
00374 unsigned char payload:7;
00375 #else
00376
00377 unsigned char cc:4;
00378 unsigned char extension:1;
00379 unsigned char padding:1;
00380 unsigned char version:2;
00381 unsigned char payload:7;
00382 unsigned char marker:1;
00383 #endif
00384 uint16 sequence;
00385 uint32 timestamp;
00386 uint32 sources[1];
00387 };
00388
00397 struct RFC2833Payload
00398 {
00399 #if __BYTE_ORDER == __BIG_ENDIAN
00400 uint8 event : 8;
00401 bool ebit : 1;
00402 bool rbit : 1;
00403 uint8 vol : 6;
00404 uint16 duration : 16;
00405 #else
00406 uint8 event : 8;
00407 uint8 vol : 6;
00408 bool rbit : 1;
00409 bool ebit : 1;
00410 uint16 duration : 16;
00411 #endif
00412 };
00413
00421 struct RTPHeaderExt
00422 {
00423 uint16 undefined;
00424 uint16 length;
00425 };
00426 #pragma pack()
00427
00428
00429
00435 inline struct RFC2833Payload *getRaw2833Payload(void)
00436 {return (struct RFC2833Payload *)getPayload();};
00437
00443 inline uint16 get2833Duration(void)
00444 {return ntohs(getRaw2833Payload()->duration);};
00445
00451 inline void set2833Duration(uint16 d)
00452 {getRaw2833Payload()->duration = htons(d);};
00453 };
00454
00465 class __EXPORT OutgoingRTPPkt : public RTPPacket
00466 {
00467 public:
00487 OutgoingRTPPkt(const uint32* const csrcs, uint16 numcsrc,
00488 const unsigned char* const hdrext, uint32 hdrextlen,
00489 const unsigned char* const data, size_t datalen,
00490 uint8 paddinglen);
00491
00505 OutgoingRTPPkt(const uint32* const csrcs, uint16 numcsrc,
00506 const unsigned char* const data, size_t datalen,
00507 uint8 paddinglen);
00508
00518 OutgoingRTPPkt(const unsigned char* const data, size_t datalen,
00519 uint8 paddinglen);
00520
00521 ~OutgoingRTPPkt()
00522 { }
00523
00527 inline void
00528 setPayloadType(PayloadType pt)
00529 { getHeader()->payload = pt; };
00530
00534 inline void
00535 setSeqNum(uint16 seq)
00536 {
00537 cachedSeqNum = seq;
00538 getHeader()->sequence = htons(seq);
00539 }
00540
00544 inline void
00545 setTimestamp(uint32 pts)
00546 {
00547 cachedTimestamp = pts;
00548 getHeader()->timestamp = htonl(pts);
00549 }
00550
00557 inline void
00558 setSSRC(uint32 ssrc) const
00559 { getHeader()->sources[0] = htonl(ssrc); }
00560
00568 inline void
00569 setSSRCNetwork(uint32 ssrc) const
00570 { getHeader()->sources[0] = ssrc; }
00571
00579 inline void
00580 setMarker(bool mark)
00581 { getHeader()->marker = mark; }
00582
00586 inline bool
00587 operator==(const OutgoingRTPPkt &p) const
00588 { return ( this->getSeqNum() == p.getSeqNum() ); }
00589
00593 inline bool
00594 operator!=(const OutgoingRTPPkt &p) const
00595 { return ( this->getSeqNum() != p.getSeqNum() ); }
00596
00597 private:
00602 OutgoingRTPPkt(const OutgoingRTPPkt &o);
00603
00608 OutgoingRTPPkt&
00609 operator=(const OutgoingRTPPkt &o);
00610
00615 void setCSRCArray(const uint32* const csrcs, uint16 numcsrc);
00616 };
00617
00630 class __EXPORT IncomingRTPPkt : public RTPPacket
00631 {
00632 public:
00645 IncomingRTPPkt(const unsigned char* block, size_t len);
00646
00647 ~IncomingRTPPkt()
00648 { }
00649
00655 inline bool
00656 isHeaderValid()
00657 { return headerValid; }
00658
00665 inline uint32
00666 getSSRC() const
00667 { return cachedSSRC; }
00668
00673 inline bool
00674 operator==(const IncomingRTPPkt &p) const
00675 { return ( (this->getSeqNum() == p.getSeqNum()) &&
00676 (this->getSSRC() == p.getSSRC()) ); }
00677
00682 inline bool
00683 operator!=(const IncomingRTPPkt &p) const
00684 { return !( *this == p ); }
00685
00686 private:
00691 IncomingRTPPkt(const IncomingRTPPkt &ip);
00692
00697 IncomingRTPPkt&
00698 operator=(const IncomingRTPPkt &ip);
00699
00701 bool headerValid;
00703 uint32 cachedSSRC;
00704
00705
00706
00707 static const uint16 RTP_INVALID_PT_MASK;
00708 static const uint16 RTP_INVALID_PT_VALUE;
00709 };
00710
00712
00713 #ifdef CCXX_NAMESPACES
00714 }
00715 #endif
00716
00717 #endif // ndef CCXX_RTP_RTPPKT_H_
00718