重写rtp框架

This commit is contained in:
xiongziliang
2021-01-31 19:19:24 +08:00
parent 5175c52abe
commit 070bf19cb5
21 changed files with 395 additions and 322 deletions

View File

@@ -11,10 +11,6 @@
#include "Common/config.h"
#include "RtpReceiver.h"
#define AV_RB16(x) \
((((const uint8_t*)(x))[0] << 8) | \
((const uint8_t*)(x))[1])
#define RTP_MAX_SIZE (10 * 1024)
namespace mediakit {
@@ -28,122 +24,67 @@ RtpReceiver::RtpReceiver() {
++index;
}
}
RtpReceiver::~RtpReceiver() {}
bool RtpReceiver::handleOneRtp(int track_index, TrackType type, int samplerate, uint8_t *rtp_raw_ptr, size_t rtp_raw_len) {
if (rtp_raw_len < 12) {
WarnL << "rtp包太小:" << rtp_raw_len;
bool RtpReceiver::handleOneRtp(int index, TrackType type, int sample_rate, uint8_t *ptr, size_t len) {
if (len < RtpPacket::kRtpHeaderSize) {
WarnL << "rtp包太小:" << len;
return false;
}
uint32_t version = rtp_raw_ptr[0] >> 6;
uint8_t padding = 0;
uint8_t ext = rtp_raw_ptr[0] & 0x10;
uint8_t csrc = rtp_raw_ptr[0] & 0x0f;
if (rtp_raw_ptr[0] & 0x20) {
//获取padding大小
padding = rtp_raw_ptr[rtp_raw_len - 1];
//移除padding flag
rtp_raw_ptr[0] &= ~0x20;
//移除padding字节
rtp_raw_len -= padding;
if (len > RTP_MAX_SIZE) {
WarnL << "超大的rtp包:" << len << " > " << RTP_MAX_SIZE;
return false;
}
if (version != 2) {
throw std::invalid_argument("非法的rtpversion != 2");
}
auto rtp_ptr = _rtp_pool.obtain();
auto &rtp = *rtp_ptr;
rtp.type = type;
rtp.interleaved = 2 * type;
rtp.mark = rtp_raw_ptr[1] >> 7;
rtp.PT = rtp_raw_ptr[1] & 0x7F;
//序列号,内存对齐
memcpy(&rtp.sequence, rtp_raw_ptr + 2, 2);
rtp.sequence = ntohs(rtp.sequence);
//时间戳,内存对齐
memcpy(&rtp.timeStamp, rtp_raw_ptr + 4, 4);
rtp.timeStamp = ntohl(rtp.timeStamp);
if (!samplerate) {
if (!sample_rate) {
//无法把时间戳转换成毫秒
return false;
}
//时间戳转换成毫秒
rtp.timeStamp = rtp.timeStamp * 1000LL / samplerate;
//ssrc,内存对齐
memcpy(&rtp.ssrc, rtp_raw_ptr + 8, 4);
rtp.ssrc = ntohl(rtp.ssrc);
if (_ssrc[track_index] != rtp.ssrc) {
if (_ssrc[track_index] == 0) {
//保存SSRC至track对象
_ssrc[track_index] = rtp.ssrc;
} else {
//ssrc错误
WarnL << "ssrc错误:" << rtp.ssrc << " != " << _ssrc[track_index];
if (_ssrc_err_count[track_index]++ > 10) {
//ssrc切换后清除老数据
WarnL << "ssrc更换:" << _ssrc[track_index] << " -> " << rtp.ssrc;
_rtp_sortor[track_index].clear();
_ssrc[track_index] = rtp.ssrc;
}
return false;
}
RtpHeader *header = (RtpHeader *) ptr;
if (header->version != RtpPacket::kRtpVersion) {
throw std::invalid_argument("非法的rtpversion字段非法");
}
//ssrc匹配正确不匹配计数清零
_ssrc_err_count[track_index] = 0;
//rtp 12个固定字节头
rtp.offset = 12;
//rtp有csrc
rtp.offset += 4 * csrc;
if (ext) {
//rtp有ext
uint16_t reserved = AV_RB16(rtp_raw_ptr + rtp.offset);
uint16_t extlen = AV_RB16(rtp_raw_ptr + rtp.offset + 2) << 2;
rtp.offset += extlen + 4;
}
if (rtp_raw_len <= rtp.offset) {
if (!header->getPayloadSize(len)) {
//无有效负载的rtp包
return false;
}
if (rtp_raw_len > RTP_MAX_SIZE) {
WarnL << "超大的rtp包:" << rtp_raw_len << " > " << RTP_MAX_SIZE;
//比对缓存ssrc
auto ssrc = ntohl(header->ssrc);
if (!_ssrc[index]) {
//保存SSRC至track对象
_ssrc[index] = ssrc;
} else if (_ssrc[index] != ssrc) {
//ssrc错误
WarnL << "ssrc错误:" << ssrc << " != " << _ssrc[index];
return false;
}
//设置rtp负载长度
rtp.setCapacity(rtp_raw_len + 4);
rtp.setSize(rtp_raw_len + 4);
uint8_t *payload_ptr = (uint8_t *) rtp.data();
payload_ptr[0] = '$';
payload_ptr[1] = rtp.interleaved;
payload_ptr[2] = (rtp_raw_len >> 8) & 0xFF;
payload_ptr[3] = rtp_raw_len & 0xFF;
//添加rtp over tcp前4个字节的偏移量
rtp.offset += 4;
//拷贝rtp负载
memcpy(payload_ptr + 4, rtp_raw_ptr, rtp_raw_len);
//排序rtp
auto seq = rtp_ptr->sequence;
onBeforeRtpSorted(rtp_ptr, track_index);
_rtp_sortor[track_index].sortPacket(seq, std::move(rtp_ptr));
auto rtp = _rtp_pool.obtain();
//需要添加4个字节的rtp over tcp头
rtp->setCapacity(RtpPacket::kRtpTcpHeaderSize + len);
rtp->setSize(RtpPacket::kRtpTcpHeaderSize + len);
rtp->sample_rate = sample_rate;
rtp->type = type;
//赋值4个字节的rtp over tcp头
uint8_t *data = (uint8_t *) rtp->data();
data[0] = '$';
data[1] = 2 * type;
data[2] = (len >> 8) & 0xFF;
data[3] = len & 0xFF;
//拷贝rtp
memcpy(&data[4], ptr, len);
onBeforeRtpSorted(rtp, index);
auto seq = rtp->getSeq();
_rtp_sortor[index].sortPacket(seq, std::move(rtp));
return true;
}
void RtpReceiver::clear() {
CLEAR_ARR(_ssrc);
CLEAR_ARR(_ssrc_err_count);
for (auto &sortor : _rtp_sortor) {
sortor.clear();
}
@@ -153,16 +94,16 @@ void RtpReceiver::setPoolSize(size_t size) {
_rtp_pool.setSize(size);
}
size_t RtpReceiver::getJitterSize(int track_index) const{
return _rtp_sortor[track_index].getJitterSize();
size_t RtpReceiver::getJitterSize(int index) const{
return _rtp_sortor[index].getJitterSize();
}
size_t RtpReceiver::getCycleCount(int track_index) const{
return _rtp_sortor[track_index].getCycleCount();
size_t RtpReceiver::getCycleCount(int index) const{
return _rtp_sortor[index].getCycleCount();
}
uint32_t RtpReceiver::getSSRC(int track_index) const{
return _ssrc[track_index];
uint32_t RtpReceiver::getSSRC(int index) const{
return _ssrc[index];
}
}//namespace mediakit