2021-04-09 20:42:36 +08:00
|
|
|
|
/*
|
|
|
|
|
* 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.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#pragma once
|
2021-03-24 16:52:41 +08:00
|
|
|
|
|
|
|
|
|
#include <memory>
|
|
|
|
|
#include <string>
|
2021-03-27 09:13:10 +08:00
|
|
|
|
#include "DtlsTransport.hpp"
|
|
|
|
|
#include "IceServer.hpp"
|
|
|
|
|
#include "SrtpSession.hpp"
|
|
|
|
|
#include "StunPacket.hpp"
|
2021-03-31 17:15:26 +08:00
|
|
|
|
#include "Sdp.h"
|
2021-04-02 17:08:11 +08:00
|
|
|
|
#include "Poller/EventPoller.h"
|
|
|
|
|
#include "Network/Socket.h"
|
2021-04-02 23:01:58 +08:00
|
|
|
|
#include "Rtsp/RtspMediaSourceImp.h"
|
2021-04-03 00:04:52 +08:00
|
|
|
|
#include "Rtcp/RtcpContext.h"
|
2021-05-11 00:54:33 +08:00
|
|
|
|
#include "Rtcp/RtcpFCI.h"
|
2021-04-02 17:08:11 +08:00
|
|
|
|
using namespace toolkit;
|
|
|
|
|
using namespace mediakit;
|
2021-03-24 16:52:41 +08:00
|
|
|
|
|
2021-03-26 11:07:03 +08:00
|
|
|
|
class WebRtcTransport : public RTC::DtlsTransport::Listener, public RTC::IceServer::Listener {
|
2021-03-24 16:52:41 +08:00
|
|
|
|
public:
|
|
|
|
|
using Ptr = std::shared_ptr<WebRtcTransport>;
|
2021-03-27 10:16:49 +08:00
|
|
|
|
WebRtcTransport(const EventPoller::Ptr &poller);
|
|
|
|
|
~WebRtcTransport() override = default;
|
|
|
|
|
|
2021-04-02 17:08:11 +08:00
|
|
|
|
/**
|
2021-04-07 17:21:59 +08:00
|
|
|
|
* 创建对象
|
|
|
|
|
*/
|
|
|
|
|
virtual void onCreate();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 销毁对象
|
2021-04-02 17:08:11 +08:00
|
|
|
|
*/
|
2021-03-27 10:16:49 +08:00
|
|
|
|
virtual void onDestory();
|
2021-03-24 16:52:41 +08:00
|
|
|
|
|
2021-04-02 17:08:11 +08:00
|
|
|
|
/**
|
|
|
|
|
* 创建webrtc answer sdp
|
|
|
|
|
* @param offer offer sdp
|
|
|
|
|
* @return answer sdp
|
|
|
|
|
*/
|
2021-03-31 17:15:26 +08:00
|
|
|
|
std::string getAnswerSdp(const string &offer);
|
|
|
|
|
|
2021-04-02 17:08:11 +08:00
|
|
|
|
/**
|
|
|
|
|
* socket收到udp数据
|
|
|
|
|
* @param buf 数据指针
|
|
|
|
|
* @param len 数据长度
|
|
|
|
|
* @param tuple 数据来源
|
|
|
|
|
*/
|
|
|
|
|
void inputSockData(char *buf, size_t len, RTC::TransportTuple *tuple);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 发送rtp
|
|
|
|
|
* @param buf rtcp内容
|
|
|
|
|
* @param len rtcp长度
|
2021-04-04 23:20:10 +08:00
|
|
|
|
* @param flush 是否flush socket
|
2021-05-11 00:54:33 +08:00
|
|
|
|
* @param ctx 用户指针
|
2021-04-02 17:08:11 +08:00
|
|
|
|
*/
|
2021-05-16 16:59:12 +08:00
|
|
|
|
void sendRtpPacket(const char *buf, size_t len, bool flush, void *ctx = nullptr);
|
|
|
|
|
void sendRtcpPacket(const char *buf, size_t len, bool flush, void *ctx = nullptr);
|
2021-03-24 16:52:41 +08:00
|
|
|
|
|
2021-04-04 23:20:10 +08:00
|
|
|
|
const EventPoller::Ptr& getPoller() const;
|
|
|
|
|
|
2021-03-26 11:07:03 +08:00
|
|
|
|
protected:
|
2021-04-02 17:08:11 +08:00
|
|
|
|
//// dtls相关的回调 ////
|
2021-04-07 17:51:06 +08:00
|
|
|
|
void OnDtlsTransportConnecting(const RTC::DtlsTransport *dtlsTransport) override;
|
2021-04-02 17:08:11 +08:00
|
|
|
|
void OnDtlsTransportConnected(const RTC::DtlsTransport *dtlsTransport,
|
|
|
|
|
RTC::SrtpSession::CryptoSuite srtpCryptoSuite,
|
|
|
|
|
uint8_t *srtpLocalKey,
|
|
|
|
|
size_t srtpLocalKeyLen,
|
|
|
|
|
uint8_t *srtpRemoteKey,
|
|
|
|
|
size_t srtpRemoteKeyLen,
|
|
|
|
|
std::string &remoteCert) override;
|
2021-03-26 11:07:03 +08:00
|
|
|
|
|
2021-04-07 17:51:06 +08:00
|
|
|
|
void OnDtlsTransportFailed(const RTC::DtlsTransport *dtlsTransport) override;
|
|
|
|
|
void OnDtlsTransportClosed(const RTC::DtlsTransport *dtlsTransport) override;
|
2021-03-26 11:07:03 +08:00
|
|
|
|
void OnDtlsTransportSendData(const RTC::DtlsTransport *dtlsTransport, const uint8_t *data, size_t len) override;
|
2021-04-07 17:51:06 +08:00
|
|
|
|
void OnDtlsTransportApplicationDataReceived(const RTC::DtlsTransport *dtlsTransport, const uint8_t *data, size_t len) override;
|
2021-03-26 11:07:03 +08:00
|
|
|
|
|
|
|
|
|
protected:
|
2021-04-02 17:08:11 +08:00
|
|
|
|
//// ice相关的回调 ///
|
2021-03-26 11:07:03 +08:00
|
|
|
|
void OnIceServerSendStunPacket(const RTC::IceServer *iceServer, const RTC::StunPacket *packet, RTC::TransportTuple *tuple) override;
|
|
|
|
|
void OnIceServerSelectedTuple(const RTC::IceServer *iceServer, RTC::TransportTuple *tuple) override;
|
|
|
|
|
void OnIceServerConnected(const RTC::IceServer *iceServer) override;
|
|
|
|
|
void OnIceServerCompleted(const RTC::IceServer *iceServer) override;
|
|
|
|
|
void OnIceServerDisconnected(const RTC::IceServer *iceServer) override;
|
|
|
|
|
|
2021-03-24 16:52:41 +08:00
|
|
|
|
protected:
|
2021-04-02 17:08:11 +08:00
|
|
|
|
virtual void onStartWebRTC() = 0;
|
2021-04-28 15:41:36 +08:00
|
|
|
|
virtual void onRtcConfigure(RtcConfigure &configure) const;
|
2021-04-05 00:12:46 +08:00
|
|
|
|
virtual void onCheckSdp(SdpType type, RtcSession &sdp);
|
2021-04-02 17:56:24 +08:00
|
|
|
|
virtual void onSendSockData(const char *buf, size_t len, struct sockaddr_in *dst, bool flush = true) = 0;
|
|
|
|
|
|
|
|
|
|
virtual void onRtp(const char *buf, size_t len) = 0;
|
|
|
|
|
virtual void onRtcp(const char *buf, size_t len) = 0;
|
2021-04-07 17:21:59 +08:00
|
|
|
|
virtual void onShutdown(const SockException &ex) = 0;
|
2021-05-12 20:51:51 +08:00
|
|
|
|
virtual void onBeforeEncryptRtp(const char *buf, size_t &len, void *ctx) = 0;
|
|
|
|
|
virtual void onBeforeEncryptRtcp(const char *buf, size_t &len, void *ctx) = 0;
|
2021-03-24 16:52:41 +08:00
|
|
|
|
|
2021-04-02 20:35:43 +08:00
|
|
|
|
protected:
|
|
|
|
|
const RtcSession& getSdp(SdpType type) const;
|
2021-04-07 20:33:53 +08:00
|
|
|
|
RTC::TransportTuple* getSelectedTuple() const;
|
2021-04-28 15:41:36 +08:00
|
|
|
|
void sendRtcpRemb(uint32_t ssrc, size_t bit_rate);
|
|
|
|
|
void sendRtcpPli(uint32_t ssrc);
|
2021-04-02 20:35:43 +08:00
|
|
|
|
|
2021-03-24 16:52:41 +08:00
|
|
|
|
private:
|
2021-04-02 17:56:24 +08:00
|
|
|
|
void onSendSockData(const char *buf, size_t len, bool flush = true);
|
2021-04-02 17:08:11 +08:00
|
|
|
|
void setRemoteDtlsFingerprint(const RtcSession &remote);
|
2021-03-24 16:52:41 +08:00
|
|
|
|
|
|
|
|
|
private:
|
2021-05-08 21:16:51 +08:00
|
|
|
|
uint8_t _srtp_buf[2000];
|
2021-04-04 23:20:10 +08:00
|
|
|
|
EventPoller::Ptr _poller;
|
2021-04-02 17:08:11 +08:00
|
|
|
|
std::shared_ptr<RTC::IceServer> _ice_server;
|
|
|
|
|
std::shared_ptr<RTC::DtlsTransport> _dtls_transport;
|
|
|
|
|
std::shared_ptr<RTC::SrtpSession> _srtp_session_send;
|
|
|
|
|
std::shared_ptr<RTC::SrtpSession> _srtp_session_recv;
|
2021-03-31 17:15:26 +08:00
|
|
|
|
RtcSession::Ptr _offer_sdp;
|
|
|
|
|
RtcSession::Ptr _answer_sdp;
|
2021-03-24 16:52:41 +08:00
|
|
|
|
};
|
|
|
|
|
|
2021-04-02 23:01:58 +08:00
|
|
|
|
class RtpReceiverImp;
|
|
|
|
|
|
2021-05-11 00:54:33 +08:00
|
|
|
|
class NackList {
|
|
|
|
|
public:
|
|
|
|
|
void push_back(RtpPacket::Ptr rtp) {
|
|
|
|
|
auto seq = rtp->getSeq();
|
2021-05-11 11:18:55 +08:00
|
|
|
|
_nack_cache_seq.emplace_back(seq);
|
|
|
|
|
_nack_cache_pkt.emplace(seq, std::move(rtp));
|
2021-05-11 00:54:33 +08:00
|
|
|
|
while (get_cache_ms() > kMaxNackMS) {
|
|
|
|
|
//需要清除部分nack缓存
|
|
|
|
|
pop_front();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename FUNC>
|
|
|
|
|
void for_each_nack(const FCI_NACK &nack, const FUNC &func) {
|
|
|
|
|
auto seq = nack.getPid();
|
|
|
|
|
for (auto bit : nack.getBitArray()) {
|
2021-05-11 11:18:55 +08:00
|
|
|
|
if (bit) {
|
2021-05-11 00:54:33 +08:00
|
|
|
|
//丢包
|
|
|
|
|
RtpPacket::Ptr *ptr = get_rtp(seq);
|
|
|
|
|
if (ptr) {
|
|
|
|
|
func(*ptr);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
++seq;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
void pop_front() {
|
2021-05-11 11:18:55 +08:00
|
|
|
|
if (_nack_cache_seq.empty()) {
|
2021-05-11 00:54:33 +08:00
|
|
|
|
return;
|
|
|
|
|
}
|
2021-05-11 11:18:55 +08:00
|
|
|
|
_nack_cache_pkt.erase(_nack_cache_seq.front());
|
|
|
|
|
_nack_cache_seq.pop_front();
|
2021-05-11 00:54:33 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RtpPacket::Ptr *get_rtp(uint16_t seq) {
|
2021-05-11 11:18:55 +08:00
|
|
|
|
auto it = _nack_cache_pkt.find(seq);
|
|
|
|
|
if (it == _nack_cache_pkt.end()) {
|
2021-05-11 00:54:33 +08:00
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
return &it->second;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32_t get_cache_ms() {
|
2021-05-11 11:18:55 +08:00
|
|
|
|
if (_nack_cache_seq.size() < 2) {
|
2021-05-11 00:54:33 +08:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
2021-05-11 11:18:55 +08:00
|
|
|
|
uint32_t back = _nack_cache_pkt[_nack_cache_seq.back()]->getStampMS();
|
|
|
|
|
uint32_t front = _nack_cache_pkt[_nack_cache_seq.front()]->getStampMS();
|
2021-05-11 00:54:33 +08:00
|
|
|
|
if (back > front) {
|
|
|
|
|
return back - front;
|
|
|
|
|
}
|
|
|
|
|
//很有可能回环了
|
|
|
|
|
return back + (UINT32_MAX - front);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
static constexpr uint32_t kMaxNackMS = 10 * 1000;
|
2021-05-11 11:18:55 +08:00
|
|
|
|
deque<uint16_t> _nack_cache_seq;
|
|
|
|
|
unordered_map<uint16_t, RtpPacket::Ptr > _nack_cache_pkt;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class NackContext {
|
|
|
|
|
public:
|
2021-05-11 12:12:28 +08:00
|
|
|
|
using onNack = function<void(const FCI_NACK &nack)>;
|
|
|
|
|
|
2021-05-11 11:18:55 +08:00
|
|
|
|
void received(uint16_t seq) {
|
|
|
|
|
if (!_last_max_seq && _seq.empty()) {
|
|
|
|
|
_last_max_seq = seq - 1;
|
|
|
|
|
}
|
|
|
|
|
_seq.emplace(seq);
|
|
|
|
|
auto max_seq = *_seq.rbegin();
|
|
|
|
|
auto min_seq = *_seq.begin();
|
|
|
|
|
auto diff = max_seq - min_seq;
|
|
|
|
|
if (!diff) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (diff > UINT32_MAX / 2) {
|
|
|
|
|
//回环
|
|
|
|
|
_seq.clear();
|
|
|
|
|
_last_max_seq = min_seq;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (_seq.size() == diff + 1 && _last_max_seq + 1 == min_seq) {
|
|
|
|
|
//都是连续的seq,未丢包
|
|
|
|
|
_seq.clear();
|
|
|
|
|
_last_max_seq = max_seq;
|
|
|
|
|
} else {
|
|
|
|
|
//seq不连续,有丢包
|
|
|
|
|
if (min_seq == _last_max_seq + 1) {
|
|
|
|
|
//前面部分seq是连续的,未丢包,移除之
|
|
|
|
|
eraseFrontSeq();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//有丢包,丢包从_last_max_seq开始
|
|
|
|
|
if (max_seq - _last_max_seq > FCI_NACK::kBitSize) {
|
|
|
|
|
vector<bool> vec;
|
|
|
|
|
vec.resize(FCI_NACK::kBitSize);
|
|
|
|
|
for (auto i = 0; i < FCI_NACK::kBitSize; ++i) {
|
|
|
|
|
vec[i] = _seq.find(_last_max_seq + i + 2) == _seq.end();
|
|
|
|
|
}
|
2021-05-11 12:12:28 +08:00
|
|
|
|
doNack(FCI_NACK(_last_max_seq + 1, vec));
|
2021-05-11 11:18:55 +08:00
|
|
|
|
_last_max_seq += FCI_NACK::kBitSize + 1;
|
|
|
|
|
if (_last_max_seq >= max_seq) {
|
|
|
|
|
_seq.clear();
|
|
|
|
|
} else {
|
|
|
|
|
auto it = _seq.emplace_hint(_seq.begin(), _last_max_seq);
|
|
|
|
|
_seq.erase(_seq.begin(), it);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-11 12:12:28 +08:00
|
|
|
|
void setOnNack(onNack cb) {
|
|
|
|
|
_cb = std::move(cb);
|
2021-05-11 11:18:55 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
2021-05-11 12:12:28 +08:00
|
|
|
|
void doNack(const FCI_NACK &nack) {
|
|
|
|
|
if (_cb) {
|
|
|
|
|
_cb(nack);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-11 11:18:55 +08:00
|
|
|
|
void eraseFrontSeq(){
|
|
|
|
|
//前面部分seq是连续的,未丢包,移除之
|
|
|
|
|
for (auto it = _seq.begin(); it != _seq.end();) {
|
|
|
|
|
if (*it != _last_max_seq + 1) {
|
|
|
|
|
//seq不连续,丢包了
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
_last_max_seq = *it;
|
|
|
|
|
it = _seq.erase(it);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
2021-05-11 12:12:28 +08:00
|
|
|
|
onNack _cb;
|
2021-05-11 11:18:55 +08:00
|
|
|
|
set<uint16_t> _seq;
|
|
|
|
|
uint16_t _last_max_seq = 0;
|
2021-05-11 00:54:33 +08:00
|
|
|
|
};
|
|
|
|
|
|
2021-04-07 20:33:53 +08:00
|
|
|
|
class WebRtcTransportImp : public WebRtcTransport, public MediaSourceEvent, public SockInfo, public std::enable_shared_from_this<WebRtcTransportImp>{
|
2021-03-24 16:52:41 +08:00
|
|
|
|
public:
|
|
|
|
|
using Ptr = std::shared_ptr<WebRtcTransportImp>;
|
2021-04-07 17:51:06 +08:00
|
|
|
|
~WebRtcTransportImp() override;
|
2021-03-24 16:52:41 +08:00
|
|
|
|
|
2021-04-02 17:08:11 +08:00
|
|
|
|
/**
|
|
|
|
|
* 创建WebRTC对象
|
|
|
|
|
* @param poller 改对象需要绑定的线程
|
|
|
|
|
* @return 对象
|
|
|
|
|
*/
|
2021-03-27 10:16:49 +08:00
|
|
|
|
static Ptr create(const EventPoller::Ptr &poller);
|
2021-03-24 16:52:41 +08:00
|
|
|
|
|
2021-04-02 17:08:11 +08:00
|
|
|
|
/**
|
|
|
|
|
* 绑定rtsp媒体源
|
|
|
|
|
* @param src 媒体源
|
2021-04-05 11:32:38 +08:00
|
|
|
|
* @param is_play 是播放还是推流
|
2021-04-02 17:08:11 +08:00
|
|
|
|
*/
|
2021-04-07 18:35:38 +08:00
|
|
|
|
void attach(const RtspMediaSource::Ptr &src, const MediaInfo &info, bool is_play = true);
|
2021-03-24 16:52:41 +08:00
|
|
|
|
|
|
|
|
|
protected:
|
2021-04-02 17:08:11 +08:00
|
|
|
|
void onStartWebRTC() override;
|
2021-04-02 17:56:24 +08:00
|
|
|
|
void onSendSockData(const char *buf, size_t len, struct sockaddr_in *dst, bool flush = true) override;
|
2021-04-05 00:12:46 +08:00
|
|
|
|
void onCheckSdp(SdpType type, RtcSession &sdp) override;
|
2021-04-02 18:28:01 +08:00
|
|
|
|
void onRtcConfigure(RtcConfigure &configure) const override;
|
2021-04-02 17:56:24 +08:00
|
|
|
|
|
|
|
|
|
void onRtp(const char *buf, size_t len) override;
|
2021-05-11 15:48:01 +08:00
|
|
|
|
void onRtp_l(const char *buf, size_t len, bool rtx);
|
|
|
|
|
|
2021-04-02 17:56:24 +08:00
|
|
|
|
void onRtcp(const char *buf, size_t len) override;
|
2021-05-12 20:51:51 +08:00
|
|
|
|
void onBeforeEncryptRtp(const char *buf, size_t &len, void *ctx) override;
|
|
|
|
|
void onBeforeEncryptRtcp(const char *buf, size_t &len, void *ctx) override {};
|
2021-05-08 21:16:51 +08:00
|
|
|
|
|
2021-04-07 17:21:59 +08:00
|
|
|
|
void onShutdown(const SockException &ex) override;
|
2021-04-02 17:08:11 +08:00
|
|
|
|
|
2021-04-07 18:18:27 +08:00
|
|
|
|
///////MediaSourceEvent override///////
|
|
|
|
|
// 关闭
|
|
|
|
|
bool close(MediaSource &sender, bool force) override;
|
|
|
|
|
// 播放总人数
|
|
|
|
|
int totalReaderCount(MediaSource &sender) override;
|
|
|
|
|
// 获取媒体源类型
|
|
|
|
|
MediaOriginType getOriginType(MediaSource &sender) const override;
|
|
|
|
|
// 获取媒体源url或者文件路径
|
|
|
|
|
string getOriginUrl(MediaSource &sender) const override;
|
|
|
|
|
// 获取媒体源客户端相关信息
|
|
|
|
|
std::shared_ptr<SockInfo> getOriginSock(MediaSource &sender) const override;
|
|
|
|
|
|
2021-04-07 20:33:53 +08:00
|
|
|
|
///////SockInfo override///////
|
|
|
|
|
//获取本机ip
|
|
|
|
|
string get_local_ip() override;
|
|
|
|
|
//获取本机端口号
|
|
|
|
|
uint16_t get_local_port() override;
|
|
|
|
|
//获取对方ip
|
|
|
|
|
string get_peer_ip() override;
|
|
|
|
|
//获取对方端口号
|
|
|
|
|
uint16_t get_peer_port() override;
|
|
|
|
|
//获取标识符
|
|
|
|
|
string getIdentifier() const override;
|
|
|
|
|
|
2021-04-02 17:08:11 +08:00
|
|
|
|
private:
|
2021-03-27 10:16:49 +08:00
|
|
|
|
WebRtcTransportImp(const EventPoller::Ptr &poller);
|
2021-04-07 17:21:59 +08:00
|
|
|
|
void onCreate() override;
|
2021-03-27 10:16:49 +08:00
|
|
|
|
void onDestory() override;
|
2021-05-11 00:54:33 +08:00
|
|
|
|
void onSendRtp(const RtpPacket::Ptr &rtp, bool flush, bool rtx = false);
|
2021-04-02 18:28:01 +08:00
|
|
|
|
SdpAttrCandidate::Ptr getIceCandidate() const;
|
2021-04-02 20:35:43 +08:00
|
|
|
|
bool canSendRtp() const;
|
2021-04-02 23:01:58 +08:00
|
|
|
|
bool canRecvRtp() const;
|
|
|
|
|
|
|
|
|
|
class RtpPayloadInfo {
|
|
|
|
|
public:
|
2021-05-12 15:40:40 +08:00
|
|
|
|
using Ptr = std::shared_ptr<RtpPayloadInfo>;
|
2021-05-12 20:51:51 +08:00
|
|
|
|
const RtcCodecPlan *plan_rtp;
|
|
|
|
|
const RtcCodecPlan *plan_rtx;
|
2021-05-16 16:12:10 +08:00
|
|
|
|
uint32_t offer_ssrc_rtp = 0;
|
|
|
|
|
uint32_t offer_ssrc_rtx = 0;
|
|
|
|
|
uint32_t answer_ssrc_rtp = 0;
|
|
|
|
|
uint32_t answer_ssrc_rtx = 0;
|
2021-04-02 23:01:58 +08:00
|
|
|
|
const RtcMedia *media;
|
2021-05-11 00:54:33 +08:00
|
|
|
|
NackList nack_list;
|
2021-05-11 11:18:55 +08:00
|
|
|
|
NackContext nack_ctx;
|
2021-05-16 16:12:10 +08:00
|
|
|
|
RtcpContext::Ptr rtcp_context_recv;
|
|
|
|
|
RtcpContext::Ptr rtcp_context_send;
|
|
|
|
|
std::shared_ptr<RtpReceiverImp> receiver;
|
2021-04-02 23:01:58 +08:00
|
|
|
|
};
|
|
|
|
|
|
2021-05-11 11:18:55 +08:00
|
|
|
|
void onSortedRtp(RtpPayloadInfo &info, RtpPacket::Ptr rtp);
|
2021-05-16 16:12:10 +08:00
|
|
|
|
void onSendNack(RtpPayloadInfo &info, const FCI_NACK &nack);
|
2021-05-16 21:49:46 +08:00
|
|
|
|
void changeRtpExtId(const RtpPayloadInfo *info, const RtpHeader *header, bool is_recv, bool is_rtx = false) const;
|
2021-03-24 16:52:41 +08:00
|
|
|
|
|
|
|
|
|
private:
|
2021-05-16 18:06:34 +08:00
|
|
|
|
uint16_t _rtx_seq[2] = {0, 0};
|
2021-04-07 18:35:38 +08:00
|
|
|
|
//用掉的总流量
|
|
|
|
|
uint64_t _bytes_usage = 0;
|
|
|
|
|
//媒体相关元数据
|
|
|
|
|
MediaInfo _media_info;
|
2021-04-07 17:51:06 +08:00
|
|
|
|
//保持自我强引用
|
|
|
|
|
Ptr _self;
|
|
|
|
|
//检测超时的定时器
|
|
|
|
|
Timer::Ptr _timer;
|
|
|
|
|
//刷新计时器
|
|
|
|
|
Ticker _alive_ticker;
|
2021-04-05 00:12:46 +08:00
|
|
|
|
//pli rtcp计时器
|
2021-04-04 23:20:10 +08:00
|
|
|
|
Ticker _pli_ticker;
|
2021-04-05 00:12:46 +08:00
|
|
|
|
//复合udp端口,接收一切rtp与rtcp
|
2021-03-24 16:52:41 +08:00
|
|
|
|
Socket::Ptr _socket;
|
2021-04-05 11:32:38 +08:00
|
|
|
|
//推流的rtsp源
|
|
|
|
|
RtspMediaSource::Ptr _push_src;
|
|
|
|
|
//播放的rtsp源
|
|
|
|
|
RtspMediaSource::Ptr _play_src;
|
|
|
|
|
//播放rtsp源的reader对象
|
2021-04-04 23:20:10 +08:00
|
|
|
|
RtspMediaSource::RingType::RingReader::Ptr _reader;
|
2021-05-16 16:12:10 +08:00
|
|
|
|
//根据发送rtp的track类型获取相关信息
|
|
|
|
|
RtpPayloadInfo::Ptr _send_rtp_info[2];
|
|
|
|
|
//根据接收rtp的pt获取相关信息
|
|
|
|
|
unordered_map<uint8_t/*pt*/, std::pair<bool/*is rtx*/,RtpPayloadInfo::Ptr> > _rtp_info_pt;
|
2021-05-10 18:11:12 +08:00
|
|
|
|
//根据rtcp的ssrc获取相关信息
|
2021-05-16 16:12:10 +08:00
|
|
|
|
unordered_map<uint32_t/*ssrc*/, std::pair<bool/*is rtx*/,RtpPayloadInfo::Ptr> > _rtp_info_ssrc;
|
2021-05-08 10:49:09 +08:00
|
|
|
|
//发送rtp时需要修改rtp ext id
|
2021-05-08 19:33:51 +08:00
|
|
|
|
map<RtpExtType, uint8_t> _rtp_ext_type_to_id;
|
2021-05-08 10:49:09 +08:00
|
|
|
|
//接收rtp时需要修改rtp ext id
|
|
|
|
|
unordered_map<uint8_t, RtpExtType> _rtp_ext_id_to_type;
|
2021-05-16 16:12:10 +08:00
|
|
|
|
};
|