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"
|
|
|
|
|
|
|
|
|
|
#define POP_HEAD(trackidx) \
|
2020-03-20 11:51:24 +08:00
|
|
|
|
auto it = _rtp_sort_cache_map[trackidx].begin(); \
|
|
|
|
|
onRtpSorted(it->second, trackidx); \
|
|
|
|
|
_rtp_sort_cache_map[trackidx].erase(it);
|
2018-12-14 17:46:12 +08:00
|
|
|
|
|
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 {
|
|
|
|
|
|
|
|
|
|
RtpReceiver::RtpReceiver() {}
|
|
|
|
|
RtpReceiver::~RtpReceiver() {}
|
|
|
|
|
|
2019-06-24 16:56:46 +08:00
|
|
|
|
bool RtpReceiver::handleOneRtp(int track_index,SdpTrack::Ptr &track, unsigned char *rtp_raw_ptr, unsigned int rtp_raw_len) {
|
2019-08-19 23:08:41 +08:00
|
|
|
|
if(rtp_raw_len < 12){
|
2019-08-20 09:22:13 +08:00
|
|
|
|
WarnL << "rtp包太小:" << rtp_raw_len;
|
2019-08-19 23:08:41 +08:00
|
|
|
|
return false;
|
|
|
|
|
}
|
2019-08-20 09:22:13 +08:00
|
|
|
|
|
|
|
|
|
uint8_t padding = 0;
|
|
|
|
|
if (rtp_raw_ptr[0] & 0x40) {
|
|
|
|
|
//获取padding大小
|
|
|
|
|
padding = rtp_raw_ptr[rtp_raw_len - 1];
|
|
|
|
|
//移除padding flag
|
|
|
|
|
rtp_raw_ptr[0] &= ~0x40;
|
|
|
|
|
//移除padding字节
|
|
|
|
|
rtp_raw_len -= padding;
|
|
|
|
|
}
|
|
|
|
|
|
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
|
|
|
|
|
2019-08-20 09:22:13 +08:00
|
|
|
|
rtp.type = track->_type;
|
2019-06-27 12:21:01 +08:00
|
|
|
|
rtp.interleaved = 2 * track->_type;
|
2019-06-24 16:56:46 +08:00
|
|
|
|
rtp.mark = rtp_raw_ptr[1] >> 7;
|
|
|
|
|
rtp.PT = rtp_raw_ptr[1] & 0x7F;
|
2019-08-20 09:22:13 +08:00
|
|
|
|
|
|
|
|
|
//序列号,内存对齐
|
|
|
|
|
memcpy(&rtp.sequence, rtp_raw_ptr + 2, 2);
|
2019-06-24 16:56:46 +08:00
|
|
|
|
rtp.sequence = ntohs(rtp.sequence);
|
2019-08-20 09:22:13 +08:00
|
|
|
|
|
|
|
|
|
//时间戳,内存对齐
|
|
|
|
|
memcpy(&rtp.timeStamp, rtp_raw_ptr + 4, 4);
|
|
|
|
|
rtp.timeStamp = ntohl(rtp.timeStamp);
|
2018-12-14 18:24:27 +08:00
|
|
|
|
|
|
|
|
|
if(!track->_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
|
|
|
|
//时间戳转换成毫秒
|
2019-08-20 09:22:13 +08:00
|
|
|
|
rtp.timeStamp = rtp.timeStamp * 1000LL / track->_samplerate;
|
|
|
|
|
|
|
|
|
|
//ssrc,内存对齐
|
|
|
|
|
memcpy(&rtp.ssrc, rtp_raw_ptr + 8, 4);
|
2019-06-24 16:56:46 +08:00
|
|
|
|
rtp.ssrc = ntohl(rtp.ssrc);
|
|
|
|
|
|
|
|
|
|
if (track->_ssrc != rtp.ssrc) {
|
|
|
|
|
if (track->_ssrc == 0) {
|
|
|
|
|
//保存SSRC至track对象
|
|
|
|
|
track->_ssrc = rtp.ssrc;
|
|
|
|
|
}else{
|
|
|
|
|
//ssrc错误
|
|
|
|
|
WarnL << "ssrc错误:" << rtp.ssrc << " != " << track->_ssrc;
|
|
|
|
|
if (_ssrc_err_count[track_index]++ > 10) {
|
|
|
|
|
//ssrc切换后清除老数据
|
|
|
|
|
WarnL << "ssrc更换:" << track->_ssrc << " -> " << rtp.ssrc;
|
|
|
|
|
_rtp_sort_cache_map[track_index].clear();
|
|
|
|
|
track->_ssrc = rtp.ssrc;
|
|
|
|
|
}
|
|
|
|
|
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中媒体数据偏移量
|
2019-06-24 16:56:46 +08:00
|
|
|
|
rtp.offset = 12 + 4;
|
|
|
|
|
int csrc = rtp_raw_ptr[0] & 0x0f;
|
|
|
|
|
int ext = rtp_raw_ptr[0] & 0x10;
|
|
|
|
|
rtp.offset += 4 * csrc;
|
|
|
|
|
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
|
|
|
|
|
2019-08-20 09:30:39 +08:00
|
|
|
|
if(rtp_raw_len + 4 <= rtp.offset){
|
2019-08-20 09:22:13 +08:00
|
|
|
|
WarnL << "无有效负载的rtp包:" << rtp_raw_len << " <= " << (int)rtp.offset;
|
2019-04-24 11:40:54 +08:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-20 09:22:13 +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负载长度
|
2019-08-20 09:22:13 +08:00
|
|
|
|
rtp.setCapacity(rtp_raw_len + 4);
|
|
|
|
|
rtp.setSize(rtp_raw_len + 4);
|
2019-06-24 16:56:46 +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);
|
|
|
|
|
//排序rtp
|
|
|
|
|
sortRtp(rtp_ptr,track_index);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2018-12-14 17:46:12 +08:00
|
|
|
|
|
2019-06-24 16:56:46 +08:00
|
|
|
|
void RtpReceiver::sortRtp(const RtpPacket::Ptr &rtp,int track_index){
|
|
|
|
|
if(rtp->sequence != _last_seq[track_index] + 1 && _last_seq[track_index] != 0){
|
2018-12-14 17:46:12 +08:00
|
|
|
|
//包乱序或丢包
|
2019-06-24 16:56:46 +08:00
|
|
|
|
_seq_ok_count[track_index] = 0;
|
|
|
|
|
_sort_started[track_index] = true;
|
|
|
|
|
if(_last_seq[track_index] > rtp->sequence && _last_seq[track_index] - rtp->sequence > 0xFF){
|
2019-04-11 18:26:40 +08:00
|
|
|
|
//sequence回环,清空所有排序缓存
|
2019-06-24 16:56:46 +08:00
|
|
|
|
while (_rtp_sort_cache_map[track_index].size()) {
|
|
|
|
|
POP_HEAD(track_index)
|
2019-04-11 18:26:40 +08:00
|
|
|
|
}
|
2019-06-24 16:56:46 +08:00
|
|
|
|
++_seq_cycle_count[track_index];
|
2019-04-11 18:26:40 +08:00
|
|
|
|
}
|
2018-12-14 17:46:12 +08:00
|
|
|
|
}else{
|
|
|
|
|
//正确序列的包
|
2019-06-24 16:56:46 +08:00
|
|
|
|
_seq_ok_count[track_index]++;
|
2018-12-14 17:46:12 +08:00
|
|
|
|
}
|
2019-06-24 16:56:46 +08:00
|
|
|
|
|
|
|
|
|
_last_seq[track_index] = rtp->sequence;
|
2018-12-14 17:46:12 +08:00
|
|
|
|
|
|
|
|
|
//开始排序缓存
|
2019-06-24 16:56:46 +08:00
|
|
|
|
if (_sort_started[track_index]) {
|
|
|
|
|
_rtp_sort_cache_map[track_index].emplace(rtp->sequence, rtp);
|
2019-05-28 17:14:36 +08:00
|
|
|
|
GET_CONFIG(uint32_t,clearCount,Rtp::kClearCount);
|
|
|
|
|
GET_CONFIG(uint32_t,maxRtpCount,Rtp::kMaxRtpCount);
|
2019-06-24 16:56:46 +08:00
|
|
|
|
if (_seq_ok_count[track_index] >= clearCount) {
|
2018-12-14 17:46:12 +08:00
|
|
|
|
//网络环境改善,需要清空排序缓存
|
2019-06-24 16:56:46 +08:00
|
|
|
|
_seq_ok_count[track_index] = 0;
|
|
|
|
|
_sort_started[track_index] = false;
|
|
|
|
|
while (_rtp_sort_cache_map[track_index].size()) {
|
|
|
|
|
POP_HEAD(track_index)
|
2018-12-14 17:46:12 +08:00
|
|
|
|
}
|
2019-06-24 16:56:46 +08:00
|
|
|
|
} else if (_rtp_sort_cache_map[track_index].size() >= maxRtpCount) {
|
2018-12-14 17:46:12 +08:00
|
|
|
|
//排序缓存溢出
|
2019-06-24 16:56:46 +08:00
|
|
|
|
POP_HEAD(track_index)
|
2018-12-14 17:46:12 +08:00
|
|
|
|
}
|
|
|
|
|
}else{
|
|
|
|
|
//正确序列
|
2019-06-24 16:56:46 +08:00
|
|
|
|
onRtpSorted(rtp, track_index);
|
2018-12-14 17:46:12 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RtpReceiver::clear() {
|
2019-06-24 16:56:46 +08:00
|
|
|
|
CLEAR_ARR(_last_seq)
|
|
|
|
|
CLEAR_ARR(_ssrc_err_count)
|
|
|
|
|
CLEAR_ARR(_seq_ok_count)
|
|
|
|
|
CLEAR_ARR(_sort_started)
|
|
|
|
|
CLEAR_ARR(_seq_cycle_count)
|
|
|
|
|
|
|
|
|
|
_rtp_sort_cache_map[0].clear();
|
|
|
|
|
_rtp_sort_cache_map[1].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){
|
|
|
|
|
return _rtp_sort_cache_map[track_index].size();
|
2019-05-09 13:35:54 +08:00
|
|
|
|
}
|
|
|
|
|
|
2019-06-24 17:01:15 +08:00
|
|
|
|
int RtpReceiver::getCycleCount(int track_index){
|
|
|
|
|
return _seq_cycle_count[track_index];
|
2019-05-09 13:35:54 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2018-12-14 17:46:12 +08:00
|
|
|
|
}//namespace mediakit
|