ZLMediaKit/webrtc/WebRtcTransport.h

359 lines
13 KiB
C++
Raw Normal View History

2022-06-18 14:34:58 +08:00
/*
2023-12-09 16:23:51 +08:00
* Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved.
2021-04-09 20:42:36 +08:00
*
2023-12-09 16:23:51 +08:00
* This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit).
2021-04-09 20:42:36 +08:00
*
2023-12-09 16:23:51 +08:00
* Use of this source code is governed by MIT-like license that can be found in the
2021-04-09 20:42:36 +08:00
* 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"
#include "Util/mini.h"
2021-04-02 17:08:11 +08:00
#include "Poller/EventPoller.h"
#include "Network/Socket.h"
2021-09-08 18:00:55 +08:00
#include "Network/Session.h"
#include "Nack.h"
2021-10-06 22:17:38 +08:00
#include "TwccContext.h"
2022-05-04 22:15:21 +08:00
#include "SctpAssociation.hpp"
2022-12-02 14:43:06 +08:00
#include "Rtcp/RtcpContext.h"
2021-06-25 15:43:47 +08:00
2022-09-18 21:03:05 +08:00
namespace mediakit {
2022-12-02 14:43:06 +08:00
2021-09-08 18:00:55 +08:00
//RTC配置项目
2022-09-18 21:03:05 +08:00
namespace Rtc {
extern const std::string kPort;
extern const std::string kTcpPort;
extern const std::string kTimeOutSec;
2021-09-08 18:00:55 +08:00
}//namespace RTC
2021-10-19 15:23:12 +08:00
class WebRtcInterface {
public:
virtual ~WebRtcInterface() = default;
virtual std::string getAnswerSdp(const std::string &offer) = 0;
virtual const std::string& getIdentifier() const = 0;
virtual const std::string& deleteRandStr() const { static std::string s_null; return s_null; }
2023-12-09 16:23:51 +08:00
virtual void setIceCandidate(std::vector<SdpAttrCandidate> cands) {}
virtual void setLocalIp(std::string localIp) {}
virtual void setPreferredTcp(bool flag) {}
2021-10-19 15:23:12 +08:00
};
class WebRtcException : public WebRtcInterface {
public:
WebRtcException(const SockException &ex) : _ex(ex) {};
std::string getAnswerSdp(const std::string &offer) override {
2021-10-19 15:23:12 +08:00
throw _ex;
}
const std::string &getIdentifier() const override {
static std::string s_null;
2021-10-19 15:23:12 +08:00
return s_null;
}
private:
SockException _ex;
};
2022-05-04 22:15:21 +08:00
class WebRtcTransport : public WebRtcInterface, public RTC::DtlsTransport::Listener, public RTC::IceServer::Listener, public std::enable_shared_from_this<WebRtcTransport>
#ifdef ENABLE_SCTP
, public RTC::SctpAssociation::Listener
#endif
{
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);
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
*/
std::string getAnswerSdp(const std::string &offer) override final;
2021-10-19 15:23:12 +08:00
/**
* id
*/
const std::string& getIdentifier() const override;
const std::string& deleteRandStr() const override;
2021-03-31 17:15:26 +08:00
2021-04-02 17:08:11 +08:00
/**
* socket收到udp数据
* @param buf
* @param len
* @param tuple
*/
void inputSockData(char *buf, int len, RTC::TransportTuple *tuple);
2021-04-02 17:08:11 +08:00
/**
* 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
*/
void sendRtpPacket(const char *buf, int len, bool flush, void *ctx = nullptr);
void sendRtcpPacket(const char *buf, int len, bool flush, void *ctx = nullptr);
void sendDatachannel(uint16_t streamId, uint32_t ppid, const char *msg, size_t len);
2021-03-24 16:52:41 +08:00
2021-04-04 23:20:10 +08:00
const EventPoller::Ptr& getPoller() const;
Session::Ptr getSession() const;
2021-04-04 23:20:10 +08:00
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 OnIceServerConnected(const RTC::IceServer *iceServer) override;
void OnIceServerCompleted(const RTC::IceServer *iceServer) override;
void OnIceServerDisconnected(const RTC::IceServer *iceServer) override;
2022-05-04 22:15:21 +08:00
#ifdef ENABLE_SCTP
void OnSctpAssociationConnecting(RTC::SctpAssociation* sctpAssociation) override;
void OnSctpAssociationConnected(RTC::SctpAssociation* sctpAssociation) override;
void OnSctpAssociationFailed(RTC::SctpAssociation* sctpAssociation) override;
void OnSctpAssociationClosed(RTC::SctpAssociation* sctpAssociation) override;
void OnSctpAssociationSendData(RTC::SctpAssociation* sctpAssociation, const uint8_t* data, size_t len) override;
void OnSctpAssociationMessageReceived(RTC::SctpAssociation *sctpAssociation, uint16_t streamId, uint32_t ppid,
const uint8_t *msg, size_t len) override;
#endif
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;
virtual void onCheckSdp(SdpType type, RtcSession &sdp) = 0;
virtual void onSendSockData(Buffer::Ptr buf, bool flush = true, RTC::TransportTuple *tuple = nullptr) = 0;
2021-04-02 17:56:24 +08:00
virtual void onRtp(const char *buf, size_t len, uint64_t stamp_ms) = 0;
2021-04-02 17:56:24 +08:00
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;
virtual void onBeforeEncryptRtp(const char *buf, int &len, void *ctx) = 0;
virtual void onBeforeEncryptRtcp(const char *buf, int &len, void *ctx) = 0;
2022-09-07 19:10:06 +08:00
virtual void onRtcpBye() = 0;
2021-03-24 16:52:41 +08:00
2021-04-02 20:35:43 +08:00
protected:
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:
void sendSockData(const char *buf, size_t len, RTC::TransportTuple *tuple);
2021-04-02 17:08:11 +08:00
void setRemoteDtlsFingerprint(const RtcSession &remote);
2021-03-24 16:52:41 +08:00
protected:
RtcSession::Ptr _offer_sdp;
RtcSession::Ptr _answer_sdp;
std::shared_ptr<RTC::IceServer> _ice_server;
2021-03-24 16:52:41 +08:00
private:
mutable std::string _delete_rand_str;
std::string _identifier;
2021-04-04 23:20:10 +08:00
EventPoller::Ptr _poller;
2021-04-02 17:08:11 +08:00
std::shared_ptr<RTC::DtlsTransport> _dtls_transport;
std::shared_ptr<RTC::SrtpSession> _srtp_session_send;
2021-07-28 11:18:09 +08:00
std::shared_ptr<RTC::SrtpSession> _srtp_session_recv;
Ticker _ticker;
// 循环池
ResourcePool<BufferRaw> _packet_pool;
2022-05-04 22:15:21 +08:00
#ifdef ENABLE_SCTP
RTC::SctpAssociationImp::Ptr _sctp;
#endif
2021-03-24 16:52:41 +08:00
};
2021-06-25 14:37:11 +08:00
class RtpChannel;
2021-06-25 15:31:13 +08:00
class MediaTrack {
public:
using Ptr = std::shared_ptr<MediaTrack>;
const RtcCodecPlan *plan_rtp;
const RtcCodecPlan *plan_rtx;
uint32_t offer_ssrc_rtp = 0;
uint32_t offer_ssrc_rtx = 0;
uint32_t answer_ssrc_rtp = 0;
uint32_t answer_ssrc_rtx = 0;
const RtcMedia *media;
RtpExtContext::Ptr rtp_ext_ctx;
//for send rtp
NackList nack_list;
2022-12-02 14:43:06 +08:00
RtcpContext::Ptr rtcp_context_send;
2021-06-25 15:31:13 +08:00
//for recv rtp
std::unordered_map<std::string/*rid*/, std::shared_ptr<RtpChannel> > rtp_channel;
2021-06-25 15:31:13 +08:00
std::shared_ptr<RtpChannel> getRtpChannel(uint32_t ssrc) const;
};
2021-11-18 18:41:23 +08:00
struct WrappedMediaTrack {
MediaTrack::Ptr track;
explicit WrappedMediaTrack(MediaTrack::Ptr ptr): track(ptr) {}
virtual ~WrappedMediaTrack() {}
2022-09-18 21:03:05 +08:00
virtual void inputRtp(const char *buf, size_t len, uint64_t stamp_ms, RtpHeader *rtp) = 0;
2021-11-18 18:41:23 +08:00
};
struct WrappedRtxTrack: public WrappedMediaTrack {
explicit WrappedRtxTrack(MediaTrack::Ptr ptr)
: WrappedMediaTrack(std::move(ptr)) {}
2022-09-18 21:03:05 +08:00
void inputRtp(const char *buf, size_t len, uint64_t stamp_ms, RtpHeader *rtp) override;
2021-11-18 18:41:23 +08:00
};
class WebRtcTransportImp;
struct WrappedRtpTrack : public WrappedMediaTrack {
explicit WrappedRtpTrack(MediaTrack::Ptr ptr, TwccContext& twcc, WebRtcTransportImp& t)
: WrappedMediaTrack(std::move(ptr))
, _twcc_ctx(twcc)
, _transport(t) {}
TwccContext& _twcc_ctx;
WebRtcTransportImp& _transport;
2022-09-18 21:03:05 +08:00
void inputRtp(const char *buf, size_t len, uint64_t stamp_ms, RtpHeader *rtp) override;
2021-11-18 18:41:23 +08:00
};
class WebRtcTransportImp : public WebRtcTransport {
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
uint64_t getBytesUsage() const;
uint64_t getDuration() const;
bool canSendRtp() const;
bool canRecvRtp() const;
2022-09-18 21:03:05 +08:00
void onSendRtp(const RtpPacket::Ptr &rtp, bool flush, bool rtx = false);
2021-03-24 16:52:41 +08:00
void createRtpChannel(const std::string &rid, uint32_t ssrc, MediaTrack &track);
void removeTuple(RTC::TransportTuple* tuple);
void safeShutdown(const SockException &ex);
2021-11-18 18:41:23 +08:00
void setPreferredTcp(bool flag) override;
void setLocalIp(std::string local_ip) override;
void setIceCandidate(std::vector<SdpAttrCandidate> cands) override;
2021-03-24 16:52:41 +08:00
protected:
void OnIceServerSelectedTuple(const RTC::IceServer *iceServer, RTC::TransportTuple *tuple) override;
WebRtcTransportImp(const EventPoller::Ptr &poller);
void OnDtlsTransportApplicationDataReceived(const RTC::DtlsTransport *dtlsTransport, const uint8_t *data, size_t len) override;
2021-04-02 17:08:11 +08:00
void onStartWebRTC() override;
void onSendSockData(Buffer::Ptr buf, bool flush = true, RTC::TransportTuple *tuple = nullptr) override;
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, uint64_t stamp_ms) override;
2021-04-02 17:56:24 +08:00
void onRtcp(const char *buf, size_t len) override;
void onBeforeEncryptRtp(const char *buf, int &len, void *ctx) override;
void onBeforeEncryptRtcp(const char *buf, int &len, void *ctx) override {};
void onCreate() override;
void onDestory() override;
2021-04-07 17:21:59 +08:00
void onShutdown(const SockException &ex) override;
virtual void onRecvRtp(MediaTrack &track, const std::string &rid, RtpPacket::Ptr rtp) {}
void updateTicker();
2022-09-18 21:03:05 +08:00
float getLossRate(TrackType type);
2022-09-07 19:10:06 +08:00
void onRtcpBye() override;
2021-04-02 17:08:11 +08:00
private:
2022-09-18 21:03:05 +08:00
void onSortedRtp(MediaTrack &track, const std::string &rid, RtpPacket::Ptr rtp);
void onSendNack(MediaTrack &track, const FCI_NACK &nack, uint32_t ssrc);
void onSendTwcc(uint32_t ssrc, const std::string &twcc_fci);
2021-11-18 18:41:23 +08:00
2021-09-10 22:31:44 +08:00
void registerSelf();
void unregisterSelf();
void unrefSelf();
void onCheckAnswer(RtcSession &sdp);
2021-03-24 16:52:41 +08:00
private:
bool _preferred_tcp = false;
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;
2021-09-10 22:31:44 +08:00
//保持自我强引用
Ptr _self;
2021-04-07 17:51:06 +08:00
//检测超时的定时器
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;
//twcc rtcp发送上下文对象
TwccContext _twcc_ctx;
2021-05-16 16:12:10 +08:00
//根据发送rtp的track类型获取相关信息
MediaTrack::Ptr _type_to_track[2];
2021-06-25 17:24:32 +08:00
//根据rtcp的ssrc获取相关信息收发rtp和rtx的ssrc都会记录
std::unordered_map<uint32_t/*ssrc*/, MediaTrack::Ptr> _ssrc_to_track;
//根据接收rtp的pt获取相关信息
std::unordered_map<uint8_t/*pt*/, std::unique_ptr<WrappedMediaTrack>> _pt_to_track;
2023-12-09 16:23:51 +08:00
std::vector<SdpAttrCandidate> _cands;
//http访问时的host ip
std::string _local_ip;
};
class WebRtcTransportManager {
public:
2021-10-19 15:23:12 +08:00
friend class WebRtcTransportImp;
2021-10-16 10:25:23 +08:00
static WebRtcTransportManager &Instance();
WebRtcTransportImp::Ptr getItem(const std::string &key);
2021-10-16 10:25:23 +08:00
private:
WebRtcTransportManager() = default;
void addItem(const std::string &key, const WebRtcTransportImp::Ptr &ptr);
void removeItem(const std::string &key);
2021-10-19 15:23:12 +08:00
private:
mutable std::mutex _mtx;
std::unordered_map<std::string, std::weak_ptr<WebRtcTransportImp> > _map;
2021-10-19 15:23:12 +08:00
};
2023-12-09 16:23:51 +08:00
class WebRtcArgs : public std::enable_shared_from_this<WebRtcArgs> {
2021-10-19 15:23:12 +08:00
public:
virtual ~WebRtcArgs() = default;
virtual variant operator[](const std::string &key) const = 0;
2021-10-19 15:23:12 +08:00
};
using onCreateWebRtc = std::function<void(const WebRtcInterface &rtc)>;
2021-10-19 15:23:12 +08:00
class WebRtcPluginManager {
public:
using Plugin = std::function<void(Session &sender, const WebRtcArgs &args, const onCreateWebRtc &cb)>;
2023-12-09 16:23:51 +08:00
using Listener = std::function<void(Session &sender, const std::string &type, const WebRtcArgs &args, const WebRtcInterface &rtc)>;
2021-10-19 15:23:12 +08:00
static WebRtcPluginManager &Instance();
void registerPlugin(const std::string &type, Plugin cb);
2023-12-09 16:23:51 +08:00
void setListener(Listener cb);
void negotiateSdp(Session &sender, const std::string &type, const WebRtcArgs &args, const onCreateWebRtc &cb);
2021-10-19 15:23:12 +08:00
private:
WebRtcPluginManager() = default;
private:
mutable std::mutex _mtx_creator;
2023-12-09 16:23:51 +08:00
Listener _listener;
std::unordered_map<std::string, Plugin> _map_creator;
2022-09-18 21:03:05 +08:00
};
}// namespace mediakit