From 9906d2e8594463fcc66746658249c7e13d8b3664 Mon Sep 17 00:00:00 2001 From: winlin Date: Sun, 3 May 2020 07:22:07 +0800 Subject: [PATCH 01/18] Refine RTC publish SDP, remove SSRC because it's recvonly. --- trunk/src/app/srs_app_http_api.cpp | 27 +++++++++++---------------- trunk/src/app/srs_app_rtc_conn.cpp | 18 ++++++++---------- trunk/src/app/srs_app_rtc_conn.hpp | 3 ++- 3 files changed, 21 insertions(+), 27 deletions(-) diff --git a/trunk/src/app/srs_app_http_api.cpp b/trunk/src/app/srs_app_http_api.cpp index f836b1bc8..d84930a81 100644 --- a/trunk/src/app/srs_app_http_api.cpp +++ b/trunk/src/app/srs_app_http_api.cpp @@ -26,6 +26,7 @@ #include #include #include +#include using namespace std; #include @@ -994,7 +995,7 @@ srs_error_t SrsGoApiRtcPlay::exchange_sdp(const std::string& app, const std::str local_sdp.addrtype_ = "IP4"; local_sdp.unicast_address_ = "0.0.0.0"; - local_sdp.session_name_ = "live_play_session"; + local_sdp.session_name_ = "SRSPlaySession"; local_sdp.msid_semantic_ = "WMS"; local_sdp.msids_.push_back(app + "/" + stream); @@ -1088,6 +1089,10 @@ srs_error_t SrsGoApiRtcPlay::exchange_sdp(const std::string& app, const std::str local_media_desc.rtcp_mux_ = true; local_media_desc.rtcp_rsize_ = true; + if (!ssrc_num) { + ssrc_num = ::getpid() * 10000 + ::getpid() * 100 + ::getpid(); + } + if (local_media_desc.sendonly_ || local_media_desc.sendrecv_) { SrsSSRCInfo ssrc_info; ssrc_info.ssrc_ = ++ssrc_num; @@ -1298,7 +1303,7 @@ srs_error_t SrsGoApiRtcPublish::exchange_sdp(const std::string& app, const std:: local_sdp.addrtype_ = "IP4"; local_sdp.unicast_address_ = "0.0.0.0"; - local_sdp.session_name_ = "live_publish_session"; + local_sdp.session_name_ = "SRSPublishSession"; local_sdp.msid_semantic_ = "WMS"; local_sdp.msids_.push_back(app + "/" + stream); @@ -1385,23 +1390,13 @@ srs_error_t SrsGoApiRtcPublish::exchange_sdp(const std::string& app, const std:: } local_sdp.media_descs_.back().session_info_.ice_options_ = "trickle"; - - if (remote_media_desc.sendonly_) { - local_media_desc.recvonly_ = true; - } else if (remote_media_desc.recvonly_) { - local_media_desc.sendonly_ = true; - } else if (remote_media_desc.sendrecv_) { - local_media_desc.sendrecv_ = true; - } local_media_desc.rtcp_mux_ = true; - if (local_media_desc.recvonly_ || local_media_desc.sendrecv_) { - SrsSSRCInfo ssrc_info; - ssrc_info.ssrc_ = ++ssrc_num; - ssrc_info.cname_ = "test_sdp_cname"; - local_media_desc.ssrc_infos_.push_back(ssrc_info); - } + // For publisher, we are always sendonly. + local_media_desc.sendonly_ = false; + local_media_desc.recvonly_ = true; + local_media_desc.sendrecv_ = false; } return err; diff --git a/trunk/src/app/srs_app_rtc_conn.cpp b/trunk/src/app/srs_app_rtc_conn.cpp index 5c58a2667..d2212cff9 100644 --- a/trunk/src/app/srs_app_rtc_conn.cpp +++ b/trunk/src/app/srs_app_rtc_conn.cpp @@ -749,6 +749,7 @@ srs_error_t SrsRtcSenderThread::cycle() ::getpid(), source->source_id(), rtc_session->encrypt, realtime, srsu2msi(mw_sleep), mw_msgs); // For RTC, notify the source to fetch keyframe for this client. + // TODO: FIXME: Should triggle by PLI from client. source->request_keyframe(); SrsMessageArray msgs(SRS_PERF_MW_MSGS); @@ -2240,7 +2241,7 @@ srs_error_t SrsRtcPublisher::notify(int type, srs_utime_t interval, srs_utime_t return err; } -SrsRtcSession::SrsRtcSession(SrsRtcServer* s, SrsRequest* r, const std::string& un, int context_id) +SrsRtcSession::SrsRtcSession(SrsRtcServer* s, SrsRequest* r, bool is_publisher, const std::string& un, int context_id) { username = un; req = r->copy(); @@ -2250,6 +2251,7 @@ SrsRtcSession::SrsRtcSession(SrsRtcServer* s, SrsRequest* r, const std::string& source = NULL; publisher = NULL; sender = NULL; + is_publisher_ = is_publisher; sendonly_skt = NULL; rtc_server = s; dtls_session = new SrsDtlsSession(this); @@ -2522,17 +2524,14 @@ srs_error_t SrsRtcSession::on_connection_established() { srs_error_t err = srs_success; - srs_trace("rtc session=%s, to=%dms connection established", id().c_str(), srsu2msi(sessionStunTimeout)); + srs_trace("RTC %s session=%s, to=%dms connection established", (is_publisher_? "Publisher":"Subscriber"), + id().c_str(), srsu2msi(sessionStunTimeout)); - if (!local_sdp.media_descs_.empty() && - (local_sdp.media_descs_.back().recvonly_ || local_sdp.media_descs_.back().sendrecv_)) { + if (is_publisher_) { if ((err = start_publish()) != srs_success) { return srs_error_wrap(err, "start publish"); } - } - - if (!local_sdp.media_descs_.empty() && - (local_sdp.media_descs_.back().sendonly_ || local_sdp.media_descs_.back().sendrecv_)) { + } else { if ((err = start_play()) != srs_success) { return srs_error_wrap(err, "start play"); } @@ -2580,7 +2579,6 @@ srs_error_t SrsRtcSession::start_publish() srs_freep(publisher); publisher = new SrsRtcPublisher(this); - publisher->request_keyframe(); uint32_t video_ssrc = 0; uint32_t audio_ssrc = 0; @@ -3361,7 +3359,7 @@ srs_error_t SrsRtcServer::create_rtc_session( } int cid = _srs_context->get_id(); - SrsRtcSession* session = new SrsRtcSession(this, req, username, cid); + SrsRtcSession* session = new SrsRtcSession(this, req, publish, username, cid); if ((err = session->initialize()) != srs_success) { srs_freep(session); return srs_error_wrap(err, "init"); diff --git a/trunk/src/app/srs_app_rtc_conn.hpp b/trunk/src/app/srs_app_rtc_conn.hpp index 7d1abae90..0623e56ea 100644 --- a/trunk/src/app/srs_app_rtc_conn.hpp +++ b/trunk/src/app/srs_app_rtc_conn.hpp @@ -311,6 +311,7 @@ private: SrsDtlsSession* dtls_session; SrsRtcSenderThread* sender; SrsRtcPublisher* publisher; + bool is_publisher_; private: SrsUdpMuxSocket* sendonly_skt; std::string username; @@ -336,7 +337,7 @@ private: sockaddr_in* blackhole_addr; srs_netfd_t blackhole_stfd; public: - SrsRtcSession(SrsRtcServer* s, SrsRequest* r, const std::string& un, int context_id); + SrsRtcSession(SrsRtcServer* s, SrsRequest* r, bool is_publisher, const std::string& un, int context_id); virtual ~SrsRtcSession(); public: SrsSdp* get_local_sdp(); From 20b4984af4afd20fba7e1c2ff5c036e103959796 Mon Sep 17 00:00:00 2001 From: winlin Date: Sun, 3 May 2020 07:43:05 +0800 Subject: [PATCH 02/18] Refine consumer dumps, extract dumps API --- trunk/src/app/srs_app_http_api.cpp | 1 + trunk/src/app/srs_app_http_stream.cpp | 17 +++++++++++------ trunk/src/app/srs_app_rtc_conn.cpp | 6 +++++- trunk/src/app/srs_app_rtmp_conn.cpp | 5 ++++- trunk/src/app/srs_app_source.cpp | 27 +++++++++++++++++---------- trunk/src/app/srs_app_source.hpp | 6 ++++-- 6 files changed, 42 insertions(+), 20 deletions(-) diff --git a/trunk/src/app/srs_app_http_api.cpp b/trunk/src/app/srs_app_http_api.cpp index d84930a81..6394f7037 100644 --- a/trunk/src/app/srs_app_http_api.cpp +++ b/trunk/src/app/srs_app_http_api.cpp @@ -1089,6 +1089,7 @@ srs_error_t SrsGoApiRtcPlay::exchange_sdp(const std::string& app, const std::str local_media_desc.rtcp_mux_ = true; local_media_desc.rtcp_rsize_ = true; + // TODO: FIXME: Avoid SSRC collision. if (!ssrc_num) { ssrc_num = ::getpid() * 10000 + ::getpid() * 100 + ::getpid(); } diff --git a/trunk/src/app/srs_app_http_stream.cpp b/trunk/src/app/srs_app_http_stream.cpp index 95a67c21a..4afe83f3e 100755 --- a/trunk/src/app/srs_app_http_stream.cpp +++ b/trunk/src/app/srs_app_http_stream.cpp @@ -128,10 +128,13 @@ srs_error_t SrsBufferCache::cycle() // the stream cache will create consumer to cache stream, // which will trigger to fetch stream from origin for edge. SrsConsumer* consumer = NULL; - if ((err = source->create_consumer(NULL, consumer, false, false, true)) != srs_success) { + SrsAutoFree(SrsConsumer, consumer); + if ((err = source->create_consumer(NULL, consumer)) != srs_success) { return srs_error_wrap(err, "create consumer"); } - SrsAutoFree(SrsConsumer, consumer); + if ((err = source->consumer_dumps(consumer, false, false, true)) != srs_success) { + return srs_error_wrap(err, "dumps consumer"); + } SrsPithyPrint* pprint = SrsPithyPrint::create_http_stream_cache(); SrsAutoFree(SrsPithyPrint, pprint); @@ -583,12 +586,14 @@ srs_error_t SrsLiveStream::do_serve_http(ISrsHttpResponseWriter* w, ISrsHttpMess // create consumer of souce, ignore gop cache, use the audio gop cache. SrsConsumer* consumer = NULL; - if ((err = source->create_consumer(NULL, consumer, true, true, !enc->has_cache())) != srs_success) { + SrsAutoFree(SrsConsumer, consumer); + if ((err = source->create_consumer(NULL, consumer)) != srs_success) { return srs_error_wrap(err, "create consumer"); } - SrsAutoFree(SrsConsumer, consumer); - srs_verbose("http: consumer created success."); - + if ((err = source->consumer_dumps(consumer, true, true, !enc->has_cache())) != srs_success) { + return srs_error_wrap(err, "dumps consumer"); + } + SrsPithyPrint* pprint = SrsPithyPrint::create_http_stream(); SrsAutoFree(SrsPithyPrint, pprint); diff --git a/trunk/src/app/srs_app_rtc_conn.cpp b/trunk/src/app/srs_app_rtc_conn.cpp index d2212cff9..efe93ff9f 100644 --- a/trunk/src/app/srs_app_rtc_conn.cpp +++ b/trunk/src/app/srs_app_rtc_conn.cpp @@ -721,7 +721,6 @@ srs_error_t SrsRtcSenderThread::cycle() SrsConsumer* consumer = NULL; SrsAutoFree(SrsConsumer, consumer); - // TODO: FIXME: Dumps the SPS/PPS from gop cache, without other frames. if ((err = source->create_consumer(NULL, consumer)) != srs_success) { return srs_error_wrap(err, "rtc create consumer, source url=%s", req->get_stream_url().c_str()); } @@ -733,6 +732,11 @@ srs_error_t SrsRtcSenderThread::cycle() // messages and drop them if the shared sender queue is full. consumer->enable_pass_timestamp(); + // TODO: FIXME: Dumps the SPS/PPS from gop cache, without other frames. + if ((err = source->consumer_dumps(consumer)) != srs_success) { + return srs_error_wrap(err, "dumps consumer, source url=%s", req->get_stream_url().c_str()); + } + realtime = _srs_config->get_realtime_enabled(req->vhost, true); mw_sleep = _srs_config->get_mw_sleep(req->vhost, true); mw_msgs = _srs_config->get_mw_msgs(req->vhost, realtime, true); diff --git a/trunk/src/app/srs_app_rtmp_conn.cpp b/trunk/src/app/srs_app_rtmp_conn.cpp index 0f8b1012a..4bcf0622e 100644 --- a/trunk/src/app/srs_app_rtmp_conn.cpp +++ b/trunk/src/app/srs_app_rtmp_conn.cpp @@ -654,10 +654,13 @@ srs_error_t SrsRtmpConn::playing(SrsSource* source) // Create a consumer of source. SrsConsumer* consumer = NULL; + SrsAutoFree(SrsConsumer, consumer); if ((err = source->create_consumer(this, consumer)) != srs_success) { return srs_error_wrap(err, "rtmp: create consumer"); } - SrsAutoFree(SrsConsumer, consumer); + if ((err = source->consumer_dumps(consumer)) != srs_success) { + return srs_error_wrap(err, "rtmp: dumps consumer"); + } // Use receiving thread to receive packets from peer. // @see: https://github.com/ossrs/srs/issues/217 diff --git a/trunk/src/app/srs_app_source.cpp b/trunk/src/app/srs_app_source.cpp index 651801600..9fe1e2cdc 100755 --- a/trunk/src/app/srs_app_source.cpp +++ b/trunk/src/app/srs_app_source.cpp @@ -2594,12 +2594,27 @@ void SrsSource::on_unpublish() } } -srs_error_t SrsSource::create_consumer(SrsConnection* conn, SrsConsumer*& consumer, bool ds, bool dm, bool dg) +srs_error_t SrsSource::create_consumer(SrsConnection* conn, SrsConsumer*& consumer) { srs_error_t err = srs_success; consumer = new SrsConsumer(this, conn); consumers.push_back(consumer); + + // for edge, when play edge stream, check the state + if (_srs_config->get_vhost_is_edge(req->vhost)) { + // notice edge to start for the first client. + if ((err = play_edge->on_client_play()) != srs_success) { + return srs_error_wrap(err, "play edge"); + } + } + + return err; +} + +srs_error_t SrsSource::consumer_dumps(SrsConsumer* consumer, bool ds, bool dm, bool dg) +{ + srs_error_t err = srs_success; srs_utime_t queue_size = _srs_config->get_queue_length(req->vhost); consumer->set_queue_size(queue_size); @@ -2636,15 +2651,7 @@ srs_error_t SrsSource::create_consumer(SrsConnection* conn, SrsConsumer*& consum } else { srs_trace("create consumer, active=%d, ignore gop cache, jitter=%d", hub->active(), jitter_algorithm); } - - // for edge, when play edge stream, check the state - if (_srs_config->get_vhost_is_edge(req->vhost)) { - // notice edge to start for the first client. - if ((err = play_edge->on_client_play()) != srs_success) { - return srs_error_wrap(err, "play edge"); - } - } - + return err; } diff --git a/trunk/src/app/srs_app_source.hpp b/trunk/src/app/srs_app_source.hpp index 7b6a96107..1d27fdbbb 100644 --- a/trunk/src/app/srs_app_source.hpp +++ b/trunk/src/app/srs_app_source.hpp @@ -599,12 +599,14 @@ public: virtual srs_error_t on_publish(); virtual void on_unpublish(); public: - // Create consumer and dumps packets in cache. + // Create consumer // @param consumer, output the create consumer. + virtual srs_error_t create_consumer(SrsConnection* conn, SrsConsumer*& consumer); + // Dumps packets in cache to consumer. // @param ds, whether dumps the sequence header. // @param dm, whether dumps the metadata. // @param dg, whether dumps the gop cache. - virtual srs_error_t create_consumer(SrsConnection* conn, SrsConsumer*& consumer, bool ds = true, bool dm = true, bool dg = true); + virtual srs_error_t consumer_dumps(SrsConsumer* consumer, bool ds = true, bool dm = true, bool dg = true); virtual void on_consumer_destroy(SrsConsumer* consumer); virtual void set_cache(bool enabled); virtual SrsRtmpJitterAlgorithm jitter(); From 1688d53f7d16dff4363348565a6296b683aa92ec Mon Sep 17 00:00:00 2001 From: winlin Date: Sun, 3 May 2020 07:51:01 +0800 Subject: [PATCH 03/18] Refine source, pass-by RTC publisher for player --- trunk/src/app/srs_app_rtc_conn.cpp | 5 ++++- trunk/src/app/srs_app_source.cpp | 10 ++++------ trunk/src/app/srs_app_source.hpp | 10 ++++------ 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/trunk/src/app/srs_app_rtc_conn.cpp b/trunk/src/app/srs_app_rtc_conn.cpp index efe93ff9f..d7d39a773 100644 --- a/trunk/src/app/srs_app_rtc_conn.cpp +++ b/trunk/src/app/srs_app_rtc_conn.cpp @@ -754,7 +754,10 @@ srs_error_t SrsRtcSenderThread::cycle() // For RTC, notify the source to fetch keyframe for this client. // TODO: FIXME: Should triggle by PLI from client. - source->request_keyframe(); + SrsRtcPublisher* publisher = source->rtc_publisher(); + if (publisher) { + publisher->request_keyframe(); + } SrsMessageArray msgs(SRS_PERF_MW_MSGS); SrsRtcPackets pkts(SRS_PERF_RTC_RTP_PACKETS); diff --git a/trunk/src/app/srs_app_source.cpp b/trunk/src/app/srs_app_source.cpp index 9fe1e2cdc..b23100f2f 100755 --- a/trunk/src/app/srs_app_source.cpp +++ b/trunk/src/app/srs_app_source.cpp @@ -1921,7 +1921,7 @@ SrsSource::SrsSource() atc = false; #ifdef SRS_RTC - rtc_publisher = NULL; + rtc_publisher_ = NULL; #endif } @@ -2706,16 +2706,14 @@ SrsMetaCache* SrsSource::cached_meta() return meta; } -void SrsSource::request_keyframe() +SrsRtcPublisher* SrsSource::rtc_publisher() { - if (rtc_publisher) { - rtc_publisher->request_keyframe(); - } + return rtc_publisher_; } void SrsSource::set_rtc_publisher(SrsRtcPublisher* v) { - rtc_publisher = v; + rtc_publisher_ = v; } srs_error_t SrsSource::on_rtc_audio(SrsSharedPtrMessage* audio) diff --git a/trunk/src/app/srs_app_source.hpp b/trunk/src/app/srs_app_source.hpp index 1d27fdbbb..5aba081d1 100644 --- a/trunk/src/app/srs_app_source.hpp +++ b/trunk/src/app/srs_app_source.hpp @@ -551,7 +551,7 @@ private: srs_utime_t die_at; #ifdef SRS_RTC private: - SrsRtcPublisher* rtc_publisher; + SrsRtcPublisher* rtc_publisher_; #endif public: SrsSource(); @@ -621,12 +621,10 @@ public: virtual std::string get_curr_origin(); #ifdef SRS_RTC public: - // Get the cached meta, as such the sps/pps. + // For RTC, we need to package SPS/PPS(in cached meta) before each IDR. SrsMetaCache* cached_meta(); - // Request keyframe for new client. - // TODO: FIXME: Maybe we could cache the keyframe. - // TODO: FIXME: Maybe we should only response for the new clients. - void request_keyframe(); + // Get and set the publisher, passed to consumer to process requests such as PLI. + SrsRtcPublisher* rtc_publisher(); void set_rtc_publisher(SrsRtcPublisher* v); // When got RTC audio message, which is encoded in opus. // TODO: FIXME: Merge with on_audio. From 5fb7c4efbc56392cfdc70a98c2472387ff1e8f09 Mon Sep 17 00:00:00 2001 From: winlin Date: Sun, 3 May 2020 09:00:05 +0800 Subject: [PATCH 04/18] RTC supports pass-by players PLI to publisher --- trunk/src/app/srs_app_http_api.cpp | 2 +- trunk/src/app/srs_app_rtc_conn.cpp | 27 ++++++++++++++++----------- trunk/src/app/srs_app_rtc_conn.hpp | 4 ++-- trunk/src/app/srs_app_sdp.cpp | 2 +- 4 files changed, 20 insertions(+), 15 deletions(-) diff --git a/trunk/src/app/srs_app_http_api.cpp b/trunk/src/app/srs_app_http_api.cpp index 6394f7037..50ca4a328 100644 --- a/trunk/src/app/srs_app_http_api.cpp +++ b/trunk/src/app/srs_app_http_api.cpp @@ -1246,7 +1246,7 @@ srs_error_t SrsGoApiRtcPublish::do_serve_http(ISrsHttpResponseWriter* w, ISrsHtt string local_sdp_str = os.str(); - srs_trace("local_sdp=%s", local_sdp_str.c_str()); + srs_verbose("local_sdp=%s", local_sdp_str.c_str()); res->set("code", SrsJsonAny::integer(ERROR_SUCCESS)); res->set("server", SrsJsonAny::integer(SrsStatistic::instance()->server_id())); diff --git a/trunk/src/app/srs_app_rtc_conn.cpp b/trunk/src/app/srs_app_rtc_conn.cpp index d7d39a773..66438e847 100644 --- a/trunk/src/app/srs_app_rtc_conn.cpp +++ b/trunk/src/app/srs_app_rtc_conn.cpp @@ -752,13 +752,6 @@ srs_error_t SrsRtcSenderThread::cycle() srs_trace("RTC source url=%s, source_id=[%d][%d], encrypt=%d, realtime=%d, mw_sleep=%dms, mw_msgs=%d", req->get_stream_url().c_str(), ::getpid(), source->source_id(), rtc_session->encrypt, realtime, srsu2msi(mw_sleep), mw_msgs); - // For RTC, notify the source to fetch keyframe for this client. - // TODO: FIXME: Should triggle by PLI from client. - SrsRtcPublisher* publisher = source->rtc_publisher(); - if (publisher) { - publisher->request_keyframe(); - } - SrsMessageArray msgs(SRS_PERF_MW_MSGS); SrsRtcPackets pkts(SRS_PERF_RTC_RTP_PACKETS); @@ -1864,6 +1857,12 @@ srs_error_t SrsRtcPublisher::send_rtcp_fb_pli(uint32_t ssrc) srs_trace("RTC PLI ssrc=%u", ssrc); + if (rtc_session->blackhole && rtc_session->blackhole_addr && rtc_session->blackhole_stfd) { + // Ignore any error for black-hole. + void* p = stream.data(); int len = stream.pos(); SrsRtcSession* s = rtc_session; + srs_sendto(s->blackhole_stfd, p, len, (sockaddr*)s->blackhole_addr, sizeof(sockaddr_in), SRS_UTIME_NO_TIMEOUT); + } + char protected_buf[kRtpPacketSize]; int nb_protected_buf = stream.pos(); if ((err = rtc_session->dtls_session->protect_rtcp(protected_buf, stream.data(), nb_protected_buf)) != srs_success) { @@ -2248,14 +2247,14 @@ srs_error_t SrsRtcPublisher::notify(int type, srs_utime_t interval, srs_utime_t return err; } -SrsRtcSession::SrsRtcSession(SrsRtcServer* s, SrsRequest* r, bool is_publisher, const std::string& un, int context_id) +SrsRtcSession::SrsRtcSession(SrsRtcServer* s, SrsSource* source, SrsRequest* r, bool is_publisher, const std::string& un, int context_id) { username = un; req = r->copy(); cid = context_id; encrypt = true; - source = NULL; + source_ = source; publisher = NULL; sender = NULL; is_publisher_ = is_publisher; @@ -2586,6 +2585,8 @@ srs_error_t SrsRtcSession::start_publish() srs_freep(publisher); publisher = new SrsRtcPublisher(this); + // Request PLI for exists players? + //publisher->request_keyframe(); uint32_t video_ssrc = 0; uint32_t audio_ssrc = 0; @@ -2793,7 +2794,11 @@ srs_error_t SrsRtcSession::on_rtcp_ps_feedback(char* buf, int nb_buf) switch (fmt) { case kPLI: { - srs_verbose("pli"); + SrsRtcPublisher* publisher = source_->rtc_publisher(); + if (publisher) { + publisher->request_keyframe(); + } + srs_trace("RTC request PLI"); break; } case kSLI: { @@ -3366,7 +3371,7 @@ srs_error_t SrsRtcServer::create_rtc_session( } int cid = _srs_context->get_id(); - SrsRtcSession* session = new SrsRtcSession(this, req, publish, username, cid); + SrsRtcSession* session = new SrsRtcSession(this, source, req, publish, username, cid); if ((err = session->initialize()) != srs_success) { srs_freep(session); return srs_error_wrap(err, "init"); diff --git a/trunk/src/app/srs_app_rtc_conn.hpp b/trunk/src/app/srs_app_rtc_conn.hpp index 0623e56ea..155536131 100644 --- a/trunk/src/app/srs_app_rtc_conn.hpp +++ b/trunk/src/app/srs_app_rtc_conn.hpp @@ -329,7 +329,7 @@ private: // TODO: FIXME: Support reload. bool encrypt; SrsRequest* req; - SrsSource* source; + SrsSource* source_; SrsSdp remote_sdp; SrsSdp local_sdp; private: @@ -337,7 +337,7 @@ private: sockaddr_in* blackhole_addr; srs_netfd_t blackhole_stfd; public: - SrsRtcSession(SrsRtcServer* s, SrsRequest* r, bool is_publisher, const std::string& un, int context_id); + SrsRtcSession(SrsRtcServer* s, SrsSource* source, SrsRequest* r, bool is_publisher, const std::string& un, int context_id); virtual ~SrsRtcSession(); public: SrsSdp* get_local_sdp(); diff --git a/trunk/src/app/srs_app_sdp.cpp b/trunk/src/app/srs_app_sdp.cpp index 4cce5295a..9fc227be6 100644 --- a/trunk/src/app/srs_app_sdp.cpp +++ b/trunk/src/app/srs_app_sdp.cpp @@ -373,7 +373,7 @@ srs_error_t SrsMediaDesc::encode(std::ostringstream& os) << " typ " << iter->type_ << " generation 0" << kCRLF; - srs_trace("local SDP candidate line=%s", os.str().c_str()); + srs_verbose("local SDP candidate line=%s", os.str().c_str()); } return err; From 157bc713a9a68132c9115ac6b09b183a1adcafb7 Mon Sep 17 00:00:00 2001 From: winlin Date: Sun, 3 May 2020 09:55:43 +0800 Subject: [PATCH 05/18] Refactor RTC session API --- trunk/src/app/srs_app_rtc_conn.cpp | 26 +++++++++++++++----------- trunk/src/app/srs_app_rtc_conn.hpp | 4 ++-- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/trunk/src/app/srs_app_rtc_conn.cpp b/trunk/src/app/srs_app_rtc_conn.cpp index 66438e847..981a034b0 100644 --- a/trunk/src/app/srs_app_rtc_conn.cpp +++ b/trunk/src/app/srs_app_rtc_conn.cpp @@ -2247,17 +2247,16 @@ srs_error_t SrsRtcPublisher::notify(int type, srs_utime_t interval, srs_utime_t return err; } -SrsRtcSession::SrsRtcSession(SrsRtcServer* s, SrsSource* source, SrsRequest* r, bool is_publisher, const std::string& un, int context_id) +SrsRtcSession::SrsRtcSession(SrsRtcServer* s) { - username = un; - req = r->copy(); - cid = context_id; + req = NULL; + cid = 0; + is_publisher_ = false; encrypt = true; - source_ = source; + source_ = NULL; publisher = NULL; sender = NULL; - is_publisher_ = is_publisher; sendonly_skt = NULL; rtc_server = s; dtls_session = new SrsDtlsSession(this); @@ -2343,10 +2342,16 @@ int SrsRtcSession::context_id() return cid; } -srs_error_t SrsRtcSession::initialize() +srs_error_t SrsRtcSession::initialize(SrsSource* source, SrsRequest* r, bool is_publisher, const std::string& un, int context_id) { srs_error_t err = srs_success; + username = un; + req = r->copy(); + cid = context_id; + is_publisher_ = is_publisher; + source_ = source; + if ((err = dtls_session->initialize(req)) != srs_success) { return srs_error_wrap(err, "init"); } @@ -2786,7 +2791,6 @@ srs_error_t SrsRtcSession::on_rtcp_ps_feedback(char* buf, int nb_buf) //uint8_t padding = first & 0x20; uint8_t fmt = first & 0x1F; - // TODO: FIXME: Dead code? /*uint8_t payload_type = */stream->read_1bytes(); /*uint16_t length = */stream->read_2bytes(); /*uint32_t ssrc_of_sender = */stream->read_4bytes(); @@ -2797,8 +2801,8 @@ srs_error_t SrsRtcSession::on_rtcp_ps_feedback(char* buf, int nb_buf) SrsRtcPublisher* publisher = source_->rtc_publisher(); if (publisher) { publisher->request_keyframe(); + srs_trace("RTC request PLI"); } - srs_trace("RTC request PLI"); break; } case kSLI: { @@ -3371,8 +3375,8 @@ srs_error_t SrsRtcServer::create_rtc_session( } int cid = _srs_context->get_id(); - SrsRtcSession* session = new SrsRtcSession(this, source, req, publish, username, cid); - if ((err = session->initialize()) != srs_success) { + SrsRtcSession* session = new SrsRtcSession(this); + if ((err = session->initialize(source, req, publish, username, cid)) != srs_success) { srs_freep(session); return srs_error_wrap(err, "init"); } diff --git a/trunk/src/app/srs_app_rtc_conn.hpp b/trunk/src/app/srs_app_rtc_conn.hpp index 155536131..290d405c8 100644 --- a/trunk/src/app/srs_app_rtc_conn.hpp +++ b/trunk/src/app/srs_app_rtc_conn.hpp @@ -337,7 +337,7 @@ private: sockaddr_in* blackhole_addr; srs_netfd_t blackhole_stfd; public: - SrsRtcSession(SrsRtcServer* s, SrsSource* source, SrsRequest* r, bool is_publisher, const std::string& un, int context_id); + SrsRtcSession(SrsRtcServer* s); virtual ~SrsRtcSession(); public: SrsSdp* get_local_sdp(); @@ -353,7 +353,7 @@ public: void switch_to_context(); int context_id(); public: - srs_error_t initialize(); + srs_error_t initialize(SrsSource* source, SrsRequest* r, bool is_publisher, const std::string& un, int context_id); // 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); From 32c4febafe648ea1667f3411e49fbb567bf37dc8 Mon Sep 17 00:00:00 2001 From: winlin Date: Sun, 3 May 2020 10:15:54 +0800 Subject: [PATCH 06/18] Refactor RTC publish packet flags. --- trunk/src/app/srs_app_rtc_conn.cpp | 18 +++--- trunk/src/app/srs_app_rtc_conn.hpp | 8 +-- trunk/src/app/srs_app_rtp_queue.cpp | 85 ++++++++++++++++------------- trunk/src/app/srs_app_rtp_queue.hpp | 19 ++++--- trunk/src/kernel/srs_kernel_rtp.cpp | 6 +- trunk/src/kernel/srs_kernel_rtp.hpp | 8 +-- 6 files changed, 77 insertions(+), 67 deletions(-) diff --git a/trunk/src/app/srs_app_rtc_conn.cpp b/trunk/src/app/srs_app_rtc_conn.cpp index 981a034b0..34dad0f46 100644 --- a/trunk/src/app/srs_app_rtc_conn.cpp +++ b/trunk/src/app/srs_app_rtc_conn.cpp @@ -1924,10 +1924,6 @@ void SrsRtcPublisher::on_before_decode_payload(SrsRtpPacket2* pkt, SrsBuffer* bu srs_error_t SrsRtcPublisher::on_audio(SrsRtpPacket2* pkt) { - pkt->is_first_packet_of_frame = true; - pkt->is_last_packet_of_frame = true; - pkt->is_key_frame = true; - // TODO: FIXME: Error check. audio_queue_->consume(audio_nack_, pkt); @@ -2005,17 +2001,17 @@ srs_error_t SrsRtcPublisher::on_video(SrsRtpPacket2* pkt) return srs_error_new(ERROR_RTC_RTP_MUXER, "FU-A payload"); } - pkt->is_first_packet_of_frame = payload->start; - pkt->is_last_packet_of_frame = payload->end; - pkt->is_key_frame = (payload->nalu_type == SrsAvcNaluTypeIDR); + pkt->video_is_first_packet = payload->start; + pkt->video_is_last_packet = payload->end; + pkt->video_is_idr = (payload->nalu_type == SrsAvcNaluTypeIDR); } else { - pkt->is_first_packet_of_frame = true; - pkt->is_last_packet_of_frame = true; + pkt->video_is_first_packet = true; + pkt->video_is_last_packet = true; if (v == kStapA) { - pkt->is_key_frame = true; + pkt->video_is_idr = true; } else { - pkt->is_key_frame = (pkt->nalu_type == SrsAvcNaluTypeIDR); + pkt->video_is_idr = (pkt->nalu_type == SrsAvcNaluTypeIDR); } } diff --git a/trunk/src/app/srs_app_rtc_conn.hpp b/trunk/src/app/srs_app_rtc_conn.hpp index 290d405c8..3f4018644 100644 --- a/trunk/src/app/srs_app_rtc_conn.hpp +++ b/trunk/src/app/srs_app_rtc_conn.hpp @@ -53,8 +53,8 @@ class SrsSource; class SrsRtpPacket2; class ISrsUdpSender; class SrsRtpQueue; -class SrsRtpH264Demuxer; -class SrsRtpOpusDemuxer; +class SrsRtpAudioQueue; +class SrsRtpVideoQueue; class SrsRtpPacket2; class ISrsCodec; class SrsRtpNackForReceiver; @@ -261,9 +261,9 @@ private: uint32_t video_ssrc; uint32_t audio_ssrc; private: - SrsRtpQueue* video_queue_; + SrsRtpVideoQueue* video_queue_; SrsRtpNackForReceiver* video_nack_; - SrsRtpQueue* audio_queue_; + SrsRtpAudioQueue* audio_queue_; SrsRtpNackForReceiver* audio_nack_; private: SrsRequest* req; diff --git a/trunk/src/app/srs_app_rtp_queue.cpp b/trunk/src/app/srs_app_rtp_queue.cpp index 5adef6e95..b685cebce 100644 --- a/trunk/src/app/srs_app_rtp_queue.cpp +++ b/trunk/src/app/srs_app_rtp_queue.cpp @@ -200,7 +200,7 @@ uint16_t SrsRtpRingBuffer::next_start_of_frame() for (uint16_t s = low_ + 1 ; s != high_; ++s) { SrsRtpPacket2*& pkt = queue_[s % capacity_]; - if (pkt && pkt->is_first_packet_of_frame) { + if (pkt && pkt->video_is_first_packet) { return s; } } @@ -216,7 +216,7 @@ uint16_t SrsRtpRingBuffer::next_keyframe() for (uint16_t s = low_ + 1 ; s != high_; ++s) { SrsRtpPacket2*& pkt = queue_[s % capacity_]; - if (pkt && pkt->is_key_frame && pkt->is_first_packet_of_frame) { + if (pkt && pkt->video_is_idr && pkt->video_is_first_packet) { return s; } } @@ -283,7 +283,6 @@ SrsRtpQueue::SrsRtpQueue(const char* tag, int capacity) num_of_packet_received_ = 0; number_of_packet_lossed_ = 0; - request_key_frame_ = false; tag_ = tag; } @@ -337,23 +336,7 @@ srs_error_t SrsRtpQueue::consume(SrsRtpNackForReceiver* nack, SrsRtpPacket2* pkt // When packets overflow, collect frame and move head to next frame start. if (queue_->overflow()) { - collect_packet(nack); - - uint16_t next = queue_->next_start_of_frame(); - - // Note that low_ mean not found, clear queue util one packet. - if (next == queue_->low()) { - next = queue_->high() - 1; - } - srs_trace("%s seq out of range [%u, %u]", tag_, queue_->low(), next); - - for (uint16_t s = queue_->low(); s != next; ++s) { - nack->remove(s); - queue_->remove(s); - } - - srs_trace("%s force update seq %u to %u", tag_, queue_->low(), next + 1); - queue_->advance_to(next + 1); + on_overflow(nack); } // Save packet at the position seq. @@ -367,16 +350,6 @@ void SrsRtpQueue::collect_frames(std::vector >& fram frames.swap(frames_); } -bool SrsRtpQueue::should_request_key_frame() -{ - if (request_key_frame_) { - request_key_frame_ = false; - return true; - } - - return request_key_frame_; -} - void SrsRtpQueue::notify_drop_seq(uint16_t seq) { uint16_t next = queue_->next_start_of_frame(); @@ -405,11 +378,6 @@ void SrsRtpQueue::notify_nack_list_full() queue_->advance_to(next + 1); } -void SrsRtpQueue::request_keyframe() -{ - request_key_frame_ = true; -} - uint32_t SrsRtpQueue::get_extended_highest_sequence() { return queue_->get_extended_highest_sequence(); @@ -471,6 +439,12 @@ srs_error_t SrsRtpAudioQueue::consume(SrsRtpNackForReceiver* nack, SrsRtpPacket2 return err; } +void SrsRtpAudioQueue::on_overflow(SrsRtpNackForReceiver* nack) +{ + collect_packet(nack); + queue_->advance_to(queue_->high()); +} + void SrsRtpAudioQueue::collect_packet(SrsRtpNackForReceiver* nack) { // When done, s point to the next available packet. @@ -505,6 +479,7 @@ void SrsRtpAudioQueue::collect_packet(SrsRtpNackForReceiver* nack) SrsRtpVideoQueue::SrsRtpVideoQueue(int capacity) : SrsRtpQueue("video", capacity) { + request_key_frame_ = false; } SrsRtpVideoQueue::~SrsRtpVideoQueue() @@ -530,6 +505,42 @@ srs_error_t SrsRtpVideoQueue::consume(SrsRtpNackForReceiver* nack, SrsRtpPacket2 return err; } +bool SrsRtpVideoQueue::should_request_key_frame() +{ + if (request_key_frame_) { + request_key_frame_ = false; + return true; + } + + return request_key_frame_; +} + +void SrsRtpVideoQueue::request_keyframe() +{ + request_key_frame_ = true; +} + +void SrsRtpVideoQueue::on_overflow(SrsRtpNackForReceiver* nack) +{ + collect_packet(nack); + + uint16_t next = queue_->next_start_of_frame(); + + // Note that low_ mean not found, clear queue util one packet. + if (next == queue_->low()) { + next = queue_->high() - 1; + } + srs_trace("%s seq out of range [%u, %u]", tag_, queue_->low(), next); + + for (uint16_t s = queue_->low(); s != next; ++s) { + nack->remove(s); + queue_->remove(s); + } + + srs_trace("%s force update seq %u to %u", tag_, queue_->low(), next + 1); + queue_->advance_to(next + 1); +} + void SrsRtpVideoQueue::collect_packet(SrsRtpNackForReceiver* nack) { while (queue_->low() != queue_->high()) { @@ -563,7 +574,7 @@ void SrsRtpVideoQueue::do_collect_packet(SrsRtpNackForReceiver* nack, vectorlow() && !pkt->is_first_packet_of_frame) { + if (next == queue_->low() && !pkt->video_is_first_packet) { break; } @@ -572,7 +583,7 @@ void SrsRtpVideoQueue::do_collect_packet(SrsRtpNackForReceiver* nack, vectorrtp_header.get_marker() || pkt->is_last_packet_of_frame) { + if (pkt->rtp_header.get_marker() || pkt->video_is_last_packet) { found = true; next++; break; diff --git a/trunk/src/app/srs_app_rtp_queue.hpp b/trunk/src/app/srs_app_rtp_queue.hpp index cb14a3d19..07472d6de 100644 --- a/trunk/src/app/srs_app_rtp_queue.hpp +++ b/trunk/src/app/srs_app_rtp_queue.hpp @@ -144,11 +144,11 @@ public: // Whether queue overflow or heavy(too many packets and need clear). bool overflow(); bool is_heavy(); - // Get the next start packet of frame. + // For video, get the next start packet of frame. // @remark If not found, return the low_, which should never be the "next" one, // because it MAY or NOT current start packet of frame but never be the next. uint16_t next_start_of_frame(); - // Get the next seq of keyframe. + // For video, get the next seq of keyframe. // @remark Return low_ if not found. uint16_t next_keyframe(); // The highest sequence number, calculate the flip back base. @@ -174,8 +174,6 @@ protected: uint64_t nn_collected_frames; std::vector > frames_; const char* tag_; -private: - bool request_key_frame_; public: SrsRtpQueue(const char* tag, int capacity); virtual ~SrsRtpQueue(); @@ -183,10 +181,8 @@ public: virtual srs_error_t consume(SrsRtpNackForReceiver* nack, SrsRtpPacket2* pkt); // TODO: FIXME: Should merge FU-A to RAW, then we can return RAW payloads. void collect_frames(std::vector >& frames); - bool should_request_key_frame(); void notify_drop_seq(uint16_t seq); void notify_nack_list_full(); - void request_keyframe(); public: uint32_t get_extended_highest_sequence(); uint8_t get_fraction_lost(); @@ -195,7 +191,7 @@ public: private: void insert_into_nack_list(SrsRtpNackForReceiver* nack, uint16_t seq_start, uint16_t seq_end); protected: - virtual void collect_packet(SrsRtpNackForReceiver* nack) = 0; + virtual void on_overflow(SrsRtpNackForReceiver* nack) = 0; }; class SrsRtpAudioQueue : public SrsRtpQueue @@ -205,20 +201,27 @@ public: virtual ~SrsRtpAudioQueue(); public: virtual srs_error_t consume(SrsRtpNackForReceiver* nack, SrsRtpPacket2* pkt); +private: + virtual void on_overflow(SrsRtpNackForReceiver* nack); protected: virtual void collect_packet(SrsRtpNackForReceiver* nack); }; class SrsRtpVideoQueue : public SrsRtpQueue { +private: + bool request_key_frame_; public: SrsRtpVideoQueue(int capacity); virtual ~SrsRtpVideoQueue(); public: virtual srs_error_t consume(SrsRtpNackForReceiver* nack, SrsRtpPacket2* pkt); + bool should_request_key_frame(); + void request_keyframe(); protected: - virtual void collect_packet(SrsRtpNackForReceiver* nack); + virtual void on_overflow(SrsRtpNackForReceiver* nack); private: + virtual void collect_packet(SrsRtpNackForReceiver* nack); virtual void do_collect_packet(SrsRtpNackForReceiver* nack, std::vector& frame); }; diff --git a/trunk/src/kernel/srs_kernel_rtp.cpp b/trunk/src/kernel/srs_kernel_rtp.cpp index c21c9157b..a27b2cdd4 100644 --- a/trunk/src/kernel/srs_kernel_rtp.cpp +++ b/trunk/src/kernel/srs_kernel_rtp.cpp @@ -277,9 +277,9 @@ SrsRtpPacket2::SrsRtpPacket2() payload = NULL; decode_handler = NULL; - is_first_packet_of_frame = false; - is_last_packet_of_frame = false; - is_key_frame = false; + video_is_first_packet = false; + video_is_last_packet = false; + video_is_idr = false; nalu_type = SrsAvcNaluTypeReserved; cache_raw = new SrsRtpRawPayload(); diff --git a/trunk/src/kernel/srs_kernel_rtp.hpp b/trunk/src/kernel/srs_kernel_rtp.hpp index fd38a4d12..baaeb0281 100644 --- a/trunk/src/kernel/srs_kernel_rtp.hpp +++ b/trunk/src/kernel/srs_kernel_rtp.hpp @@ -114,10 +114,10 @@ public: int padding; // Decoder helper. public: - // Helper information for decoder. - bool is_first_packet_of_frame; - bool is_last_packet_of_frame; - bool is_key_frame; + // Helper information for video decoder only. + bool video_is_first_packet; + bool video_is_last_packet; + bool video_is_idr; // The first byte as nalu type, for video decoder only. SrsAvcNaluType nalu_type; // The original payload bytes length. From 2a0562da5e3202448e90a4d51f21bddd9a908e1d Mon Sep 17 00:00:00 2001 From: winlin Date: Sun, 3 May 2020 11:14:11 +0800 Subject: [PATCH 07/18] Refine RTC, disable NASM, SENDMMSG, SRTP-NASM --- trunk/3rdparty/st-srs/io.c | 10 +++++--- trunk/3rdparty/st-srs/public.h | 4 +-- trunk/auto/auto_headers.sh | 5 ---- trunk/auto/depends.sh | 2 +- trunk/auto/options.sh | 37 +++------------------------- trunk/src/app/srs_app_config.cpp | 2 +- trunk/src/app/srs_app_listener.hpp | 4 +-- trunk/src/app/srs_app_rtc_conn.cpp | 22 ++++++++--------- trunk/src/app/srs_app_rtc_conn.hpp | 10 ++++---- trunk/src/protocol/srs_sip_stack.cpp | 6 ++--- trunk/src/service/srs_service_st.cpp | 8 +++--- trunk/src/service/srs_service_st.hpp | 16 ++++++------ 12 files changed, 44 insertions(+), 82 deletions(-) diff --git a/trunk/3rdparty/st-srs/io.c b/trunk/3rdparty/st-srs/io.c index f4345aa89..35a3110c6 100644 --- a/trunk/3rdparty/st-srs/io.c +++ b/trunk/3rdparty/st-srs/io.c @@ -743,16 +743,18 @@ int st_sendmsg(_st_netfd_t *fd, const struct msghdr *msg, int flags, st_utime_t } -#if defined(MD_HAVE_SENDMMSG) && defined(__linux__) && defined(_GNU_SOURCE) -int st_sendmmsg(st_netfd_t fd, struct mmsghdr *msgvec, unsigned int vlen, int flags, st_utime_t timeout) +int st_sendmmsg(st_netfd_t fd, void *msgvec, unsigned int vlen, int flags, st_utime_t timeout) { +#if !defined(MD_HAVE_SENDMMSG) || !defined(_GNU_SOURCE) + return -1; +#else int n; int left; struct mmsghdr *p; left = (int)vlen; while (left > 0) { - p = msgvec + (vlen - left); + p = (struct mmsghdr*)msgvec + (vlen - left); if ((n = sendmmsg(fd->osfd, p, left, flags)) < 0) { if (errno == EINTR) @@ -772,8 +774,8 @@ int st_sendmmsg(st_netfd_t fd, struct mmsghdr *msgvec, unsigned int vlen, int fl return n; } return (int)vlen - left; -} #endif +} /* diff --git a/trunk/3rdparty/st-srs/public.h b/trunk/3rdparty/st-srs/public.h index 332f3291c..a581adc08 100644 --- a/trunk/3rdparty/st-srs/public.h +++ b/trunk/3rdparty/st-srs/public.h @@ -151,9 +151,7 @@ extern int st_recvfrom(st_netfd_t fd, void *buf, int len, struct sockaddr *from, extern int st_sendto(st_netfd_t fd, const void *msg, int len, const struct sockaddr *to, int tolen, st_utime_t timeout); extern int st_recvmsg(st_netfd_t fd, struct msghdr *msg, int flags, st_utime_t timeout); extern int st_sendmsg(st_netfd_t fd, const struct msghdr *msg, int flags, st_utime_t timeout); -#if defined(__linux__) && defined(_GNU_SOURCE) -extern int st_sendmmsg(st_netfd_t fd, struct mmsghdr *msgvec, unsigned int vlen, int flags, st_utime_t timeout); -#endif +extern int st_sendmmsg(st_netfd_t fd, void *msgvec, unsigned int vlen, int flags, st_utime_t timeout); extern st_netfd_t st_open(const char *path, int oflags, mode_t mode); #ifdef DEBUG diff --git a/trunk/auto/auto_headers.sh b/trunk/auto/auto_headers.sh index bcbfe95b8..772d0aeba 100755 --- a/trunk/auto/auto_headers.sh +++ b/trunk/auto/auto_headers.sh @@ -165,11 +165,6 @@ if [ $SRS_SENDMMSG = YES ]; then else srs_undefine_macro "SRS_SENDMMSG" $SRS_AUTO_HEADERS_H fi -if [ $SRS_HAS_SENDMMSG = YES ]; then - srs_define_macro "SRS_HAS_SENDMMSG" $SRS_AUTO_HEADERS_H -else - srs_undefine_macro "SRS_HAS_SENDMMSG" $SRS_AUTO_HEADERS_H -fi if [ $SRS_DEBUG = YES ]; then srs_define_macro "SRS_DEBUG" $SRS_AUTO_HEADERS_H diff --git a/trunk/auto/depends.sh b/trunk/auto/depends.sh index f9723193f..484ba2567 100755 --- a/trunk/auto/depends.sh +++ b/trunk/auto/depends.sh @@ -347,7 +347,7 @@ if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then _ST_MAKE=darwin-debug && _ST_EXTRA_CFLAGS="-DMD_HAVE_KQUEUE" && _ST_LD=${SRS_TOOL_CC} && _ST_OBJ="DARWIN_`uname -r`_DBG" fi # For UDP sendmmsg, disable it if not suppported. - if [[ $SRS_HAS_SENDMMSG == YES ]]; then + if [[ $SRS_SENDMMSG == YES ]]; then echo "Build ST with UDP sendmmsg support." _ST_EXTRA_CFLAGS="$_ST_EXTRA_CFLAGS -DMD_HAVE_SENDMMSG -D_GNU_SOURCE" else diff --git a/trunk/auto/options.sh b/trunk/auto/options.sh index cd7cfe8e4..a5848485b 100755 --- a/trunk/auto/options.sh +++ b/trunk/auto/options.sh @@ -118,11 +118,9 @@ SRS_EXTRA_FLAGS= # ##################################################################################### # Performance optimize. -SRS_NASM=YES -SRS_SRTP_ASM=YES -SRS_SENDMMSG=YES -SRS_HAS_SENDMMSG=YES -SRS_DETECT_SENDMMSG=YES +SRS_NASM=NO +SRS_SRTP_ASM=NO +SRS_SENDMMSG=NO SRS_DEBUG=NO ##################################################################################### @@ -257,8 +255,6 @@ function parse_user_option() { --export-librtmp-project) SRS_EXPORT_LIBRTMP_PROJECT=${value} ;; --export-librtmp-single) SRS_EXPORT_LIBRTMP_SINGLE=${value} ;; - --detect-sendmmsg) if [[ $value == off ]]; then SRS_DETECT_SENDMMSG=NO; else SRS_DETECT_SENDMMSG=YES; fi ;; - --has-sendmmsg) if [[ $value == off ]]; then SRS_HAS_SENDMMSG=NO; else SRS_HAS_SENDMMSG=YES; fi ;; --sendmmsg) if [[ $value == off ]]; then SRS_SENDMMSG=NO; else SRS_SENDMMSG=YES; fi ;; --without-srtp-nasm) SRS_SRTP_ASM=NO ;; @@ -612,31 +608,6 @@ function apply_user_detail_options() { echo "Disable SRTP ASM, because NASM is disabled." SRS_SRTP_ASM=NO fi - - # Detect whether has sendmmsg. - # @see http://man7.org/linux/man-pages/man2/sendmmsg.2.html - if [[ $SRS_DETECT_SENDMMSG == YES ]]; then - mkdir -p ${SRS_OBJS} && - echo " #include " > ${SRS_OBJS}/_tmp_sendmmsg_detect.c - echo " int main(int argc, char** argv) { " >> ${SRS_OBJS}/_tmp_sendmmsg_detect.c - echo " struct mmsghdr hdr; " >> ${SRS_OBJS}/_tmp_sendmmsg_detect.c - echo " hdr.msg_len = 0; " >> ${SRS_OBJS}/_tmp_sendmmsg_detect.c - echo " return 0; " >> ${SRS_OBJS}/_tmp_sendmmsg_detect.c - echo " } " >> ${SRS_OBJS}/_tmp_sendmmsg_detect.c - ${SRS_TOOL_CC} -c ${SRS_OBJS}/_tmp_sendmmsg_detect.c -D_GNU_SOURCE -o /dev/null >/dev/null 2>&1 - ret=$?; rm -f ${SRS_OBJS}/_tmp_sendmmsg_detect.c; - if [[ $ret -ne 0 ]]; then - SRS_HAS_SENDMMSG=NO - fi - fi - - # If system has no sendmmsg, disable sendmmsg. - if [[ $SRS_HAS_SENDMMSG == NO ]]; then - if [[ $SRS_SENDMMSG == YES ]]; then - echo "Disable UDP sendmmsg automatically" - SRS_SENDMMSG=NO - fi - fi } apply_user_detail_options @@ -666,8 +637,6 @@ function regenerate_options() { if [ $SRS_NASM = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --nasm=on"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --nasm=off"; fi if [ $SRS_SRTP_ASM = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --srtp-nasm=on"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --srtp-nasm=off"; fi if [ $SRS_SENDMMSG = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --sendmmsg=on"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --sendmmsg=off"; fi - if [ $SRS_DETECT_SENDMMSG = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --detect-sendmmsg=on"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --detect-sendmmsg=off"; fi - if [ $SRS_HAS_SENDMMSG = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --has-sendmmsg=on"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --has-sendmmsg=off"; fi if [ $SRS_CLEAN = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --clean=on"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --clean=off"; fi if [ $SRS_GPERF = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --gperf=on"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --gperf=off"; fi if [ $SRS_GPERF_MC = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --gmc=on"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --gmc=off"; fi diff --git a/trunk/src/app/srs_app_config.cpp b/trunk/src/app/srs_app_config.cpp index 12c990cf4..b234d3f38 100644 --- a/trunk/src/app/srs_app_config.cpp +++ b/trunk/src/app/srs_app_config.cpp @@ -4781,7 +4781,7 @@ bool SrsConfig::get_rtc_server_encrypt() int SrsConfig::get_rtc_server_sendmmsg() { -#if !defined(SRS_HAS_SENDMMSG) || !defined(SRS_SENDMMSG) +#if !defined(SRS_SENDMMSG) return 1; #else static int DEFAULT = 256; diff --git a/trunk/src/app/srs_app_listener.hpp b/trunk/src/app/srs_app_listener.hpp index 46fd11a7e..5fd32f07c 100644 --- a/trunk/src/app/srs_app_listener.hpp +++ b/trunk/src/app/srs_app_listener.hpp @@ -138,9 +138,9 @@ public: virtual ~ISrsUdpSender(); public: // Fetch a mmsghdr from sender's cache. - virtual srs_error_t fetch(mmsghdr** pphdr) = 0; + virtual srs_error_t fetch(srs_mmsghdr** pphdr) = 0; // Notify the sender to send out the msg. - virtual srs_error_t sendmmsg(mmsghdr* hdr) = 0; + virtual srs_error_t sendmmsg(srs_mmsghdr* hdr) = 0; // Whether sender exceed the max queue, that is, overflow. virtual bool overflow() = 0; // Set the queue extra ratio, for example, when mw_msgs > 0, we need larger queue. diff --git a/trunk/src/app/srs_app_rtc_conn.cpp b/trunk/src/app/srs_app_rtc_conn.cpp index 34dad0f46..51c5f7ed4 100644 --- a/trunk/src/app/srs_app_rtc_conn.cpp +++ b/trunk/src/app/srs_app_rtc_conn.cpp @@ -965,7 +965,7 @@ srs_error_t SrsRtcSenderThread::send_packets(SrsRtcPackets& packets) // Fetch a cached message from queue. // TODO: FIXME: Maybe encrypt in async, so the state of mhdr maybe not ready. - mmsghdr* mhdr = NULL; + srs_mmsghdr* mhdr = NULL; if ((err = sender->fetch(&mhdr)) != srs_success) { return srs_error_wrap(err, "fetch msghdr"); } @@ -1028,7 +1028,7 @@ srs_error_t SrsRtcSenderThread::send_packets_gso(SrsRtcPackets& packets) ISrsUdpSender* sender = rtc_session->sendonly_skt->sender(); // Previous handler, if has the same size, we can use GSO. - mmsghdr* gso_mhdr = NULL; int gso_size = 0; int gso_encrypt = 0; int gso_cursor = 0; + srs_mmsghdr* gso_mhdr = NULL; int gso_size = 0; int gso_encrypt = 0; int gso_cursor = 0; // GSO, N packets has same length, the final one may not. bool using_gso = false; bool gso_final = false; // The message will marshal in iovec. @@ -1099,7 +1099,7 @@ srs_error_t SrsRtcSenderThread::send_packets_gso(SrsRtcPackets& packets) } // For GSO, reuse mhdr if possible. - mmsghdr* mhdr = gso_mhdr; + srs_mmsghdr* mhdr = gso_mhdr; if (!mhdr) { // Fetch a cached message from queue. // TODO: FIXME: Maybe encrypt in async, so the state of mhdr maybe not ready. @@ -2970,13 +2970,13 @@ srs_error_t SrsUdpMuxSender::initialize(srs_netfd_t fd, int senders) return err; } -void SrsUdpMuxSender::free_mhdrs(std::vector& mhdrs) +void SrsUdpMuxSender::free_mhdrs(std::vector& mhdrs) { int nn_mhdrs = (int)mhdrs.size(); for (int i = 0; i < nn_mhdrs; i++) { // @see https://linux.die.net/man/2/sendmmsg // @see https://linux.die.net/man/2/sendmsg - mmsghdr* hdr = &mhdrs[i]; + srs_mmsghdr* hdr = &mhdrs[i]; // Free control for GSO. char* msg_control = (char*)hdr->msg_hdr.msg_control; @@ -2993,13 +2993,13 @@ void SrsUdpMuxSender::free_mhdrs(std::vector& mhdrs) mhdrs.clear(); } -srs_error_t SrsUdpMuxSender::fetch(mmsghdr** pphdr) +srs_error_t SrsUdpMuxSender::fetch(srs_mmsghdr** pphdr) { // TODO: FIXME: Maybe need to shrink? if (cache_pos >= (int)cache.size()) { // @see https://linux.die.net/man/2/sendmmsg // @see https://linux.die.net/man/2/sendmsg - mmsghdr mhdr; + srs_mmsghdr mhdr; mhdr.msg_len = 0; mhdr.msg_hdr.msg_flags = 0; @@ -3040,7 +3040,7 @@ void SrsUdpMuxSender::set_extra_ratio(int r) max_sendmmsg, gso, queue_length, nn_senders, extra_ratio, extra_queue, cache_pos, (int)cache.size(), (int)hotspot.size()); } -srs_error_t SrsUdpMuxSender::sendmmsg(mmsghdr* hdr) +srs_error_t SrsUdpMuxSender::sendmmsg(srs_mmsghdr* hdr) { if (waiting_msgs) { waiting_msgs = false; @@ -3092,7 +3092,7 @@ srs_error_t SrsUdpMuxSender::cycle() // Send out all messages. // @see https://linux.die.net/man/2/sendmmsg // @see https://linux.die.net/man/2/sendmsg - mmsghdr* p = &hotspot[0]; mmsghdr* end = p + pos; + srs_mmsghdr* p = &hotspot[0]; srs_mmsghdr* end = p + pos; for (p = &hotspot[0]; p < end; p += max_sendmmsg) { int vlen = (int)(end - p); vlen = srs_min(max_sendmmsg, vlen); @@ -3113,7 +3113,7 @@ srs_error_t SrsUdpMuxSender::cycle() // @see https://linux.die.net/man/2/sendmmsg // @see https://linux.die.net/man/2/sendmsg for (int i = 0; i < pos; i++) { - mmsghdr* mhdr = &hotspot[i]; + srs_mmsghdr* mhdr = &hotspot[i]; nn_writen += (int)mhdr->msg_len; @@ -3159,7 +3159,7 @@ srs_error_t SrsUdpMuxSender::cycle() int nn_cache = 0; int nn_hotspot_size = (int)hotspot.size(); for (int i = 0; i < nn_hotspot_size; i++) { - mmsghdr* hdr = &hotspot[i]; + srs_mmsghdr* hdr = &hotspot[i]; nn_cache += hdr->msg_hdr.msg_iovlen; } diff --git a/trunk/src/app/srs_app_rtc_conn.hpp b/trunk/src/app/srs_app_rtc_conn.hpp index 3f4018644..35c01b3a6 100644 --- a/trunk/src/app/srs_app_rtc_conn.hpp +++ b/trunk/src/app/srs_app_rtc_conn.hpp @@ -388,9 +388,9 @@ private: private: // Hotspot msgs, we are working on it. // @remark We will wait util all messages are ready. - std::vector hotspot; + std::vector hotspot; // Cache msgs, for other coroutines to fill it. - std::vector cache; + std::vector cache; int cache_pos; // The max number of messages for sendmmsg. If 1, we use sendmsg to send. int max_sendmmsg; @@ -405,10 +405,10 @@ public: public: virtual srs_error_t initialize(srs_netfd_t fd, int senders); private: - void free_mhdrs(std::vector& mhdrs); + void free_mhdrs(std::vector& mhdrs); public: - virtual srs_error_t fetch(mmsghdr** pphdr); - virtual srs_error_t sendmmsg(mmsghdr* hdr); + virtual srs_error_t fetch(srs_mmsghdr** pphdr); + virtual srs_error_t sendmmsg(srs_mmsghdr* hdr); virtual bool overflow(); virtual void set_extra_ratio(int r); public: diff --git a/trunk/src/protocol/srs_sip_stack.cpp b/trunk/src/protocol/srs_sip_stack.cpp index 19d959723..65a383dfd 100644 --- a/trunk/src/protocol/srs_sip_stack.cpp +++ b/trunk/src/protocol/srs_sip_stack.cpp @@ -635,9 +635,9 @@ srs_error_t SrsSipStack::do_parse_request(SrsSipRequest* req, const char* recv_m std::vector vec_device_status = srs_string_split(body_map["Response@DeviceList@Item@Status"], ","); //map key:devicd_id value:status - for(int i=0 ; i i) { + if ((int)vec_device_id.size() > i) { status = vec_device_status.at(i); } @@ -653,7 +653,7 @@ srs_error_t SrsSipStack::do_parse_request(SrsSipRequest* req, const char* recv_m if (cmdtype == "Keepalive"){ //TODO: ???? std::vector vec_device_id = srs_string_split(body_map["Notify@Info@DeviceID"], ","); - for(int i=0; idevice_list_map[vec_device_id.at(i)] = "OFF"; } }else{ diff --git a/trunk/src/service/srs_service_st.cpp b/trunk/src/service/srs_service_st.cpp index 73e2252ac..78e3705d8 100644 --- a/trunk/src/service/srs_service_st.cpp +++ b/trunk/src/service/srs_service_st.cpp @@ -412,12 +412,12 @@ int srs_sendmsg(srs_netfd_t stfd, const struct msghdr *msg, int flags, srs_utime return st_sendmsg((st_netfd_t)stfd, msg, flags, (st_utime_t)timeout); } -int srs_sendmmsg(srs_netfd_t stfd, struct mmsghdr *msgvec, unsigned int vlen, int flags, srs_utime_t timeout) +int srs_sendmmsg(srs_netfd_t stfd, struct srs_mmsghdr *msgvec, unsigned int vlen, int flags, srs_utime_t timeout) { -#if !defined(SRS_HAS_SENDMMSG) || !defined(SRS_SENDMMSG) +#if !defined(SRS_SENDMMSG) // @see http://man7.org/linux/man-pages/man2/sendmmsg.2.html for (int i = 0; i < (int)vlen; ++i) { - struct mmsghdr* p = msgvec + i; + struct srs_mmsghdr* p = msgvec + i; int n = srs_sendmsg(stfd, &p->msg_hdr, flags, timeout); if (n < 0) { // An error is returned only if no datagrams could be sent. @@ -457,7 +457,7 @@ int srs_sendmmsg(srs_netfd_t stfd, struct mmsghdr *msgvec, unsigned int vlen, in return 1; } - return st_sendmmsg((st_netfd_t)stfd, msgvec, vlen, flags, (st_utime_t)timeout); + return st_sendmmsg((st_netfd_t)stfd, (void*)msgvec, vlen, flags, (st_utime_t)timeout); #endif } diff --git a/trunk/src/service/srs_service_st.hpp b/trunk/src/service/srs_service_st.hpp index 7d789b2cc..f3f0a8e80 100644 --- a/trunk/src/service/srs_service_st.hpp +++ b/trunk/src/service/srs_service_st.hpp @@ -92,15 +92,13 @@ extern int srs_sendto(srs_netfd_t stfd, void *buf, int len, const struct sockadd extern int srs_recvmsg(srs_netfd_t stfd, struct msghdr *msg, int flags, srs_utime_t timeout); extern int srs_sendmsg(srs_netfd_t stfd, const struct msghdr *msg, int flags, srs_utime_t timeout); -#if !defined(SRS_HAS_SENDMMSG) - // @see http://man7.org/linux/man-pages/man2/sendmmsg.2.html - #include - struct mmsghdr { - struct msghdr msg_hdr; /* Message header */ - unsigned int msg_len; /* Number of bytes transmitted */ - }; -#endif -extern int srs_sendmmsg(srs_netfd_t stfd, struct mmsghdr *msgvec, unsigned int vlen, int flags, srs_utime_t timeout); +// @see http://man7.org/linux/man-pages/man2/sendmmsg.2.html +#include +struct srs_mmsghdr { + struct msghdr msg_hdr; /* Message header */ + unsigned int msg_len; /* Number of bytes transmitted */ +}; +extern int srs_sendmmsg(srs_netfd_t stfd, struct srs_mmsghdr *msgvec, unsigned int vlen, int flags, srs_utime_t timeout); extern srs_netfd_t srs_accept(srs_netfd_t stfd, struct sockaddr *addr, int *addrlen, srs_utime_t timeout); From f71b8335200a249114287766cf09a9d3bd38cc02 Mon Sep 17 00:00:00 2001 From: winlin Date: Sun, 3 May 2020 11:32:54 +0800 Subject: [PATCH 08/18] Refine sendmmsg, move to ST --- trunk/3rdparty/st-srs/io.c | 29 +++++++++++++++--- trunk/3rdparty/st-srs/public.h | 10 +++++- trunk/auto/options.sh | 5 +++ trunk/configure | 2 +- trunk/src/service/srs_service_st.cpp | 46 +--------------------------- 5 files changed, 40 insertions(+), 52 deletions(-) diff --git a/trunk/3rdparty/st-srs/io.c b/trunk/3rdparty/st-srs/io.c index 35a3110c6..7e05f99ae 100644 --- a/trunk/3rdparty/st-srs/io.c +++ b/trunk/3rdparty/st-srs/io.c @@ -742,12 +742,9 @@ int st_sendmsg(_st_netfd_t *fd, const struct msghdr *msg, int flags, st_utime_t return n; } - -int st_sendmmsg(st_netfd_t fd, void *msgvec, unsigned int vlen, int flags, st_utime_t timeout) +int st_sendmmsg(st_netfd_t fd, struct st_mmsghdr *msgvec, unsigned int vlen, int flags, st_utime_t timeout) { -#if !defined(MD_HAVE_SENDMMSG) || !defined(_GNU_SOURCE) - return -1; -#else +#if defined(MD_HAVE_SENDMMSG) && defined(_GNU_SOURCE) int n; int left; struct mmsghdr *p; @@ -774,6 +771,28 @@ int st_sendmmsg(st_netfd_t fd, void *msgvec, unsigned int vlen, int flags, st_ut return n; } return (int)vlen - left; +#else + struct st_mmsghdr *p; + int i, n; + + // @see http://man7.org/linux/man-pages/man2/sendmmsg.2.html + for (i = 0; i < (int)vlen; ++i) { + p = msgvec + i; + n = st_sendmsg(fd, &p->msg_hdr, flags, timeout); + if (n < 0) { + // An error is returned only if no datagrams could be sent. + if (i == 0) { + return n; + } + return i + 1; + } + + p->msg_len = n; + } + + // Returns the number of messages sent from msgvec; if this is less than vlen, the caller can retry with a + // further sendmmsg() call to send the remaining messages. + return vlen; #endif } diff --git a/trunk/3rdparty/st-srs/public.h b/trunk/3rdparty/st-srs/public.h index a581adc08..80fd93346 100644 --- a/trunk/3rdparty/st-srs/public.h +++ b/trunk/3rdparty/st-srs/public.h @@ -151,7 +151,15 @@ extern int st_recvfrom(st_netfd_t fd, void *buf, int len, struct sockaddr *from, extern int st_sendto(st_netfd_t fd, const void *msg, int len, const struct sockaddr *to, int tolen, st_utime_t timeout); extern int st_recvmsg(st_netfd_t fd, struct msghdr *msg, int flags, st_utime_t timeout); extern int st_sendmsg(st_netfd_t fd, const struct msghdr *msg, int flags, st_utime_t timeout); -extern int st_sendmmsg(st_netfd_t fd, void *msgvec, unsigned int vlen, int flags, st_utime_t timeout); + +// @see http://man7.org/linux/man-pages/man2/sendmmsg.2.html +#include +struct st_mmsghdr { + struct msghdr msg_hdr; /* Message header */ + unsigned int msg_len; /* Number of bytes transmitted */ +}; +extern int st_sendmmsg(st_netfd_t fd, struct st_mmsghdr *msgvec, unsigned int vlen, int flags, st_utime_t timeout); + extern st_netfd_t st_open(const char *path, int oflags, mode_t mode); #ifdef DEBUG diff --git a/trunk/auto/options.sh b/trunk/auto/options.sh index a5848485b..97f6dcf92 100755 --- a/trunk/auto/options.sh +++ b/trunk/auto/options.sh @@ -608,6 +608,11 @@ function apply_user_detail_options() { echo "Disable SRTP ASM, because NASM is disabled." SRS_SRTP_ASM=NO fi + + if [[ $SRS_OSX == YES && $SRS_SENDMMSG == YES ]]; then + echo "Disable sendmmsg for OSX" + SRS_SENDMMSG=NO + fi } apply_user_detail_options diff --git a/trunk/configure b/trunk/configure index 974a9163b..115e5f8d5 100755 --- a/trunk/configure +++ b/trunk/configure @@ -188,7 +188,7 @@ if [[ $SRS_GCOV == YES ]]; then SrsLinkOptions="${SrsLinkOptions} ${SrsGcov}"; fi # For FFMPEG/RTC. -if [[ $SRS_RTC == YES && $SRS_NASM == NO ]]; then +if [[ $SRS_RTC == YES && $SRS_NASM == NO && $SRS_OSX == NO ]]; then SrsLinkOptions="${SrsLinkOptions} -lrt"; fi diff --git a/trunk/src/service/srs_service_st.cpp b/trunk/src/service/srs_service_st.cpp index 78e3705d8..e7181cae4 100644 --- a/trunk/src/service/srs_service_st.cpp +++ b/trunk/src/service/srs_service_st.cpp @@ -414,51 +414,7 @@ int srs_sendmsg(srs_netfd_t stfd, const struct msghdr *msg, int flags, srs_utime int srs_sendmmsg(srs_netfd_t stfd, struct srs_mmsghdr *msgvec, unsigned int vlen, int flags, srs_utime_t timeout) { -#if !defined(SRS_SENDMMSG) - // @see http://man7.org/linux/man-pages/man2/sendmmsg.2.html - for (int i = 0; i < (int)vlen; ++i) { - struct srs_mmsghdr* p = msgvec + i; - int n = srs_sendmsg(stfd, &p->msg_hdr, flags, timeout); - if (n < 0) { - // An error is returned only if no datagrams could be sent. - if (i == 0) { - return n; - } - return i + 1; - } - - p->msg_len = n; - } - // Returns the number of messages sent from msgvec; if this is less than vlen, the caller can retry with a - // further sendmmsg() call to send the remaining messages. - return vlen; -#else - if (vlen == 1) { - #if 1 - int r0 = srs_sendmsg(stfd, &msgvec->msg_hdr, flags, timeout); - if (r0 < 0) { - return r0; - } - msgvec->msg_len = r0; - #else - msgvec->msg_len = 0; - - int tolen = (int)msgvec->msg_hdr.msg_namelen; - const struct sockaddr* to = (const struct sockaddr*)msgvec->msg_hdr.msg_name; - for (int i = 0; i < (int)msgvec->msg_hdr.msg_iovlen; i++) { - iovec* iov = msgvec->msg_hdr.msg_iov + i; - int r0 = srs_sendto(stfd, (void*)iov->iov_base, (int)iov->iov_len, to, tolen, timeout); - if (r0 < 0) { - return r0; - } - msgvec->msg_len += r0; - } - #endif - - return 1; - } - return st_sendmmsg((st_netfd_t)stfd, (void*)msgvec, vlen, flags, (st_utime_t)timeout); -#endif + return st_sendmmsg((st_netfd_t)stfd, (struct st_mmsghdr*)msgvec, vlen, flags, (st_utime_t)timeout); } srs_netfd_t srs_accept(srs_netfd_t stfd, struct sockaddr *addr, int *addrlen, srs_utime_t timeout) From ef64c5e2bda8d40f891759a5c6a8e86f5095c33c Mon Sep 17 00:00:00 2001 From: winlin Date: Sun, 3 May 2020 13:11:38 +0800 Subject: [PATCH 09/18] Refine RTC, reject when config disabled. --- trunk/research/players/rtc_player.html | 4 ++++ trunk/research/players/rtc_publisher.html | 9 +++++++++ trunk/src/app/srs_app_config.cpp | 2 +- trunk/src/app/srs_app_config.hpp | 2 +- trunk/src/app/srs_app_http_api.cpp | 22 ++++++++++++++++++++++ trunk/src/app/srs_app_sdp.cpp | 2 +- trunk/src/kernel/srs_kernel_error.hpp | 1 + 7 files changed, 39 insertions(+), 3 deletions(-) diff --git a/trunk/research/players/rtc_player.html b/trunk/research/players/rtc_player.html index c78fcdb5b..03d23bd13 100644 --- a/trunk/research/players/rtc_player.html +++ b/trunk/research/players/rtc_player.html @@ -112,6 +112,9 @@ contentType:'application/json', dataType: 'json' }).done(function(data) { console.log("Got answer: ", data); + if (data.code) { + reject(data); return; + } resolve(data.sdp); }).fail(function(reason){ reject(reason); @@ -120,6 +123,7 @@ }).then(function(answer) { return pc.setRemoteDescription(new RTCSessionDescription({type: 'answer', sdp: answer})); }).catch(function(reason) { + pc.close(); $('#rtc_media_player').hide(); throw reason; }); }; diff --git a/trunk/research/players/rtc_publisher.html b/trunk/research/players/rtc_publisher.html index ce183782d..0035a20aa 100644 --- a/trunk/research/players/rtc_publisher.html +++ b/trunk/research/players/rtc_publisher.html @@ -124,6 +124,9 @@ contentType:'application/json', dataType: 'json' }).done(function(data) { console.log("Got answer: ", data); + if (data.code) { + reject(data); return; + } resolve(data.sdp); }).fail(function(reason){ reject(reason); @@ -132,6 +135,12 @@ }).then(function(answer) { return pc.setRemoteDescription(new RTCSessionDescription({type: 'answer', sdp: answer})); }).catch(function(reason) { + pc.getLocalStreams().forEach(function(stream){ + stream.getTracks().forEach(function(track) { + track.stop(); + }); + }); + pc.close(); $('#rtc_media_player').hide(); throw reason; }); }; diff --git a/trunk/src/app/srs_app_config.cpp b/trunk/src/app/srs_app_config.cpp index b234d3f38..3f740346a 100644 --- a/trunk/src/app/srs_app_config.cpp +++ b/trunk/src/app/srs_app_config.cpp @@ -4679,7 +4679,7 @@ srs_utime_t SrsConfig::get_stream_caster_gb28181_sip_query_catalog_interval(SrsC return (srs_utime_t)(::atoi(conf->arg0().c_str()) * SRS_UTIME_SECONDS); } -int SrsConfig::get_rtc_server_enabled() +bool SrsConfig::get_rtc_server_enabled() { SrsConfDirective* conf = root->get("rtc_server"); return get_rtc_server_enabled(conf); diff --git a/trunk/src/app/srs_app_config.hpp b/trunk/src/app/srs_app_config.hpp index ab9ac5ac2..44d4ccb00 100644 --- a/trunk/src/app/srs_app_config.hpp +++ b/trunk/src/app/srs_app_config.hpp @@ -521,7 +521,7 @@ public: // rtc section public: - virtual int get_rtc_server_enabled(); + virtual bool get_rtc_server_enabled(); virtual bool get_rtc_server_enabled(SrsConfDirective* conf); virtual int get_rtc_server_listen(); virtual std::string get_rtc_server_candidates(); diff --git a/trunk/src/app/srs_app_http_api.cpp b/trunk/src/app/srs_app_http_api.cpp index 50ca4a328..57b67453e 100644 --- a/trunk/src/app/srs_app_http_api.cpp +++ b/trunk/src/app/srs_app_http_api.cpp @@ -918,6 +918,17 @@ srs_error_t SrsGoApiRtcPlay::do_serve_http(ISrsHttpResponseWriter* w, ISrsHttpMe request.vhost = parsed_vhost->arg0(); } + // Whether enabled. + bool server_enabled = _srs_config->get_rtc_server_enabled(); + bool rtc_enabled = _srs_config->get_rtc_enabled(request.vhost); + if (server_enabled && !rtc_enabled) { + srs_warn("RTC disabled in vhost %s", request.vhost.c_str()); + } + if (!server_enabled || !rtc_enabled) { + return srs_error_new(ERROR_RTC_DISABLED, "Disabled server=%d, rtc=%d, vhost=%s", + server_enabled, rtc_enabled, request.vhost.c_str()); + } + // TODO: FIXME: Maybe need a better name? // TODO: FIXME: When server enabled, but vhost disabled, should report error. SrsRtcSession* rtc_session = NULL; @@ -1232,6 +1243,17 @@ srs_error_t SrsGoApiRtcPublish::do_serve_http(ISrsHttpResponseWriter* w, ISrsHtt request.vhost = parsed_vhost->arg0(); } + // Whether enabled. + bool server_enabled = _srs_config->get_rtc_server_enabled(); + bool rtc_enabled = _srs_config->get_rtc_enabled(request.vhost); + if (server_enabled && !rtc_enabled) { + srs_warn("RTC disabled in vhost %s", request.vhost.c_str()); + } + if (!server_enabled || !rtc_enabled) { + return srs_error_new(ERROR_RTC_DISABLED, "Disabled server=%d, rtc=%d, vhost=%s", + server_enabled, rtc_enabled, request.vhost.c_str()); + } + // TODO: FIXME: Maybe need a better name? // TODO: FIXME: When server enabled, but vhost disabled, should report error. SrsRtcSession* rtc_session = NULL; diff --git a/trunk/src/app/srs_app_sdp.cpp b/trunk/src/app/srs_app_sdp.cpp index 9fc227be6..0dc001f60 100644 --- a/trunk/src/app/srs_app_sdp.cpp +++ b/trunk/src/app/srs_app_sdp.cpp @@ -528,7 +528,7 @@ srs_error_t SrsMediaDesc::parse_attr_mid(const std::string& value) std::istringstream is(value); // mid_ means m-line id FETCH(is, mid_); - srs_trace("mid=%s", mid_.c_str()); + srs_verbose("mid=%s", mid_.c_str()); return err; } diff --git a/trunk/src/kernel/srs_kernel_error.hpp b/trunk/src/kernel/srs_kernel_error.hpp index 9f88c1dda..597d0bb32 100644 --- a/trunk/src/kernel/srs_kernel_error.hpp +++ b/trunk/src/kernel/srs_kernel_error.hpp @@ -349,6 +349,7 @@ #define ERROR_RTC_SDP_EXCHANGE 5018 #define ERROR_RTC_API_BODY 5019 #define ERROR_RTC_SOURCE_BUSY 5020 +#define ERROR_RTC_DISABLED 5021 /////////////////////////////////////////////////////// // GB28181 API error. From 9c8b7279f05b10aaa227a85e3adc175ad0290cf7 Mon Sep 17 00:00:00 2001 From: winlin Date: Sun, 3 May 2020 13:37:04 +0800 Subject: [PATCH 10/18] Refactor RTC publisher queue, rename sender to player --- trunk/src/app/srs_app_rtc_conn.cpp | 60 ++++++++++----------- trunk/src/app/srs_app_rtc_conn.hpp | 11 ++-- trunk/src/app/srs_app_rtp_queue.cpp | 83 +++++++++-------------------- trunk/src/app/srs_app_rtp_queue.hpp | 21 +++----- 4 files changed, 65 insertions(+), 110 deletions(-) diff --git a/trunk/src/app/srs_app_rtc_conn.cpp b/trunk/src/app/srs_app_rtc_conn.cpp index 51c5f7ed4..e41c4b572 100644 --- a/trunk/src/app/srs_app_rtc_conn.cpp +++ b/trunk/src/app/srs_app_rtc_conn.cpp @@ -595,7 +595,7 @@ SrsRtpPacket2* SrsRtcPackets::at(int index) return cache + index; } -SrsRtcSenderThread::SrsRtcSenderThread(SrsRtcSession* s, int parent_cid) +SrsRtcPlayer::SrsRtcPlayer(SrsRtcSession* s, int parent_cid) { _parent_cid = parent_cid; trd = new SrsDummyCoroutine(); @@ -618,14 +618,14 @@ SrsRtcSenderThread::SrsRtcSenderThread(SrsRtcSession* s, int parent_cid) _srs_config->subscribe(this); } -SrsRtcSenderThread::~SrsRtcSenderThread() +SrsRtcPlayer::~SrsRtcPlayer() { _srs_config->unsubscribe(this); srs_freep(trd); } -srs_error_t SrsRtcSenderThread::initialize(const uint32_t& vssrc, const uint32_t& assrc, const uint16_t& v_pt, const uint16_t& a_pt) +srs_error_t SrsRtcPlayer::initialize(const uint32_t& vssrc, const uint32_t& assrc, const uint16_t& v_pt, const uint16_t& a_pt) { srs_error_t err = srs_success; @@ -644,7 +644,7 @@ srs_error_t SrsRtcSenderThread::initialize(const uint32_t& vssrc, const uint32_t return err; } -srs_error_t SrsRtcSenderThread::on_reload_rtc_server() +srs_error_t SrsRtcPlayer::on_reload_rtc_server() { gso = _srs_config->get_rtc_server_gso(); merge_nalus = _srs_config->get_rtc_server_merge_nalus(); @@ -655,7 +655,7 @@ srs_error_t SrsRtcSenderThread::on_reload_rtc_server() return srs_success; } -srs_error_t SrsRtcSenderThread::on_reload_vhost_play(string vhost) +srs_error_t SrsRtcPlayer::on_reload_vhost_play(string vhost) { SrsRequest* req = rtc_session->req; @@ -672,17 +672,17 @@ srs_error_t SrsRtcSenderThread::on_reload_vhost_play(string vhost) return srs_success; } -srs_error_t SrsRtcSenderThread::on_reload_vhost_realtime(string vhost) +srs_error_t SrsRtcPlayer::on_reload_vhost_realtime(string vhost) { return on_reload_vhost_play(vhost); } -int SrsRtcSenderThread::cid() +int SrsRtcPlayer::cid() { return trd->cid(); } -srs_error_t SrsRtcSenderThread::start() +srs_error_t SrsRtcPlayer::start() { srs_error_t err = srs_success; @@ -696,17 +696,17 @@ srs_error_t SrsRtcSenderThread::start() return err; } -void SrsRtcSenderThread::stop() +void SrsRtcPlayer::stop() { trd->stop(); } -void SrsRtcSenderThread::stop_loop() +void SrsRtcPlayer::stop_loop() { trd->interrupt(); } -srs_error_t SrsRtcSenderThread::cycle() +srs_error_t SrsRtcPlayer::cycle() { srs_error_t err = srs_success; @@ -833,7 +833,7 @@ srs_error_t SrsRtcSenderThread::cycle() } } -srs_error_t SrsRtcSenderThread::send_messages( +srs_error_t SrsRtcPlayer::send_messages( SrsSource* source, SrsSharedPtrMessage** msgs, int nb_msgs, SrsRtcPackets& packets ) { srs_error_t err = srs_success; @@ -866,7 +866,7 @@ srs_error_t SrsRtcSenderThread::send_messages( return err; } -srs_error_t SrsRtcSenderThread::messages_to_packets( +srs_error_t SrsRtcPlayer::messages_to_packets( SrsSource* source, SrsSharedPtrMessage** msgs, int nb_msgs, SrsRtcPackets& packets ) { srs_error_t err = srs_success; @@ -951,7 +951,7 @@ srs_error_t SrsRtcSenderThread::messages_to_packets( return err; } -srs_error_t SrsRtcSenderThread::send_packets(SrsRtcPackets& packets) +srs_error_t SrsRtcPlayer::send_packets(SrsRtcPackets& packets) { srs_error_t err = srs_success; @@ -1019,7 +1019,7 @@ srs_error_t SrsRtcSenderThread::send_packets(SrsRtcPackets& packets) } // TODO: FIXME: We can gather and pad audios, because they have similar size. -srs_error_t SrsRtcSenderThread::send_packets_gso(SrsRtcPackets& packets) +srs_error_t SrsRtcPlayer::send_packets_gso(SrsRtcPackets& packets) { srs_error_t err = srs_success; @@ -1222,7 +1222,7 @@ srs_error_t SrsRtcSenderThread::send_packets_gso(SrsRtcPackets& packets) return err; } -srs_error_t SrsRtcSenderThread::package_nalus(SrsSharedPtrMessage* msg, SrsRtcPackets& packets) +srs_error_t SrsRtcPlayer::package_nalus(SrsSharedPtrMessage* msg, SrsRtcPackets& packets) { srs_error_t err = srs_success; @@ -1312,7 +1312,7 @@ srs_error_t SrsRtcSenderThread::package_nalus(SrsSharedPtrMessage* msg, SrsRtcPa return err; } -srs_error_t SrsRtcSenderThread::package_opus(SrsSample* sample, SrsRtcPackets& packets, int nn_max_payload) +srs_error_t SrsRtcPlayer::package_opus(SrsSample* sample, SrsRtcPackets& packets, int nn_max_payload) { srs_error_t err = srs_success; @@ -1348,7 +1348,7 @@ srs_error_t SrsRtcSenderThread::package_opus(SrsSample* sample, SrsRtcPackets& p return err; } -srs_error_t SrsRtcSenderThread::package_fu_a(SrsSharedPtrMessage* msg, SrsSample* sample, int fu_payload_size, SrsRtcPackets& packets) +srs_error_t SrsRtcPlayer::package_fu_a(SrsSharedPtrMessage* msg, SrsSample* sample, int fu_payload_size, SrsRtcPackets& packets) { srs_error_t err = srs_success; @@ -1389,7 +1389,7 @@ srs_error_t SrsRtcSenderThread::package_fu_a(SrsSharedPtrMessage* msg, SrsSample } // Single NAL Unit Packet @see https://tools.ietf.org/html/rfc6184#section-5.6 -srs_error_t SrsRtcSenderThread::package_single_nalu(SrsSharedPtrMessage* msg, SrsSample* sample, SrsRtcPackets& packets) +srs_error_t SrsRtcPlayer::package_single_nalu(SrsSharedPtrMessage* msg, SrsSample* sample, SrsRtcPackets& packets) { srs_error_t err = srs_success; @@ -1409,7 +1409,7 @@ srs_error_t SrsRtcSenderThread::package_single_nalu(SrsSharedPtrMessage* msg, Sr return err; } -srs_error_t SrsRtcSenderThread::package_stap_a(SrsSource* source, SrsSharedPtrMessage* msg, SrsRtcPackets& packets) +srs_error_t SrsRtcPlayer::package_stap_a(SrsSource* source, SrsSharedPtrMessage* msg, SrsRtcPackets& packets) { srs_error_t err = srs_success; @@ -1937,7 +1937,7 @@ srs_error_t SrsRtcPublisher::collect_audio_frames() srs_error_t err = srs_success; std::vector > frames; - audio_queue_->collect_frames(frames); + audio_queue_->collect_frames(audio_nack_, frames); for (size_t i = 0; i < frames.size(); ++i) { vector& packets = frames[i]; @@ -2031,7 +2031,7 @@ srs_error_t SrsRtcPublisher::on_video(SrsRtpPacket2* pkt) srs_error_t SrsRtcPublisher::collect_video_frames() { std::vector > frames; - video_queue_->collect_frames(frames); + video_queue_->collect_frames(video_nack_, frames); for (size_t i = 0; i < frames.size(); ++i) { vector& packets = frames[i]; @@ -2252,7 +2252,7 @@ SrsRtcSession::SrsRtcSession(SrsRtcServer* s) source_ = NULL; publisher = NULL; - sender = NULL; + player = NULL; sendonly_skt = NULL; rtc_server = s; dtls_session = new SrsDtlsSession(this); @@ -2268,7 +2268,7 @@ SrsRtcSession::SrsRtcSession(SrsRtcServer* s) SrsRtcSession::~SrsRtcSession() { - srs_freep(sender); + srs_freep(player); srs_freep(publisher); srs_freep(dtls_session); srs_freep(req); @@ -2551,8 +2551,8 @@ srs_error_t SrsRtcSession::start_play() { srs_error_t err = srs_success; - srs_freep(sender); - sender = new SrsRtcSenderThread(this, _srs_context->get_id()); + srs_freep(player); + player = new SrsRtcPlayer(this, _srs_context->get_id()); uint32_t video_ssrc = 0; uint32_t audio_ssrc = 0; @@ -2569,12 +2569,12 @@ srs_error_t SrsRtcSession::start_play() } } - if ((err = sender->initialize(video_ssrc, audio_ssrc, video_payload_type, audio_payload_type)) != srs_success) { - return srs_error_wrap(err, "SrsRtcSenderThread init"); + if ((err = player->initialize(video_ssrc, audio_ssrc, video_payload_type, audio_payload_type)) != srs_success) { + return srs_error_wrap(err, "SrsRtcPlayer init"); } - if ((err = sender->start()) != srs_success) { - return srs_error_wrap(err, "start SrsRtcSenderThread"); + if ((err = player->start()) != srs_success) { + return srs_error_wrap(err, "start SrsRtcPlayer"); } return err; diff --git a/trunk/src/app/srs_app_rtc_conn.hpp b/trunk/src/app/srs_app_rtc_conn.hpp index 35c01b3a6..5522c986f 100644 --- a/trunk/src/app/srs_app_rtc_conn.hpp +++ b/trunk/src/app/srs_app_rtc_conn.hpp @@ -194,8 +194,7 @@ public: SrsRtpPacket2* at(int index); }; -// TODO: FIXME: Rename to RTC player or subscriber. -class SrsRtcSenderThread : virtual public ISrsCoroutineHandler, virtual public ISrsReloadHandler +class SrsRtcPlayer : virtual public ISrsCoroutineHandler, virtual public ISrsReloadHandler { protected: SrsCoroutine* trd; @@ -221,8 +220,8 @@ private: int mw_msgs; bool realtime; public: - SrsRtcSenderThread(SrsRtcSession* s, int parent_cid); - virtual ~SrsRtcSenderThread(); + SrsRtcPlayer(SrsRtcSession* s, int parent_cid); + virtual ~SrsRtcPlayer(); public: srs_error_t initialize(const uint32_t& vssrc, const uint32_t& assrc, const uint16_t& v_pt, const uint16_t& a_pt); // interface ISrsReloadHandler @@ -303,13 +302,13 @@ public: class SrsRtcSession { friend class SrsDtlsSession; - friend class SrsRtcSenderThread; + friend class SrsRtcPlayer; friend class SrsRtcPublisher; private: SrsRtcServer* rtc_server; SrsRtcSessionStateType session_state; SrsDtlsSession* dtls_session; - SrsRtcSenderThread* sender; + SrsRtcPlayer* player; SrsRtcPublisher* publisher; bool is_publisher_; private: diff --git a/trunk/src/app/srs_app_rtp_queue.cpp b/trunk/src/app/srs_app_rtp_queue.cpp index b685cebce..a3831949f 100644 --- a/trunk/src/app/srs_app_rtp_queue.cpp +++ b/trunk/src/app/srs_app_rtp_queue.cpp @@ -187,11 +187,6 @@ bool SrsRtpRingBuffer::overflow() return high_ - low_ >= capacity_; } -bool SrsRtpRingBuffer::is_heavy() -{ - return high_ - low_ >= capacity_ / 2; -} - uint16_t SrsRtpRingBuffer::next_start_of_frame() { if (low_ == high_) { @@ -269,7 +264,7 @@ SrsRtpPacket2* SrsRtpRingBuffer::at(uint16_t seq) return queue_[seq % capacity_]; } -SrsRtpQueue::SrsRtpQueue(const char* tag, int capacity) +SrsRtpQueue::SrsRtpQueue(int capacity) { nn_collected_frames = 0; queue_ = new SrsRtpRingBuffer(capacity); @@ -282,8 +277,6 @@ SrsRtpQueue::SrsRtpQueue(const char* tag, int capacity) num_of_packet_received_ = 0; number_of_packet_lossed_ = 0; - - tag_ = tag; } SrsRtpQueue::~SrsRtpQueue() @@ -329,27 +322,17 @@ srs_error_t SrsRtpQueue::consume(SrsRtpNackForReceiver* nack, SrsRtpPacket2* pkt uint16_t nack_low = 0, nack_high = 0; queue_->update(seq, !nn_collected_frames, nack_low, nack_high); if (srs_rtp_seq_distance(nack_low, nack_high)) { - srs_trace("%s update nack seq=%u, startup=%d, range [%u, %u]", tag_, seq, !nn_collected_frames, nack_low, nack_high); + srs_trace("update nack seq=%u, startup=%d, range [%u, %u]", seq, !nn_collected_frames, nack_low, nack_high); insert_into_nack_list(nack, nack_low, nack_high); } } - // When packets overflow, collect frame and move head to next frame start. - if (queue_->overflow()) { - on_overflow(nack); - } - // Save packet at the position seq. queue_->set(seq, pkt); return err; } -void SrsRtpQueue::collect_frames(std::vector >& frames) -{ - frames.swap(frames_); -} - void SrsRtpQueue::notify_drop_seq(uint16_t seq) { uint16_t next = queue_->next_start_of_frame(); @@ -360,7 +343,7 @@ void SrsRtpQueue::notify_drop_seq(uint16_t seq) } // When NACK is timeout, move to the next start of frame. - srs_trace("%s nack drop seq=%u, drop range [%u, %u]", tag_, seq, queue_->low(), next + 1); + srs_trace("nack drop seq=%u, drop range [%u, %u]", seq, queue_->low(), next + 1); queue_->advance_to(next + 1); } @@ -374,7 +357,7 @@ void SrsRtpQueue::notify_nack_list_full() } // When NACK is overflow, move to the next keyframe. - srs_trace("%s nack overflow drop range [%u, %u]", tag_, queue_->low(), next + 1); + srs_trace("nack overflow drop range [%u, %u]", queue_->low(), next + 1); queue_->advance_to(next + 1); } @@ -417,7 +400,7 @@ void SrsRtpQueue::insert_into_nack_list(SrsRtpNackForReceiver* nack, uint16_t se nack->check_queue_size(); } -SrsRtpAudioQueue::SrsRtpAudioQueue(int capacity) : SrsRtpQueue("audio", capacity) +SrsRtpAudioQueue::SrsRtpAudioQueue(int capacity) : SrsRtpQueue(capacity) { } @@ -425,27 +408,21 @@ SrsRtpAudioQueue::~SrsRtpAudioQueue() { } -srs_error_t SrsRtpAudioQueue::consume(SrsRtpNackForReceiver* nack, SrsRtpPacket2* pkt) +void SrsRtpAudioQueue::collect_frames(SrsRtpNackForReceiver* nack, std::vector >& frames) { - srs_error_t err = srs_success; + collect_packet(frames, nack); - if ((err = SrsRtpQueue::consume(nack, pkt)) != srs_success) { - return srs_error_wrap(err, "audio queue"); + if (queue_->overflow()) { + on_overflow(nack); } - - // For audio, always try to collect frame, because each packet is a frame. - collect_packet(nack); - - return err; } void SrsRtpAudioQueue::on_overflow(SrsRtpNackForReceiver* nack) { - collect_packet(nack); queue_->advance_to(queue_->high()); } -void SrsRtpAudioQueue::collect_packet(SrsRtpNackForReceiver* nack) +void SrsRtpAudioQueue::collect_packet(vector >& frames, SrsRtpNackForReceiver* nack) { // When done, s point to the next available packet. uint16_t next = queue_->low(); @@ -455,7 +432,7 @@ void SrsRtpAudioQueue::collect_packet(SrsRtpNackForReceiver* nack) // Not found or in NACK, stop collecting frame. if (!pkt || nack->find(next) != NULL) { - srs_trace("%s wait for nack seq=%u", tag_, next); + srs_trace("wait for nack seq=%u", next); break; } @@ -465,19 +442,19 @@ void SrsRtpAudioQueue::collect_packet(SrsRtpNackForReceiver* nack) // Done, we got the last packet of frame. nn_collected_frames++; - frames_.push_back(frame); + frames.push_back(frame); } if (queue_->low() != next) { // Reset the range of packets to NULL in buffer. queue_->reset(queue_->low(), next); - srs_verbose("%s collect on frame, update head seq=%u t %u", tag_, queue_->low(), next); + srs_verbose("collect on frame, update head seq=%u t %u", queue_->low(), next); queue_->advance_to(next); } } -SrsRtpVideoQueue::SrsRtpVideoQueue(int capacity) : SrsRtpQueue("video", capacity) +SrsRtpVideoQueue::SrsRtpVideoQueue(int capacity) : SrsRtpQueue(capacity) { request_key_frame_ = false; } @@ -486,23 +463,13 @@ SrsRtpVideoQueue::~SrsRtpVideoQueue() { } -srs_error_t SrsRtpVideoQueue::consume(SrsRtpNackForReceiver* nack, SrsRtpPacket2* pkt) +void SrsRtpVideoQueue::collect_frames(SrsRtpNackForReceiver* nack, std::vector >& frames) { - srs_error_t err = srs_success; + collect_packet(frames, nack); - if ((err = SrsRtpQueue::consume(nack, pkt)) != srs_success) { - return srs_error_wrap(err, "video queue"); + if (queue_->overflow()) { + on_overflow(nack); } - - // Collect packets to frame when: - // 1. Marker bit means the last packet of frame received. - // 2. Queue has lots of packets, the load is heavy. - // TODO: FIMXE: For real-time, we should collect each frame ASAP. - if (pkt->rtp_header.get_marker() || queue_->is_heavy()) { - collect_packet(nack); - } - - return err; } bool SrsRtpVideoQueue::should_request_key_frame() @@ -522,26 +489,24 @@ void SrsRtpVideoQueue::request_keyframe() void SrsRtpVideoQueue::on_overflow(SrsRtpNackForReceiver* nack) { - collect_packet(nack); - uint16_t next = queue_->next_start_of_frame(); // Note that low_ mean not found, clear queue util one packet. if (next == queue_->low()) { next = queue_->high() - 1; } - srs_trace("%s seq out of range [%u, %u]", tag_, queue_->low(), next); + srs_trace("seq out of range [%u, %u]", queue_->low(), next); for (uint16_t s = queue_->low(); s != next; ++s) { nack->remove(s); queue_->remove(s); } - srs_trace("%s force update seq %u to %u", tag_, queue_->low(), next + 1); + srs_trace("force update seq %u to %u", queue_->low(), next + 1); queue_->advance_to(next + 1); } -void SrsRtpVideoQueue::collect_packet(SrsRtpNackForReceiver* nack) +void SrsRtpVideoQueue::collect_packet(vector >& frames, SrsRtpNackForReceiver* nack) { while (queue_->low() != queue_->high()) { vector frame; @@ -553,7 +518,7 @@ void SrsRtpVideoQueue::collect_packet(SrsRtpNackForReceiver* nack) } nn_collected_frames++; - frames_.push_back(frame); + frames.push_back(frame); } } @@ -569,7 +534,7 @@ void SrsRtpVideoQueue::do_collect_packet(SrsRtpNackForReceiver* nack, vectorfind(next) != NULL) { - srs_trace("%s wait for nack seq=%u", tag_, next); + srs_trace("wait for nack seq=%u", next); break; } @@ -599,7 +564,7 @@ void SrsRtpVideoQueue::do_collect_packet(SrsRtpNackForReceiver* nack, vectorreset(queue_->low(), next); - srs_verbose("%s collect on frame, update head seq=%u t %u", tag_, queue_->low(), next); + srs_verbose("collect on frame, update head seq=%u t %u", queue_->low(), next); queue_->advance_to(next); } } diff --git a/trunk/src/app/srs_app_rtp_queue.hpp b/trunk/src/app/srs_app_rtp_queue.hpp index 07472d6de..a605df185 100644 --- a/trunk/src/app/srs_app_rtp_queue.hpp +++ b/trunk/src/app/srs_app_rtp_queue.hpp @@ -143,7 +143,6 @@ public: void reset(uint16_t low, uint16_t high); // Whether queue overflow or heavy(too many packets and need clear). bool overflow(); - bool is_heavy(); // For video, get the next start packet of frame. // @remark If not found, return the low_, which should never be the "next" one, // because it MAY or NOT current start packet of frame but never be the next. @@ -172,15 +171,11 @@ private: protected: SrsRtpRingBuffer* queue_; uint64_t nn_collected_frames; - std::vector > frames_; - const char* tag_; public: - SrsRtpQueue(const char* tag, int capacity); + SrsRtpQueue(int capacity); virtual ~SrsRtpQueue(); public: virtual srs_error_t consume(SrsRtpNackForReceiver* nack, SrsRtpPacket2* pkt); - // TODO: FIXME: Should merge FU-A to RAW, then we can return RAW payloads. - void collect_frames(std::vector >& frames); void notify_drop_seq(uint16_t seq); void notify_nack_list_full(); public: @@ -190,8 +185,6 @@ public: uint32_t get_interarrival_jitter(); private: void insert_into_nack_list(SrsRtpNackForReceiver* nack, uint16_t seq_start, uint16_t seq_end); -protected: - virtual void on_overflow(SrsRtpNackForReceiver* nack) = 0; }; class SrsRtpAudioQueue : public SrsRtpQueue @@ -200,11 +193,10 @@ public: SrsRtpAudioQueue(int capacity); virtual ~SrsRtpAudioQueue(); public: - virtual srs_error_t consume(SrsRtpNackForReceiver* nack, SrsRtpPacket2* pkt); + virtual void collect_frames(SrsRtpNackForReceiver* nack, std::vector >& frames); private: virtual void on_overflow(SrsRtpNackForReceiver* nack); -protected: - virtual void collect_packet(SrsRtpNackForReceiver* nack); + virtual void collect_packet(std::vector >& frames, SrsRtpNackForReceiver* nack); }; class SrsRtpVideoQueue : public SrsRtpQueue @@ -215,13 +207,12 @@ public: SrsRtpVideoQueue(int capacity); virtual ~SrsRtpVideoQueue(); public: - virtual srs_error_t consume(SrsRtpNackForReceiver* nack, SrsRtpPacket2* pkt); + virtual void collect_frames(SrsRtpNackForReceiver* nack, std::vector >& frames); bool should_request_key_frame(); void request_keyframe(); -protected: - virtual void on_overflow(SrsRtpNackForReceiver* nack); private: - virtual void collect_packet(SrsRtpNackForReceiver* nack); + virtual void on_overflow(SrsRtpNackForReceiver* nack); + virtual void collect_packet(std::vector >& frames, SrsRtpNackForReceiver* nack); virtual void do_collect_packet(SrsRtpNackForReceiver* nack, std::vector& frame); }; From a23f1028748f963faaa8a64d2f77d5c4776d1f15 Mon Sep 17 00:00:00 2001 From: winlin Date: Sun, 3 May 2020 13:49:53 +0800 Subject: [PATCH 11/18] Refactor RTC, rename variables. --- trunk/src/app/srs_app_http_api.cpp | 30 ++-- trunk/src/app/srs_app_http_api.hpp | 8 +- trunk/src/app/srs_app_rtc_conn.cpp | 250 ++++++++++++++--------------- trunk/src/app/srs_app_rtc_conn.hpp | 56 +++---- 4 files changed, 171 insertions(+), 173 deletions(-) diff --git a/trunk/src/app/srs_app_http_api.cpp b/trunk/src/app/srs_app_http_api.cpp index 57b67453e..6041e3ced 100644 --- a/trunk/src/app/srs_app_http_api.cpp +++ b/trunk/src/app/srs_app_http_api.cpp @@ -789,9 +789,9 @@ srs_error_t SrsGoApiStreams::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessa #ifdef SRS_RTC uint32_t SrsGoApiRtcPlay::ssrc_num = 0; -SrsGoApiRtcPlay::SrsGoApiRtcPlay(SrsRtcServer* rtc_svr) +SrsGoApiRtcPlay::SrsGoApiRtcPlay(SrsRtcServer* server) { - rtc_server = rtc_svr; + server_ = server; } SrsGoApiRtcPlay::~SrsGoApiRtcPlay() @@ -929,16 +929,15 @@ srs_error_t SrsGoApiRtcPlay::do_serve_http(ISrsHttpResponseWriter* w, ISrsHttpMe server_enabled, rtc_enabled, request.vhost.c_str()); } - // TODO: FIXME: Maybe need a better name? // TODO: FIXME: When server enabled, but vhost disabled, should report error. - SrsRtcSession* rtc_session = NULL; - if ((err = rtc_server->create_rtc_session(&request, remote_sdp, local_sdp, eip, false, &rtc_session)) != srs_success) { + SrsRtcSession* session = NULL; + if ((err = server_->create_session(&request, remote_sdp, local_sdp, eip, false, &session)) != srs_success) { return srs_error_wrap(err, "create session"); } if (encrypt.empty()) { - rtc_session->set_encrypt(_srs_config->get_rtc_server_encrypt()); + session->set_encrypt(_srs_config->get_rtc_server_encrypt()); } else { - rtc_session->set_encrypt(encrypt != "false"); + session->set_encrypt(encrypt != "false"); } ostringstream os; @@ -956,9 +955,9 @@ srs_error_t SrsGoApiRtcPlay::do_serve_http(ISrsHttpResponseWriter* w, ISrsHttpMe // TODO: add candidates in response json? res->set("sdp", SrsJsonAny::str(local_sdp_str.c_str())); - res->set("sessionid", SrsJsonAny::str(rtc_session->id().c_str())); + res->set("sessionid", SrsJsonAny::str(session->id().c_str())); - srs_trace("RTC sid=%s, offer=%dB, answer=%dB", rtc_session->id().c_str(), remote_sdp_str.length(), local_sdp_str.length()); + srs_trace("RTC sid=%s, offer=%dB, answer=%dB", session->id().c_str(), remote_sdp_str.length(), local_sdp_str.length()); return err; } @@ -1119,9 +1118,9 @@ srs_error_t SrsGoApiRtcPlay::exchange_sdp(const std::string& app, const std::str uint32_t SrsGoApiRtcPublish::ssrc_num = 0; -SrsGoApiRtcPublish::SrsGoApiRtcPublish(SrsRtcServer* rtc_svr) +SrsGoApiRtcPublish::SrsGoApiRtcPublish(SrsRtcServer* server) { - rtc_server = rtc_svr; + server_ = server; } SrsGoApiRtcPublish::~SrsGoApiRtcPublish() @@ -1254,10 +1253,9 @@ srs_error_t SrsGoApiRtcPublish::do_serve_http(ISrsHttpResponseWriter* w, ISrsHtt server_enabled, rtc_enabled, request.vhost.c_str()); } - // TODO: FIXME: Maybe need a better name? // TODO: FIXME: When server enabled, but vhost disabled, should report error. - SrsRtcSession* rtc_session = NULL; - if ((err = rtc_server->create_rtc_session(&request, remote_sdp, local_sdp, eip, true, &rtc_session)) != srs_success) { + SrsRtcSession* session = NULL; + if ((err = server_->create_session(&request, remote_sdp, local_sdp, eip, true, &session)) != srs_success) { return srs_error_wrap(err, "create session"); } @@ -1276,9 +1274,9 @@ srs_error_t SrsGoApiRtcPublish::do_serve_http(ISrsHttpResponseWriter* w, ISrsHtt // TODO: add candidates in response json? res->set("sdp", SrsJsonAny::str(local_sdp_str.c_str())); - res->set("sessionid", SrsJsonAny::str(rtc_session->id().c_str())); + res->set("sessionid", SrsJsonAny::str(session->id().c_str())); - srs_trace("RTC sid=%s, offer=%dB, answer=%dB", rtc_session->id().c_str(), remote_sdp_str.length(), local_sdp_str.length()); + srs_trace("RTC sid=%s, offer=%dB, answer=%dB", session->id().c_str(), remote_sdp_str.length(), local_sdp_str.length()); return err; } diff --git a/trunk/src/app/srs_app_http_api.hpp b/trunk/src/app/srs_app_http_api.hpp index ae1467fd1..638fbbb5d 100644 --- a/trunk/src/app/srs_app_http_api.hpp +++ b/trunk/src/app/srs_app_http_api.hpp @@ -173,9 +173,9 @@ class SrsGoApiRtcPlay : public ISrsHttpHandler public: static uint32_t ssrc_num; private: - SrsRtcServer* rtc_server; + SrsRtcServer* server_; public: - SrsGoApiRtcPlay(SrsRtcServer* rtc_svr); + SrsGoApiRtcPlay(SrsRtcServer* server); virtual ~SrsGoApiRtcPlay(); public: virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); @@ -190,9 +190,9 @@ class SrsGoApiRtcPublish : public ISrsHttpHandler public: static uint32_t ssrc_num; private: - SrsRtcServer* rtc_server; + SrsRtcServer* server_; public: - SrsGoApiRtcPublish(SrsRtcServer* rtc_svr); + SrsGoApiRtcPublish(SrsRtcServer* server); virtual ~SrsGoApiRtcPublish(); public: virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); diff --git a/trunk/src/app/srs_app_rtc_conn.cpp b/trunk/src/app/srs_app_rtc_conn.cpp index e41c4b572..df078d71e 100644 --- a/trunk/src/app/srs_app_rtc_conn.cpp +++ b/trunk/src/app/srs_app_rtc_conn.cpp @@ -161,9 +161,9 @@ SrsNtp SrsNtp::to_time_ms(uint64_t ntp) } -SrsDtlsSession::SrsDtlsSession(SrsRtcSession* s) +SrsRtcDtls::SrsRtcDtls(SrsRtcSession* s) { - rtc_session = s; + session_ = s; dtls = NULL; bio_in = NULL; @@ -178,7 +178,7 @@ SrsDtlsSession::SrsDtlsSession(SrsRtcSession* s) handshake_done = false; } -SrsDtlsSession::~SrsDtlsSession() +SrsRtcDtls::~SrsRtcDtls() { if (dtls) { // this function will free bio_in and bio_out @@ -195,7 +195,7 @@ SrsDtlsSession::~SrsDtlsSession() } } -srs_error_t SrsDtlsSession::initialize(SrsRequest* r) +srs_error_t SrsRtcDtls::initialize(SrsRequest* r) { srs_error_t err = srs_success; @@ -225,7 +225,7 @@ srs_error_t SrsDtlsSession::initialize(SrsRequest* r) return err; } -srs_error_t SrsDtlsSession::handshake() +srs_error_t SrsRtcDtls::handshake() { srs_error_t err = srs_success; @@ -257,21 +257,21 @@ srs_error_t SrsDtlsSession::handshake() } if (out_bio_len) { - if ((err = rtc_session->sendonly_skt->sendto(out_bio_data, out_bio_len, 0)) != srs_success) { + if ((err = session_->sendonly_skt->sendto(out_bio_data, out_bio_len, 0)) != srs_success) { return srs_error_wrap(err, "send dtls packet"); } } - if (rtc_session->blackhole && rtc_session->blackhole_addr && rtc_session->blackhole_stfd) { + if (session_->blackhole && session_->blackhole_addr && session_->blackhole_stfd) { // Ignore any error for black-hole. - void* p = out_bio_data; int len = out_bio_len; SrsRtcSession* s = rtc_session; + void* p = out_bio_data; int len = out_bio_len; SrsRtcSession* s = session_; srs_sendto(s->blackhole_stfd, p, len, (sockaddr*)s->blackhole_addr, sizeof(sockaddr_in), SRS_UTIME_NO_TIMEOUT); } return err; } -srs_error_t SrsDtlsSession::on_dtls(char* data, int nb_data) +srs_error_t SrsRtcDtls::on_dtls(char* data, int nb_data) { srs_error_t err = srs_success; if (BIO_reset(bio_in) != 1) { @@ -286,9 +286,9 @@ srs_error_t SrsDtlsSession::on_dtls(char* data, int nb_data) return srs_error_new(ERROR_OpenSslBIOWrite, "BIO_write"); } - if (rtc_session->blackhole && rtc_session->blackhole_addr && rtc_session->blackhole_stfd) { + if (session_->blackhole && session_->blackhole_addr && session_->blackhole_stfd) { // Ignore any error for black-hole. - void* p = data; int len = nb_data; SrsRtcSession* s = rtc_session; + void* p = data; int len = nb_data; SrsRtcSession* s = session_; srs_sendto(s->blackhole_stfd, p, len, (sockaddr*)s->blackhole_addr, sizeof(sockaddr_in), SRS_UTIME_NO_TIMEOUT); } @@ -310,20 +310,20 @@ srs_error_t SrsDtlsSession::on_dtls(char* data, int nb_data) return err; } -srs_error_t SrsDtlsSession::on_dtls_handshake_done() +srs_error_t SrsRtcDtls::on_dtls_handshake_done() { srs_error_t err = srs_success; - srs_trace("rtc session=%s, DTLS handshake done.", rtc_session->id().c_str()); + srs_trace("rtc session=%s, DTLS handshake done.", session_->id().c_str()); handshake_done = true; if ((err = srtp_initialize()) != srs_success) { return srs_error_wrap(err, "srtp init failed"); } - return rtc_session->on_connection_established(); + return session_->on_connection_established(); } -srs_error_t SrsDtlsSession::on_dtls_application_data(const char* buf, const int nb_buf) +srs_error_t SrsRtcDtls::on_dtls_application_data(const char* buf, const int nb_buf) { srs_error_t err = srs_success; @@ -332,7 +332,7 @@ srs_error_t SrsDtlsSession::on_dtls_application_data(const char* buf, const int return err; } -srs_error_t SrsDtlsSession::srtp_initialize() +srs_error_t SrsRtcDtls::srtp_initialize() { srs_error_t err = srs_success; @@ -366,7 +366,7 @@ srs_error_t SrsDtlsSession::srtp_initialize() return err; } -srs_error_t SrsDtlsSession::srtp_send_init() +srs_error_t SrsRtcDtls::srtp_send_init() { srs_error_t err = srs_success; @@ -401,7 +401,7 @@ srs_error_t SrsDtlsSession::srtp_send_init() return err; } -srs_error_t SrsDtlsSession::srtp_recv_init() +srs_error_t SrsRtcDtls::srtp_recv_init() { srs_error_t err = srs_success; @@ -433,7 +433,7 @@ srs_error_t SrsDtlsSession::srtp_recv_init() return err; } -srs_error_t SrsDtlsSession::protect_rtp(char* out_buf, const char* in_buf, int& nb_out_buf) +srs_error_t SrsRtcDtls::protect_rtp(char* out_buf, const char* in_buf, int& nb_out_buf) { srs_error_t err = srs_success; @@ -450,7 +450,7 @@ srs_error_t SrsDtlsSession::protect_rtp(char* out_buf, const char* in_buf, int& } // TODO: FIXME: Merge with protect_rtp. -srs_error_t SrsDtlsSession::protect_rtp2(void* rtp_hdr, int* len_ptr) +srs_error_t SrsRtcDtls::protect_rtp2(void* rtp_hdr, int* len_ptr) { srs_error_t err = srs_success; @@ -465,7 +465,7 @@ srs_error_t SrsDtlsSession::protect_rtp2(void* rtp_hdr, int* len_ptr) return err; } -srs_error_t SrsDtlsSession::unprotect_rtp(char* out_buf, const char* in_buf, int& nb_out_buf) +srs_error_t SrsRtcDtls::unprotect_rtp(char* out_buf, const char* in_buf, int& nb_out_buf) { srs_error_t err = srs_success; @@ -481,7 +481,7 @@ srs_error_t SrsDtlsSession::unprotect_rtp(char* out_buf, const char* in_buf, int return srs_error_new(ERROR_RTC_SRTP_UNPROTECT, "rtp unprotect failed"); } -srs_error_t SrsDtlsSession::protect_rtcp(char* out_buf, const char* in_buf, int& nb_out_buf) +srs_error_t SrsRtcDtls::protect_rtcp(char* out_buf, const char* in_buf, int& nb_out_buf) { srs_error_t err = srs_success; @@ -497,7 +497,7 @@ srs_error_t SrsDtlsSession::protect_rtcp(char* out_buf, const char* in_buf, int& return srs_error_new(ERROR_RTC_SRTP_PROTECT, "rtcp protect failed"); } -srs_error_t SrsDtlsSession::unprotect_rtcp(char* out_buf, const char* in_buf, int& nb_out_buf) +srs_error_t SrsRtcDtls::unprotect_rtcp(char* out_buf, const char* in_buf, int& nb_out_buf) { srs_error_t err = srs_success; @@ -513,7 +513,7 @@ srs_error_t SrsDtlsSession::unprotect_rtcp(char* out_buf, const char* in_buf, in return srs_error_new(ERROR_RTC_SRTP_UNPROTECT, "rtcp unprotect failed"); } -SrsRtcPackets::SrsRtcPackets(int nn_cache_max) +SrsRtcOutgoingPackets::SrsRtcOutgoingPackets(int nn_cache_max) { #if defined(SRS_DEBUG) debug_id = 0; @@ -535,13 +535,13 @@ SrsRtcPackets::SrsRtcPackets(int nn_cache_max) cache = new SrsRtpPacket2[nn_cache]; } -SrsRtcPackets::~SrsRtcPackets() +SrsRtcOutgoingPackets::~SrsRtcOutgoingPackets() { srs_freepa(cache); nn_cache = 0; } -void SrsRtcPackets::reset(bool gso, bool merge_nalus) +void SrsRtcOutgoingPackets::reset(bool gso, bool merge_nalus) { for (int i = 0; i < cursor; i++) { SrsRtpPacket2* packet = cache + i; @@ -565,7 +565,7 @@ void SrsRtcPackets::reset(bool gso, bool merge_nalus) cursor = 0; } -SrsRtpPacket2* SrsRtcPackets::fetch() +SrsRtpPacket2* SrsRtcOutgoingPackets::fetch() { if (cursor >= nn_cache) { return NULL; @@ -573,23 +573,23 @@ SrsRtpPacket2* SrsRtcPackets::fetch() return cache + (cursor++); } -SrsRtpPacket2* SrsRtcPackets::back() +SrsRtpPacket2* SrsRtcOutgoingPackets::back() { srs_assert(cursor > 0); return cache + cursor - 1; } -int SrsRtcPackets::size() +int SrsRtcOutgoingPackets::size() { return cursor; } -int SrsRtcPackets::capacity() +int SrsRtcOutgoingPackets::capacity() { return nn_cache; } -SrsRtpPacket2* SrsRtcPackets::at(int index) +SrsRtpPacket2* SrsRtcOutgoingPackets::at(int index) { srs_assert(index < cursor); return cache + index; @@ -600,7 +600,7 @@ SrsRtcPlayer::SrsRtcPlayer(SrsRtcSession* s, int parent_cid) _parent_cid = parent_cid; trd = new SrsDummyCoroutine(); - rtc_session = s; + session_ = s; gso = false; merge_nalus = false; @@ -657,7 +657,7 @@ srs_error_t SrsRtcPlayer::on_reload_rtc_server() srs_error_t SrsRtcPlayer::on_reload_vhost_play(string vhost) { - SrsRequest* req = rtc_session->req; + SrsRequest* req = session_->req; if (req->vhost != vhost) { return srs_success; @@ -711,7 +711,7 @@ srs_error_t SrsRtcPlayer::cycle() srs_error_t err = srs_success; SrsSource* source = NULL; - SrsRequest* req = rtc_session->req; + SrsRequest* req = session_->req; // TODO: FIXME: Should refactor it, directly use http server as handler. ISrsSourceHandler* handler = _srs_hybrid->srs()->instance(); @@ -742,7 +742,7 @@ srs_error_t SrsRtcPlayer::cycle() mw_msgs = _srs_config->get_mw_msgs(req->vhost, realtime, true); // We merged write more messages, so we need larger queue. - ISrsUdpSender* sender = rtc_session->sendonly_skt->sender(); + ISrsUdpSender* sender = session_->sendonly_skt->sender(); if (mw_msgs > 2) { sender->set_extra_ratio(150); } else if (mw_msgs > 0) { @@ -750,15 +750,15 @@ srs_error_t SrsRtcPlayer::cycle() } srs_trace("RTC source url=%s, source_id=[%d][%d], encrypt=%d, realtime=%d, mw_sleep=%dms, mw_msgs=%d", req->get_stream_url().c_str(), - ::getpid(), source->source_id(), rtc_session->encrypt, realtime, srsu2msi(mw_sleep), mw_msgs); + ::getpid(), source->source_id(), session_->encrypt, realtime, srsu2msi(mw_sleep), mw_msgs); SrsMessageArray msgs(SRS_PERF_MW_MSGS); - SrsRtcPackets pkts(SRS_PERF_RTC_RTP_PACKETS); + SrsRtcOutgoingPackets pkts(SRS_PERF_RTC_RTP_PACKETS); SrsPithyPrint* pprint = SrsPithyPrint::create_rtc_play(); SrsAutoFree(SrsPithyPrint, pprint); - srs_trace("rtc session=%s, start play", rtc_session->id().c_str()); + srs_trace("rtc session=%s, start play", session_->id().c_str()); bool stat_enabled = _srs_config->get_rtc_server_perf_stat(); SrsStatistic* stat = SrsStatistic::instance(); @@ -834,12 +834,12 @@ srs_error_t SrsRtcPlayer::cycle() } srs_error_t SrsRtcPlayer::send_messages( - SrsSource* source, SrsSharedPtrMessage** msgs, int nb_msgs, SrsRtcPackets& packets + SrsSource* source, SrsSharedPtrMessage** msgs, int nb_msgs, SrsRtcOutgoingPackets& packets ) { srs_error_t err = srs_success; // If DTLS is not OK, drop all messages. - if (!rtc_session->dtls_session) { + if (!session_->dtls_) { return err; } @@ -867,11 +867,11 @@ srs_error_t SrsRtcPlayer::send_messages( } srs_error_t SrsRtcPlayer::messages_to_packets( - SrsSource* source, SrsSharedPtrMessage** msgs, int nb_msgs, SrsRtcPackets& packets + SrsSource* source, SrsSharedPtrMessage** msgs, int nb_msgs, SrsRtcOutgoingPackets& packets ) { srs_error_t err = srs_success; - ISrsUdpSender* sender = rtc_session->sendonly_skt->sender(); + ISrsUdpSender* sender = session_->sendonly_skt->sender(); for (int i = 0; i < nb_msgs; i++) { SrsSharedPtrMessage* msg = msgs[i]; @@ -951,13 +951,13 @@ srs_error_t SrsRtcPlayer::messages_to_packets( return err; } -srs_error_t SrsRtcPlayer::send_packets(SrsRtcPackets& packets) +srs_error_t SrsRtcPlayer::send_packets(SrsRtcOutgoingPackets& packets) { srs_error_t err = srs_success; // Cache the encrypt flag and sender. - bool encrypt = rtc_session->encrypt; - ISrsUdpSender* sender = rtc_session->sendonly_skt->sender(); + bool encrypt = session_->encrypt; + ISrsUdpSender* sender = session_->sendonly_skt->sender(); int nn_packets = packets.size(); for (int i = 0; i < nn_packets; i++) { @@ -991,7 +991,7 @@ srs_error_t SrsRtcPlayer::send_packets(SrsRtcPackets& packets) // Whether encrypt the RTP bytes. if (encrypt) { int nn_encrypt = (int)iov->iov_len; - if ((err = rtc_session->dtls_session->protect_rtp2(iov->iov_base, &nn_encrypt)) != srs_success) { + if ((err = session_->dtls_->protect_rtp2(iov->iov_base, &nn_encrypt)) != srs_success) { return srs_error_wrap(err, "srtp protect"); } iov->iov_len = (size_t)nn_encrypt; @@ -1000,8 +1000,8 @@ srs_error_t SrsRtcPlayer::send_packets(SrsRtcPackets& packets) packets.nn_rtp_bytes += (int)iov->iov_len; // Set the address and control information. - sockaddr_in* addr = (sockaddr_in*)rtc_session->sendonly_skt->peer_addr(); - socklen_t addrlen = (socklen_t)rtc_session->sendonly_skt->peer_addrlen(); + sockaddr_in* addr = (sockaddr_in*)session_->sendonly_skt->peer_addr(); + socklen_t addrlen = (socklen_t)session_->sendonly_skt->peer_addrlen(); mhdr->msg_hdr.msg_name = (sockaddr_in*)addr; mhdr->msg_hdr.msg_namelen = (socklen_t)addrlen; @@ -1019,13 +1019,13 @@ srs_error_t SrsRtcPlayer::send_packets(SrsRtcPackets& packets) } // TODO: FIXME: We can gather and pad audios, because they have similar size. -srs_error_t SrsRtcPlayer::send_packets_gso(SrsRtcPackets& packets) +srs_error_t SrsRtcPlayer::send_packets_gso(SrsRtcOutgoingPackets& packets) { srs_error_t err = srs_success; // Cache the encrypt flag and sender. - bool encrypt = rtc_session->encrypt; - ISrsUdpSender* sender = rtc_session->sendonly_skt->sender(); + bool encrypt = session_->encrypt; + ISrsUdpSender* sender = session_->sendonly_skt->sender(); // Previous handler, if has the same size, we can use GSO. srs_mmsghdr* gso_mhdr = NULL; int gso_size = 0; int gso_encrypt = 0; int gso_cursor = 0; @@ -1138,7 +1138,7 @@ srs_error_t SrsRtcPlayer::send_packets_gso(SrsRtcPackets& packets) // Whether encrypt the RTP bytes. if (encrypt) { int nn_encrypt = (int)iov->iov_len; - if ((err = rtc_session->dtls_session->protect_rtp2(iov->iov_base, &nn_encrypt)) != srs_success) { + if ((err = session_->dtls_->protect_rtp2(iov->iov_base, &nn_encrypt)) != srs_success) { return srs_error_wrap(err, "srtp protect"); } iov->iov_len = (size_t)nn_encrypt; @@ -1178,8 +1178,8 @@ srs_error_t SrsRtcPlayer::send_packets_gso(SrsRtcPackets& packets) if (do_send) { // Set the address and control information. - sockaddr_in* addr = (sockaddr_in*)rtc_session->sendonly_skt->peer_addr(); - socklen_t addrlen = (socklen_t)rtc_session->sendonly_skt->peer_addrlen(); + sockaddr_in* addr = (sockaddr_in*)session_->sendonly_skt->peer_addr(); + socklen_t addrlen = (socklen_t)session_->sendonly_skt->peer_addrlen(); mhdr->msg_hdr.msg_name = (sockaddr_in*)addr; mhdr->msg_hdr.msg_namelen = (socklen_t)addrlen; @@ -1222,7 +1222,7 @@ srs_error_t SrsRtcPlayer::send_packets_gso(SrsRtcPackets& packets) return err; } -srs_error_t SrsRtcPlayer::package_nalus(SrsSharedPtrMessage* msg, SrsRtcPackets& packets) +srs_error_t SrsRtcPlayer::package_nalus(SrsSharedPtrMessage* msg, SrsRtcOutgoingPackets& packets) { srs_error_t err = srs_success; @@ -1312,7 +1312,7 @@ srs_error_t SrsRtcPlayer::package_nalus(SrsSharedPtrMessage* msg, SrsRtcPackets& return err; } -srs_error_t SrsRtcPlayer::package_opus(SrsSample* sample, SrsRtcPackets& packets, int nn_max_payload) +srs_error_t SrsRtcPlayer::package_opus(SrsSample* sample, SrsRtcOutgoingPackets& packets, int nn_max_payload) { srs_error_t err = srs_success; @@ -1348,7 +1348,7 @@ srs_error_t SrsRtcPlayer::package_opus(SrsSample* sample, SrsRtcPackets& packets return err; } -srs_error_t SrsRtcPlayer::package_fu_a(SrsSharedPtrMessage* msg, SrsSample* sample, int fu_payload_size, SrsRtcPackets& packets) +srs_error_t SrsRtcPlayer::package_fu_a(SrsSharedPtrMessage* msg, SrsSample* sample, int fu_payload_size, SrsRtcOutgoingPackets& packets) { srs_error_t err = srs_success; @@ -1389,7 +1389,7 @@ srs_error_t SrsRtcPlayer::package_fu_a(SrsSharedPtrMessage* msg, SrsSample* samp } // Single NAL Unit Packet @see https://tools.ietf.org/html/rfc6184#section-5.6 -srs_error_t SrsRtcPlayer::package_single_nalu(SrsSharedPtrMessage* msg, SrsSample* sample, SrsRtcPackets& packets) +srs_error_t SrsRtcPlayer::package_single_nalu(SrsSharedPtrMessage* msg, SrsSample* sample, SrsRtcOutgoingPackets& packets) { srs_error_t err = srs_success; @@ -1409,7 +1409,7 @@ srs_error_t SrsRtcPlayer::package_single_nalu(SrsSharedPtrMessage* msg, SrsSampl return err; } -srs_error_t SrsRtcPlayer::package_stap_a(SrsSource* source, SrsSharedPtrMessage* msg, SrsRtcPackets& packets) +srs_error_t SrsRtcPlayer::package_stap_a(SrsSource* source, SrsSharedPtrMessage* msg, SrsRtcOutgoingPackets& packets) { srs_error_t err = srs_success; @@ -1468,7 +1468,7 @@ SrsRtcPublisher::SrsRtcPublisher(SrsRtcSession* session) { report_timer = new SrsHourGlass(this, 200 * SRS_UTIME_MILLISECONDS); - rtc_session = session; + session_ = session; video_queue_ = new SrsRtpVideoQueue(1000); video_nack_ = new SrsRtpNackForReceiver(video_queue_, 1000 * 2 / 3); audio_queue_ = new SrsRtpAudioQueue(100); @@ -1683,7 +1683,7 @@ srs_error_t SrsRtcPublisher::on_rtcp_xr(char* buf, int nb_buf) void SrsRtcPublisher::check_send_nacks(SrsRtpNackForReceiver* nack, uint32_t ssrc) { // If DTLS is not OK, drop all messages. - if (!rtc_session->dtls_session) { + if (!session_->dtls_) { return; } @@ -1713,9 +1713,9 @@ void SrsRtcPublisher::check_send_nacks(SrsRtpNackForReceiver* nack, uint32_t ssr int nb_protected_buf = stream.pos(); // FIXME: Merge nack rtcp into one packets. - if (rtc_session->dtls_session->protect_rtcp(protected_buf, stream.data(), nb_protected_buf) == srs_success) { + if (session_->dtls_->protect_rtcp(protected_buf, stream.data(), nb_protected_buf) == srs_success) { // TODO: FIXME: Check error. - rtc_session->sendonly_skt->sendto(protected_buf, nb_protected_buf, 0); + session_->sendonly_skt->sendto(protected_buf, nb_protected_buf, 0); } ++iter; @@ -1727,7 +1727,7 @@ srs_error_t SrsRtcPublisher::send_rtcp_rr(uint32_t ssrc, SrsRtpQueue* rtp_queue) srs_error_t err = srs_success; // If DTLS is not OK, drop all messages. - if (!rtc_session->dtls_session) { + if (!session_->dtls_) { return err; } @@ -1768,12 +1768,12 @@ srs_error_t SrsRtcPublisher::send_rtcp_rr(uint32_t ssrc, SrsRtpQueue* rtp_queue) char protected_buf[kRtpPacketSize]; int nb_protected_buf = stream.pos(); - if ((err = rtc_session->dtls_session->protect_rtcp(protected_buf, stream.data(), nb_protected_buf)) != srs_success) { + if ((err = session_->dtls_->protect_rtcp(protected_buf, stream.data(), nb_protected_buf)) != srs_success) { return srs_error_wrap(err, "protect rtcp rr"); } // TDOO: FIXME: Check error. - rtc_session->sendonly_skt->sendto(protected_buf, nb_protected_buf, 0); + session_->sendonly_skt->sendto(protected_buf, nb_protected_buf, 0); return err; } @@ -1782,7 +1782,7 @@ srs_error_t SrsRtcPublisher::send_rtcp_xr_rrtr(uint32_t ssrc) srs_error_t err = srs_success; // If DTLS is not OK, drop all messages. - if (!rtc_session->dtls_session) { + if (!session_->dtls_) { return err; } @@ -1828,12 +1828,12 @@ srs_error_t SrsRtcPublisher::send_rtcp_xr_rrtr(uint32_t ssrc) char protected_buf[kRtpPacketSize]; int nb_protected_buf = stream.pos(); - if ((err = rtc_session->dtls_session->protect_rtcp(protected_buf, stream.data(), nb_protected_buf)) != srs_success) { + if ((err = session_->dtls_->protect_rtcp(protected_buf, stream.data(), nb_protected_buf)) != srs_success) { return srs_error_wrap(err, "protect rtcp xr"); } // TDOO: FIXME: Check error. - rtc_session->sendonly_skt->sendto(protected_buf, nb_protected_buf, 0); + session_->sendonly_skt->sendto(protected_buf, nb_protected_buf, 0); return err; } @@ -1843,7 +1843,7 @@ srs_error_t SrsRtcPublisher::send_rtcp_fb_pli(uint32_t ssrc) srs_error_t err = srs_success; // If DTLS is not OK, drop all messages. - if (!rtc_session->dtls_session) { + if (!session_->dtls_) { return err; } @@ -1857,20 +1857,20 @@ srs_error_t SrsRtcPublisher::send_rtcp_fb_pli(uint32_t ssrc) srs_trace("RTC PLI ssrc=%u", ssrc); - if (rtc_session->blackhole && rtc_session->blackhole_addr && rtc_session->blackhole_stfd) { + if (session_->blackhole && session_->blackhole_addr && session_->blackhole_stfd) { // Ignore any error for black-hole. - void* p = stream.data(); int len = stream.pos(); SrsRtcSession* s = rtc_session; + void* p = stream.data(); int len = stream.pos(); SrsRtcSession* s = session_; srs_sendto(s->blackhole_stfd, p, len, (sockaddr*)s->blackhole_addr, sizeof(sockaddr_in), SRS_UTIME_NO_TIMEOUT); } char protected_buf[kRtpPacketSize]; int nb_protected_buf = stream.pos(); - if ((err = rtc_session->dtls_session->protect_rtcp(protected_buf, stream.data(), nb_protected_buf)) != srs_success) { + if ((err = session_->dtls_->protect_rtcp(protected_buf, stream.data(), nb_protected_buf)) != srs_success) { return srs_error_wrap(err, "protect rtcp psfb pli"); } // TDOO: FIXME: Check error. - rtc_session->sendonly_skt->sendto(protected_buf, nb_protected_buf, 0); + session_->sendonly_skt->sendto(protected_buf, nb_protected_buf, 0); return err; } @@ -2224,7 +2224,7 @@ srs_error_t SrsRtcPublisher::do_collect_video_frame(std::vector& void SrsRtcPublisher::request_keyframe() { int scid = _srs_context->get_id(); - int pcid = rtc_session->context_id(); + int pcid = session_->context_id(); srs_trace("RTC play=[%d][%d] request keyframe from publish=[%d][%d]", ::getpid(), scid, ::getpid(), pcid); video_queue_->request_keyframe(); @@ -2251,11 +2251,11 @@ SrsRtcSession::SrsRtcSession(SrsRtcServer* s) encrypt = true; source_ = NULL; - publisher = NULL; - player = NULL; + publisher_ = NULL; + player_ = NULL; sendonly_skt = NULL; - rtc_server = s; - dtls_session = new SrsDtlsSession(this); + server_ = s; + dtls_ = new SrsRtcDtls(this); session_state = INIT; last_stun_time = 0; @@ -2268,9 +2268,9 @@ SrsRtcSession::SrsRtcSession(SrsRtcServer* s) SrsRtcSession::~SrsRtcSession() { - srs_freep(player); - srs_freep(publisher); - srs_freep(dtls_session); + srs_freep(player_); + srs_freep(publisher_); + srs_freep(dtls_); srs_freep(req); srs_close_stfd(blackhole_stfd); srs_freep(blackhole_addr); @@ -2348,7 +2348,7 @@ srs_error_t SrsRtcSession::initialize(SrsSource* source, SrsRequest* r, bool is_ is_publisher_ = is_publisher; source_ = source; - if ((err = dtls_session->initialize(req)) != srs_success) { + if ((err = dtls_->initialize(req)) != srs_success) { return srs_error_wrap(err, "init"); } @@ -2415,20 +2415,20 @@ srs_error_t SrsRtcSession::on_stun(SrsUdpMuxSocket* skt, SrsStunPacket* r) srs_error_t SrsRtcSession::on_dtls(char* data, int nb_data) { - return dtls_session->on_dtls(data, nb_data); + return dtls_->on_dtls(data, nb_data); } srs_error_t SrsRtcSession::on_rtcp(char* data, int nb_data) { srs_error_t err = srs_success; - if (dtls_session == NULL) { + if (dtls_ == NULL) { return srs_error_new(ERROR_RTC_RTCP, "recv unexpect rtp packet before dtls done"); } char unprotected_buf[kRtpPacketSize]; int nb_unprotected_buf = nb_data; - if ((err = dtls_session->unprotect_rtcp(unprotected_buf, data, nb_unprotected_buf)) != srs_success) { + if ((err = dtls_->unprotect_rtcp(unprotected_buf, data, nb_unprotected_buf)) != srs_success) { return srs_error_wrap(err, "rtcp unprotect failed"); } @@ -2503,17 +2503,17 @@ srs_error_t SrsRtcSession::on_rtp(char* data, int nb_data) { srs_error_t err = srs_success; - if (publisher == NULL) { + if (publisher_ == NULL) { return srs_error_new(ERROR_RTC_RTCP, "rtc publisher null"); } - if (dtls_session == NULL) { + if (dtls_ == NULL) { return srs_error_new(ERROR_RTC_RTCP, "recv unexpect rtp packet before dtls done"); } int nb_unprotected_buf = nb_data; char* unprotected_buf = new char[kRtpPacketSize]; - if ((err = dtls_session->unprotect_rtp(unprotected_buf, data, nb_unprotected_buf)) != srs_success) { + if ((err = dtls_->unprotect_rtp(unprotected_buf, data, nb_unprotected_buf)) != srs_success) { srs_freepa(unprotected_buf); return srs_error_wrap(err, "rtp unprotect failed"); } @@ -2524,7 +2524,7 @@ srs_error_t SrsRtcSession::on_rtp(char* data, int nb_data) srs_sendto(blackhole_stfd, p, len, (sockaddr*)blackhole_addr, sizeof(sockaddr_in), SRS_UTIME_NO_TIMEOUT); } - return publisher->on_rtp(unprotected_buf, nb_unprotected_buf); + return publisher_->on_rtp(unprotected_buf, nb_unprotected_buf); } srs_error_t SrsRtcSession::on_connection_established() @@ -2551,8 +2551,8 @@ srs_error_t SrsRtcSession::start_play() { srs_error_t err = srs_success; - srs_freep(player); - player = new SrsRtcPlayer(this, _srs_context->get_id()); + srs_freep(player_); + player_ = new SrsRtcPlayer(this, _srs_context->get_id()); uint32_t video_ssrc = 0; uint32_t audio_ssrc = 0; @@ -2569,11 +2569,11 @@ srs_error_t SrsRtcSession::start_play() } } - if ((err = player->initialize(video_ssrc, audio_ssrc, video_payload_type, audio_payload_type)) != srs_success) { + if ((err = player_->initialize(video_ssrc, audio_ssrc, video_payload_type, audio_payload_type)) != srs_success) { return srs_error_wrap(err, "SrsRtcPlayer init"); } - if ((err = player->start()) != srs_success) { + if ((err = player_->start()) != srs_success) { return srs_error_wrap(err, "start SrsRtcPlayer"); } @@ -2584,10 +2584,10 @@ srs_error_t SrsRtcSession::start_publish() { srs_error_t err = srs_success; - srs_freep(publisher); - publisher = new SrsRtcPublisher(this); + srs_freep(publisher_); + publisher_ = new SrsRtcPublisher(this); // Request PLI for exists players? - //publisher->request_keyframe(); + //publisher_->request_keyframe(); uint32_t video_ssrc = 0; uint32_t audio_ssrc = 0; @@ -2605,7 +2605,7 @@ srs_error_t SrsRtcSession::start_publish() } // FIXME: err process. - if ((err = publisher->initialize(video_ssrc, audio_ssrc, req)) != srs_success) { + if ((err = publisher_->initialize(video_ssrc, audio_ssrc, req)) != srs_success) { return srs_error_wrap(err, "rtc publisher init"); } @@ -2671,7 +2671,7 @@ srs_error_t SrsRtcSession::on_binding_request(SrsStunPacket* r) set_session_state(DOING_DTLS_HANDSHAKE); peer_id = sendonly_skt->get_peer_id(); - rtc_server->insert_into_id_sessions(peer_id, this); + server_->insert_into_id_sessions(peer_id, this); set_session_state(DOING_DTLS_HANDSHAKE); srs_trace("rtc session=%s, STUN done, waitting DTLS handshake.", id().c_str()); @@ -2690,7 +2690,7 @@ srs_error_t SrsRtcSession::on_rtcp_feedback(char* buf, int nb_buf) { srs_error_t err = srs_success; - if (!dtls_session) { + if (!dtls_) { return err; } @@ -2764,7 +2764,7 @@ srs_error_t SrsRtcSession::on_rtcp_feedback(char* buf, int nb_buf) // TODO: FIXME: Check error. pkt->encode(&buf); - dtls_session->protect_rtp(protected_buf, protected_buf, nb_protected_buf); + dtls_->protect_rtp(protected_buf, protected_buf, nb_protected_buf); sendonly_skt->sendto(protected_buf, nb_protected_buf, 0); } @@ -2823,20 +2823,20 @@ srs_error_t SrsRtcSession::on_rtcp_ps_feedback(char* buf, int nb_buf) srs_error_t SrsRtcSession::on_rtcp_xr(char* buf, int nb_buf) { - if (publisher == NULL) { + if (publisher_ == NULL) { return srs_error_new(ERROR_RTC_RTCP, "rtc publisher null"); } - return publisher->on_rtcp_xr(buf, nb_buf); + return publisher_->on_rtcp_xr(buf, nb_buf); } srs_error_t SrsRtcSession::on_rtcp_sender_report(char* buf, int nb_buf) { - if (publisher == NULL) { + if (publisher_ == NULL) { return srs_error_new(ERROR_RTC_RTCP, "rtc publisher null"); } - return publisher->on_rtcp_sender_report(buf, nb_buf); + return publisher_->on_rtcp_sender_report(buf, nb_buf); } srs_error_t SrsRtcSession::on_rtcp_receiver_report(char* buf, int nb_buf) @@ -3275,12 +3275,12 @@ srs_error_t SrsRtcServer::on_udp_packet(SrsUdpMuxSocket* skt) srs_error_t err = srs_success; char* data = skt->data(); int size = skt->size(); - SrsRtcSession* rtc_session = find_rtc_session_by_peer_id(skt->get_peer_id()); + SrsRtcSession* session = find_session_by_peer_id(skt->get_peer_id()); - if (rtc_session) { + if (session) { // Now, we got the RTC session to handle the packet, switch to its context // to make all logs write to the "correct" pid+cid. - rtc_session->switch_to_context(); + session->switch_to_context(); } // For STUN, the peer address may change. @@ -3292,32 +3292,32 @@ srs_error_t SrsRtcServer::on_udp_packet(SrsUdpMuxSocket* skt) srs_verbose("recv stun packet from %s, use-candidate=%d, ice-controlled=%d, ice-controlling=%d", skt->get_peer_id().c_str(), sr.get_use_candidate(), sr.get_ice_controlled(), sr.get_ice_controlling()); - if (!rtc_session) { - rtc_session = find_rtc_session_by_username(sr.get_username()); - if (rtc_session) { - rtc_session->switch_to_context(); + if (!session) { + session = find_session_by_username(sr.get_username()); + if (session) { + session->switch_to_context(); } } - if (rtc_session == NULL) { - return srs_error_new(ERROR_RTC_STUN, "can not find rtc_session, stun username=%s, peer_id=%s", + if (session == NULL) { + return srs_error_new(ERROR_RTC_STUN, "can not find session, stun username=%s, peer_id=%s", sr.get_username().c_str(), skt->get_peer_id().c_str()); } - return rtc_session->on_stun(skt, &sr); + return session->on_stun(skt, &sr); } // For DTLS, RTCP or RTP, which does not support peer address changing. - if (rtc_session == NULL) { - return srs_error_new(ERROR_RTC_STUN, "can not find rtc_session, peer_id=%s", skt->get_peer_id().c_str()); + if (session == NULL) { + return srs_error_new(ERROR_RTC_STUN, "can not find session, peer_id=%s", skt->get_peer_id().c_str()); } if (is_dtls((uint8_t*)data, size)) { - return rtc_session->on_dtls(data, size); + return session->on_dtls(data, size); } else if (is_rtp_or_rtcp((uint8_t*)data, size)) { if (is_rtcp((uint8_t*)data, size)) { - return rtc_session->on_rtcp(data, size); + return session->on_rtcp(data, size); } - return rtc_session->on_rtp(data, size); + return session->on_rtp(data, size); } return srs_error_new(ERROR_RTC_UDP, "unknown udp packet type"); @@ -3340,7 +3340,7 @@ srs_error_t SrsRtcServer::listen_api() return err; } -srs_error_t SrsRtcServer::create_rtc_session( +srs_error_t SrsRtcServer::create_session( SrsRequest* req, const SrsSdp& remote_sdp, SrsSdp& local_sdp, const std::string& mock_eip, bool publish, SrsRtcSession** psession ) { @@ -3404,9 +3404,9 @@ srs_error_t SrsRtcServer::create_rtc_session( return err; } -bool SrsRtcServer::insert_into_id_sessions(const string& peer_id, SrsRtcSession* rtc_session) +bool SrsRtcServer::insert_into_id_sessions(const string& peer_id, SrsRtcSession* session) { - return map_id_session.insert(make_pair(peer_id, rtc_session)).second; + return map_id_session.insert(make_pair(peer_id, session)).second; } void SrsRtcServer::check_and_clean_timeout_session() @@ -3440,7 +3440,7 @@ int SrsRtcServer::nn_sessions() return (int)map_username_session.size(); } -SrsRtcSession* SrsRtcServer::find_rtc_session_by_peer_id(const string& peer_id) +SrsRtcSession* SrsRtcServer::find_session_by_peer_id(const string& peer_id) { map::iterator iter = map_id_session.find(peer_id); if (iter == map_id_session.end()) { @@ -3450,7 +3450,7 @@ SrsRtcSession* SrsRtcServer::find_rtc_session_by_peer_id(const string& peer_id) return iter->second; } -SrsRtcSession* SrsRtcServer::find_rtc_session_by_username(const std::string& username) +SrsRtcSession* SrsRtcServer::find_session_by_username(const std::string& username) { map::iterator iter = map_username_session.find(username); if (iter == map_username_session.end()) { diff --git a/trunk/src/app/srs_app_rtc_conn.hpp b/trunk/src/app/srs_app_rtc_conn.hpp index 5522c986f..9babd62e0 100644 --- a/trunk/src/app/srs_app_rtc_conn.hpp +++ b/trunk/src/app/srs_app_rtc_conn.hpp @@ -103,10 +103,10 @@ enum SrsRtcSessionStateType CLOSED = 4, }; -class SrsDtlsSession +class SrsRtcDtls { private: - SrsRtcSession* rtc_session; + SrsRtcSession* session_; SSL* dtls; BIO* bio_in; @@ -121,8 +121,8 @@ private: bool handshake_done; public: - SrsDtlsSession(SrsRtcSession* s); - virtual ~SrsDtlsSession(); + SrsRtcDtls(SrsRtcSession* s); + virtual ~SrsRtcDtls(); srs_error_t initialize(SrsRequest* r); @@ -143,8 +143,8 @@ private: srs_error_t srtp_recv_init(); }; -// A group of RTP packets. -class SrsRtcPackets +// A group of RTP packets for outgoing(send to players). +class SrsRtcOutgoingPackets { public: bool use_gso; @@ -183,8 +183,8 @@ private: int nn_cache; SrsRtpPacket2* cache; public: - SrsRtcPackets(int nn_cache_max); - virtual ~SrsRtcPackets(); + SrsRtcOutgoingPackets(int nn_cache_max); + virtual ~SrsRtcOutgoingPackets(); public: void reset(bool gso, bool merge_nalus); SrsRtpPacket2* fetch(); @@ -200,7 +200,7 @@ protected: SrsCoroutine* trd; int _parent_cid; private: - SrsRtcSession* rtc_session; + SrsRtcSession* session_; uint32_t video_ssrc; uint32_t audio_ssrc; uint16_t video_payload_type; @@ -238,17 +238,17 @@ public: public: virtual srs_error_t cycle(); private: - srs_error_t send_messages(SrsSource* source, SrsSharedPtrMessage** msgs, int nb_msgs, SrsRtcPackets& packets); - srs_error_t messages_to_packets(SrsSource* source, SrsSharedPtrMessage** msgs, int nb_msgs, SrsRtcPackets& packets); - srs_error_t send_packets(SrsRtcPackets& packets); - srs_error_t send_packets_gso(SrsRtcPackets& packets); + srs_error_t send_messages(SrsSource* source, SrsSharedPtrMessage** msgs, int nb_msgs, SrsRtcOutgoingPackets& packets); + srs_error_t messages_to_packets(SrsSource* source, SrsSharedPtrMessage** msgs, int nb_msgs, SrsRtcOutgoingPackets& packets); + srs_error_t send_packets(SrsRtcOutgoingPackets& packets); + srs_error_t send_packets_gso(SrsRtcOutgoingPackets& packets); private: - srs_error_t package_opus(SrsSample* sample, SrsRtcPackets& packets, int nn_max_payload); + srs_error_t package_opus(SrsSample* sample, SrsRtcOutgoingPackets& packets, int nn_max_payload); private: - srs_error_t package_fu_a(SrsSharedPtrMessage* msg, SrsSample* sample, int fu_payload_size, SrsRtcPackets& packets); - srs_error_t package_nalus(SrsSharedPtrMessage* msg, SrsRtcPackets& packets); - srs_error_t package_single_nalu(SrsSharedPtrMessage* msg, SrsSample* sample, SrsRtcPackets& packets); - srs_error_t package_stap_a(SrsSource* source, SrsSharedPtrMessage* msg, SrsRtcPackets& packets); + srs_error_t package_fu_a(SrsSharedPtrMessage* msg, SrsSample* sample, int fu_payload_size, SrsRtcOutgoingPackets& packets); + srs_error_t package_nalus(SrsSharedPtrMessage* msg, SrsRtcOutgoingPackets& packets); + srs_error_t package_single_nalu(SrsSharedPtrMessage* msg, SrsSample* sample, SrsRtcOutgoingPackets& packets); + srs_error_t package_stap_a(SrsSource* source, SrsSharedPtrMessage* msg, SrsRtcOutgoingPackets& packets); }; class SrsRtcPublisher : virtual public ISrsHourGlass, virtual public ISrsRtpPacketDecodeHandler @@ -256,7 +256,7 @@ class SrsRtcPublisher : virtual public ISrsHourGlass, virtual public ISrsRtpPack private: SrsHourGlass* report_timer; private: - SrsRtcSession* rtc_session; + SrsRtcSession* session_; uint32_t video_ssrc; uint32_t audio_ssrc; private: @@ -301,15 +301,15 @@ public: class SrsRtcSession { - friend class SrsDtlsSession; + friend class SrsRtcDtls; friend class SrsRtcPlayer; friend class SrsRtcPublisher; private: - SrsRtcServer* rtc_server; + SrsRtcServer* server_; SrsRtcSessionStateType session_state; - SrsDtlsSession* dtls_session; - SrsRtcPlayer* player; - SrsRtcPublisher* publisher; + SrsRtcDtls* dtls_; + SrsRtcPlayer* player_; + SrsRtcPublisher* publisher_; bool is_publisher_; private: SrsUdpMuxSocket* sendonly_skt; @@ -438,16 +438,16 @@ public: virtual srs_error_t on_udp_packet(SrsUdpMuxSocket* skt); public: virtual srs_error_t listen_api(); - srs_error_t create_rtc_session( + srs_error_t create_session( SrsRequest* req, const SrsSdp& remote_sdp, SrsSdp& local_sdp, const std::string& mock_eip, bool publish, SrsRtcSession** psession ); - bool insert_into_id_sessions(const std::string& peer_id, SrsRtcSession* rtc_session); + bool insert_into_id_sessions(const std::string& peer_id, SrsRtcSession* session); void check_and_clean_timeout_session(); int nn_sessions(); private: - SrsRtcSession* find_rtc_session_by_username(const std::string& ufrag); - SrsRtcSession* find_rtc_session_by_peer_id(const std::string& peer_id); + SrsRtcSession* find_session_by_username(const std::string& ufrag); + SrsRtcSession* find_session_by_peer_id(const std::string& peer_id); // interface ISrsHourGlass public: virtual srs_error_t notify(int type, srs_utime_t interval, srs_utime_t tick); From a812183144f412acbb99e8e5b82ae16d82fc2a0d Mon Sep 17 00:00:00 2001 From: winlin Date: Sun, 3 May 2020 14:28:51 +0800 Subject: [PATCH 12/18] Refactor the RTC sender audio queue --- trunk/research/players/rtc_publisher.html | 6 ++--- trunk/src/app/srs_app_rtc_conn.cpp | 14 +++++------- trunk/src/app/srs_app_rtp_queue.cpp | 27 ++++++----------------- trunk/src/app/srs_app_rtp_queue.hpp | 5 +---- 4 files changed, 16 insertions(+), 36 deletions(-) diff --git a/trunk/research/players/rtc_publisher.html b/trunk/research/players/rtc_publisher.html index 0035a20aa..bb33c9dec 100644 --- a/trunk/research/players/rtc_publisher.html +++ b/trunk/research/players/rtc_publisher.html @@ -72,9 +72,9 @@ var constraints = { "audio": true, "video": { - "width": { "min": "480", "max": "1920" }, - "height": { "min": "320", "max": "1080" }, - "frameRate": { "min": "15", "max": "60" } + "width": { "min": "480", "max": "720" }, + "height": { "min": "320", "max": "480" }, + "frameRate": { "min": "15", "max": "30" } } }; navigator.mediaDevices.getUserMedia( diff --git a/trunk/src/app/srs_app_rtc_conn.cpp b/trunk/src/app/srs_app_rtc_conn.cpp index df078d71e..19a8d24e1 100644 --- a/trunk/src/app/srs_app_rtc_conn.cpp +++ b/trunk/src/app/srs_app_rtc_conn.cpp @@ -1936,20 +1936,16 @@ srs_error_t SrsRtcPublisher::collect_audio_frames() { srs_error_t err = srs_success; - std::vector > frames; + std::vector frames; audio_queue_->collect_frames(audio_nack_, frames); for (size_t i = 0; i < frames.size(); ++i) { - vector& packets = frames[i]; + SrsRtpPacket2* pkt = frames[i]; - for (size_t j = 0; j < packets.size(); ++j) { - SrsRtpPacket2* pkt = packets[j]; + // TODO: FIXME: Check error. + do_collect_audio_frame(pkt); - // TODO: FIXME: Check error. - do_collect_audio_frame(pkt); - - srs_freep(pkt); - } + srs_freep(pkt); } return err; diff --git a/trunk/src/app/srs_app_rtp_queue.cpp b/trunk/src/app/srs_app_rtp_queue.cpp index a3831949f..511ff90a1 100644 --- a/trunk/src/app/srs_app_rtp_queue.cpp +++ b/trunk/src/app/srs_app_rtp_queue.cpp @@ -408,21 +408,7 @@ SrsRtpAudioQueue::~SrsRtpAudioQueue() { } -void SrsRtpAudioQueue::collect_frames(SrsRtpNackForReceiver* nack, std::vector >& frames) -{ - collect_packet(frames, nack); - - if (queue_->overflow()) { - on_overflow(nack); - } -} - -void SrsRtpAudioQueue::on_overflow(SrsRtpNackForReceiver* nack) -{ - queue_->advance_to(queue_->high()); -} - -void SrsRtpAudioQueue::collect_packet(vector >& frames, SrsRtpNackForReceiver* nack) +void SrsRtpAudioQueue::collect_frames(SrsRtpNackForReceiver* nack, vector& frames) { // When done, s point to the next available packet. uint16_t next = queue_->low(); @@ -437,12 +423,8 @@ void SrsRtpAudioQueue::collect_packet(vector >& frames, S } // OK, collect packet to frame. - vector frame; - frame.push_back(pkt); - - // Done, we got the last packet of frame. nn_collected_frames++; - frames.push_back(frame); + frames.push_back(pkt); } if (queue_->low() != next) { @@ -452,6 +434,11 @@ void SrsRtpAudioQueue::collect_packet(vector >& frames, S srs_verbose("collect on frame, update head seq=%u t %u", queue_->low(), next); queue_->advance_to(next); } + + // For audio, if overflow, clear all packets. + if (queue_->overflow()) { + queue_->advance_to(queue_->high()); + } } SrsRtpVideoQueue::SrsRtpVideoQueue(int capacity) : SrsRtpQueue(capacity) diff --git a/trunk/src/app/srs_app_rtp_queue.hpp b/trunk/src/app/srs_app_rtp_queue.hpp index a605df185..445b2c6a7 100644 --- a/trunk/src/app/srs_app_rtp_queue.hpp +++ b/trunk/src/app/srs_app_rtp_queue.hpp @@ -193,10 +193,7 @@ public: SrsRtpAudioQueue(int capacity); virtual ~SrsRtpAudioQueue(); public: - virtual void collect_frames(SrsRtpNackForReceiver* nack, std::vector >& frames); -private: - virtual void on_overflow(SrsRtpNackForReceiver* nack); - virtual void collect_packet(std::vector >& frames, SrsRtpNackForReceiver* nack); + virtual void collect_frames(SrsRtpNackForReceiver* nack, std::vector& frames); }; class SrsRtpVideoQueue : public SrsRtpQueue From 47ed16eda14698f2b02a8c1596227b540b773d7c Mon Sep 17 00:00:00 2001 From: winlin Date: Sun, 3 May 2020 17:41:00 +0800 Subject: [PATCH 13/18] Refactor RTC publisher queue, covert FU-A to RAW. --- trunk/src/app/srs_app_rtc_conn.cpp | 136 ++++----------------------- trunk/src/app/srs_app_rtc_conn.hpp | 7 +- trunk/src/app/srs_app_rtp_queue.cpp | 139 +++++++++++++++++++++++----- trunk/src/app/srs_app_rtp_queue.hpp | 7 +- 4 files changed, 139 insertions(+), 150 deletions(-) diff --git a/trunk/src/app/srs_app_rtc_conn.cpp b/trunk/src/app/srs_app_rtc_conn.cpp index 19a8d24e1..2cf983012 100644 --- a/trunk/src/app/srs_app_rtc_conn.cpp +++ b/trunk/src/app/srs_app_rtc_conn.cpp @@ -1924,18 +1924,14 @@ void SrsRtcPublisher::on_before_decode_payload(SrsRtpPacket2* pkt, SrsBuffer* bu srs_error_t SrsRtcPublisher::on_audio(SrsRtpPacket2* pkt) { + srs_error_t err = srs_success; + // TODO: FIXME: Error check. audio_queue_->consume(audio_nack_, pkt); check_send_nacks(audio_nack_, audio_ssrc); - return collect_audio_frames(); -} - -srs_error_t SrsRtcPublisher::collect_audio_frames() -{ - srs_error_t err = srs_success; - + // Collect all audio frames. std::vector frames; audio_queue_->collect_frames(audio_nack_, frames); @@ -1943,7 +1939,7 @@ srs_error_t SrsRtcPublisher::collect_audio_frames() SrsRtpPacket2* pkt = frames[i]; // TODO: FIXME: Check error. - do_collect_audio_frame(pkt); + collect_audio_frame(pkt); srs_freep(pkt); } @@ -1951,7 +1947,7 @@ srs_error_t SrsRtcPublisher::collect_audio_frames() return err; } -srs_error_t SrsRtcPublisher::do_collect_audio_frame(SrsRtpPacket2* pkt) +srs_error_t SrsRtcPublisher::collect_audio_frame(SrsRtpPacket2* pkt) { srs_error_t err = srs_success; @@ -1989,28 +1985,6 @@ srs_error_t SrsRtcPublisher::do_collect_audio_frame(SrsRtpPacket2* pkt) srs_error_t SrsRtcPublisher::on_video(SrsRtpPacket2* pkt) { - uint8_t v = (uint8_t)pkt->nalu_type; - if (v == kFuA) { - SrsRtpFUAPayload2* payload = dynamic_cast(pkt->payload); - if (!payload) { - srs_freep(pkt); - return srs_error_new(ERROR_RTC_RTP_MUXER, "FU-A payload"); - } - - pkt->video_is_first_packet = payload->start; - pkt->video_is_last_packet = payload->end; - pkt->video_is_idr = (payload->nalu_type == SrsAvcNaluTypeIDR); - } else { - pkt->video_is_first_packet = true; - pkt->video_is_last_packet = true; - - if (v == kStapA) { - pkt->video_is_idr = true; - } else { - pkt->video_is_idr = (pkt->nalu_type == SrsAvcNaluTypeIDR); - } - } - // TODO: FIXME: Error check. video_queue_->consume(video_nack_, pkt); @@ -2021,110 +1995,35 @@ srs_error_t SrsRtcPublisher::on_video(SrsRtpPacket2* pkt) check_send_nacks(video_nack_, video_ssrc); - return collect_video_frames(); -} - -srs_error_t SrsRtcPublisher::collect_video_frames() -{ - std::vector > frames; + // Collect video frames. + std::vector frames; video_queue_->collect_frames(video_nack_, frames); for (size_t i = 0; i < frames.size(); ++i) { - vector& packets = frames[i]; - if (packets.empty()) { - continue; - } + SrsRtpPacket2* pkt = frames[i]; // TODO: FIXME: Check error. - do_collect_video_frame(packets); + collect_video_frame(pkt); - for (size_t j = 0; j < packets.size(); ++j) { - SrsRtpPacket2* pkt = packets[j]; - srs_freep(pkt); - } + srs_freep(pkt); } return srs_success; } -srs_error_t SrsRtcPublisher::do_collect_video_frame(std::vector& packets) +srs_error_t SrsRtcPublisher::collect_video_frame(SrsRtpPacket2* pkt) { srs_error_t err = srs_success; - // Although a video frame may contain many packets, they share the same NALU type. - SrsRtpPacket2* head = packets.at(0); - SrsAvcNaluType nalu_type = head->nalu_type; - int64_t timestamp = head->rtp_header.get_timestamp(); + int64_t timestamp = pkt->rtp_header.get_timestamp(); - // For FU-A or STAP-A, there must be more than one packets. - if (nalu_type == (SrsAvcNaluType)kFuA) { - if (packets.size() < 2) { - return srs_error_new(ERROR_RTC_RTP_MUXER, "FU-A/STAP-A %#x %d packets", nalu_type, packets.size()); - } - } else { - // For others type, should be one packet for one frame. - if (packets.size() != 1) { - return srs_error_new(ERROR_RTC_RTP_MUXER, "NonFU-A %d packets", packets.size()); - } - } - - // For FU-A, group packets to one video frame. - if (nalu_type == (SrsAvcNaluType)kFuA) { - int nn_nalus = 0; - for (size_t i = 0; i < packets.size(); ++i) { - SrsRtpPacket2* pkt = packets[i]; - SrsRtpFUAPayload2* payload = dynamic_cast(pkt->payload); - if (!payload) { - return srs_error_new(ERROR_RTC_RTP_MUXER, "FU-A payload"); - } - nn_nalus += payload->size; - } - if (!nn_nalus) { - return err; - } - - // TODO: FIXME: Directly covert to sample for performance. - // 5 bytes FLV tag header. - // 4 bytes NALU IBMF header, define by sequence header. - // 1 byte NALU header. - nn_nalus += 1; - int nn_payload = nn_nalus + 5 + 4; - char* data = new char[nn_payload]; - SrsBuffer buf(data, nn_payload); - - SrsRtpFUAPayload2* head_payload = dynamic_cast(head->payload); - if (head_payload->nalu_type == SrsAvcNaluTypeIDR) { - buf.write_1bytes(0x17); // Keyframe. - srs_trace("RTC got IDR %d bytes", nn_nalus); - } else { - buf.write_1bytes(0x27); // Not Keyframe. - } - buf.write_1bytes(0x01); // Not Sequence header. - buf.write_3bytes(0x00); // CTS. - buf.write_4bytes(nn_nalus); - - buf.write_1bytes(head_payload->nri | head_payload->nalu_type); // NALU header. - - for (size_t i = 0; i < packets.size(); ++i) { - SrsRtpPacket2* pkt = packets[i]; - SrsRtpFUAPayload2* payload = dynamic_cast(pkt->payload); - buf.write_bytes(payload->payload, payload->size); - } - - SrsMessageHeader header; - header.message_type = RTMP_MSG_VideoMessage; - // TODO: FIXME: Maybe the tbn is not 90k. - header.timestamp = (timestamp / 90) & 0x3fffffff; - SrsCommonMessage* shared_video = new SrsCommonMessage(); - SrsAutoFree(SrsCommonMessage, shared_video); - // TODO: FIXME: Check error. - shared_video->create(&header, data, nn_payload); - return source->on_video(shared_video); + // No FU-A, because we convert it to RAW RTP packet. + if (pkt->nalu_type == (SrsAvcNaluType)kFuA) { + return srs_error_new(ERROR_RTC_RTP_MUXER, "invalid FU-A"); } // For STAP-A, it must be SPS/PPS, and only one packet. - if (nalu_type == (SrsAvcNaluType)kStapA) { - SrsRtpPacket2* pkt = head; + if (pkt->nalu_type == (SrsAvcNaluType)kStapA) { SrsRtpSTAPPayload* payload = dynamic_cast(pkt->payload); if (!payload) { return srs_error_new(ERROR_RTC_RTP_MUXER, "STAP-A payload"); @@ -2178,7 +2077,6 @@ srs_error_t SrsRtcPublisher::do_collect_video_frame(std::vector& } // For RAW NALU, should be one RAW packet. - SrsRtpPacket2* pkt = head; SrsRtpRawPayload* payload = dynamic_cast(pkt->payload); if (!payload) { return srs_error_new(ERROR_RTC_RTP_MUXER, "RAW-NALU payload"); @@ -2194,7 +2092,7 @@ srs_error_t SrsRtcPublisher::do_collect_video_frame(std::vector& char* data = new char[nn_payload]; SrsBuffer buf(data, nn_payload); - if (nalu_type == SrsAvcNaluTypeIDR) { + if (pkt->nalu_type == SrsAvcNaluTypeIDR) { buf.write_1bytes(0x17); // Keyframe. srs_trace("RTC got IDR %d bytes", nn_payload); } else { diff --git a/trunk/src/app/srs_app_rtc_conn.hpp b/trunk/src/app/srs_app_rtc_conn.hpp index 9babd62e0..2c3474b46 100644 --- a/trunk/src/app/srs_app_rtc_conn.hpp +++ b/trunk/src/app/srs_app_rtc_conn.hpp @@ -58,6 +58,7 @@ class SrsRtpVideoQueue; class SrsRtpPacket2; class ISrsCodec; class SrsRtpNackForReceiver; +class SrsRtpIncommingVideoFrame; const uint8_t kSR = 200; const uint8_t kRR = 201; @@ -287,11 +288,9 @@ public: virtual void on_before_decode_payload(SrsRtpPacket2* pkt, SrsBuffer* buf, ISrsCodec** ppayload); private: srs_error_t on_audio(SrsRtpPacket2* pkt); - srs_error_t collect_audio_frames(); - srs_error_t do_collect_audio_frame(SrsRtpPacket2* packet); + srs_error_t collect_audio_frame(SrsRtpPacket2* pkt); srs_error_t on_video(SrsRtpPacket2* pkt); - srs_error_t collect_video_frames(); - srs_error_t do_collect_video_frame(std::vector& packets); + srs_error_t collect_video_frame(SrsRtpPacket2* pkt); public: void request_keyframe(); // interface ISrsHourGlass diff --git a/trunk/src/app/srs_app_rtp_queue.cpp b/trunk/src/app/srs_app_rtp_queue.cpp index 511ff90a1..7f7070c7f 100644 --- a/trunk/src/app/srs_app_rtp_queue.cpp +++ b/trunk/src/app/srs_app_rtp_queue.cpp @@ -450,9 +450,53 @@ SrsRtpVideoQueue::~SrsRtpVideoQueue() { } -void SrsRtpVideoQueue::collect_frames(SrsRtpNackForReceiver* nack, std::vector >& frames) +srs_error_t SrsRtpVideoQueue::consume(SrsRtpNackForReceiver* nack, SrsRtpPacket2* pkt) { - collect_packet(frames, nack); + srs_error_t err = srs_success; + + uint8_t v = (uint8_t)pkt->nalu_type; + if (v == kFuA) { + SrsRtpFUAPayload2* payload = dynamic_cast(pkt->payload); + if (!payload) { + srs_freep(pkt); + return srs_error_new(ERROR_RTC_RTP_MUXER, "FU-A payload"); + } + + pkt->video_is_first_packet = payload->start; + pkt->video_is_last_packet = payload->end; + pkt->video_is_idr = (payload->nalu_type == SrsAvcNaluTypeIDR); + } else { + pkt->video_is_first_packet = true; + pkt->video_is_last_packet = true; + + if (v == kStapA) { + pkt->video_is_idr = true; + } else { + pkt->video_is_idr = (pkt->nalu_type == SrsAvcNaluTypeIDR); + } + } + + if ((err = SrsRtpQueue::consume(nack, pkt)) != srs_success) { + return srs_error_wrap(err, "video consume"); + } + + return err; +} + +void SrsRtpVideoQueue::collect_frames(SrsRtpNackForReceiver* nack, std::vector& frames) +{ + while (queue_->low() != queue_->high()) { + SrsRtpPacket2* pkt = NULL; + + collect_packet(nack, &pkt); + + if (!pkt) { + return; + } + + nn_collected_frames++; + frames.push_back(pkt); + } if (queue_->overflow()) { on_overflow(nack); @@ -493,41 +537,27 @@ void SrsRtpVideoQueue::on_overflow(SrsRtpNackForReceiver* nack) queue_->advance_to(next + 1); } -void SrsRtpVideoQueue::collect_packet(vector >& frames, SrsRtpNackForReceiver* nack) -{ - while (queue_->low() != queue_->high()) { - vector frame; - - do_collect_packet(nack, frame); - - if (frame.empty()) { - return; - } - - nn_collected_frames++; - frames.push_back(frame); - } -} - // TODO: FIXME: Should refer to the FU-A original video frame, to avoid finding for each packet. -void SrsRtpVideoQueue::do_collect_packet(SrsRtpNackForReceiver* nack, vector& frame) +void SrsRtpVideoQueue::collect_packet(SrsRtpNackForReceiver* nack, SrsRtpPacket2** ppkt) { // When done, s point to the next available packet. uint16_t next = queue_->low(); bool found = false; + vector frame; + for (; next != queue_->high(); ++next) { SrsRtpPacket2* pkt = queue_->at(next); // Not found or in NACK, stop collecting frame. if (!pkt || nack->find(next) != NULL) { srs_trace("wait for nack seq=%u", next); - break; + return; } // Ignore when the first packet not the start. if (next == queue_->low() && !pkt->video_is_first_packet) { - break; + return; } // OK, collect packet to frame. @@ -542,17 +572,78 @@ void SrsRtpVideoQueue::do_collect_packet(SrsRtpNackForReceiver* nack, vectorhigh()) { + if (cur != queue_->high()) { // Reset the range of packets to NULL in buffer. queue_->reset(queue_->low(), next); srs_verbose("collect on frame, update head seq=%u t %u", queue_->low(), next); queue_->advance_to(next); } + + // Merge packets to one packet. + covert_packet(frame, ppkt); + return; +} + +void SrsRtpVideoQueue::covert_packet(std::vector& frame, SrsRtpPacket2** ppkt) +{ + if (frame.size() == 1) { + *ppkt = frame[0]; + return; + } + + // If more than one packet in a frame, it must be FU-A. + SrsRtpPacket2* head = frame.at(0); + SrsAvcNaluType nalu_type = head->nalu_type; + + // Covert FU-A to one RAW RTP packet. + int nn_nalus = 0; + for (size_t i = 0; i < frame.size(); ++i) { + SrsRtpPacket2* pkt = frame[i]; + SrsRtpFUAPayload2* payload = dynamic_cast(pkt->payload); + if (!payload) { + nn_nalus = 0; + break; + } + nn_nalus += payload->size; + } + + // Invalid packets, ignore. + if (nalu_type != (SrsAvcNaluType)kFuA || !nn_nalus) { + for (int i = 0; i < (int)frame.size(); i++) { + SrsRtpPacket2* pkt = frame[i]; + srs_freep(pkt); + } + return; + } + + // Merge to one RAW RTP packet. + // TODO: FIXME: Should covert to multiple NALU RTP packet to avoid copying. + SrsRtpPacket2* pkt = new SrsRtpPacket2(); + pkt->rtp_header = head->rtp_header; + + SrsRtpFUAPayload2* head_payload = dynamic_cast(head->payload); + pkt->nalu_type = head_payload->nalu_type; + + SrsRtpRawPayload* payload = pkt->reuse_raw(); + payload->nn_payload = nn_nalus + 1; + payload->payload = new char[payload->nn_payload]; + + SrsBuffer buf(payload->payload, payload->nn_payload); + + buf.write_1bytes(head_payload->nri | head_payload->nalu_type); // NALU header. + + for (size_t i = 0; i < frame.size(); ++i) { + SrsRtpPacket2* pkt = frame[i]; + SrsRtpFUAPayload2* payload = dynamic_cast(pkt->payload); + buf.write_bytes(payload->payload, payload->size); + } + + *ppkt = pkt; } diff --git a/trunk/src/app/srs_app_rtp_queue.hpp b/trunk/src/app/srs_app_rtp_queue.hpp index 445b2c6a7..d5674f429 100644 --- a/trunk/src/app/srs_app_rtp_queue.hpp +++ b/trunk/src/app/srs_app_rtp_queue.hpp @@ -204,13 +204,14 @@ public: SrsRtpVideoQueue(int capacity); virtual ~SrsRtpVideoQueue(); public: - virtual void collect_frames(SrsRtpNackForReceiver* nack, std::vector >& frames); + virtual srs_error_t consume(SrsRtpNackForReceiver* nack, SrsRtpPacket2* pkt); + virtual void collect_frames(SrsRtpNackForReceiver* nack, std::vector& frame); bool should_request_key_frame(); void request_keyframe(); private: virtual void on_overflow(SrsRtpNackForReceiver* nack); - virtual void collect_packet(std::vector >& frames, SrsRtpNackForReceiver* nack); - virtual void do_collect_packet(SrsRtpNackForReceiver* nack, std::vector& frame); + virtual void collect_packet(SrsRtpNackForReceiver* nack, SrsRtpPacket2** ppkt); + virtual void covert_packet(std::vector& frame, SrsRtpPacket2** ppkt); }; #endif From 45f35e3ec8f96362251d1dbe3911bd793f224e99 Mon Sep 17 00:00:00 2001 From: winlin Date: Sun, 3 May 2020 17:43:38 +0800 Subject: [PATCH 14/18] Refactor RTC publisher, rename pkt to frame --- trunk/src/app/srs_app_rtc_conn.cpp | 32 +++++++++++++++--------------- trunk/src/app/srs_app_rtc_conn.hpp | 4 ++-- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/trunk/src/app/srs_app_rtc_conn.cpp b/trunk/src/app/srs_app_rtc_conn.cpp index 2cf983012..35ae6fef1 100644 --- a/trunk/src/app/srs_app_rtc_conn.cpp +++ b/trunk/src/app/srs_app_rtc_conn.cpp @@ -1936,22 +1936,22 @@ srs_error_t SrsRtcPublisher::on_audio(SrsRtpPacket2* pkt) audio_queue_->collect_frames(audio_nack_, frames); for (size_t i = 0; i < frames.size(); ++i) { - SrsRtpPacket2* pkt = frames[i]; + SrsRtpPacket2* frame = frames[i]; // TODO: FIXME: Check error. - collect_audio_frame(pkt); + on_audio_frame(frame); - srs_freep(pkt); + srs_freep(frame); } return err; } -srs_error_t SrsRtcPublisher::collect_audio_frame(SrsRtpPacket2* pkt) +srs_error_t SrsRtcPublisher::on_audio_frame(SrsRtpPacket2* frame) { srs_error_t err = srs_success; - SrsRtpRawPayload* payload = dynamic_cast(pkt->payload); + SrsRtpRawPayload* payload = dynamic_cast(frame->payload); if (!payload) { return srs_error_new(ERROR_RTC_RTP_MUXER, "OPUS payload"); @@ -1965,7 +1965,7 @@ srs_error_t SrsRtcPublisher::collect_audio_frame(SrsRtpPacket2* pkt) SrsMessageHeader header; header.message_type = RTMP_MSG_AudioMessage; // TODO: FIXME: Maybe the tbn is not 90k. - header.timestamp = pkt->rtp_header.get_timestamp() / 90; + header.timestamp = frame->rtp_header.get_timestamp() / 90; SrsSharedPtrMessage msg; // TODO: FIXME: Check error. @@ -2000,31 +2000,31 @@ srs_error_t SrsRtcPublisher::on_video(SrsRtpPacket2* pkt) video_queue_->collect_frames(video_nack_, frames); for (size_t i = 0; i < frames.size(); ++i) { - SrsRtpPacket2* pkt = frames[i]; + SrsRtpPacket2* frame = frames[i]; // TODO: FIXME: Check error. - collect_video_frame(pkt); + on_video_frame(frame); - srs_freep(pkt); + srs_freep(frame); } return srs_success; } -srs_error_t SrsRtcPublisher::collect_video_frame(SrsRtpPacket2* pkt) +srs_error_t SrsRtcPublisher::on_video_frame(SrsRtpPacket2* frame) { srs_error_t err = srs_success; - int64_t timestamp = pkt->rtp_header.get_timestamp(); + int64_t timestamp = frame->rtp_header.get_timestamp(); // No FU-A, because we convert it to RAW RTP packet. - if (pkt->nalu_type == (SrsAvcNaluType)kFuA) { + if (frame->nalu_type == (SrsAvcNaluType)kFuA) { return srs_error_new(ERROR_RTC_RTP_MUXER, "invalid FU-A"); } // For STAP-A, it must be SPS/PPS, and only one packet. - if (pkt->nalu_type == (SrsAvcNaluType)kStapA) { - SrsRtpSTAPPayload* payload = dynamic_cast(pkt->payload); + if (frame->nalu_type == (SrsAvcNaluType)kStapA) { + SrsRtpSTAPPayload* payload = dynamic_cast(frame->payload); if (!payload) { return srs_error_new(ERROR_RTC_RTP_MUXER, "STAP-A payload"); } @@ -2077,7 +2077,7 @@ srs_error_t SrsRtcPublisher::collect_video_frame(SrsRtpPacket2* pkt) } // For RAW NALU, should be one RAW packet. - SrsRtpRawPayload* payload = dynamic_cast(pkt->payload); + SrsRtpRawPayload* payload = dynamic_cast(frame->payload); if (!payload) { return srs_error_new(ERROR_RTC_RTP_MUXER, "RAW-NALU payload"); } @@ -2092,7 +2092,7 @@ srs_error_t SrsRtcPublisher::collect_video_frame(SrsRtpPacket2* pkt) char* data = new char[nn_payload]; SrsBuffer buf(data, nn_payload); - if (pkt->nalu_type == SrsAvcNaluTypeIDR) { + if (frame->nalu_type == SrsAvcNaluTypeIDR) { buf.write_1bytes(0x17); // Keyframe. srs_trace("RTC got IDR %d bytes", nn_payload); } else { diff --git a/trunk/src/app/srs_app_rtc_conn.hpp b/trunk/src/app/srs_app_rtc_conn.hpp index 2c3474b46..ae83274ac 100644 --- a/trunk/src/app/srs_app_rtc_conn.hpp +++ b/trunk/src/app/srs_app_rtc_conn.hpp @@ -288,9 +288,9 @@ public: virtual void on_before_decode_payload(SrsRtpPacket2* pkt, SrsBuffer* buf, ISrsCodec** ppayload); private: srs_error_t on_audio(SrsRtpPacket2* pkt); - srs_error_t collect_audio_frame(SrsRtpPacket2* pkt); + srs_error_t on_audio_frame(SrsRtpPacket2* frame); srs_error_t on_video(SrsRtpPacket2* pkt); - srs_error_t collect_video_frame(SrsRtpPacket2* pkt); + srs_error_t on_video_frame(SrsRtpPacket2* frame); public: void request_keyframe(); // interface ISrsHourGlass From 2dc8e8dca1c2c44d7f68dadccd4a3f2f064f7d56 Mon Sep 17 00:00:00 2001 From: winlin Date: Sun, 3 May 2020 17:57:07 +0800 Subject: [PATCH 15/18] Refactor RTC publish ring buffer --- trunk/src/app/srs_app_rtp_queue.cpp | 134 +++++++++++++++------------- trunk/src/app/srs_app_rtp_queue.hpp | 22 +++-- 2 files changed, 86 insertions(+), 70 deletions(-) diff --git a/trunk/src/app/srs_app_rtp_queue.cpp b/trunk/src/app/srs_app_rtp_queue.cpp index 7f7070c7f..b0b015128 100644 --- a/trunk/src/app/srs_app_rtp_queue.cpp +++ b/trunk/src/app/srs_app_rtp_queue.cpp @@ -187,38 +187,6 @@ bool SrsRtpRingBuffer::overflow() return high_ - low_ >= capacity_; } -uint16_t SrsRtpRingBuffer::next_start_of_frame() -{ - if (low_ == high_) { - return low_; - } - - for (uint16_t s = low_ + 1 ; s != high_; ++s) { - SrsRtpPacket2*& pkt = queue_[s % capacity_]; - if (pkt && pkt->video_is_first_packet) { - return s; - } - } - - return low_; -} - -uint16_t SrsRtpRingBuffer::next_keyframe() -{ - if (low_ == high_) { - return low_; - } - - for (uint16_t s = low_ + 1 ; s != high_; ++s) { - SrsRtpPacket2*& pkt = queue_[s % capacity_]; - if (pkt && pkt->video_is_idr && pkt->video_is_first_packet) { - return s; - } - } - - return low_; -} - uint32_t SrsRtpRingBuffer::get_extended_highest_sequence() { return nn_seq_flip_backs * 65536 + high_; @@ -333,34 +301,6 @@ srs_error_t SrsRtpQueue::consume(SrsRtpNackForReceiver* nack, SrsRtpPacket2* pkt return err; } -void SrsRtpQueue::notify_drop_seq(uint16_t seq) -{ - uint16_t next = queue_->next_start_of_frame(); - - // Note that low_ mean not found, clear queue util one packet. - if (next == queue_->low()) { - next = queue_->high() - 1; - } - - // When NACK is timeout, move to the next start of frame. - srs_trace("nack drop seq=%u, drop range [%u, %u]", seq, queue_->low(), next + 1); - queue_->advance_to(next + 1); -} - -void SrsRtpQueue::notify_nack_list_full() -{ - uint16_t next = queue_->next_keyframe(); - - // Note that low_ mean not found, clear queue util one packet. - if (next == queue_->low()) { - next = queue_->high() - 1; - } - - // When NACK is overflow, move to the next keyframe. - srs_trace("nack overflow drop range [%u, %u]", queue_->low(), next + 1); - queue_->advance_to(next + 1); -} - uint32_t SrsRtpQueue::get_extended_highest_sequence() { return queue_->get_extended_highest_sequence(); @@ -408,6 +348,18 @@ SrsRtpAudioQueue::~SrsRtpAudioQueue() { } +void SrsRtpAudioQueue::notify_drop_seq(uint16_t seq) +{ + // TODO: FIXME: The seq may be greater than high. + queue_->advance_to(seq + 1); +} + +void SrsRtpAudioQueue::notify_nack_list_full() +{ + // TODO: FIXME: Maybe we should not drop all packets. + queue_->advance_to(queue_->high()); +} + void SrsRtpAudioQueue::collect_frames(SrsRtpNackForReceiver* nack, vector& frames) { // When done, s point to the next available packet. @@ -450,6 +402,34 @@ SrsRtpVideoQueue::~SrsRtpVideoQueue() { } +void SrsRtpVideoQueue::notify_drop_seq(uint16_t seq) +{ + uint16_t next = next_start_of_frame(); + + // Note that low_ mean not found, clear queue util one packet. + if (next == queue_->low()) { + next = queue_->high() - 1; + } + + // When NACK is timeout, move to the next start of frame. + srs_trace("nack drop seq=%u, drop range [%u, %u]", seq, queue_->low(), next + 1); + queue_->advance_to(next + 1); +} + +void SrsRtpVideoQueue::notify_nack_list_full() +{ + uint16_t next = next_keyframe(); + + // Note that low_ mean not found, clear queue util one packet. + if (next == queue_->low()) { + next = queue_->high() - 1; + } + + // When NACK is overflow, move to the next keyframe. + srs_trace("nack overflow drop range [%u, %u]", queue_->low(), next + 1); + queue_->advance_to(next + 1); +} + srs_error_t SrsRtpVideoQueue::consume(SrsRtpNackForReceiver* nack, SrsRtpPacket2* pkt) { srs_error_t err = srs_success; @@ -520,7 +500,7 @@ void SrsRtpVideoQueue::request_keyframe() void SrsRtpVideoQueue::on_overflow(SrsRtpNackForReceiver* nack) { - uint16_t next = queue_->next_start_of_frame(); + uint16_t next = next_start_of_frame(); // Note that low_ mean not found, clear queue util one packet. if (next == queue_->low()) { @@ -647,3 +627,35 @@ void SrsRtpVideoQueue::covert_packet(std::vector& frame, SrsRtpP *ppkt = pkt; } +uint16_t SrsRtpVideoQueue::next_start_of_frame() +{ + if (queue_->low() == queue_->high()) { + return queue_->low(); + } + + for (uint16_t s = queue_->low() + 1 ; s != queue_->high(); ++s) { + SrsRtpPacket2* pkt = queue_->at(s); + if (pkt && pkt->video_is_first_packet) { + return s; + } + } + + return queue_->low(); +} + +uint16_t SrsRtpVideoQueue::next_keyframe() +{ + if (queue_->low() == queue_->high()) { + return queue_->low(); + } + + for (uint16_t s = queue_->low() + 1 ; s != queue_->high(); ++s) { + SrsRtpPacket2* pkt = queue_->at(s); + if (pkt && pkt->video_is_idr && pkt->video_is_first_packet) { + return s; + } + } + + return queue_->low(); +} + diff --git a/trunk/src/app/srs_app_rtp_queue.hpp b/trunk/src/app/srs_app_rtp_queue.hpp index d5674f429..7ef0485e1 100644 --- a/trunk/src/app/srs_app_rtp_queue.hpp +++ b/trunk/src/app/srs_app_rtp_queue.hpp @@ -143,13 +143,6 @@ public: void reset(uint16_t low, uint16_t high); // Whether queue overflow or heavy(too many packets and need clear). bool overflow(); - // For video, get the next start packet of frame. - // @remark If not found, return the low_, which should never be the "next" one, - // because it MAY or NOT current start packet of frame but never be the next. - uint16_t next_start_of_frame(); - // For video, get the next seq of keyframe. - // @remark Return low_ if not found. - uint16_t next_keyframe(); // The highest sequence number, calculate the flip back base. uint32_t get_extended_highest_sequence(); // Update the sequence, got the nack range by [low, high]. @@ -176,8 +169,8 @@ public: virtual ~SrsRtpQueue(); public: virtual srs_error_t consume(SrsRtpNackForReceiver* nack, SrsRtpPacket2* pkt); - void notify_drop_seq(uint16_t seq); - void notify_nack_list_full(); + virtual void notify_drop_seq(uint16_t seq) = 0; + virtual void notify_nack_list_full() = 0; public: uint32_t get_extended_highest_sequence(); uint8_t get_fraction_lost(); @@ -193,6 +186,8 @@ public: SrsRtpAudioQueue(int capacity); virtual ~SrsRtpAudioQueue(); public: + virtual void notify_drop_seq(uint16_t seq); + virtual void notify_nack_list_full(); virtual void collect_frames(SrsRtpNackForReceiver* nack, std::vector& frames); }; @@ -204,6 +199,8 @@ public: SrsRtpVideoQueue(int capacity); virtual ~SrsRtpVideoQueue(); public: + virtual void notify_drop_seq(uint16_t seq); + virtual void notify_nack_list_full(); virtual srs_error_t consume(SrsRtpNackForReceiver* nack, SrsRtpPacket2* pkt); virtual void collect_frames(SrsRtpNackForReceiver* nack, std::vector& frame); bool should_request_key_frame(); @@ -212,6 +209,13 @@ private: virtual void on_overflow(SrsRtpNackForReceiver* nack); virtual void collect_packet(SrsRtpNackForReceiver* nack, SrsRtpPacket2** ppkt); virtual void covert_packet(std::vector& frame, SrsRtpPacket2** ppkt); + // For video, get the next start packet of frame. + // @remark If not found, return the low_, which should never be the "next" one, + // because it MAY or NOT current start packet of frame but never be the next. + uint16_t next_start_of_frame(); + // For video, get the next seq of keyframe. + // @remark Return low_ if not found. + uint16_t next_keyframe(); }; #endif From 128fc9d8c7bd8f84e270a0d8669075d9ac49458e Mon Sep 17 00:00:00 2001 From: winlin Date: Sun, 3 May 2020 18:07:09 +0800 Subject: [PATCH 16/18] Refactor publisher ring buffer, allow startup drop frame --- trunk/src/app/srs_app_rtp_queue.cpp | 17 +++++------------ trunk/src/app/srs_app_rtp_queue.hpp | 3 +-- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/trunk/src/app/srs_app_rtp_queue.cpp b/trunk/src/app/srs_app_rtp_queue.cpp index b0b015128..618065c1a 100644 --- a/trunk/src/app/srs_app_rtp_queue.cpp +++ b/trunk/src/app/srs_app_rtp_queue.cpp @@ -192,7 +192,7 @@ uint32_t SrsRtpRingBuffer::get_extended_highest_sequence() return nn_seq_flip_backs * 65536 + high_; } -void SrsRtpRingBuffer::update(uint16_t seq, bool startup, uint16_t& nack_low, uint16_t& nack_high) +void SrsRtpRingBuffer::update(uint16_t seq, uint16_t& nack_low, uint16_t& nack_high) { if (!initialized_) { initialized_ = true; @@ -219,11 +219,8 @@ void SrsRtpRingBuffer::update(uint16_t seq, bool startup, uint16_t& nack_low, ui // When startup, we may receive packets in chaos order. // Because we don't know the ISN(initiazlie sequence number), the first packet // we received maybe no the first packet client sent. - if (startup) { - nack_low = seq + 1; - nack_high = low_; - low_ = seq; - } + // @remark We only log a warning, because it seems ok for publisher. + srs_warn("too old seq %u, range [%u, %u]", seq, low_, high_); } } @@ -234,7 +231,6 @@ SrsRtpPacket2* SrsRtpRingBuffer::at(uint16_t seq) SrsRtpQueue::SrsRtpQueue(int capacity) { - nn_collected_frames = 0; queue_ = new SrsRtpRingBuffer(capacity); jitter_ = 0; @@ -288,9 +284,9 @@ srs_error_t SrsRtpQueue::consume(SrsRtpNackForReceiver* nack, SrsRtpPacket2* pkt if (!nack_info) { ++num_of_packet_received_; uint16_t nack_low = 0, nack_high = 0; - queue_->update(seq, !nn_collected_frames, nack_low, nack_high); + queue_->update(seq, nack_low, nack_high); if (srs_rtp_seq_distance(nack_low, nack_high)) { - srs_trace("update nack seq=%u, startup=%d, range [%u, %u]", seq, !nn_collected_frames, nack_low, nack_high); + srs_trace("update seq=%u, nack range [%u, %u]", seq, nack_low, nack_high); insert_into_nack_list(nack, nack_low, nack_high); } } @@ -374,8 +370,6 @@ void SrsRtpAudioQueue::collect_frames(SrsRtpNackForReceiver* nack, vector Date: Sun, 3 May 2020 19:09:48 +0800 Subject: [PATCH 17/18] Refine RTC publisher, no cache. 4.0.25 --- trunk/src/app/srs_app_rtp_queue.cpp | 168 +++++++++++++-------------- trunk/src/app/srs_app_rtp_queue.hpp | 46 ++++---- trunk/src/core/srs_core_version4.hpp | 2 +- 3 files changed, 103 insertions(+), 113 deletions(-) diff --git a/trunk/src/app/srs_app_rtp_queue.cpp b/trunk/src/app/srs_app_rtp_queue.cpp index 618065c1a..3702e775f 100644 --- a/trunk/src/app/srs_app_rtp_queue.cpp +++ b/trunk/src/app/srs_app_rtp_queue.cpp @@ -131,7 +131,7 @@ void SrsRtpNackForReceiver::update_rtt(int rtt) SrsRtpRingBuffer::SrsRtpRingBuffer(int capacity) { nn_seq_flip_backs = 0; - high_ = low_ = 0; + begin = end = 0; capacity_ = (uint16_t)capacity; initialized_ = false; @@ -144,19 +144,21 @@ SrsRtpRingBuffer::~SrsRtpRingBuffer() srs_freepa(queue_); } -uint16_t SrsRtpRingBuffer::low() +bool SrsRtpRingBuffer::empty() { - return low_; + return begin == end; } -uint16_t SrsRtpRingBuffer::high() +int SrsRtpRingBuffer::size() { - return high_; + int size = srs_rtp_seq_distance(begin, end); + srs_assert(size >= 0); + return size; } void SrsRtpRingBuffer::advance_to(uint16_t seq) { - low_ = seq; + begin = seq; } void SrsRtpRingBuffer::set(uint16_t at, SrsRtpPacket2* pkt) @@ -175,52 +177,54 @@ void SrsRtpRingBuffer::remove(uint16_t at) set(at, NULL); } -void SrsRtpRingBuffer::reset(uint16_t low, uint16_t high) +void SrsRtpRingBuffer::reset(uint16_t first, uint16_t last) { - for (uint16_t s = low; s != high; ++s) { + for (uint16_t s = first; s != last; ++s) { queue_[s % capacity_] = NULL; } } bool SrsRtpRingBuffer::overflow() { - return high_ - low_ >= capacity_; + return srs_rtp_seq_distance(begin, end) >= capacity_; } uint32_t SrsRtpRingBuffer::get_extended_highest_sequence() { - return nn_seq_flip_backs * 65536 + high_; + return nn_seq_flip_backs * 65536 + end - 1; } -void SrsRtpRingBuffer::update(uint16_t seq, uint16_t& nack_low, uint16_t& nack_high) +void SrsRtpRingBuffer::update(uint16_t seq, uint16_t& nack_first, uint16_t& nack_last) { if (!initialized_) { initialized_ = true; - low_ = high_ = seq; + begin = seq; + end = seq + 1; return; } // Normal sequence, seq follows high_. - if (srs_rtp_seq_distance(high_, seq)) { - nack_low = high_ + 1; - nack_high = seq; + if (srs_rtp_seq_distance(end, seq) >= 0) { + nack_first = end + 1; + nack_last = seq + 1; // When distance(seq,high_)>0 and seq0 and 1<65535. - if (seq < high_) { + // TODO: FIXME: The first flip may be dropped. + if (seq < end) { ++nn_seq_flip_backs; } - high_ = seq; + end = seq + 1; return; } // Out-of-order sequence, seq before low_. - if (srs_rtp_seq_distance(seq, low_)) { + if (srs_rtp_seq_distance(seq, begin) > 0) { // When startup, we may receive packets in chaos order. // Because we don't know the ISN(initiazlie sequence number), the first packet // we received maybe no the first packet client sent. // @remark We only log a warning, because it seems ok for publisher. - srs_warn("too old seq %u, range [%u, %u]", seq, low_, high_); + srs_warn("too old seq %u, range [%u, %u]", seq, begin, end); } } @@ -283,11 +287,11 @@ srs_error_t SrsRtpQueue::consume(SrsRtpNackForReceiver* nack, SrsRtpPacket2* pkt // OK, we got one new RTP packet, which is not in NACK. if (!nack_info) { ++num_of_packet_received_; - uint16_t nack_low = 0, nack_high = 0; - queue_->update(seq, nack_low, nack_high); - if (srs_rtp_seq_distance(nack_low, nack_high)) { - srs_trace("update seq=%u, nack range [%u, %u]", seq, nack_low, nack_high); - insert_into_nack_list(nack, nack_low, nack_high); + uint16_t nack_first = 0, nack_last = 0; + queue_->update(seq, nack_first, nack_last); + if (srs_rtp_seq_distance(nack_first, nack_last) > 0) { + srs_trace("update seq=%u, nack range [%u, %u]", seq, nack_first, nack_last); + insert_into_nack_list(nack, nack_first, nack_last); } } @@ -326,9 +330,9 @@ uint32_t SrsRtpQueue::get_interarrival_jitter() return static_cast(jitter_); } -void SrsRtpQueue::insert_into_nack_list(SrsRtpNackForReceiver* nack, uint16_t seq_start, uint16_t seq_end) +void SrsRtpQueue::insert_into_nack_list(SrsRtpNackForReceiver* nack, uint16_t first, uint16_t last) { - for (uint16_t s = seq_start; s != seq_end; ++s) { + for (uint16_t s = first; s != last; ++s) { nack->insert(s); ++number_of_packet_lossed_; } @@ -346,22 +350,26 @@ SrsRtpAudioQueue::~SrsRtpAudioQueue() void SrsRtpAudioQueue::notify_drop_seq(uint16_t seq) { - // TODO: FIXME: The seq may be greater than high. - queue_->advance_to(seq + 1); + uint16_t next = seq + 1; + if (srs_rtp_seq_distance(queue_->end, seq) > 0) { + seq = queue_->end; + } + srs_trace("nack drop seq=%u, drop range [%u, %u, %u]", seq, queue_->begin, next, queue_->end); + + queue_->advance_to(next); } void SrsRtpAudioQueue::notify_nack_list_full() { // TODO: FIXME: Maybe we should not drop all packets. - queue_->advance_to(queue_->high()); + queue_->advance_to(queue_->end); } void SrsRtpAudioQueue::collect_frames(SrsRtpNackForReceiver* nack, vector& frames) { - // When done, s point to the next available packet. - uint16_t next = queue_->low(); - - for (; next != queue_->high(); ++next) { + // When done, next point to the next available packet. + uint16_t next = queue_->begin; + for (; next != queue_->end; ++next) { SrsRtpPacket2* pkt = queue_->at(next); // Not found or in NACK, stop collecting frame. @@ -373,17 +381,17 @@ void SrsRtpAudioQueue::collect_frames(SrsRtpNackForReceiver* nack, vectorlow() != next) { + if (next != queue_->begin) { // Reset the range of packets to NULL in buffer. - queue_->reset(queue_->low(), next); + queue_->reset(queue_->begin, next); - srs_verbose("collect on frame, update head seq=%u t %u", queue_->low(), next); + srs_verbose("RTC collect audio [%u, %u, %u]", queue_->begin, next, queue_->end); queue_->advance_to(next); } // For audio, if overflow, clear all packets. if (queue_->overflow()) { - queue_->advance_to(queue_->high()); + queue_->advance_to(queue_->end); } } @@ -398,30 +406,20 @@ SrsRtpVideoQueue::~SrsRtpVideoQueue() void SrsRtpVideoQueue::notify_drop_seq(uint16_t seq) { - uint16_t next = next_start_of_frame(); + // If not found start frame, return the end, and we will clear queue. + uint16_t next = next_start_of_frame(seq); + srs_trace("nack drop seq=%u, drop range [%u, %u, %u]", seq, queue_->begin, next, queue_->end); - // Note that low_ mean not found, clear queue util one packet. - if (next == queue_->low()) { - next = queue_->high() - 1; - } - - // When NACK is timeout, move to the next start of frame. - srs_trace("nack drop seq=%u, drop range [%u, %u]", seq, queue_->low(), next + 1); - queue_->advance_to(next + 1); + queue_->advance_to(next); } void SrsRtpVideoQueue::notify_nack_list_full() { + // If not found start frame, return the end, and we will clear queue. uint16_t next = next_keyframe(); + srs_trace("nack overflow, drop range [%u, %u, %u]", queue_->begin, next, queue_->end); - // Note that low_ mean not found, clear queue util one packet. - if (next == queue_->low()) { - next = queue_->high() - 1; - } - - // When NACK is overflow, move to the next keyframe. - srs_trace("nack overflow drop range [%u, %u]", queue_->low(), next + 1); - queue_->advance_to(next + 1); + queue_->advance_to(next); } srs_error_t SrsRtpVideoQueue::consume(SrsRtpNackForReceiver* nack, SrsRtpPacket2* pkt) @@ -459,13 +457,13 @@ srs_error_t SrsRtpVideoQueue::consume(SrsRtpNackForReceiver* nack, SrsRtpPacket2 void SrsRtpVideoQueue::collect_frames(SrsRtpNackForReceiver* nack, std::vector& frames) { - while (queue_->low() != queue_->high()) { + while (true) { SrsRtpPacket2* pkt = NULL; - collect_packet(nack, &pkt); + collect_frame(nack, &pkt); if (!pkt) { - return; + break; } frames.push_back(pkt); @@ -493,33 +491,27 @@ void SrsRtpVideoQueue::request_keyframe() void SrsRtpVideoQueue::on_overflow(SrsRtpNackForReceiver* nack) { - uint16_t next = next_start_of_frame(); + // If not found start frame, return the end, and we will clear queue. + uint16_t next = next_start_of_frame(queue_->begin); + srs_trace("on overflow, remove range [%u, %u, %u]", queue_->begin, next, queue_->end); - // Note that low_ mean not found, clear queue util one packet. - if (next == queue_->low()) { - next = queue_->high() - 1; - } - srs_trace("seq out of range [%u, %u]", queue_->low(), next); - - for (uint16_t s = queue_->low(); s != next; ++s) { + for (uint16_t s = queue_->begin; s != next; ++s) { nack->remove(s); queue_->remove(s); } - srs_trace("force update seq %u to %u", queue_->low(), next + 1); - queue_->advance_to(next + 1); + queue_->advance_to(next); } // TODO: FIXME: Should refer to the FU-A original video frame, to avoid finding for each packet. -void SrsRtpVideoQueue::collect_packet(SrsRtpNackForReceiver* nack, SrsRtpPacket2** ppkt) +void SrsRtpVideoQueue::collect_frame(SrsRtpNackForReceiver* nack, SrsRtpPacket2** ppkt) { - // When done, s point to the next available packet. - uint16_t next = queue_->low(); - bool found = false; vector frame; - for (; next != queue_->high(); ++next) { + // When done, next point to the next available packet. + uint16_t next = queue_->begin; + for (; next != queue_->end; ++next) { SrsRtpPacket2* pkt = queue_->at(next); // Not found or in NACK, stop collecting frame. @@ -529,7 +521,7 @@ void SrsRtpVideoQueue::collect_packet(SrsRtpNackForReceiver* nack, SrsRtpPacket2 } // Ignore when the first packet not the start. - if (next == queue_->low() && !pkt->video_is_first_packet) { + if (next == queue_->begin && !pkt->video_is_first_packet) { return; } @@ -549,21 +541,20 @@ void SrsRtpVideoQueue::collect_packet(SrsRtpNackForReceiver* nack, SrsRtpPacket2 return; } - uint16_t cur = next - 1; - if (cur != queue_->high()) { + if (next != queue_->begin) { // Reset the range of packets to NULL in buffer. - queue_->reset(queue_->low(), next); + queue_->reset(queue_->begin, next); - srs_verbose("collect on frame, update head seq=%u t %u", queue_->low(), next); + srs_verbose("RTC collect video [%u, %u, %u]", queue_->begin, next, queue_->end); queue_->advance_to(next); } // Merge packets to one packet. - covert_packet(frame, ppkt); + covert_frame(frame, ppkt); return; } -void SrsRtpVideoQueue::covert_packet(std::vector& frame, SrsRtpPacket2** ppkt) +void SrsRtpVideoQueue::covert_frame(std::vector& frame, SrsRtpPacket2** ppkt) { if (frame.size() == 1) { *ppkt = frame[0]; @@ -620,35 +611,34 @@ void SrsRtpVideoQueue::covert_packet(std::vector& frame, SrsRtpP *ppkt = pkt; } -uint16_t SrsRtpVideoQueue::next_start_of_frame() +uint16_t SrsRtpVideoQueue::next_start_of_frame(uint16_t seq) { - if (queue_->low() == queue_->high()) { - return queue_->low(); + uint16_t s = seq; + if (srs_rtp_seq_distance(seq, queue_->begin) >= 0) { + s = queue_->begin + 1; } - for (uint16_t s = queue_->low() + 1 ; s != queue_->high(); ++s) { + for (; s != queue_->end; ++s) { SrsRtpPacket2* pkt = queue_->at(s); if (pkt && pkt->video_is_first_packet) { return s; } } - return queue_->low(); + return queue_->end; } uint16_t SrsRtpVideoQueue::next_keyframe() { - if (queue_->low() == queue_->high()) { - return queue_->low(); - } + uint16_t s = queue_->begin + 1; - for (uint16_t s = queue_->low() + 1 ; s != queue_->high(); ++s) { + for (; s != queue_->end; ++s) { SrsRtpPacket2* pkt = queue_->at(s); if (pkt && pkt->video_is_idr && pkt->video_is_first_packet) { return s; } } - return queue_->low(); + return queue_->end; } diff --git a/trunk/src/app/srs_app_rtp_queue.hpp b/trunk/src/app/srs_app_rtp_queue.hpp index 60ee7a162..7b3d496e9 100644 --- a/trunk/src/app/srs_app_rtp_queue.hpp +++ b/trunk/src/app/srs_app_rtp_queue.hpp @@ -66,9 +66,9 @@ struct SrsRtpNackInfo // distance(low=3, high=65534) === (int16_t)(uint16_t)((uint16_t)3-(uint16_t)65534) === 5 // distance(low=65532, high=65534) === (int16_t)(uint16_t)((uint16_t)65532-(uint16_t)65534) === -2 // For RTP sequence, it's only uint16 and may flip back, so 3 maybe 3+0xffff. -inline bool srs_rtp_seq_distance(const uint16_t& low, const uint16_t& high) +inline int16_t srs_rtp_seq_distance(const uint16_t& low, const uint16_t& high) { - return ((int16_t)(high - low)) > 0; + return (int16_t)(high - low); } class SrsRtpNackForReceiver @@ -76,7 +76,7 @@ class SrsRtpNackForReceiver private: struct SeqComp { bool operator()(const uint16_t& low, const uint16_t& high) const { - return srs_rtp_seq_distance(low, high); + return srs_rtp_seq_distance(low, high) > 0; } }; private: @@ -124,29 +124,34 @@ private: uint64_t nn_seq_flip_backs; // Whether initialized, because we use uint16 so we can't use -1. bool initialized_; -private: - // Current position we are working at. - uint16_t low_; - uint16_t high_; +public: + // The begin iterator for ring buffer. + // For example, when got 1 elems, the begin is 0. + uint16_t begin; + // The end iterator for ring buffer. + // For example, when got 1 elems, the end is 1. + uint16_t end; public: SrsRtpRingBuffer(int capacity); virtual ~SrsRtpRingBuffer(); public: - // Move the position of buffer. - uint16_t low(); - uint16_t high(); + // Whether the ring buffer is empty. + bool empty(); + // Get the count of elems in ring buffer. + int size(); + // Move the low position of buffer to seq. void advance_to(uint16_t seq); // Free the packet at position. void set(uint16_t at, SrsRtpPacket2* pkt); void remove(uint16_t at); - // Directly reset range [low, high] to NULL. - void reset(uint16_t low, uint16_t high); + // Directly reset range [first, last) to NULL. + void reset(uint16_t first, uint16_t last); // Whether queue overflow or heavy(too many packets and need clear). bool overflow(); // The highest sequence number, calculate the flip back base. uint32_t get_extended_highest_sequence(); - // Update the sequence, got the nack range by [low, high]. - void update(uint16_t seq, uint16_t& nack_low, uint16_t& nack_high); + // Update the sequence, got the nack range by [first, last). + void update(uint16_t seq, uint16_t& nack_first, uint16_t& nack_last); // Get the packet by seq. SrsRtpPacket2* at(uint16_t seq); }; @@ -176,7 +181,7 @@ public: uint32_t get_cumulative_number_of_packets_lost(); uint32_t get_interarrival_jitter(); private: - void insert_into_nack_list(SrsRtpNackForReceiver* nack, uint16_t seq_start, uint16_t seq_end); + void insert_into_nack_list(SrsRtpNackForReceiver* nack, uint16_t first, uint16_t last); }; class SrsRtpAudioQueue : public SrsRtpQueue @@ -206,14 +211,9 @@ public: void request_keyframe(); private: virtual void on_overflow(SrsRtpNackForReceiver* nack); - virtual void collect_packet(SrsRtpNackForReceiver* nack, SrsRtpPacket2** ppkt); - virtual void covert_packet(std::vector& frame, SrsRtpPacket2** ppkt); - // For video, get the next start packet of frame. - // @remark If not found, return the low_, which should never be the "next" one, - // because it MAY or NOT current start packet of frame but never be the next. - uint16_t next_start_of_frame(); - // For video, get the next seq of keyframe. - // @remark Return low_ if not found. + virtual void collect_frame(SrsRtpNackForReceiver* nack, SrsRtpPacket2** ppkt); + virtual void covert_frame(std::vector& frame, SrsRtpPacket2** ppkt); + uint16_t next_start_of_frame(uint16_t seq); uint16_t next_keyframe(); }; diff --git a/trunk/src/core/srs_core_version4.hpp b/trunk/src/core/srs_core_version4.hpp index abaee8484..a5eb4d404 100644 --- a/trunk/src/core/srs_core_version4.hpp +++ b/trunk/src/core/srs_core_version4.hpp @@ -24,6 +24,6 @@ #ifndef SRS_CORE_VERSION4_HPP #define SRS_CORE_VERSION4_HPP -#define SRS_VERSION4_REVISION 24 +#define SRS_VERSION4_REVISION 25 #endif From 47df22df9e9b9d5e21c4ad47d6aec69c63c17276 Mon Sep 17 00:00:00 2001 From: winlin Date: Sun, 3 May 2020 20:19:45 +0800 Subject: [PATCH 18/18] Refine RTC, no trickle for ice-lite, disable algorithms right-now --- trunk/research/players/rtc_player.html | 2 +- trunk/research/players/rtc_publisher.html | 8 ++-- trunk/src/app/srs_app_http_api.cpp | 37 +++++++++++++---- trunk/src/app/srs_app_sdp.cpp | 48 ++++++++++++----------- 4 files changed, 60 insertions(+), 35 deletions(-) diff --git a/trunk/research/players/rtc_player.html b/trunk/research/players/rtc_player.html index 03d23bd13..28416fd4b 100644 --- a/trunk/research/players/rtc_player.html +++ b/trunk/research/players/rtc_player.html @@ -46,7 +46,7 @@ - +