2020-02-28 15:18:39 +00:00
|
|
|
/**
|
|
|
|
* The MIT License (MIT)
|
|
|
|
*
|
2020-03-31 10:03:04 +00:00
|
|
|
* Copyright (c) 2013-2020 John
|
2020-02-28 15:18:39 +00:00
|
|
|
*
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
|
|
* this software and associated documentation files (the "Software"), to deal in
|
|
|
|
* the Software without restriction, including without limitation the rights to
|
|
|
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
|
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
|
|
|
* subject to the following conditions:
|
|
|
|
*
|
|
|
|
* The above copyright notice and this permission notice shall be included in all
|
|
|
|
* copies or substantial portions of the Software.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
|
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
|
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
|
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
|
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef SRS_APP_RTC_CONN_HPP
|
|
|
|
#define SRS_APP_RTC_CONN_HPP
|
|
|
|
|
|
|
|
#include <srs_core.hpp>
|
2020-03-07 16:30:31 +00:00
|
|
|
#include <srs_app_listener.hpp>
|
2020-03-06 15:01:48 +00:00
|
|
|
#include <srs_service_st.hpp>
|
2020-03-12 16:24:56 +00:00
|
|
|
#include <srs_kernel_utility.hpp>
|
2020-03-14 14:11:01 +00:00
|
|
|
#include <srs_rtmp_stack.hpp>
|
2020-03-17 09:56:37 +00:00
|
|
|
#include <srs_app_hybrid.hpp>
|
2020-03-19 04:58:04 +00:00
|
|
|
#include <srs_app_hourglass.hpp>
|
2020-05-11 04:07:55 +00:00
|
|
|
#include <srs_app_rtc_sdp.hpp>
|
2020-04-10 10:14:33 +00:00
|
|
|
#include <srs_app_reload.hpp>
|
2020-05-11 04:07:55 +00:00
|
|
|
#include <srs_kernel_rtc_rtp.hpp>
|
2020-05-19 10:14:48 +00:00
|
|
|
#include <srs_kernel_rtc_rtcp.hpp>
|
2020-05-11 04:07:55 +00:00
|
|
|
#include <srs_app_rtc_queue.hpp>
|
2020-06-02 11:00:31 +00:00
|
|
|
#include <srs_app_rtc_source.hpp>
|
2020-06-25 04:03:21 +00:00
|
|
|
#include <srs_app_rtc_dtls.hpp>
|
2020-02-28 15:18:39 +00:00
|
|
|
|
|
|
|
#include <string>
|
|
|
|
#include <map>
|
2020-03-02 14:47:40 +00:00
|
|
|
#include <vector>
|
2020-04-05 08:53:08 +00:00
|
|
|
#include <sys/socket.h>
|
2020-02-28 15:18:39 +00:00
|
|
|
|
2020-03-12 16:24:56 +00:00
|
|
|
class SrsUdpMuxSocket;
|
2020-03-09 11:46:27 +00:00
|
|
|
class SrsConsumer;
|
2020-02-28 15:18:39 +00:00
|
|
|
class SrsStunPacket;
|
2020-03-09 11:46:27 +00:00
|
|
|
class SrsRtcServer;
|
2020-07-07 08:37:34 +00:00
|
|
|
class SrsRtcConnection;
|
2020-03-12 16:24:56 +00:00
|
|
|
class SrsSharedPtrMessage;
|
2020-07-08 11:01:33 +00:00
|
|
|
class SrsRtcStream;
|
2020-04-11 14:54:44 +00:00
|
|
|
class SrsRtpPacket2;
|
2020-05-02 01:15:49 +00:00
|
|
|
class ISrsCodec;
|
2020-05-02 02:07:55 +00:00
|
|
|
class SrsRtpNackForReceiver;
|
2020-05-03 09:41:00 +00:00
|
|
|
class SrsRtpIncommingVideoFrame;
|
2020-05-14 10:33:31 +00:00
|
|
|
class SrsRtpRingBuffer;
|
2020-05-24 13:40:23 +00:00
|
|
|
class SrsRtcConsumer;
|
2020-07-15 05:11:35 +00:00
|
|
|
class SrsRtcAudioSendTrack;
|
|
|
|
class SrsRtcVideoSendTrack;
|
2020-07-27 04:28:15 +00:00
|
|
|
class SrsErrorPithyPrint;
|
2020-03-12 16:24:56 +00:00
|
|
|
|
2020-03-14 14:11:01 +00:00
|
|
|
const uint8_t kSR = 200;
|
|
|
|
const uint8_t kRR = 201;
|
2020-03-12 16:24:56 +00:00
|
|
|
const uint8_t kSDES = 202;
|
2020-03-14 14:11:01 +00:00
|
|
|
const uint8_t kBye = 203;
|
|
|
|
const uint8_t kApp = 204;
|
|
|
|
|
|
|
|
// @see: https://tools.ietf.org/html/rfc4585#section-6.1
|
|
|
|
const uint8_t kRtpFb = 205;
|
|
|
|
const uint8_t kPsFb = 206;
|
2020-04-23 09:08:21 +00:00
|
|
|
const uint8_t kXR = 207;
|
2020-03-14 14:11:01 +00:00
|
|
|
|
|
|
|
// @see: https://tools.ietf.org/html/rfc4585#section-6.3
|
|
|
|
const uint8_t kPLI = 1;
|
|
|
|
const uint8_t kSLI = 2;
|
|
|
|
const uint8_t kRPSI = 3;
|
|
|
|
const uint8_t kAFB = 15;
|
2020-03-12 16:24:56 +00:00
|
|
|
|
2020-07-07 08:37:34 +00:00
|
|
|
enum SrsRtcConnectionStateType
|
2020-02-28 15:18:39 +00:00
|
|
|
{
|
2020-03-16 14:01:09 +00:00
|
|
|
// TODO: FIXME: Should prefixed by enum name.
|
2020-02-28 15:18:39 +00:00
|
|
|
INIT = -1,
|
2020-05-05 23:37:00 +00:00
|
|
|
WAITING_ANSWER = 1,
|
|
|
|
WAITING_STUN = 2,
|
|
|
|
DOING_DTLS_HANDSHAKE = 3,
|
|
|
|
ESTABLISHED = 4,
|
|
|
|
CLOSED = 5,
|
2020-02-28 15:18:39 +00:00
|
|
|
};
|
|
|
|
|
2020-08-07 04:50:54 +00:00
|
|
|
// The transport for RTC connection.
|
|
|
|
class ISrsRtcTransport : public ISrsDtlsCallback
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
ISrsRtcTransport();
|
|
|
|
virtual ~ISrsRtcTransport();
|
|
|
|
public:
|
|
|
|
virtual srs_error_t initialize(SrsSessionConfig* cfg) = 0;
|
|
|
|
virtual srs_error_t start_active_handshake() = 0;
|
|
|
|
virtual srs_error_t on_dtls(char* data, int nb_data) = 0;
|
|
|
|
public:
|
|
|
|
virtual srs_error_t protect_rtp(const char* plaintext, char* cipher, int& nb_cipher) = 0;
|
|
|
|
virtual srs_error_t protect_rtcp(const char* plaintext, char* cipher, int& nb_cipher) = 0;
|
|
|
|
virtual srs_error_t protect_rtp2(void* rtp_hdr, int* len_ptr) = 0;
|
|
|
|
virtual srs_error_t unprotect_rtp(const char* cipher, char* plaintext, int& nb_plaintext) = 0;
|
|
|
|
virtual srs_error_t unprotect_rtcp(const char* cipher, char* plaintext, int& nb_plaintext) = 0;
|
|
|
|
};
|
|
|
|
|
2020-07-24 02:08:01 +00:00
|
|
|
// The security transport, use DTLS/SRTP to protect the data.
|
2020-08-07 04:50:54 +00:00
|
|
|
class SrsSecurityTransport : public ISrsRtcTransport
|
2020-02-28 15:18:39 +00:00
|
|
|
{
|
2020-03-06 15:01:48 +00:00
|
|
|
private:
|
2020-07-07 08:37:34 +00:00
|
|
|
SrsRtcConnection* session_;
|
2020-06-25 04:03:21 +00:00
|
|
|
SrsDtls* dtls_;
|
2020-06-25 12:47:17 +00:00
|
|
|
SrsSRTP* srtp_;
|
2020-03-06 15:01:48 +00:00
|
|
|
bool handshake_done;
|
2020-02-28 15:18:39 +00:00
|
|
|
public:
|
2020-07-07 08:37:34 +00:00
|
|
|
SrsSecurityTransport(SrsRtcConnection* s);
|
2020-06-25 04:03:21 +00:00
|
|
|
virtual ~SrsSecurityTransport();
|
2020-03-06 15:01:48 +00:00
|
|
|
|
2020-06-27 03:13:53 +00:00
|
|
|
srs_error_t initialize(SrsSessionConfig* cfg);
|
|
|
|
// When play role of dtls client, it send handshake.
|
|
|
|
srs_error_t start_active_handshake();
|
2020-04-30 06:49:37 +00:00
|
|
|
srs_error_t on_dtls(char* data, int nb_data);
|
2020-03-12 16:24:56 +00:00
|
|
|
public:
|
2020-06-25 12:47:17 +00:00
|
|
|
// Encrypt the input plaintext to output cipher with nb_cipher bytes.
|
|
|
|
// @remark Note that the nb_cipher is the size of input plaintext, and
|
|
|
|
// it also is the length of output cipher when return.
|
|
|
|
srs_error_t protect_rtp(const char* plaintext, char* cipher, int& nb_cipher);
|
|
|
|
srs_error_t protect_rtcp(const char* plaintext, char* cipher, int& nb_cipher);
|
|
|
|
// Encrypt the input rtp_hdr with *len_ptr bytes.
|
|
|
|
// @remark the input plaintext and out cipher reuse rtp_hdr.
|
2020-04-13 07:24:41 +00:00
|
|
|
srs_error_t protect_rtp2(void* rtp_hdr, int* len_ptr);
|
2020-06-25 12:47:17 +00:00
|
|
|
// Decrypt the input cipher to output cipher with nb_cipher bytes.
|
|
|
|
// @remark Note that the nb_plaintext is the size of input cipher, and
|
|
|
|
// it also is the length of output plaintext when return.
|
|
|
|
srs_error_t unprotect_rtp(const char* cipher, char* plaintext, int& nb_plaintext);
|
|
|
|
srs_error_t unprotect_rtcp(const char* cipher, char* plaintext, int& nb_plaintext);
|
2020-06-25 04:03:21 +00:00
|
|
|
// implement ISrsDtlsCallback
|
|
|
|
public:
|
|
|
|
virtual srs_error_t on_dtls_handshake_done();
|
|
|
|
virtual srs_error_t on_dtls_application_data(const char* data, const int len);
|
|
|
|
virtual srs_error_t write_dtls_data(void* data, int size);
|
2020-03-07 16:30:31 +00:00
|
|
|
private:
|
2020-03-09 11:46:27 +00:00
|
|
|
srs_error_t srtp_initialize();
|
2020-03-06 15:01:48 +00:00
|
|
|
};
|
|
|
|
|
2020-08-07 04:50:54 +00:00
|
|
|
// Semi security transport, setup DTLS and SRTP, with SRTP decrypt, without SRTP encrypt.
|
|
|
|
class SrsSemiSecurityTransport : public SrsSecurityTransport
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
SrsSemiSecurityTransport(SrsRtcConnection* s);
|
|
|
|
virtual ~SrsSemiSecurityTransport();
|
|
|
|
public:
|
|
|
|
virtual srs_error_t protect_rtp(const char* plaintext, char* cipher, int& nb_cipher);
|
|
|
|
virtual srs_error_t protect_rtcp(const char* plaintext, char* cipher, int& nb_cipher);
|
|
|
|
virtual srs_error_t protect_rtp2(void* rtp_hdr, int* len_ptr);
|
|
|
|
};
|
|
|
|
|
2020-08-07 06:33:52 +00:00
|
|
|
// Plaintext transport, without DTLS or SRTP.
|
|
|
|
class SrsPlaintextTransport : public ISrsRtcTransport
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
SrsRtcConnection* session_;
|
|
|
|
public:
|
|
|
|
SrsPlaintextTransport(SrsRtcConnection* s);
|
|
|
|
virtual ~SrsPlaintextTransport();
|
|
|
|
public:
|
|
|
|
virtual srs_error_t initialize(SrsSessionConfig* cfg);
|
|
|
|
virtual srs_error_t start_active_handshake();
|
|
|
|
virtual srs_error_t on_dtls(char* data, int nb_data);
|
|
|
|
virtual srs_error_t on_dtls_handshake_done();
|
|
|
|
virtual srs_error_t on_dtls_application_data(const char* data, const int len);
|
|
|
|
virtual srs_error_t write_dtls_data(void* data, int size);
|
|
|
|
public:
|
|
|
|
virtual srs_error_t protect_rtp(const char* plaintext, char* cipher, int& nb_cipher);
|
|
|
|
virtual srs_error_t protect_rtcp(const char* plaintext, char* cipher, int& nb_cipher);
|
|
|
|
virtual srs_error_t protect_rtp2(void* rtp_hdr, int* len_ptr);
|
|
|
|
virtual srs_error_t unprotect_rtp(const char* cipher, char* plaintext, int& nb_plaintext);
|
|
|
|
virtual srs_error_t unprotect_rtcp(const char* cipher, char* plaintext, int& nb_plaintext);
|
|
|
|
};
|
|
|
|
|
2020-05-03 05:49:53 +00:00
|
|
|
// A group of RTP packets for outgoing(send to players).
|
2020-07-24 02:08:01 +00:00
|
|
|
class SrsRtcPlayStreamStatistic
|
2020-04-13 08:50:24 +00:00
|
|
|
{
|
2020-04-16 02:05:17 +00:00
|
|
|
public:
|
2020-04-17 08:36:56 +00:00
|
|
|
// The total bytes of AVFrame packets.
|
2020-04-13 08:50:24 +00:00
|
|
|
int nn_bytes;
|
2020-04-17 08:36:56 +00:00
|
|
|
// The total bytes of RTP packets.
|
|
|
|
int nn_rtp_bytes;
|
2020-04-16 02:05:17 +00:00
|
|
|
// The total padded bytes.
|
|
|
|
int nn_padding_bytes;
|
|
|
|
public:
|
2020-04-14 12:12:14 +00:00
|
|
|
// The RTP packets send out by sendmmsg or sendmsg. Note that if many packets group to
|
|
|
|
// one msghdr by GSO, it's only one RTP packet, because we only send once.
|
2020-04-13 08:50:24 +00:00
|
|
|
int nn_rtp_pkts;
|
2020-04-14 12:12:14 +00:00
|
|
|
// For video, the samples or NALUs.
|
2020-05-13 12:13:25 +00:00
|
|
|
// TODO: FIXME: Remove it because we may don't know.
|
2020-04-13 08:50:24 +00:00
|
|
|
int nn_samples;
|
2020-04-14 12:12:14 +00:00
|
|
|
// For audio, the generated extra audio packets.
|
|
|
|
// For example, when transcoding AAC to opus, may many extra payloads for a audio.
|
2020-05-13 12:13:25 +00:00
|
|
|
// TODO: FIXME: Remove it because we may don't know.
|
2020-04-13 09:11:46 +00:00
|
|
|
int nn_extras;
|
2020-04-14 12:12:14 +00:00
|
|
|
// The original audio messages.
|
2020-04-13 08:50:24 +00:00
|
|
|
int nn_audios;
|
2020-04-14 12:12:14 +00:00
|
|
|
// The original video messages.
|
2020-04-13 08:50:24 +00:00
|
|
|
int nn_videos;
|
2020-04-15 07:58:17 +00:00
|
|
|
// The number of padded packet.
|
|
|
|
int nn_paddings;
|
2020-04-13 08:50:24 +00:00
|
|
|
public:
|
2020-07-24 02:08:01 +00:00
|
|
|
SrsRtcPlayStreamStatistic();
|
|
|
|
virtual ~SrsRtcPlayStreamStatistic();
|
2020-04-13 08:50:24 +00:00
|
|
|
};
|
|
|
|
|
2020-07-07 09:20:15 +00:00
|
|
|
// A RTC play stream, client pull and play stream from SRS.
|
2020-07-27 10:33:49 +00:00
|
|
|
class SrsRtcPlayStream : virtual public ISrsCoroutineHandler, virtual public ISrsReloadHandler, virtual public ISrsHourGlass
|
2020-03-09 11:46:27 +00:00
|
|
|
{
|
2020-07-27 10:33:49 +00:00
|
|
|
private:
|
2020-07-05 15:26:55 +00:00
|
|
|
SrsContextId _parent_cid;
|
2020-05-04 06:47:58 +00:00
|
|
|
SrsCoroutine* trd;
|
2020-07-07 08:37:34 +00:00
|
|
|
SrsRtcConnection* session_;
|
2020-04-11 09:52:14 +00:00
|
|
|
private:
|
2020-08-06 05:51:12 +00:00
|
|
|
SrsRequest* req_;
|
|
|
|
SrsRtcStream* source_;
|
2020-07-27 10:33:49 +00:00
|
|
|
SrsHourGlass* timer_;
|
2020-07-15 05:11:35 +00:00
|
|
|
// key: publish_ssrc, value: send track to process rtp/rtcp
|
|
|
|
std::map<uint32_t, SrsRtcAudioSendTrack*> audio_tracks_;
|
|
|
|
std::map<uint32_t, SrsRtcVideoSendTrack*> video_tracks_;
|
2020-04-17 06:24:24 +00:00
|
|
|
private:
|
2020-05-04 06:47:58 +00:00
|
|
|
// For merged-write messages.
|
2020-04-18 02:04:45 +00:00
|
|
|
int mw_msgs;
|
|
|
|
bool realtime;
|
2020-05-04 12:42:30 +00:00
|
|
|
// Whether enabled nack.
|
|
|
|
bool nack_enabled_;
|
2020-07-21 03:38:41 +00:00
|
|
|
private:
|
2020-07-15 05:11:35 +00:00
|
|
|
// Whether palyer started.
|
|
|
|
bool is_started;
|
2020-07-24 02:08:01 +00:00
|
|
|
// The statistic for consumer to send packets to player.
|
|
|
|
SrsRtcPlayStreamStatistic info;
|
2020-03-09 11:46:27 +00:00
|
|
|
public:
|
2020-07-07 09:20:15 +00:00
|
|
|
SrsRtcPlayStream(SrsRtcConnection* s, SrsContextId parent_cid);
|
|
|
|
virtual ~SrsRtcPlayStream();
|
2020-03-30 07:16:29 +00:00
|
|
|
public:
|
2020-07-15 05:11:35 +00:00
|
|
|
srs_error_t initialize(SrsRequest* request, std::map<uint32_t, SrsRtcTrackDescription*> sub_relations);
|
2020-04-13 08:50:24 +00:00
|
|
|
// interface ISrsReloadHandler
|
|
|
|
public:
|
2020-04-18 02:04:45 +00:00
|
|
|
virtual srs_error_t on_reload_vhost_play(std::string vhost);
|
|
|
|
virtual srs_error_t on_reload_vhost_realtime(std::string vhost);
|
2020-03-09 11:46:27 +00:00
|
|
|
public:
|
2020-07-05 15:26:55 +00:00
|
|
|
virtual SrsContextId cid();
|
2020-03-09 11:46:27 +00:00
|
|
|
public:
|
|
|
|
virtual srs_error_t start();
|
|
|
|
virtual void stop();
|
2020-04-13 05:58:34 +00:00
|
|
|
public:
|
|
|
|
virtual srs_error_t cycle();
|
2020-03-12 16:24:56 +00:00
|
|
|
private:
|
2020-07-24 02:08:01 +00:00
|
|
|
srs_error_t send_packets(SrsRtcStream* source, const std::vector<SrsRtpPacket2*>& pkts, SrsRtcPlayStreamStatistic& info);
|
2020-05-04 06:47:58 +00:00
|
|
|
public:
|
|
|
|
void nack_fetch(std::vector<SrsRtpPacket2*>& pkts, uint32_t ssrc, uint16_t seq);
|
2020-08-03 04:49:12 +00:00
|
|
|
// Directly set the status of track, generally for init to set the default value.
|
2020-08-03 05:12:39 +00:00
|
|
|
void set_all_tracks_status(bool status);
|
2020-07-27 10:33:49 +00:00
|
|
|
// interface ISrsHourGlass
|
|
|
|
public:
|
|
|
|
virtual srs_error_t notify(int type, srs_utime_t interval, srs_utime_t tick);
|
2020-05-08 08:25:09 +00:00
|
|
|
public:
|
|
|
|
srs_error_t on_rtcp(char* data, int nb_data);
|
|
|
|
private:
|
|
|
|
srs_error_t on_rtcp_sr(char* buf, int nb_buf);
|
|
|
|
srs_error_t on_rtcp_xr(char* buf, int nb_buf);
|
|
|
|
srs_error_t on_rtcp_feedback(char* data, int nb_data);
|
|
|
|
srs_error_t on_rtcp_ps_feedback(char* data, int nb_data);
|
|
|
|
srs_error_t on_rtcp_rr(char* data, int nb_data);
|
2020-07-15 05:11:35 +00:00
|
|
|
uint32_t get_video_publish_ssrc(uint32_t play_ssrc);
|
2020-03-09 11:46:27 +00:00
|
|
|
};
|
2020-03-07 16:30:31 +00:00
|
|
|
|
2020-07-07 09:20:15 +00:00
|
|
|
// A RTC publish stream, client push and publish stream to SRS.
|
|
|
|
class SrsRtcPublishStream : virtual public ISrsHourGlass, virtual public ISrsRtpPacketDecodeHandler, virtual public ISrsRtcPublishStream
|
2020-04-23 09:08:21 +00:00
|
|
|
{
|
2020-04-23 15:14:30 +00:00
|
|
|
private:
|
2020-07-27 10:33:49 +00:00
|
|
|
SrsHourGlass* timer_;
|
2020-05-07 08:01:03 +00:00
|
|
|
uint64_t nn_audio_frames;
|
2020-04-23 09:08:21 +00:00
|
|
|
private:
|
2020-07-07 08:37:34 +00:00
|
|
|
SrsRtcConnection* session_;
|
2020-06-29 02:59:39 +00:00
|
|
|
uint16_t pt_to_drop_;
|
|
|
|
// Whether enabled nack.
|
|
|
|
bool nack_enabled_;
|
2020-04-23 09:08:21 +00:00
|
|
|
private:
|
2020-05-14 10:33:31 +00:00
|
|
|
bool request_keyframe_;
|
2020-04-23 09:08:21 +00:00
|
|
|
private:
|
2020-04-26 08:12:23 +00:00
|
|
|
SrsRequest* req;
|
2020-07-08 11:01:33 +00:00
|
|
|
SrsRtcStream* source;
|
2020-05-04 09:49:39 +00:00
|
|
|
// Simulators.
|
|
|
|
int nn_simulate_nack_drop;
|
2020-04-23 15:14:30 +00:00
|
|
|
private:
|
2020-07-15 05:11:35 +00:00
|
|
|
// track vector
|
|
|
|
std::vector<SrsRtcAudioRecvTrack*> audio_tracks_;
|
|
|
|
std::vector<SrsRtcVideoRecvTrack*> video_tracks_;
|
2020-05-19 10:14:48 +00:00
|
|
|
private:
|
2020-07-02 06:51:32 +00:00
|
|
|
int twcc_id_;
|
2020-05-19 10:14:48 +00:00
|
|
|
uint8_t twcc_fb_count_;
|
|
|
|
SrsRtcpTWCC rtcp_twcc_;
|
2020-06-26 07:24:37 +00:00
|
|
|
SrsRtpExtensionTypes extension_types_;
|
2020-07-15 05:11:35 +00:00
|
|
|
bool is_started;
|
2020-04-23 09:08:21 +00:00
|
|
|
public:
|
2020-07-07 09:20:15 +00:00
|
|
|
SrsRtcPublishStream(SrsRtcConnection* session);
|
|
|
|
virtual ~SrsRtcPublishStream();
|
2020-04-23 09:08:21 +00:00
|
|
|
public:
|
2020-07-15 05:11:35 +00:00
|
|
|
srs_error_t initialize(SrsRequest* req, SrsRtcStreamDescription* stream_desc);
|
|
|
|
srs_error_t start();
|
2020-08-04 05:45:17 +00:00
|
|
|
// Directly set the status of track, generally for init to set the default value.
|
|
|
|
void set_all_tracks_status(bool status);
|
2020-04-23 15:14:30 +00:00
|
|
|
private:
|
2020-07-15 05:11:35 +00:00
|
|
|
srs_error_t send_rtcp_rr();
|
|
|
|
srs_error_t send_rtcp_xr_rrtr();
|
2020-04-30 02:00:07 +00:00
|
|
|
public:
|
2020-04-30 06:49:37 +00:00
|
|
|
srs_error_t on_rtp(char* buf, int nb_buf);
|
2020-08-05 08:38:23 +00:00
|
|
|
private:
|
|
|
|
srs_error_t do_on_rtp(char* plaintext, int nb_plaintext);
|
|
|
|
public:
|
2020-05-14 06:26:19 +00:00
|
|
|
virtual void on_before_decode_payload(SrsRtpPacket2* pkt, SrsBuffer* buf, ISrsRtpPayloader** ppayload);
|
2020-04-23 09:08:21 +00:00
|
|
|
private:
|
2020-06-28 06:01:58 +00:00
|
|
|
srs_error_t send_periodic_twcc();
|
2020-05-14 02:47:21 +00:00
|
|
|
public:
|
|
|
|
srs_error_t on_rtcp(char* data, int nb_data);
|
|
|
|
private:
|
2020-05-08 08:25:09 +00:00
|
|
|
srs_error_t on_rtcp_sr(char* buf, int nb_buf);
|
|
|
|
srs_error_t on_rtcp_xr(char* buf, int nb_buf);
|
|
|
|
srs_error_t on_rtcp_feedback(char* data, int nb_data);
|
|
|
|
srs_error_t on_rtcp_ps_feedback(char* data, int nb_data);
|
|
|
|
srs_error_t on_rtcp_rr(char* data, int nb_data);
|
2020-04-23 15:14:30 +00:00
|
|
|
public:
|
2020-07-15 05:11:35 +00:00
|
|
|
void request_keyframe(uint32_t ssrc);
|
2020-04-23 15:14:30 +00:00
|
|
|
// interface ISrsHourGlass
|
|
|
|
public:
|
|
|
|
virtual srs_error_t notify(int type, srs_utime_t interval, srs_utime_t tick);
|
2020-05-04 06:47:58 +00:00
|
|
|
public:
|
|
|
|
void simulate_nack_drop(int nn);
|
2020-05-04 12:42:30 +00:00
|
|
|
private:
|
|
|
|
void simulate_drop_packet(SrsRtpHeader* h, int nn_bytes);
|
2020-05-19 10:14:48 +00:00
|
|
|
private:
|
|
|
|
srs_error_t on_twcc(uint16_t sn);
|
2020-07-15 05:11:35 +00:00
|
|
|
SrsRtcAudioRecvTrack* get_audio_track(uint32_t ssrc);
|
|
|
|
SrsRtcVideoRecvTrack* get_video_track(uint32_t ssrc);
|
|
|
|
void update_rtt(uint32_t ssrc, int rtt);
|
|
|
|
void update_send_report_time(uint32_t ssrc, const SrsNtp& ntp);
|
2020-04-23 09:08:21 +00:00
|
|
|
};
|
|
|
|
|
2020-07-23 07:14:54 +00:00
|
|
|
// The statistics for RTC connection.
|
2020-07-24 01:25:30 +00:00
|
|
|
class SrsRtcConnectionStatistic
|
2020-07-23 07:14:54 +00:00
|
|
|
{
|
|
|
|
public:
|
2020-07-24 01:25:30 +00:00
|
|
|
int nn_publishers; int nn_subscribers;
|
|
|
|
int nn_rr; int nn_xr; int nn_sr; int nn_nack; int nn_pli;
|
2020-07-23 07:14:54 +00:00
|
|
|
uint64_t nn_in_twcc; uint64_t nn_in_rtp; uint64_t nn_in_audios; uint64_t nn_in_videos;
|
|
|
|
uint64_t nn_out_twcc; uint64_t nn_out_rtp; uint64_t nn_out_audios; uint64_t nn_out_videos;
|
|
|
|
private:
|
|
|
|
srs_utime_t born;
|
|
|
|
srs_utime_t dead;
|
|
|
|
public:
|
2020-07-24 01:25:30 +00:00
|
|
|
SrsRtcConnectionStatistic();
|
|
|
|
virtual ~SrsRtcConnectionStatistic();
|
2020-07-23 07:14:54 +00:00
|
|
|
public:
|
|
|
|
std::string summary();
|
|
|
|
};
|
|
|
|
|
2020-07-07 08:37:34 +00:00
|
|
|
// A RTC Peer Connection, SDP level object.
|
2020-07-28 09:48:19 +00:00
|
|
|
class SrsRtcConnection : virtual public ISrsHourGlass
|
2020-03-06 15:01:48 +00:00
|
|
|
{
|
2020-06-25 04:03:21 +00:00
|
|
|
friend class SrsSecurityTransport;
|
2020-07-07 09:20:15 +00:00
|
|
|
friend class SrsRtcPlayStream;
|
|
|
|
friend class SrsRtcPublishStream;
|
2020-05-21 13:59:30 +00:00
|
|
|
public:
|
|
|
|
bool disposing_;
|
2020-07-24 01:25:30 +00:00
|
|
|
SrsRtcConnectionStatistic* stat_;
|
2020-02-28 15:18:39 +00:00
|
|
|
private:
|
2020-05-03 05:49:53 +00:00
|
|
|
SrsRtcServer* server_;
|
2020-07-07 08:37:34 +00:00
|
|
|
SrsRtcConnectionStateType state_;
|
2020-08-07 04:50:54 +00:00
|
|
|
ISrsRtcTransport* transport_;
|
2020-07-07 09:20:15 +00:00
|
|
|
SrsRtcPlayStream* player_;
|
|
|
|
SrsRtcPublishStream* publisher_;
|
2020-05-02 23:22:07 +00:00
|
|
|
bool is_publisher_;
|
2020-07-28 09:48:19 +00:00
|
|
|
SrsHourGlass* timer_;
|
2020-04-30 06:49:37 +00:00
|
|
|
private:
|
2020-07-25 01:33:18 +00:00
|
|
|
// The local:remote username, such as m5x0n128:jvOm where local name is m5x0n128.
|
2020-05-04 06:47:58 +00:00
|
|
|
std::string username_;
|
2020-07-25 01:33:18 +00:00
|
|
|
// The peer address, client maybe use more than one address, it's the current selected one.
|
|
|
|
SrsUdpMuxSocket* sendonly_skt;
|
|
|
|
// The address list, client may use multiple addresses.
|
|
|
|
std::map<std::string, SrsUdpMuxSocket*> peer_addresses_;
|
2020-04-30 06:49:37 +00:00
|
|
|
private:
|
|
|
|
// The timeout of session, keep alive by STUN ping pong.
|
2020-07-24 02:08:01 +00:00
|
|
|
srs_utime_t session_timeout;
|
2020-03-12 16:24:56 +00:00
|
|
|
srs_utime_t last_stun_time;
|
2020-03-17 04:33:08 +00:00
|
|
|
private:
|
|
|
|
// For each RTC session, we use a specified cid for debugging logs.
|
2020-07-05 15:26:55 +00:00
|
|
|
SrsContextId cid;
|
2020-08-07 07:45:18 +00:00
|
|
|
// TODO: FIXME: Rename to req_.
|
2020-04-30 06:49:37 +00:00
|
|
|
SrsRequest* req;
|
|
|
|
SrsSdp remote_sdp;
|
|
|
|
SrsSdp local_sdp;
|
2020-07-21 03:38:41 +00:00
|
|
|
private:
|
|
|
|
// twcc handler
|
|
|
|
int twcc_id_;
|
|
|
|
// Simulators.
|
|
|
|
int nn_simulate_player_nack_drop;
|
2020-07-27 04:28:15 +00:00
|
|
|
// Pithy print for address change, use port as error code.
|
|
|
|
SrsErrorPithyPrint* pp_address_change;
|
2020-03-09 11:46:27 +00:00
|
|
|
public:
|
2020-07-21 04:03:18 +00:00
|
|
|
SrsRtcConnection(SrsRtcServer* s, SrsContextId context_id);
|
2020-07-07 08:37:34 +00:00
|
|
|
virtual ~SrsRtcConnection();
|
2020-03-07 16:30:31 +00:00
|
|
|
public:
|
2020-07-15 05:11:35 +00:00
|
|
|
// TODO: FIXME: save only connection info.
|
2020-05-02 01:15:49 +00:00
|
|
|
SrsSdp* get_local_sdp();
|
2020-03-30 07:16:29 +00:00
|
|
|
void set_local_sdp(const SrsSdp& sdp);
|
2020-05-02 01:15:49 +00:00
|
|
|
SrsSdp* get_remote_sdp();
|
|
|
|
void set_remote_sdp(const SrsSdp& sdp);
|
2020-07-22 10:20:21 +00:00
|
|
|
// Connection level state machine, for ARQ of UDP packets.
|
2020-07-07 08:37:34 +00:00
|
|
|
SrsRtcConnectionStateType state();
|
|
|
|
void set_state(SrsRtcConnectionStateType state);
|
2020-07-25 01:33:18 +00:00
|
|
|
// Get username pair for this connection, used as ID of session.
|
2020-05-04 06:47:58 +00:00
|
|
|
std::string username();
|
2020-07-25 01:33:18 +00:00
|
|
|
// Get all addresses client used.
|
|
|
|
std::vector<SrsUdpMuxSocket*> peer_addresses();
|
2020-07-22 10:20:21 +00:00
|
|
|
public:
|
2020-03-17 04:33:08 +00:00
|
|
|
void switch_to_context();
|
2020-07-05 15:26:55 +00:00
|
|
|
SrsContextId context_id();
|
2020-07-22 10:20:21 +00:00
|
|
|
public:
|
2020-07-15 05:11:35 +00:00
|
|
|
srs_error_t add_publisher(SrsRequest* request, const SrsSdp& remote_sdp, SrsSdp& local_sdp);
|
|
|
|
srs_error_t add_player(SrsRequest* request, const SrsSdp& remote_sdp, SrsSdp& local_sdp);
|
2020-07-16 04:29:40 +00:00
|
|
|
// server send offer sdp to client, local sdp derivate from source stream desc.
|
|
|
|
srs_error_t add_player2(SrsRequest* request, SrsSdp& local_sdp);
|
2020-03-12 16:24:56 +00:00
|
|
|
public:
|
2020-06-27 03:13:53 +00:00
|
|
|
// Before initialize, user must set the local SDP, which is used to inititlize DTLS.
|
2020-08-07 07:45:18 +00:00
|
|
|
srs_error_t initialize(SrsRequest* r, bool is_publisher, bool dtls, bool srtp, std::string username);
|
2020-04-30 06:49:37 +00:00
|
|
|
// The peer address may change, we can identify that by STUN messages.
|
|
|
|
srs_error_t on_stun(SrsUdpMuxSocket* skt, SrsStunPacket* r);
|
|
|
|
srs_error_t on_dtls(char* data, int nb_data);
|
|
|
|
srs_error_t on_rtp(char* data, int nb_data);
|
2020-05-08 08:25:09 +00:00
|
|
|
srs_error_t on_rtcp(char* data, int nb_data);
|
2020-07-21 03:38:41 +00:00
|
|
|
srs_error_t on_rtcp_feedback(char* buf, int nb_buf);
|
2020-04-30 06:49:37 +00:00
|
|
|
public:
|
|
|
|
srs_error_t on_connection_established();
|
|
|
|
srs_error_t start_play();
|
|
|
|
srs_error_t start_publish();
|
2020-04-08 05:30:28 +00:00
|
|
|
bool is_stun_timeout();
|
2020-04-30 06:49:37 +00:00
|
|
|
void update_sendonly_socket(SrsUdpMuxSocket* skt);
|
2020-07-28 09:48:19 +00:00
|
|
|
// interface ISrsHourGlass
|
|
|
|
public:
|
|
|
|
virtual srs_error_t notify(int type, srs_utime_t interval, srs_utime_t tick);
|
2020-07-15 05:11:35 +00:00
|
|
|
public:
|
|
|
|
// send rtcp
|
2020-07-26 13:23:58 +00:00
|
|
|
void check_send_nacks(SrsRtpNackForReceiver* nack, uint32_t ssrc, uint32_t& sent_nacks);
|
2020-07-15 05:11:35 +00:00
|
|
|
srs_error_t send_rtcp_rr(uint32_t ssrc, SrsRtpRingBuffer* rtp_queue, const uint64_t& last_send_systime, const SrsNtp& last_send_ntp);
|
|
|
|
srs_error_t send_rtcp_xr_rrtr(uint32_t ssrc);
|
|
|
|
srs_error_t send_rtcp_fb_pli(uint32_t ssrc);
|
2020-05-04 06:47:58 +00:00
|
|
|
public:
|
|
|
|
// Simulate the NACK to drop nn packets.
|
|
|
|
void simulate_nack_drop(int nn);
|
2020-07-21 03:38:41 +00:00
|
|
|
void simulate_player_drop_packet(SrsRtpHeader* h, int nn_bytes);
|
2020-07-24 02:08:01 +00:00
|
|
|
srs_error_t do_send_packets(const std::vector<SrsRtpPacket2*>& pkts, SrsRtcPlayStreamStatistic& info);
|
2020-08-03 04:49:12 +00:00
|
|
|
// Directly set the status of play track, generally for init to set the default value.
|
2020-08-04 05:45:17 +00:00
|
|
|
void set_all_tracks_status(bool status);
|
2020-03-07 16:30:31 +00:00
|
|
|
private:
|
2020-04-30 06:49:37 +00:00
|
|
|
srs_error_t on_binding_request(SrsStunPacket* r);
|
2020-07-15 05:11:35 +00:00
|
|
|
// publish media capabilitiy negotiate
|
|
|
|
srs_error_t negotiate_publish_capability(SrsRequest* req, const SrsSdp& remote_sdp, SrsRtcStreamDescription* stream_desc);
|
|
|
|
srs_error_t generate_publish_local_sdp(SrsRequest* req, SrsSdp& local_sdp, SrsRtcStreamDescription* stream_desc);
|
|
|
|
// play media capabilitiy negotiate
|
2020-08-06 08:21:52 +00:00
|
|
|
//TODO: Use StreamDescription to negotiate and remove first negotiate_play_capability function
|
2020-07-15 05:11:35 +00:00
|
|
|
srs_error_t negotiate_play_capability(SrsRequest* req, const SrsSdp& remote_sdp, std::map<uint32_t, SrsRtcTrackDescription*>& sub_relations);
|
2020-08-06 08:21:52 +00:00
|
|
|
srs_error_t negotiate_play_capability(SrsRequest* req, SrsRtcStreamDescription* req_stream_desc, std::map<uint32_t, SrsRtcTrackDescription*>& sub_relations);
|
2020-07-16 04:29:40 +00:00
|
|
|
srs_error_t fetch_source_capability(SrsRequest* req, std::map<uint32_t, SrsRtcTrackDescription*>& sub_relations);
|
2020-07-15 05:11:35 +00:00
|
|
|
srs_error_t generate_play_local_sdp(SrsRequest* req, SrsSdp& local_sdp, SrsRtcStreamDescription* stream_desc);
|
|
|
|
srs_error_t create_player(SrsRequest* request, std::map<uint32_t, SrsRtcTrackDescription*> sub_relations);
|
|
|
|
srs_error_t create_publisher(SrsRequest* request, SrsRtcStreamDescription* stream_desc);
|
2020-03-12 16:24:56 +00:00
|
|
|
};
|
|
|
|
|
2020-05-22 10:14:15 +00:00
|
|
|
class ISrsRtcHijacker
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
ISrsRtcHijacker();
|
|
|
|
virtual ~ISrsRtcHijacker();
|
|
|
|
public:
|
|
|
|
// When start publisher by RTC.
|
2020-07-07 09:20:15 +00:00
|
|
|
virtual srs_error_t on_start_publish(SrsRtcConnection* session, SrsRtcPublishStream* publisher, SrsRequest* req) = 0;
|
2020-05-22 10:44:32 +00:00
|
|
|
// When got RTP plaintext packet.
|
2020-07-07 09:20:15 +00:00
|
|
|
virtual srs_error_t on_rtp_packet(SrsRtcConnection* session, SrsRtcPublishStream* publisher, SrsRequest* req, SrsRtpPacket2* pkt) = 0;
|
2020-05-24 13:40:23 +00:00
|
|
|
// When start player by RTC.
|
2020-07-07 09:20:15 +00:00
|
|
|
virtual srs_error_t on_start_play(SrsRtcConnection* session, SrsRtcPlayStream* player, SrsRequest* req) = 0;
|
2020-05-24 13:40:23 +00:00
|
|
|
// When start consuming for player for RTC.
|
2020-07-07 09:20:15 +00:00
|
|
|
virtual srs_error_t on_start_consume(SrsRtcConnection* session, SrsRtcPlayStream* player, SrsRequest* req, SrsRtcConsumer* consumer) = 0;
|
2020-05-22 10:14:15 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
extern ISrsRtcHijacker* _srs_rtc_hijacker;
|
|
|
|
|
2020-02-28 15:18:39 +00:00
|
|
|
#endif
|
|
|
|
|