一个 RTP 包由一个 12 字节的 RTP 包头和随后的 RTP 有效载荷组成。包头的第 3 和第 4 个字节包含 RTP 包序列号的最高有效字节和最低有效字节 Seq Num= (MSB< <8)+LSB
字符 pszPacket[12];
...
长 lSeq = ???? - 如何从数据包中获取序列号?
unsigned short seq = (packet[2] << 8) | packet[3];
请注意,这假设packet
是一个数组unsigned char
。
当然这只是“long lSeq = (unsigned char)(pszPacket[2] << 8) | (unsigned char)pszPacket[3];”?
假设我们有一个指向包含整个 RTP 数据包(包括 RTP 标头)的字节缓冲区的指针,称为 rtpBuffer,我们可以使用以下代码提取位置 2 和 3 中的 16 位字:
int8_t *rtpBuffer;
uint16_t packetSeqNbr = ntohs(*(reinterpret_cast<uint16_t *>(rtpBuffer + 2)));
ntohs() 用于将网络字节顺序转换为主机字节顺序,以便代码可移植到不同的机器。
如果您需要适当的实现:
typedef struct _RTPHeader
{
//first byte
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
unsigned int CC:4; /* CC field */
unsigned int X:1; /* X field */
unsigned int P:1; /* padding flag */
unsigned int version:2;
#elif G_BYTE_ORDER == G_BIG_ENDIAN
unsigned int version:2;
unsigned int P:1; /* padding flag */
unsigned int X:1; /* X field */
unsigned int CC:4; /* CC field*/
#else
#error "G_BYTE_ORDER should be big or little endian."
#endif
//second byte
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
unsigned int PT:7; /* PT field */
unsigned int M:1; /* M field */
#elif G_BYTE_ORDER == G_BIG_ENDIAN
unsigned int M:1; /* M field */
unsigned int PT:7; /* PT field */
#else
#error "G_BYTE_ORDER should be big or little endian."
#endif
guint16 seq_num; /* length of the recovery */
guint32 TS; /* Timestamp */
guint32 ssrc;
} RTPHeader; //12 bytes
你可以做的是:
char pszPacket[12];
RTPHeader* myRTPPacket = (RTPHeader*) pszPacket;
printf("Sequence number is: %hu", myRTPPacket->seq_num;
unsigned __int16 seq = _rotr16( *( unsigned __int16* )&packet[2] , 8 );