WebRtcTransport.h 7.88 KB
Newer Older
xiongziliang committed
1 2 3 4 5 6 7 8 9 10 11
/*
 * 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
12 13 14

#include <memory>
#include <string>
ziyue committed
15 16 17 18
#include "DtlsTransport.hpp"
#include "IceServer.hpp"
#include "SrtpSession.hpp"
#include "StunPacket.hpp"
ziyue committed
19
#include "Sdp.h"
ziyue committed
20 21
#include "Poller/EventPoller.h"
#include "Network/Socket.h"
xiongziliang committed
22
#include "Rtsp/RtspMediaSourceImp.h"
xiongziliang committed
23
#include "Rtcp/RtcpContext.h"
ziyue committed
24 25
using namespace toolkit;
using namespace mediakit;
26

ziyue committed
27
class WebRtcTransport : public RTC::DtlsTransport::Listener, public RTC::IceServer::Listener  {
28 29
public:
    using Ptr = std::shared_ptr<WebRtcTransport>;
ziyue committed
30 31 32
    WebRtcTransport(const EventPoller::Ptr &poller);
    ~WebRtcTransport() override = default;

ziyue committed
33
    /**
xia-chu committed
34 35 36 37 38 39
     * 创建对象
     */
    virtual void onCreate();

    /**
     * 销毁对象
ziyue committed
40
     */
ziyue committed
41
    virtual void onDestory();
42

ziyue committed
43 44 45 46 47
    /**
     * 创建webrtc answer sdp
     * @param offer offer sdp
     * @return answer sdp
     */
ziyue committed
48 49
    std::string getAnswerSdp(const string &offer);

ziyue committed
50 51 52 53 54 55 56 57 58 59 60 61
    /**
     * 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长度
62 63
     * @param flush 是否flush socket
     * @param pt rtp payload type
ziyue committed
64
     */
65
    void sendRtpPacket(char *buf, size_t len, bool flush, uint8_t pt);
xiongziliang committed
66
    void sendRtcpPacket(char *buf, size_t len, bool flush);
67

68 69
    const EventPoller::Ptr& getPoller() const;

70
protected:
ziyue committed
71
    ////  dtls相关的回调 ////
xia-chu committed
72
    void OnDtlsTransportConnecting(const RTC::DtlsTransport *dtlsTransport) override;
ziyue committed
73 74 75 76 77 78 79
    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;
ziyue committed
80

xia-chu committed
81 82
    void OnDtlsTransportFailed(const RTC::DtlsTransport *dtlsTransport) override;
    void OnDtlsTransportClosed(const RTC::DtlsTransport *dtlsTransport) override;
ziyue committed
83
    void OnDtlsTransportSendData(const RTC::DtlsTransport *dtlsTransport, const uint8_t *data, size_t len) override;
xia-chu committed
84
    void OnDtlsTransportApplicationDataReceived(const RTC::DtlsTransport *dtlsTransport, const uint8_t *data, size_t len) override;
ziyue committed
85 86

protected:
ziyue committed
87
    //// ice相关的回调 ///
ziyue committed
88 89 90 91 92 93 94
    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:
ziyue committed
95 96
    virtual void onStartWebRTC() = 0;
    virtual void onRtcConfigure(RtcConfigure &configure) const {}
xiongziliang committed
97
    virtual void onCheckSdp(SdpType type, RtcSession &sdp);
ziyue committed
98 99 100 101
    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;
xia-chu committed
102
    virtual void onShutdown(const SockException &ex) = 0;
103

xiongziliang committed
104 105
protected:
    const RtcSession& getSdp(SdpType type) const;
106
    RTC::TransportTuple* getSelectedTuple() const;
xiongziliang committed
107

108
private:
ziyue committed
109
    void onSendSockData(const char *buf, size_t len, bool flush = true);
ziyue committed
110
    void setRemoteDtlsFingerprint(const RtcSession &remote);
111 112

private:
113
    EventPoller::Ptr _poller;
ziyue committed
114 115 116 117
    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;
ziyue committed
118 119
    RtcSession::Ptr _offer_sdp;
    RtcSession::Ptr _answer_sdp;
120 121
};

xiongziliang committed
122 123
class RtpReceiverImp;

124
class WebRtcTransportImp : public WebRtcTransport, public MediaSourceEvent, public SockInfo, public std::enable_shared_from_this<WebRtcTransportImp>{
125 126
public:
    using Ptr = std::shared_ptr<WebRtcTransportImp>;
xia-chu committed
127
    ~WebRtcTransportImp() override;
128

ziyue committed
129 130 131 132 133
    /**
     * 创建WebRTC对象
     * @param poller 改对象需要绑定的线程
     * @return 对象
     */
ziyue committed
134
    static Ptr create(const EventPoller::Ptr &poller);
135

ziyue committed
136 137 138
    /**
     * 绑定rtsp媒体源
     * @param src 媒体源
139
     * @param is_play 是播放还是推流
ziyue committed
140
     */
xia-chu committed
141
    void attach(const RtspMediaSource::Ptr &src, const MediaInfo &info, bool is_play = true);
142 143

protected:
ziyue committed
144
    void onStartWebRTC() override;
ziyue committed
145
    void onSendSockData(const char *buf, size_t len, struct sockaddr_in *dst, bool flush = true) override;
xiongziliang committed
146
    void onCheckSdp(SdpType type, RtcSession &sdp) override;
ziyue committed
147
    void onRtcConfigure(RtcConfigure &configure) const override;
ziyue committed
148 149 150

    void onRtp(const char *buf, size_t len) override;
    void onRtcp(const char *buf, size_t len) override;
xia-chu committed
151
    void onShutdown(const SockException &ex) override;
ziyue committed
152

153 154 155 156 157 158 159 160 161 162 163 164
    ///////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;

165 166 167 168 169 170 171 172 173 174 175 176
    ///////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;

ziyue committed
177
private:
ziyue committed
178
    WebRtcTransportImp(const EventPoller::Ptr &poller);
xia-chu committed
179
    void onCreate() override;
ziyue committed
180
    void onDestory() override;
ziyue committed
181
    void onSendRtp(const RtpPacket::Ptr &rtp, bool flush);
ziyue committed
182
    SdpAttrCandidate::Ptr getIceCandidate() const;
xiongziliang committed
183
    bool canSendRtp() const;
xiongziliang committed
184 185 186 187 188 189 190 191
    bool canRecvRtp() const;

    class RtpPayloadInfo {
    public:
        bool is_common_rtp;
        const RtcCodecPlan *plan;
        const RtcMedia *media;
        std::shared_ptr<RtpReceiverImp> receiver;
xiongziliang committed
192 193
        RtcpContext::Ptr rtcp_context_recv;
        RtcpContext::Ptr rtcp_context_send;
xiongziliang committed
194 195 196 197
    };

    void onSortedRtp(const RtpPayloadInfo &info,RtpPacket::Ptr rtp);
    void onBeforeSortedRtp(const RtpPayloadInfo &info,const RtpPacket::Ptr &rtp);
198 199

private:
xia-chu committed
200 201 202 203
    //用掉的总流量
    uint64_t _bytes_usage = 0;
    //媒体相关元数据
    MediaInfo _media_info;
xia-chu committed
204 205 206 207 208 209
    //保持自我强引用
    Ptr _self;
    //检测超时的定时器
    Timer::Ptr _timer;
    //刷新计时器
    Ticker _alive_ticker;
xiongziliang committed
210
    //pli rtcp计时器
211
    Ticker _pli_ticker;
xiongziliang committed
212 213 214
    //rtc rtp推流的视频ssrc
    uint32_t _recv_video_ssrc;
    //记录协商的rtp的pt类型
215
    uint8_t _send_rtp_pt[2] = {0xFF, 0xFF};
xiongziliang committed
216
    //复合udp端口,接收一切rtp与rtcp
217
    Socket::Ptr _socket;
218 219 220 221 222
    //推流的rtsp源
    RtspMediaSource::Ptr _push_src;
    //播放的rtsp源
    RtspMediaSource::Ptr _play_src;
    //播放rtsp源的reader对象
223
    RtspMediaSource::RingType::RingReader::Ptr _reader;
xiongziliang committed
224
    //根据rtp的pt获取相关信息
225
    unordered_map<uint8_t, RtpPayloadInfo> _rtp_info_pt;
xiongziliang committed
226
    //根据推流端rtp的ssrc获取相关信息
227
    unordered_map<uint32_t, RtpPayloadInfo*> _rtp_info_ssrc;
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246
};