ZLMediaKit/src/Rtsp/RtpReceiver.cpp

134 lines
3.8 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/xia-chu/ZLMediaKit).
2018-12-14 17:46:12 +08:00
*
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"
namespace mediakit {
2021-06-25 16:24:44 +08:00
RtpTrack::RtpTrack() {
setOnSort([this](uint16_t seq, RtpPacket::Ptr &packet) {
onRtpSorted(std::move(packet));
});
}
uint32_t RtpTrack::getSSRC() const {
return _ssrc;
2020-10-01 19:02:14 +08:00
}
2021-01-31 19:19:24 +08:00
2021-06-25 16:24:44 +08:00
void RtpTrack::clear() {
_ssrc = 0;
_ssrc_alive.resetTime();
PacketSortor<RtpPacket::Ptr>::clear();
}
2018-12-14 17:46:12 +08:00
RtpPacket::Ptr RtpTrack::inputRtp(TrackType type, int sample_rate, uint8_t *ptr, size_t len) {
2021-01-31 19:19:24 +08:00
if (len < RtpPacket::kRtpHeaderSize) {
WarnL << "rtp包太小:" << len;
return nullptr;
2019-08-19 23:08:41 +08:00
}
2021-08-11 15:48:15 +08:00
GET_CONFIG(uint32_t, rtpMaxSize, Rtp::kRtpMaxSize);
if (len > 1024 * rtpMaxSize) {
WarnL << "超大的rtp包:" << len << " > " << 1024 * rtpMaxSize;
return nullptr;
2020-10-24 23:32:43 +08:00
}
2021-01-31 19:19:24 +08:00
if (!sample_rate) {
2019-06-24 16:56:46 +08:00
//无法把时间戳转换成毫秒
return nullptr;
2018-12-14 18:24:27 +08:00
}
2021-01-31 19:19:24 +08:00
RtpHeader *header = (RtpHeader *) ptr;
if (header->version != RtpPacket::kRtpVersion) {
throw BadRtpException("非法的rtpversion字段非法");
2018-12-14 17:46:12 +08:00
}
2021-01-31 19:19:24 +08:00
if (!header->getPayloadSize(len)) {
2020-12-19 19:47:43 +08:00
//无有效负载的rtp包
return nullptr;
2019-04-24 11:40:54 +08:00
}
2021-01-31 19:19:24 +08:00
//比对缓存ssrc
auto ssrc = ntohl(header->ssrc);
2021-06-25 16:24:44 +08:00
if (!_ssrc) {
2021-04-11 20:35:00 +08:00
//记录并锁定ssrc
2021-06-25 16:24:44 +08:00
_ssrc = ssrc;
_ssrc_alive.resetTime();
} else if (_ssrc == ssrc) {
2021-04-11 20:35:00 +08:00
//ssrc匹配正确,刷新计时器
2021-06-25 16:24:44 +08:00
_ssrc_alive.resetTime();
2021-04-11 20:35:00 +08:00
} else {
2021-01-31 19:19:24 +08:00
//ssrc错误
2021-06-25 16:24:44 +08:00
if (_ssrc_alive.elapsedTime() < 3 * 1000) {
2021-04-11 20:35:00 +08:00
//接受正确ssrc的rtp在10秒内那么我们认为存在多路rtp,忽略掉ssrc不匹配的rtp
2021-06-25 16:24:44 +08:00
WarnL << "ssrc不匹配,rtp已丢弃:" << ssrc << " != " << _ssrc;
return nullptr;
2021-04-11 20:35:00 +08:00
}
2021-06-25 16:24:44 +08:00
InfoL << "rtp流ssrc切换:" << _ssrc << " -> " << ssrc;
_ssrc = ssrc;
_ssrc_alive.resetTime();
2019-06-24 16:56:46 +08:00
}
2021-02-05 11:28:50 +08:00
auto rtp = RtpPacket::create();
2021-01-31 19:19:24 +08:00
//需要添加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);
if (_disable_ntp) {
//不支持ntp时间戳例如国标推流那么直接使用rtp时间戳
rtp->ntp_stamp = rtp->getStamp() * uint64_t(1000) / sample_rate;
} else {
//设置ntp时间戳
rtp->ntp_stamp = _ntp_stamp.getNtpStamp(ntohl(rtp->getHeader()->stamp), sample_rate);
}
2021-06-25 16:24:44 +08:00
onBeforeRtpSorted(rtp);
sortPacket(rtp->getSeq(), rtp);
return rtp;
2019-06-24 16:56:46 +08:00
}
2018-12-14 17:46:12 +08:00
2021-09-02 21:17:59 +08:00
void RtpTrack::setNtpStamp(uint32_t rtp_stamp, uint64_t ntp_stamp_ms) {
_disable_ntp = rtp_stamp == 0 && ntp_stamp_ms == 0;
if (!_disable_ntp) {
_ntp_stamp.setNtpStamp(rtp_stamp, ntp_stamp_ms);
2021-08-22 15:13:20 +08:00
}
}
2021-06-25 16:24:44 +08:00
////////////////////////////////////////////////////////////////////////////////////
void RtpTrackImp::setOnSorted(OnSorted cb) {
_on_sorted = std::move(cb);
2018-12-14 17:46:12 +08:00
}
2021-06-25 16:24:44 +08:00
void RtpTrackImp::setBeforeSorted(BeforeSorted cb) {
_on_before_sorted = std::move(cb);
2019-05-09 13:35:54 +08:00
}
2021-06-25 16:24:44 +08:00
void RtpTrackImp::onRtpSorted(RtpPacket::Ptr rtp) {
if (_on_sorted) {
_on_sorted(std::move(rtp));
}
2019-05-09 13:35:54 +08:00
}
2021-06-25 16:24:44 +08:00
void RtpTrackImp::onBeforeRtpSorted(const RtpPacket::Ptr &rtp) {
if (_on_before_sorted) {
_on_before_sorted(rtp);
}
2020-12-27 18:11:10 +08:00
}
2019-05-09 13:35:54 +08:00
2018-12-14 17:46:12 +08:00
}//namespace mediakit