ZLMediaKit/src/Rtsp/RtpReceiver.cpp

116 lines
3.3 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xia-chu/ZLMediaKit).
*
* 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.
*/
#include "Common/config.h"
#include "RtpReceiver.h"
#define RTP_MAX_SIZE (10 * 1024)
namespace mediakit {
RtpReceiver::RtpReceiver() {
int index = 0;
for (auto &sortor : _rtp_sortor) {
sortor.setOnSort([this, index](uint16_t seq, RtpPacket::Ptr &packet) {
onRtpSorted(std::move(packet), index);
});
++index;
}
}
RtpReceiver::~RtpReceiver() {}
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;
}
if (len > RTP_MAX_SIZE) {
WarnL << "超大的rtp包:" << len << " > " << RTP_MAX_SIZE;
return false;
}
if (!sample_rate) {
//无法把时间戳转换成毫秒
return false;
}
RtpHeader *header = (RtpHeader *) ptr;
if (header->version != RtpPacket::kRtpVersion) {
throw BadRtpException("非法的rtpversion字段非法");
}
if (!header->getPayloadSize(len)) {
//无有效负载的rtp包
return false;
}
//比对缓存ssrc
auto ssrc = ntohl(header->ssrc);
if (!_ssrc[index]) {
//记录并锁定ssrc
_ssrc[index] = ssrc;
_ssrc_alive[index].resetTime();
} else if (_ssrc[index] == ssrc) {
//ssrc匹配正确,刷新计时器
_ssrc_alive[index].resetTime();
} else {
//ssrc错误
if (_ssrc_alive[index].elapsedTime() < 3 * 1000) {
//接受正确ssrc的rtp在10秒内那么我们认为存在多路rtp,忽略掉ssrc不匹配的rtp
WarnL << "ssrc不匹配,rtp已丢弃:" << ssrc << " != " << _ssrc[index];
return false;
}
InfoL << "rtp流ssrc切换:" << _ssrc[index] << " -> " << ssrc;
_ssrc[index] = ssrc;
_ssrc_alive[index].resetTime();
}
auto rtp = RtpPacket::create();
//需要添加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);
for (auto &sortor : _rtp_sortor) {
sortor.clear();
}
}
size_t RtpReceiver::getJitterSize(int index) const{
return _rtp_sortor[index].getJitterSize();
}
size_t RtpReceiver::getCycleCount(int index) const{
return _rtp_sortor[index].getCycleCount();
}
uint32_t RtpReceiver::getSSRC(int index) const{
return _ssrc[index];
}
}//namespace mediakit