扩展(X):1 比特,若设置扩展比特,固定头(仅)后面跟随一个头扩展。
RTP 提供扩展机制以允许实现个性化:某些新的与负载格式独立的功能要求的附加信息在RTP 数据包头中传输。设计此方法可以使其它没有扩展的交互忽略此头扩展。RTP扩展头格式如图2所示。
图2 RTP扩展头格式
若 RTP 固定头中的扩展比特位置 1,则一个长度可变的头扩展部分被加到 RTP 固定头之后。头扩展包含 16 比特的长度域,指示扩展项中 32 比特字的个数,不包括 4 个字节扩展头(因此零是有效值)。RTP 固定头之后只允许有一个头扩展。为允许多个互操作实现独立生成不同的头扩展,或某种特定实现有多种不同的头扩展,扩展项的前 16 比特用以识别标识符或参数。这 16 比特的格式由具体实现的上层协议定义。基本的 RTP 说明并不定义任何头扩展本身。
RTP包解析
static int parsingRTPPacket(uint8_t *data, size_t size) {
if (size < 12) {
//Too short to be a valid RTP header.
return -1;
}
if ((data[0] >> 6) != 2) {
//Currently, the version is 2, if is not 2, unsupported.
return -1;
}
if (data[0] & 0x20) {
// Padding present.
size_t paddingLength = data[size - 1];
if (paddingLength + 12 > size) {
return -1;
}
size -= paddingLength;
}
int numCSRCs = data[0] & 0x0f;
size_t payloadOffset = 12 + 4 * numCSRCs;
if (size < payloadOffset) {
// Not enough data to fit the basic header and all the CSRC entries.
return -1;
}
if (data[0] & 0x10) {
// Header extension present.
if (size < payloadOffset + 4) {
// Not enough data to fit the basic header, all CSRC entries and the first 4 bytes of the extension header.
return -1;
}
const uint8_t *extensionData = &data[payloadOffset];
size_t extensionLength = 4 * (extensionData[2] << 8 | extensionData[3]);
if (size < payloadOffset + 4 + extensionLength) {
return -1;
}
payloadOffset += (4 + extensionLength);
}
uint32_t rtpTime = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
uint32_t srcId = data[8] << 24 | data[9] << 16 | data[10] << 8 | data[11];
uint32_t seqNum = data[2] << 8 | data[3];
return 0;
}