/* * Copyright (c) 2016-present The ZLMediaKit project authors. All Rights Reserved. * * This file is part of ZLMediaKit(https://github.com/ZLMediaKit/ZLMediaKit). * * Use of this source code is governed by MIT-like 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 #include #include #include "DtlsTransport.hpp" #include "IceServer.hpp" #include "SrtpSession.hpp" #include "StunPacket.hpp" #include "Sdp.h" #include "Util/mini.h" #include "Poller/EventPoller.h" #include "Network/Socket.h" #include "Network/Session.h" #include "Nack.h" #include "TwccContext.h" #include "SctpAssociation.hpp" #include "Rtcp/RtcpContext.h" namespace mediakit { // RTC配置项目 [AUTO-TRANSLATED:65784416] // RTC configuration project namespace Rtc { extern const std::string kPort; extern const std::string kTcpPort; extern const std::string kTimeOutSec; extern const std::string kTranscodeG711; }//namespace RTC 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; } virtual void setIceCandidate(std::vector cands) {} virtual void setLocalIp(std::string localIp) {} virtual void setPreferredTcp(bool flag) {} }; class WebRtcException : public WebRtcInterface { public: WebRtcException(const SockException &ex) : _ex(ex) {}; std::string getAnswerSdp(const std::string &offer) override { throw _ex; } const std::string &getIdentifier() const override { static std::string s_null; return s_null; } private: SockException _ex; }; class WebRtcTransport : public WebRtcInterface, public RTC::DtlsTransport::Listener, public RTC::IceServer::Listener, public std::enable_shared_from_this #ifdef ENABLE_SCTP , public RTC::SctpAssociation::Listener #endif { public: using Ptr = std::shared_ptr; WebRtcTransport(const EventPoller::Ptr &poller); /** * 创建对象 * Create object * [AUTO-TRANSLATED:830344e4] */ virtual void onCreate(); /** * 销毁对象 * Destroy object * [AUTO-TRANSLATED:1016b97b] */ virtual void onDestory(); /** * 创建webrtc answer sdp * @param offer offer sdp * @return answer sdp * Create webrtc answer sdp * @param offer offer sdp * @return answer sdp * [AUTO-TRANSLATED:d9b027d7] */ std::string getAnswerSdp(const std::string &offer) override final; /** * 获取对象唯一id * Get object unique id * [AUTO-TRANSLATED:9ad519c6] */ const std::string& getIdentifier() const override; const std::string& deleteRandStr() const override; /** * socket收到udp数据 * @param buf 数据指针 * @param len 数据长度 * @param tuple 数据来源 * Socket receives udp data * @param buf data pointer * @param len data length * @param tuple data source * [AUTO-TRANSLATED:1ee86069] */ void inputSockData(char *buf, int len, RTC::TransportTuple *tuple); /** * 发送rtp * @param buf rtcp内容 * @param len rtcp长度 * @param flush 是否flush socket * @param ctx 用户指针 * Send rtp * @param buf rtcp content * @param len rtcp length * @param flush whether to flush socket * @param ctx user pointer * [AUTO-TRANSLATED:aa833695] */ 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); const EventPoller::Ptr& getPoller() const; Session::Ptr getSession() const; protected: // // dtls相关的回调 //// [AUTO-TRANSLATED:31a1f32c] // // dtls related callbacks //// void OnDtlsTransportConnecting(const RTC::DtlsTransport *dtlsTransport) override; 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; void OnDtlsTransportFailed(const RTC::DtlsTransport *dtlsTransport) override; void OnDtlsTransportClosed(const RTC::DtlsTransport *dtlsTransport) override; void OnDtlsTransportSendData(const RTC::DtlsTransport *dtlsTransport, const uint8_t *data, size_t len) override; void OnDtlsTransportApplicationDataReceived(const RTC::DtlsTransport *dtlsTransport, const uint8_t *data, size_t len) override; protected: // // ice相关的回调 /// [AUTO-TRANSLATED:30abf693] // // ice related callbacks /// 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; #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 protected: virtual void onStartWebRTC() = 0; 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; virtual void onRtp(const char *buf, size_t len, uint64_t stamp_ms) = 0; virtual void onRtcp(const char *buf, size_t len) = 0; 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; virtual void onRtcpBye() = 0; protected: void sendRtcpRemb(uint32_t ssrc, size_t bit_rate); void sendRtcpPli(uint32_t ssrc); private: void sendSockData(const char *buf, size_t len, RTC::TransportTuple *tuple); void setRemoteDtlsFingerprint(const RtcSession &remote); protected: RtcSession::Ptr _offer_sdp; RtcSession::Ptr _answer_sdp; std::shared_ptr _ice_server; private: mutable std::string _delete_rand_str; std::string _identifier; EventPoller::Ptr _poller; std::shared_ptr _dtls_transport; std::shared_ptr _srtp_session_send; std::shared_ptr _srtp_session_recv; Ticker _ticker; // 循环池 [AUTO-TRANSLATED:b7059f37] // Cycle pool ResourcePool _packet_pool; #ifdef ENABLE_SCTP RTC::SctpAssociationImp::Ptr _sctp; #endif }; class RtpChannel; class MediaTrack { public: using Ptr = std::shared_ptr; 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; RtcpContext::Ptr rtcp_context_send; //for recv rtp std::unordered_map > rtp_channel; std::shared_ptr getRtpChannel(uint32_t ssrc) const; }; struct WrappedMediaTrack { MediaTrack::Ptr track; explicit WrappedMediaTrack(MediaTrack::Ptr ptr): track(ptr) {} virtual ~WrappedMediaTrack() {} virtual void inputRtp(const char *buf, size_t len, uint64_t stamp_ms, RtpHeader *rtp) = 0; }; struct WrappedRtxTrack: public WrappedMediaTrack { explicit WrappedRtxTrack(MediaTrack::Ptr ptr) : WrappedMediaTrack(std::move(ptr)) {} void inputRtp(const char *buf, size_t len, uint64_t stamp_ms, RtpHeader *rtp) override; }; 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; void inputRtp(const char *buf, size_t len, uint64_t stamp_ms, RtpHeader *rtp) override; }; class WebRtcTransportImp : public WebRtcTransport { public: using Ptr = std::shared_ptr; ~WebRtcTransportImp() override; uint64_t getBytesUsage() const; uint64_t getDuration() const; bool canSendRtp() const; bool canRecvRtp() const; void onSendRtp(const RtpPacket::Ptr &rtp, bool flush, bool rtx = false); void createRtpChannel(const std::string &rid, uint32_t ssrc, MediaTrack &track); void removeTuple(RTC::TransportTuple* tuple); void safeShutdown(const SockException &ex); void setPreferredTcp(bool flag) override; void setLocalIp(std::string local_ip) override; void setIceCandidate(std::vector cands) override; 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; void onStartWebRTC() override; void onSendSockData(Buffer::Ptr buf, bool flush = true, RTC::TransportTuple *tuple = nullptr) override; void onCheckSdp(SdpType type, RtcSession &sdp) override; void onRtcConfigure(RtcConfigure &configure) const override; void onRtp(const char *buf, size_t len, uint64_t stamp_ms) override; 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; void onShutdown(const SockException &ex) override; virtual void onRecvRtp(MediaTrack &track, const std::string &rid, RtpPacket::Ptr rtp) {} void updateTicker(); float getLossRate(TrackType type); void onRtcpBye() override; private: 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); void registerSelf(); void unregisterSelf(); void unrefSelf(); void onCheckAnswer(RtcSession &sdp); private: bool _preferred_tcp = false; uint16_t _rtx_seq[2] = {0, 0}; // 用掉的总流量 [AUTO-TRANSLATED:713b61c9] // Total traffic used uint64_t _bytes_usage = 0; // 保持自我强引用 [AUTO-TRANSLATED:c2dc228f] // Keep self strong reference Ptr _self; // 检测超时的定时器 [AUTO-TRANSLATED:a58e1388] // Timeout detection timer Timer::Ptr _timer; // 刷新计时器 [AUTO-TRANSLATED:61eb11e5] // Refresh timer Ticker _alive_ticker; // pli rtcp计时器 [AUTO-TRANSLATED:a1a5fd18] // pli rtcp timer Ticker _pli_ticker; // twcc rtcp发送上下文对象 [AUTO-TRANSLATED:aef6476a] // twcc rtcp send context object TwccContext _twcc_ctx; // 根据发送rtp的track类型获取相关信息 [AUTO-TRANSLATED:ff31c272] // Get relevant information based on the track type of the sent rtp MediaTrack::Ptr _type_to_track[2]; // 根据rtcp的ssrc获取相关信息,收发rtp和rtx的ssrc都会记录 [AUTO-TRANSLATED:6c57cd48] // Get relevant information based on the ssrc of the rtcp, the ssrc of sending and receiving rtp and rtx will be recorded std::unordered_map _ssrc_to_track; // 根据接收rtp的pt获取相关信息 [AUTO-TRANSLATED:39e56d7d] // Get relevant information based on the pt of the received rtp std::unordered_map> _pt_to_track; std::vector _cands; // http访问时的host ip [AUTO-TRANSLATED:e8fe6957] // Host ip for http access std::string _local_ip; }; class WebRtcTransportManager { public: friend class WebRtcTransportImp; static WebRtcTransportManager &Instance(); WebRtcTransportImp::Ptr getItem(const std::string &key); private: WebRtcTransportManager() = default; void addItem(const std::string &key, const WebRtcTransportImp::Ptr &ptr); void removeItem(const std::string &key); private: mutable std::mutex _mtx; std::unordered_map > _map; }; class WebRtcArgs : public std::enable_shared_from_this { public: virtual ~WebRtcArgs() = default; virtual variant operator[](const std::string &key) const = 0; }; using onCreateWebRtc = std::function; class WebRtcPluginManager { public: using Plugin = std::function; using Listener = std::function; static WebRtcPluginManager &Instance(); void registerPlugin(const std::string &type, Plugin cb); void setListener(Listener cb); void negotiateSdp(Session &sender, const std::string &type, const WebRtcArgs &args, const onCreateWebRtc &cb); private: WebRtcPluginManager() = default; private: mutable std::mutex _mtx_creator; Listener _listener; std::unordered_map _map_creator; }; }// namespace mediakit