#ifndef __RTP_HEADER_H__
#define __RTP_HEADER_H__
typedef unsigned short WORD;
typedef unsigned long DWORD;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned int u_int32_t;
typedef unsigned short u_int16_t;
typedef unsigned char u_int8_t;
typedef struct
{
WORD cc: 4; /* csrc count */
WORD ext: 1; /* header extension flag */
WORD pad: 1; /* padding flag - for encryption */
WORD ver: 2; /* protocal version */
WORD pt: 7; /* payload type */
WORD mk: 1; /* marker bit - for profile */
WORD seq; /* sequence number of this packet */
DWORD ts; /* timestamp of this packet */
DWORD ssrc; /* source of packet */
} RTP_HEADER;
class RtpHeader {
public:
RtpHeader(uint8_t *buf, int len);
virtual ~RtpHeader();
uint8_t* payload();
int length() { return fLength; }
int payloadLen();
uint16_t version() { return fVersion; }
uint16_t padding() { return fPadding; }
uint16_t extension() { return fExtension; }
uint16_t csrcCount() { return fCSRCCount; }
uint16_t markerBit() { return fMarkerBit; }
uint16_t payloadType() { return fPayloadType; }
uint16_t sequenceNum() { return fSequenceNum; }
uint32_t timestamp() { return fTimestamp; }
uint32_t ssrc() { return fSSRC; }
private:
uint8_t* fBuf;
int fLength;
uint16_t fVersion;
uint16_t fPadding;
uint16_t fExtension;
uint16_t fCSRCCount;
uint16_t fMarkerBit;
uint16_t fPayloadType;
uint16_t fSequenceNum;
uint32_t fTimestamp;
uint32_t fSSRC;
uint8_t *fCurPtr;
};
#endif
< RTPHeader.cpp >
#include <Winsock2.h>
#include "RTPHeader.h"
#include "RTPHeader.h"
RtpHeader::RtpHeader(uint8_t *buf, int len) : fBuf(NULL), fLength(0), fVersion(0), fPadding(0), fExtension(0), fCSRCCount(0),
fMarkerBit(0), fPayloadType(0), fSequenceNum(0), fTimestamp(0), fSSRC(0)
{
if (len < sizeof(RTP_HEADER))
return;
fBuf = fCurPtr = buf;
fLength = len;
RTP_HEADER *p = (RTP_HEADER *)buf;
fCSRCCount = p->cc;
fExtension = p->ext;
fPadding = p->pad;
fVersion = p->ver;
fPayloadType = p->pt;
fMarkerBit = p->mk;
fSequenceNum = ntohs(p->seq);
fTimestamp = ntohl(p->ts);
fSSRC = ntohl(p->ssrc);
fCurPtr += sizeof(RTP_HEADER);
// check RTP version (it must be 2)
if (fVersion != 2)
DPRINTF("invalid rtp version %u\n", fVersion);
// skip CSRC
if (fCSRCCount > 0) {
if (payloadLen() <= fCSRCCount*4) {
DPRINTF("invalid rtp header, CSRC count error %u\n", fCSRCCount);
} else {
fCurPtr += (fCSRCCount*4);
}
}
// skip Extension field
if (fExtension) {
if (payloadLen() <= 4) {
DPRINTF("invalid rtp header, extension length error\n");
} else {
unsigned extHdr = ntohl(*(unsigned *)fCurPtr); fCurPtr += 4;
unsigned remExtSize = 4*(extHdr&0xFFFF);
if (payloadLen() <= remExtSize) {
DPRINTF("invalid rtp header, extension size error %u\n", remExtSize);
} else {
fCurPtr += remExtSize;
}
}
}
// remove padding
if (fPadding) {
if (payloadLen() <= 0) {
DPRINTF("invalid rtp header, padding error\n");
} else {
unsigned numPaddingBytes = (unsigned)fBuf[fLength-1];
if (payloadLen() <= numPaddingBytes) {
DPRINTF("invalid rtp header, padding number error\n");
} else {
fLength -= numPaddingBytes;
fPadding = p->pad = 0;
fPadding = p->pad = 0;
}
}
}
}
RtpHeader::~RtpHeader()
{
}
uint8_t* RtpHeader::payload()
{
return fCurPtr;
}
int RtpHeader::payloadLen()
{
uint8_t *ptrLast = &fBuf[fLength-1];
return ptrLast-fCurPtr+1;
}
< 사용 >
...
RtpHeader *rtp = new RtpHeader((uint8_t*)buf, len);
unsigned short pt = rtp->payloadType();
unsigned short mk = rtp->markerBit();
unsigned short seqnum = rtp->sequenceNum();
unsigned int ts = rtp->timestamp();
unsigned int rtpSSRC = rtp->ssrc();
delete rtp;