ZLMediaKit/webrtc/WebRtcTransport.h

252 lines
9.1 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.
*/
#pragma once
#include <memory>
#include <string>
#include "DtlsTransport.hpp"
#include "IceServer.hpp"
#include "SrtpSession.hpp"
#include "StunPacket.hpp"
#include "Sdp.h"
#include "Poller/EventPoller.h"
#include "Network/Socket.h"
#include "Rtsp/RtspMediaSourceImp.h"
#include "Rtcp/RtcpContext.h"
#include "Rtcp/RtcpFCI.h"
#include "Nack.h"
using namespace toolkit;
using namespace mediakit;
class WebRtcTransport : public RTC::DtlsTransport::Listener, public RTC::IceServer::Listener {
public:
using Ptr = std::shared_ptr<WebRtcTransport>;
WebRtcTransport(const EventPoller::Ptr &poller);
~WebRtcTransport() override = default;
/**
* 创建对象
*/
virtual void onCreate();
/**
* 销毁对象
*/
virtual void onDestory();
/**
* 创建webrtc answer sdp
* @param offer offer sdp
* @return answer sdp
*/
std::string getAnswerSdp(const string &offer);
/**
* 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长度
* @param flush 是否flush socket
* @param ctx 用户指针
*/
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);
const EventPoller::Ptr& getPoller() const;
protected:
//// dtls相关的回调 ////
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相关的回调 ///
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;
protected:
virtual void onStartWebRTC() = 0;
virtual void onRtcConfigure(RtcConfigure &configure) const;
virtual void onCheckSdp(SdpType type, RtcSession &sdp);
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;
virtual void onShutdown(const SockException &ex) = 0;
virtual void onBeforeEncryptRtp(const char *buf, size_t &len, void *ctx) = 0;
virtual void onBeforeEncryptRtcp(const char *buf, size_t &len, void *ctx) = 0;
protected:
const RtcSession& getSdp(SdpType type) const;
RTC::TransportTuple* getSelectedTuple() const;
void sendRtcpRemb(uint32_t ssrc, size_t bit_rate);
void sendRtcpPli(uint32_t ssrc);
private:
void onSendSockData(const char *buf, size_t len, bool flush = true);
void setRemoteDtlsFingerprint(const RtcSession &remote);
private:
uint8_t _srtp_buf[2000];
EventPoller::Ptr _poller;
std::shared_ptr<RTC::IceServer> _ice_server;
std::shared_ptr<RTC::DtlsTransport> _dtls_transport;
std::shared_ptr<RTC::SrtpSession> _srtp_session_send;
RtcSession::Ptr _offer_sdp;
RtcSession::Ptr _answer_sdp;
function<std::shared_ptr<RTC::SrtpSession>() > _srtp_session_recv_alloc;
std::unordered_map<uint8_t /*pt*/, std::shared_ptr<RTC::SrtpSession> > _srtp_session_recv;
};
class RtpChannel;
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;
RtcpContext::Ptr rtcp_context_send;
//for recv rtp
unordered_map<string/*rid*/, std::shared_ptr<RtpChannel> > rtp_channel;
std::shared_ptr<RtpChannel> getRtpChannel(uint32_t ssrc) const;
};
class WebRtcTransportImp : public WebRtcTransport, public MediaSourceEvent, public SockInfo, public std::enable_shared_from_this<WebRtcTransportImp>{
public:
using Ptr = std::shared_ptr<WebRtcTransportImp>;
~WebRtcTransportImp() override;
/**
* 创建WebRTC对象
* @param poller 改对象需要绑定的线程
* @return 对象
*/
static Ptr create(const EventPoller::Ptr &poller);
/**
* 绑定rtsp媒体源
* @param src 媒体源
* @param is_play 是播放还是推流
*/
void attach(const RtspMediaSource::Ptr &src, const MediaInfo &info, bool is_play = true);
protected:
void onStartWebRTC() override;
void onSendSockData(const char *buf, size_t len, struct sockaddr_in *dst, bool flush = true) override;
void onCheckSdp(SdpType type, RtcSession &sdp) override;
void onRtcConfigure(RtcConfigure &configure) const override;
void onRtp(const char *buf, size_t len) override;
void onRtcp(const char *buf, size_t len) override;
void onBeforeEncryptRtp(const char *buf, size_t &len, void *ctx) override;
void onBeforeEncryptRtcp(const char *buf, size_t &len, void *ctx) override {};
void onShutdown(const SockException &ex) override;
///////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;
///////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;
private:
WebRtcTransportImp(const EventPoller::Ptr &poller);
void onCreate() override;
void onDestory() override;
void onSendRtp(const RtpPacket::Ptr &rtp, bool flush, bool rtx = false);
SdpAttrCandidate::Ptr getIceCandidate() const;
bool canSendRtp() const;
bool canRecvRtp() const;
void onSortedRtp(MediaTrack &track, const string &rid, RtpPacket::Ptr rtp);
void onSendNack(MediaTrack &track, const FCI_NACK &nack, uint32_t ssrc);
void createRtpChannel(const string &rid, uint32_t ssrc, const MediaTrack::Ptr &track);
private:
bool _simulcast = false;
uint16_t _rtx_seq[2] = {0, 0};
//用掉的总流量
uint64_t _bytes_usage = 0;
//媒体相关元数据
MediaInfo _media_info;
//保持自我强引用
Ptr _self;
//检测超时的定时器
Timer::Ptr _timer;
//刷新计时器
Ticker _alive_ticker;
//pli rtcp计时器
Ticker _pli_ticker;
//复合udp端口接收一切rtp与rtcp
Socket::Ptr _socket;
//推流的rtsp源
RtspMediaSource::Ptr _push_src;
unordered_map<string/*rid*/, RtspMediaSource::Ptr> _push_src_simulcast;
//播放的rtsp源
RtspMediaSource::Ptr _play_src;
//播放rtsp源的reader对象
RtspMediaSource::RingType::RingReader::Ptr _reader;
//根据发送rtp的track类型获取相关信息
MediaTrack::Ptr _type_to_track[2];
//根据接收rtp的pt获取相关信息
unordered_map<uint8_t/*pt*/, std::pair<bool/*is rtx*/,MediaTrack::Ptr> > _pt_to_track;
//根据rtcp的ssrc获取相关信息收发rtp和rtx的ssrc都会记录
unordered_map<uint32_t/*ssrc*/, MediaTrack::Ptr> _ssrc_to_track;
};