206 lines
6.2 KiB
C++
206 lines
6.2 KiB
C++
/*
|
|
* 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.
|
|
*/
|
|
|
|
#ifndef ZLMEDIAKIT_SRTCALLER_H
|
|
#define ZLMEDIAKIT_SRTCALLER_H
|
|
|
|
//srt
|
|
#include "srt/Packet.hpp"
|
|
#include "srt/Crypto.hpp"
|
|
#include "srt/PacketQueue.hpp"
|
|
#include "srt/PacketSendQueue.hpp"
|
|
#include "srt/Statistic.hpp"
|
|
|
|
#include "Poller/EventPoller.h"
|
|
#include "Network/Socket.h"
|
|
#include "Poller/Timer.h"
|
|
#include "Util/TimeTicker.h"
|
|
#include "Common/MultiMediaSourceMuxer.h"
|
|
#include "Rtp/Decoder.h"
|
|
#include "TS/TSMediaSource.h"
|
|
#include <memory>
|
|
#include <string>
|
|
|
|
|
|
namespace mediakit {
|
|
|
|
// 解析srt 信令url的工具类
|
|
class SrtUrl {
|
|
public:
|
|
void parse(const std::string &url);
|
|
|
|
public:
|
|
std::string _full_url;
|
|
std::string _params;
|
|
std::string _streamid;
|
|
sockaddr_storage _addr;
|
|
|
|
private:
|
|
uint16_t _port;
|
|
std::string _host;
|
|
};
|
|
|
|
// 实现了webrtc代理拉流功能
|
|
class SrtCaller : public std::enable_shared_from_this<SrtCaller>{
|
|
public:
|
|
using Ptr = std::shared_ptr<SrtCaller>;
|
|
|
|
using SteadyClock = std::chrono::steady_clock;
|
|
using TimePoint = std::chrono::time_point<SteadyClock>;
|
|
|
|
SrtCaller(const toolkit::EventPoller::Ptr &poller);
|
|
virtual ~SrtCaller();
|
|
|
|
const toolkit::EventPoller::Ptr &getPoller() const {return _poller;}
|
|
|
|
virtual void inputSockData(uint8_t *buf, int len, struct sockaddr *addr);
|
|
virtual void onSendTSData(const SRT::Buffer::Ptr &buffer, bool flush);
|
|
|
|
size_t getRecvSpeed() const;
|
|
size_t getRecvTotalBytes() const;
|
|
size_t getSendSpeed() const;
|
|
size_t getSendTotalBytes() const;
|
|
|
|
protected:
|
|
|
|
virtual void onConnect();
|
|
virtual void onHandShakeFinished();
|
|
virtual void onResult(const toolkit::SockException &ex);
|
|
|
|
virtual void onSRTData(SRT::DataPacket::Ptr pkt);
|
|
|
|
virtual uint16_t getLatency() = 0;
|
|
virtual int getLatencyMul();
|
|
virtual int getPktBufSize();
|
|
virtual float getTimeOutSec();
|
|
|
|
virtual bool isPlayer() = 0;
|
|
|
|
private:
|
|
void doHandshake();
|
|
|
|
void sendHandshakeInduction();
|
|
void sendHandshakeConclusion();
|
|
void sendACKPacket();
|
|
void sendLightACKPacket();
|
|
void sendNAKPacket(std::list<SRT::PacketQueue::LostPair> &lost_list);
|
|
void sendMsgDropReq(uint32_t first, uint32_t last);
|
|
void sendKeepLivePacket();
|
|
void sendShutDown();
|
|
void tryAnnounceKeyMaterial();
|
|
void sendControlPacket(SRT::ControlPacket::Ptr pkt, bool flush = true);
|
|
void sendDataPacket(SRT::DataPacket::Ptr pkt, char *buf, int len, bool flush = false);
|
|
void sendPacket(toolkit::Buffer::Ptr pkt, bool flush);
|
|
|
|
void handleHandshake(uint8_t *buf, int len, struct sockaddr *addr);
|
|
void handleHandshakeInduction(SRT::HandshakePacket &pkt, struct sockaddr *addr);
|
|
void handleHandshakeConclusion(SRT::HandshakePacket &pkt, struct sockaddr *addr);
|
|
void handleACK(uint8_t *buf, int len, struct sockaddr *addr);
|
|
void handleACKACK(uint8_t *buf, int len, struct sockaddr *addr);
|
|
void handleNAK(uint8_t *buf, int len, struct sockaddr *addr);
|
|
void handleDropReq(uint8_t *buf, int len, struct sockaddr *addr);
|
|
void handleKeeplive(uint8_t *buf, int len, struct sockaddr *addr);
|
|
void handleShutDown(uint8_t *buf, int len, struct sockaddr *addr);
|
|
void handlePeerError(uint8_t *buf, int len, struct sockaddr *addr);
|
|
void handleCongestionWarning(uint8_t *buf, int len, struct sockaddr *addr);
|
|
void handleUserDefinedType(uint8_t *buf, int len, struct sockaddr *addr);
|
|
void handleDataPacket(uint8_t *buf, int len, struct sockaddr *addr);
|
|
void handleKeyMaterialReqPacket(uint8_t *buf, int len, struct sockaddr *addr);
|
|
void handleKeyMaterialRspPacket(uint8_t *buf, int len, struct sockaddr *addr);
|
|
|
|
void checkAndSendAckNak();
|
|
void createTimerForCheckAlive();
|
|
|
|
std::string generateStreamId();
|
|
uint32_t generateSocketId();
|
|
int32_t generateInitSeq();
|
|
size_t getPayloadSize();
|
|
|
|
virtual std::string getPassphrase() = 0;
|
|
|
|
protected:
|
|
SrtUrl _url;
|
|
toolkit::EventPoller::Ptr _poller;
|
|
|
|
bool _is_handleshake_finished = false;
|
|
|
|
private:
|
|
toolkit::Socket::Ptr _socket;
|
|
|
|
TimePoint _now;
|
|
TimePoint _start_timestamp;
|
|
// for calculate rtt for delay
|
|
TimePoint _induction_ts;
|
|
|
|
//the initial value of RTT is 100 milliseconds
|
|
//RTTVar is 50 milliseconds
|
|
uint32_t _rtt = 100 * 1000;
|
|
uint32_t _rtt_variance = 50 * 1000;
|
|
|
|
//local
|
|
uint32_t _socket_id = 0;
|
|
uint32_t _init_seq_number = 0;
|
|
uint32_t _mtu = 1500;
|
|
uint32_t _max_flow_window_size = 8192;
|
|
uint16_t _delay = 120;
|
|
|
|
//peer
|
|
uint32_t _sync_cookie = 0;
|
|
uint32_t _peer_socket_id;
|
|
|
|
// for handshake
|
|
SRT::Timer::Ptr _handleshake_timer;
|
|
SRT::HandshakePacket::Ptr _handleshake_req;
|
|
|
|
// for keeplive
|
|
SRT::Ticker _send_ticker;
|
|
SRT::Timer::Ptr _keeplive_timer;
|
|
|
|
// for alive
|
|
SRT::Ticker _alive_ticker;
|
|
SRT::Timer::Ptr _alive_timer;
|
|
|
|
// for recv
|
|
SRT::PacketQueueInterface::Ptr _recv_buf;
|
|
uint32_t _last_pkt_seq = 0;
|
|
|
|
// Ack
|
|
SRT::UTicker _ack_ticker;
|
|
uint32_t _last_ack_pkt_seq = 0;
|
|
uint32_t _light_ack_pkt_count = 0;
|
|
uint32_t _ack_number_count = 0;
|
|
std::map<uint32_t, TimePoint> _ack_send_timestamp;
|
|
// Full Ack
|
|
// Link Capacity and Receiving Rate Estimation
|
|
std::shared_ptr<SRT::PacketRecvRateContext> _pkt_recv_rate_context;
|
|
std::shared_ptr<SRT::EstimatedLinkCapacityContext> _estimated_link_capacity_context;
|
|
|
|
// Nak
|
|
SRT::UTicker _nak_ticker;
|
|
|
|
//for Send
|
|
SRT::PacketSendQueue::Ptr _send_buf;
|
|
SRT::ResourcePool<SRT::BufferRaw> _packet_pool;
|
|
uint32_t _send_packet_seq_number = 0;
|
|
uint32_t _send_msg_number = 1;
|
|
|
|
//AckAck
|
|
uint32_t _last_recv_ackack_seq_num = 0;
|
|
|
|
// for encryption
|
|
SRT::Crypto::Ptr _crypto;
|
|
SRT::Timer::Ptr _announce_timer;
|
|
SRT::KeyMaterialPacket::Ptr _announce_req;
|
|
};
|
|
|
|
} /* namespace mediakit */
|
|
#endif /* ZLMEDIAKIT_SRTCALLER_H */
|
|
|