本文共 4755 字,大约阅读时间需要 15 分钟。
RTP需要RTCP为其服务质量提供保证,因此下面介绍一下RTCP的相关知识。2) RTP将RTP 数据包发往UDP端口对中偶数端口;RTCP将RTCP控制包发往UDP端口对中的接收端口。
RTCP的bit图
// 0 1 2 3 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ //byte=0 |V=2|P| RC | PT=SR=200 | length | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // 4 | SSRC of sender | // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ // 8 | NTP timestamp, most significant word | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // 12 | NTP timestamp, least significant word | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // 16 | RTP timestamp | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // 20 | sender's packet count | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // 24 | sender's octet count | // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ // 28 |V=2|P| SC | PT=SDES=202 | length | // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ // 32 | SSRC/CSRC_1 | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // 36 | CNAME=1 | length | user and domain name ... // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+生成RTCP包的代码:
void CreateSendReportRtcp(std::string &buffer, uint32_t ssrc, uint32_t timestamp, int sendPacketsNum, int sendBytesNum) { buffer.resize(40); *(uint8_t*)&buffer[0] = (uint8_t)(2 << 6); // V=2, P=RC=0 *(uint8_t*)&buffer[1] = (uint8_t)200; // PT=SR=200 *(uint16_t*)&buffer[2] = (uint16_t)htons(6); // length (7 32-bit words, minus one) *(uint32_t*)&buffer[4] = (uint32_t)htonl(ssrc); *(uint32_t*)&buffer[8] = (uint32_t)(timestamp >> 32); // High 32-bits *(uint32_t*)&buffer[12] = (uint32_t)(timestamp & 0xFFFFFFFF); // Low 32-bits *(uint32_t*)&buffer[16] = (uint32_t)htonl(timestamp); *(uint32_t*)&buffer[20] = (uint32_t)htonl(sendPacketsNum); *(uint32_t*)&buffer[24] = (uint32_t)htonl(sendBytesNum); *(uint8_t*)&buffer[28] = (uint8_t)(2 << 6 | 1); // V=2, P=0, SC=1 *(uint8_t*)&buffer[29] = (uint8_t)202; *(uint16_t*)&buffer[30] = (uint16_t)htons(2); *(uint32_t*)&buffer[32] = (uint32_t)htonl(ssrc); *(uint8_t*)&buffer[36] = (uint8_t)1; *(uint8_t*)&buffer[37] = (uint8_t)0; *(uint16_t*)&buffer[38] = (uint16_t)0; }注意:CNAME是用来音视频同步的,因为在写接口的过程中没有涉及音视频同步,所以CNAME均设为空。
转载地址:http://srpmi.baihongyu.com/