ZLMediaKit/src/Rtsp/RtpReceiver.cpp

162 lines
4.6 KiB
C++
Raw Normal View History

2018-12-14 17:46:12 +08:00
/*
2020-04-04 20:30:09 +08:00
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
2018-12-14 17:46:12 +08:00
*
* This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
*
2020-04-04 20:30:09 +08:00
* Use of this source code is governed by MIT license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
2018-12-14 17:46:12 +08:00
*/
#include "Common/config.h"
#include "RtpReceiver.h"
2019-06-24 16:56:46 +08:00
#define AV_RB16(x) \
2018-12-14 17:46:12 +08:00
((((const uint8_t*)(x))[0] << 8) | \
((const uint8_t*)(x))[1])
2019-06-24 16:56:46 +08:00
#define RTP_MAX_SIZE (10 * 1024)
2018-12-14 17:46:12 +08:00
namespace mediakit {
2020-10-01 19:02:14 +08:00
RtpReceiver::RtpReceiver() {
int index = 0;
for (auto &sortor : _rtp_sortor) {
2020-10-01 21:33:07 +08:00
sortor.setOnSort([this, index](uint16_t seq, RtpPacket::Ptr &packet) {
2020-10-01 19:02:14 +08:00
onRtpSorted(packet, index);
});
++index;
}
}
2018-12-14 17:46:12 +08:00
RtpReceiver::~RtpReceiver() {}
2020-07-08 23:23:11 +08:00
bool RtpReceiver::handleOneRtp(int track_index, TrackType type, int samplerate, unsigned char *rtp_raw_ptr, unsigned int rtp_raw_len) {
2020-10-01 21:33:07 +08:00
if (rtp_raw_len < 12) {
WarnL << "rtp包太小:" << rtp_raw_len;
2019-08-19 23:08:41 +08:00
return false;
}
2020-10-24 23:32:43 +08:00
uint32_t version = rtp_raw_ptr[0] >> 6;
uint8_t padding = 0;
2020-10-24 23:32:43 +08:00
uint8_t ext = rtp_raw_ptr[0] & 0x10;
uint8_t csrc = rtp_raw_ptr[0] & 0x0f;
2020-05-08 21:57:56 +08:00
if (rtp_raw_ptr[0] & 0x20) {
//获取padding大小
padding = rtp_raw_ptr[rtp_raw_len - 1];
//移除padding flag
2020-05-08 21:57:56 +08:00
rtp_raw_ptr[0] &= ~0x20;
//移除padding字节
rtp_raw_len -= padding;
}
2020-10-24 23:32:43 +08:00
if (version != 2) {
throw std::invalid_argument("非法的rtpversion != 2");
}
2019-06-24 16:56:46 +08:00
auto rtp_ptr = _rtp_pool.obtain();
auto &rtp = *rtp_ptr;
2018-12-14 17:46:12 +08:00
2020-07-08 23:23:11 +08:00
rtp.type = type;
rtp.interleaved = 2 * type;
2019-06-24 16:56:46 +08:00
rtp.mark = rtp_raw_ptr[1] >> 7;
rtp.PT = rtp_raw_ptr[1] & 0x7F;
//序列号,内存对齐
memcpy(&rtp.sequence, rtp_raw_ptr + 2, 2);
2019-06-24 16:56:46 +08:00
rtp.sequence = ntohs(rtp.sequence);
//时间戳,内存对齐
memcpy(&rtp.timeStamp, rtp_raw_ptr + 4, 4);
rtp.timeStamp = ntohl(rtp.timeStamp);
2018-12-14 18:24:27 +08:00
2020-10-01 21:33:07 +08:00
if (!samplerate) {
2019-06-24 16:56:46 +08:00
//无法把时间戳转换成毫秒
2018-12-14 18:24:27 +08:00
return false;
}
2018-12-14 17:46:12 +08:00
//时间戳转换成毫秒
2020-07-08 23:23:11 +08:00
rtp.timeStamp = rtp.timeStamp * 1000LL / samplerate;
//ssrc,内存对齐
memcpy(&rtp.ssrc, rtp_raw_ptr + 8, 4);
2019-06-24 16:56:46 +08:00
rtp.ssrc = ntohl(rtp.ssrc);
2020-07-08 23:23:11 +08:00
if (_ssrc[track_index] != rtp.ssrc) {
if (_ssrc[track_index] == 0) {
2019-06-24 16:56:46 +08:00
//保存SSRC至track对象
2020-07-08 23:23:11 +08:00
_ssrc[track_index] = rtp.ssrc;
2020-10-01 21:33:07 +08:00
} else {
2019-06-24 16:56:46 +08:00
//ssrc错误
2020-07-08 23:23:11 +08:00
WarnL << "ssrc错误:" << rtp.ssrc << " != " << _ssrc[track_index];
2019-06-24 16:56:46 +08:00
if (_ssrc_err_count[track_index]++ > 10) {
//ssrc切换后清除老数据
2020-07-08 23:23:11 +08:00
WarnL << "ssrc更换:" << _ssrc[track_index] << " -> " << rtp.ssrc;
2020-10-01 19:02:14 +08:00
_rtp_sortor[track_index].clear();
2020-07-08 23:23:11 +08:00
_ssrc[track_index] = rtp.ssrc;
2019-06-24 16:56:46 +08:00
}
return false;
2018-12-14 17:46:12 +08:00
}
}
2019-06-24 16:56:46 +08:00
//ssrc匹配正确不匹配计数清零
_ssrc_err_count[track_index] = 0;
2018-12-14 17:46:12 +08:00
2019-06-24 16:07:44 +08:00
//获取rtp中媒体数据偏移量
2020-10-01 21:33:07 +08:00
rtp.offset = 12 + 4;
rtp.offset += 4 * csrc;
2019-06-24 16:56:46 +08:00
if (ext && rtp_raw_len >= rtp.offset) {
2018-12-14 17:46:12 +08:00
/* calculate the header extension length (stored as number of 32-bit words) */
2019-06-24 16:56:46 +08:00
ext = (AV_RB16(rtp_raw_ptr + rtp.offset - 2) + 1) << 2;
rtp.offset += ext;
2018-12-14 17:46:12 +08:00
}
2019-04-24 11:40:54 +08:00
2020-10-01 21:33:07 +08:00
if (rtp_raw_len + 4 <= rtp.offset) {
WarnL << "无有效负载的rtp包:" << rtp_raw_len << " <= " << (int) rtp.offset;
2019-04-24 11:40:54 +08:00
return false;
}
2020-10-01 21:33:07 +08:00
if (rtp_raw_len > RTP_MAX_SIZE) {
WarnL << "超大的rtp包:" << rtp_raw_len << " > " << RTP_MAX_SIZE;
2019-06-24 16:56:46 +08:00
return false;
}
//设置rtp负载长度
rtp.setCapacity(rtp_raw_len + 4);
rtp.setSize(rtp_raw_len + 4);
2020-10-01 21:33:07 +08:00
uint8_t *payload_ptr = (uint8_t *) rtp.data();
2019-06-24 16:07:44 +08:00
payload_ptr[0] = '$';
2019-06-24 16:56:46 +08:00
payload_ptr[1] = rtp.interleaved;
payload_ptr[2] = rtp_raw_len >> 8;
payload_ptr[3] = (rtp_raw_len & 0x00FF);
2019-06-24 16:07:44 +08:00
//拷贝rtp负载
2019-06-24 16:56:46 +08:00
memcpy(payload_ptr + 4, rtp_raw_ptr, rtp_raw_len);
2020-10-24 23:28:56 +08:00
2019-06-24 16:56:46 +08:00
//排序rtp
2020-10-24 23:28:56 +08:00
auto seq = rtp_ptr->sequence;
_rtp_sortor[track_index].sortPacket(seq, std::move(rtp_ptr));
2019-06-24 16:56:46 +08:00
return true;
}
2018-12-14 17:46:12 +08:00
void RtpReceiver::clear() {
2020-07-08 23:23:11 +08:00
CLEAR_ARR(_ssrc);
CLEAR_ARR(_ssrc_err_count);
2020-10-01 19:02:14 +08:00
for (auto &sortor : _rtp_sortor) {
sortor.clear();
}
2018-12-14 17:46:12 +08:00
}
void RtpReceiver::setPoolSize(int size) {
2019-06-24 16:56:46 +08:00
_rtp_pool.setSize(size);
2018-12-14 17:46:12 +08:00
}
2019-06-24 17:01:15 +08:00
int RtpReceiver::getJitterSize(int track_index){
2020-10-01 19:02:14 +08:00
return _rtp_sortor[track_index].getJitterSize();
2019-05-09 13:35:54 +08:00
}
2019-06-24 17:01:15 +08:00
int RtpReceiver::getCycleCount(int track_index){
2020-10-01 19:02:14 +08:00
return _rtp_sortor[track_index].getCycleCount();
2019-05-09 13:35:54 +08:00
}
2018-12-14 17:46:12 +08:00
}//namespace mediakit