diff --git a/trunk/conf/full.conf b/trunk/conf/full.conf index 3457350b9..fac379948 100644 --- a/trunk/conf/full.conf +++ b/trunk/conf/full.conf @@ -309,7 +309,7 @@ srt_server { ############################################################################################# # WebRTC server section ############################################################################################# -rtc { +rtc_server { # Whether enable WebRTC server. # default: off enabled on; diff --git a/trunk/conf/rtc.conf b/trunk/conf/rtc.conf index 300b81d6f..f4578cec5 100644 --- a/trunk/conf/rtc.conf +++ b/trunk/conf/rtc.conf @@ -18,7 +18,7 @@ http_api { stats { network 0; } -rtc { +rtc_server { enabled on; # Listen at udp://8000 listen 8000; @@ -32,5 +32,9 @@ rtc { } vhost __defaultVhost__ { + rtc { + enabled on; + bframe discard; + } } diff --git a/trunk/configure b/trunk/configure index ab9402506..df55f860e 100755 --- a/trunk/configure +++ b/trunk/configure @@ -256,7 +256,7 @@ if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then "srs_app_ingest" "srs_app_ffmpeg" "srs_app_utility" "srs_app_edge" "srs_app_heartbeat" "srs_app_empty" "srs_app_http_client" "srs_app_http_static" "srs_app_recv_thread" "srs_app_security" "srs_app_statistic" "srs_app_hds" - "srs_app_mpegts_udp" "srs_app_rtp" "srs_app_rtc_conn" "srs_app_dtls" "srs_app_rtsp" "srs_app_listener" "srs_app_async_call" + "srs_app_mpegts_udp" "srs_app_rtc" "srs_app_rtc_conn" "srs_app_dtls" "srs_app_rtsp" "srs_app_listener" "srs_app_async_call" "srs_app_caster_flv" "srs_app_process" "srs_app_ng_exec" "srs_app_hourglass" "srs_app_dash" "srs_app_fragment" "srs_app_dvr" "srs_app_coworkers" "srs_app_hybrid") diff --git a/trunk/src/app/srs_app_config.cpp b/trunk/src/app/srs_app_config.cpp index b79fdadd7..7ec283f5f 100644 --- a/trunk/src/app/srs_app_config.cpp +++ b/trunk/src/app/srs_app_config.cpp @@ -3486,7 +3486,7 @@ srs_error_t SrsConfig::check_normal_config() && n != "srs_log_tank" && n != "srs_log_level" && n != "srs_log_file" && n != "max_connections" && n != "daemon" && n != "heartbeat" && n != "http_api" && n != "stats" && n != "vhost" && n != "pithy_print_ms" - && n != "http_server" && n != "stream_caster" && n != "rtc" && n != "srt_server" + && n != "http_server" && n != "stream_caster" && n != "rtc_server" && n != "srt_server" && n != "utc_time" && n != "work_dir" && n != "asprocess" && n != "ff_log_level" && n != "grace_final_wait" && n != "force_grace_quit" && n != "grace_start_wait" && n != "empty_ip_ok" && n != "disable_daemon_for_docker" @@ -3673,7 +3673,7 @@ srs_error_t SrsConfig::check_normal_config() && n != "play" && n != "publish" && n != "cluster" && n != "security" && n != "http_remux" && n != "dash" && n != "http_static" && n != "hds" && n != "exec" - && n != "in_ack_size" && n != "out_ack_size") { + && n != "in_ack_size" && n != "out_ack_size" && n != "rtc") { return srs_error_new(ERROR_SYSTEM_CONFIG_INVALID, "illegal vhost.%s", n.c_str()); } // for each sub directives of vhost. @@ -3819,6 +3819,13 @@ srs_error_t SrsConfig::check_normal_config() return srs_error_new(ERROR_SYSTEM_CONFIG_INVALID, "illegal vhost.bandcheck.%s of %s", m.c_str(), vhost->arg0().c_str()); } } + } else if (n == "rtc") { + for (int j = 0; j < (int)conf->directives.size(); j++) { + string m = conf->at(j)->name; + if (m != "enabled" && m != "bframe") { + return srs_error_new(ERROR_SYSTEM_CONFIG_INVALID, "illegal vhost.bandcheck.%s of %s", m.c_str(), vhost->arg0().c_str()); + } + } } } } @@ -4266,13 +4273,13 @@ int SrsConfig::get_stream_caster_rtp_port_max(SrsConfDirective* conf) return ::atoi(conf->arg0().c_str()); } -int SrsConfig::get_rtc_enabled() +int SrsConfig::get_rtc_server_enabled() { - SrsConfDirective* conf = root->get("rtc"); - return get_rtc_enabled(conf); + SrsConfDirective* conf = root->get("rtc_server"); + return get_rtc_server_enabled(conf); } -bool SrsConfig::get_rtc_enabled(SrsConfDirective* conf) +bool SrsConfig::get_rtc_server_enabled(SrsConfDirective* conf) { static bool DEFAULT = false; @@ -4288,11 +4295,11 @@ bool SrsConfig::get_rtc_enabled(SrsConfDirective* conf) return SRS_CONF_PERFER_FALSE(conf->arg0()); } -int SrsConfig::get_rtc_listen() +int SrsConfig::get_rtc_server_listen() { static int DEFAULT = 8000; - SrsConfDirective* conf = root->get("rtc"); + SrsConfDirective* conf = root->get("rtc_server"); if (!conf) { return DEFAULT; } @@ -4305,11 +4312,11 @@ int SrsConfig::get_rtc_listen() return ::atoi(conf->arg0().c_str()); } -std::string SrsConfig::get_rtc_candidates() +std::string SrsConfig::get_rtc_server_candidates() { static string DEFAULT = "*"; - SrsConfDirective* conf = root->get("rtc"); + SrsConfDirective* conf = root->get("rtc_server"); if (!conf) { return DEFAULT; } @@ -4332,6 +4339,48 @@ std::string SrsConfig::get_rtc_candidates() return (conf->arg0().c_str()); } +SrsConfDirective* SrsConfig::get_rtc(string vhost) +{ + SrsConfDirective* conf = get_vhost(vhost); + return conf? conf->get("rtc") : NULL; +} + +bool SrsConfig::get_rtc_enabled(string vhost) +{ + static bool DEFAULT = false; + + SrsConfDirective* conf = get_rtc(vhost); + + if (!conf) { + return DEFAULT; + } + + conf = conf->get("enabled"); + if (!conf || conf->arg0().empty()) { + return DEFAULT; + } + + return SRS_CONF_PERFER_FALSE(conf->arg0()); +} + +bool SrsConfig::get_rtc_bframe_discard(string vhost) +{ + static bool DEFAULT = false; + + SrsConfDirective* conf = get_rtc(vhost); + + if (!conf) { + return DEFAULT; + } + + conf = conf->get("enabled"); + if (!conf || conf->arg0().empty()) { + return DEFAULT; + } + + return conf->arg0() == "discard"; +} + SrsConfDirective* SrsConfig::get_vhost(string vhost, bool try_default_vhost) { srs_assert(root); diff --git a/trunk/src/app/srs_app_config.hpp b/trunk/src/app/srs_app_config.hpp index 768e8368f..e50aff296 100644 --- a/trunk/src/app/srs_app_config.hpp +++ b/trunk/src/app/srs_app_config.hpp @@ -501,10 +501,14 @@ public: // rtc section public: - virtual int get_rtc_enabled(); - virtual bool get_rtc_enabled(SrsConfDirective* conf); - virtual int get_rtc_listen(); - virtual std::string get_rtc_candidates(); + virtual int 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(); + + SrsConfDirective* get_rtc(std::string vhost); + bool get_rtc_enabled(std::string vhost); + bool get_rtc_bframe_discard(std::string vhost); // vhost specified section public: diff --git a/trunk/src/app/srs_app_rtp.cpp b/trunk/src/app/srs_app_rtc.cpp similarity index 90% rename from trunk/src/app/srs_app_rtp.cpp rename to trunk/src/app/srs_app_rtc.cpp index de8932018..26351e4da 100644 --- a/trunk/src/app/srs_app_rtp.cpp +++ b/trunk/src/app/srs_app_rtc.cpp @@ -21,7 +21,7 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include +#include #include #include @@ -49,11 +49,13 @@ using namespace std; #include #include #include +#include #include SrsRtpMuxer::SrsRtpMuxer() { sequence = 0; + discard_bframe = false; } SrsRtpMuxer::~SrsRtpMuxer() @@ -99,9 +101,10 @@ srs_error_t SrsRtpMuxer::frame_to_packet(SrsSharedPtrMessage* shared_frame, SrsF } srs_verbose("nal_type=%d, slice type=%d", nal_type, slice_type); - // TODO: Use config to determine how to process B frame if (slice_type == SrsAvcSliceTypeB || slice_type == SrsAvcSliceTypeB1) { - continue; + if (discard_bframe) { + continue; + } } } @@ -179,11 +182,8 @@ srs_error_t SrsRtpMuxer::packet_fu_a(SrsSharedPtrMessage* shared_frame, SrsForma p += packet_size; nb_left -= packet_size; - srs_verbose("rtp fu-a nalu, size=%u, seq=%u, timestamp=%lu, ssrc=%u, payloadtype=%u, rtp header=%s, payload=%s", - sample->size, sequence, (shared_frame->timestamp * 90), kVideoSSRC, kH264PayloadType, - srs_string_dumps_hex(stream->data(), 12).c_str(), - srs_string_dumps_hex(stream->data() + 12, stream->pos() - 12).c_str()); - + srs_verbose("rtp fu-a nalu, size=%u, seq=%u, timestamp=%lu, ssrc=%u, payloadtype=%u", + sample->size, sequence, (shared_frame->timestamp * 90), kVideoSSRC, kH264PayloadType); SrsRtpSharedPacket* rtp_shared_pkt = new SrsRtpSharedPacket(); rtp_shared_pkt->create((shared_frame->timestamp * 90), sequence++, kVideoSSRC, kH264PayloadType, stream->data(), stream->pos()); @@ -224,11 +224,8 @@ srs_error_t SrsRtpMuxer::packet_single_nalu(SrsSharedPtrMessage* shared_frame, S stream->write_bytes(sample->bytes, sample->size); - srs_verbose("sample=%s", srs_string_dumps_hex(sample->bytes, sample->size).c_str()); - srs_verbose("rtp single nalu, size=%u, seq=%u, timestamp=%lu, ssrc=%u, payloadtype=%u, rtp header=%s, payload=%s", - sample->size, sequence, (shared_frame->timestamp * 90), kVideoSSRC, kH264PayloadType, - srs_string_dumps_hex(stream->data(), 12).c_str(), - srs_string_dumps_hex(stream->data() + 12, stream->pos() - 12).c_str()); + srs_verbose("rtp single nalu, size=%u, seq=%u, timestamp=%lu, ssrc=%u, payloadtype=%u", + sample->size, sequence, (shared_frame->timestamp * 90), kVideoSSRC, kH264PayloadType); SrsRtpSharedPacket* rtp_shared_pkt = new SrsRtpSharedPacket(); rtp_shared_pkt->create((shared_frame->timestamp * 90), sequence++, kVideoSSRC, kH264PayloadType, stream->data(), stream->pos()); @@ -275,10 +272,8 @@ srs_error_t SrsRtpMuxer::packet_stap_a(const string &sps, const string& pps, Srs stream->write_2bytes(pps.size()); stream->write_bytes((char*)pps.data(), pps.size()); - srs_verbose("rtp stap-a nalu, size=%u, seq=%u, timestamp=%lu, ssrc=%u, payloadtype=%u, rtp header=%s, payload=%s", - (sps.size() + pps.size()), sequence, (shared_frame->timestamp * 90), kVideoSSRC, kH264PayloadType, - srs_string_dumps_hex(stream->data(), 12).c_str(), - srs_string_dumps_hex(stream->data() + 12, stream->pos() - 12).c_str()); + srs_verbose("rtp stap-a nalu, size=%u, seq=%u, timestamp=%lu, ssrc=%u, payloadtype=%u", + (sps.size() + pps.size()), sequence, (shared_frame->timestamp * 90), kVideoSSRC, kH264PayloadType); SrsRtpSharedPacket* rtp_shared_pkt = new SrsRtpSharedPacket(); rtp_shared_pkt->create((shared_frame->timestamp * 90), sequence++, kVideoSSRC, kH264PayloadType, stream->data(), stream->pos()); @@ -288,7 +283,7 @@ srs_error_t SrsRtpMuxer::packet_stap_a(const string &sps, const string& pps, Srs return err; } -SrsRtp::SrsRtp() +SrsRtc::SrsRtc() { req = NULL; hub = NULL; @@ -298,12 +293,12 @@ SrsRtp::SrsRtp() last_update_time = 0; } -SrsRtp::~SrsRtp() +SrsRtc::~SrsRtc() { srs_freep(rtp_h264_muxer); } -void SrsRtp::dispose() +void SrsRtc::dispose() { if (enabled) { on_unpublish(); @@ -311,14 +306,14 @@ void SrsRtp::dispose() } // TODO: FIXME: Dead code? -srs_error_t SrsRtp::cycle() +srs_error_t SrsRtc::cycle() { srs_error_t err = srs_success; return err; } -srs_error_t SrsRtp::initialize(SrsOriginHub* h, SrsRequest* r) +srs_error_t SrsRtc::initialize(SrsOriginHub* h, SrsRequest* r) { srs_error_t err = srs_success; @@ -326,11 +321,12 @@ srs_error_t SrsRtp::initialize(SrsOriginHub* h, SrsRequest* r) req = r; rtp_h264_muxer = new SrsRtpMuxer(); + rtp_h264_muxer->discard_bframe = _srs_config->get_rtc_bframe_discard(req->vhost); return err; } -srs_error_t SrsRtp::on_publish() +srs_error_t SrsRtc::on_publish() { srs_error_t err = srs_success; @@ -341,6 +337,10 @@ srs_error_t SrsRtp::on_publish() if (enabled) { return err; } + + if (!_srs_config->get_rtc_enabled(req->vhost)) { + return err; + } // if enabled, open the muxer. enabled = true; @@ -351,7 +351,7 @@ srs_error_t SrsRtp::on_publish() return err; } -void SrsRtp::on_unpublish() +void SrsRtc::on_unpublish() { // support multiple unpublish. if (!enabled) { @@ -361,7 +361,7 @@ void SrsRtp::on_unpublish() enabled = false; } -srs_error_t SrsRtp::on_audio(SrsSharedPtrMessage* shared_audio, SrsFormat* format) +srs_error_t SrsRtc::on_audio(SrsSharedPtrMessage* shared_audio, SrsFormat* format) { srs_error_t err = srs_success; @@ -391,7 +391,7 @@ srs_error_t SrsRtp::on_audio(SrsSharedPtrMessage* shared_audio, SrsFormat* forma return err; } -srs_error_t SrsRtp::on_video(SrsSharedPtrMessage* shared_video, SrsFormat* format) +srs_error_t SrsRtc::on_video(SrsSharedPtrMessage* shared_video, SrsFormat* format) { srs_error_t err = srs_success; diff --git a/trunk/src/app/srs_app_rtp.hpp b/trunk/src/app/srs_app_rtc.hpp similarity index 93% rename from trunk/src/app/srs_app_rtp.hpp rename to trunk/src/app/srs_app_rtc.hpp index 842d82620..2a047d110 100644 --- a/trunk/src/app/srs_app_rtp.hpp +++ b/trunk/src/app/srs_app_rtc.hpp @@ -21,8 +21,8 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#ifndef SRS_APP_RTP_HPP -#define SRS_APP_RTP_HPP +#ifndef SRS_APP_RTC_HPP +#define SRS_APP_RTC_HPP #include @@ -53,12 +53,15 @@ const uint8_t kEnd = 0x40; // FIXME: ssrc can relate to source const uint32_t kVideoSSRC = 3233846889; +// TODO: Define interface class like ISrsRtpMuxer to support SrsRtpOpusMuxer and so on. class SrsRtpMuxer { private: uint16_t sequence; std::string sps; std::string pps; +public: + bool discard_bframe; public: SrsRtpMuxer(); virtual ~SrsRtpMuxer(); @@ -70,7 +73,7 @@ private: srs_error_t packet_stap_a(const std::string &sps, const std::string& pps, SrsSharedPtrMessage* shared_frame, std::vector& rtp_packet_vec); }; -class SrsRtp +class SrsRtc { private: SrsRequest* req; @@ -80,8 +83,8 @@ private: SrsRtpMuxer* rtp_h264_muxer; SrsOriginHub* hub; public: - SrsRtp(); - virtual ~SrsRtp(); + SrsRtc(); + virtual ~SrsRtc(); public: virtual void dispose(); virtual srs_error_t cycle(); diff --git a/trunk/src/app/srs_app_rtc_conn.cpp b/trunk/src/app/srs_app_rtc_conn.cpp index 6eef83fba..77de89bd6 100644 --- a/trunk/src/app/srs_app_rtc_conn.cpp +++ b/trunk/src/app/srs_app_rtc_conn.cpp @@ -46,7 +46,7 @@ using namespace std; #include #include #include -#include +#include #include #include #include @@ -101,7 +101,7 @@ std::vector SrsCandidate::get_candidate_ips() { std::vector candidate_ips; - string candidate = _srs_config->get_rtc_candidates(); + string candidate = _srs_config->get_rtc_server_candidates(); if (candidate == "*" || candidate == "0.0.0.0") { std::vector tmp = srs_get_local_ips(); for (int i = 0; i < (int)tmp.size(); ++i) { @@ -189,7 +189,7 @@ srs_error_t SrsSdp::encode(string& sdp_str) std::vector candidate_ips = SrsCandidate::get_candidate_ips(); for (int i = 0; i < (int)candidate_ips.size(); ++i) { ostringstream os; - os << "a=candidate:10 1 udp 2115783679 " << candidate_ips[i] << " " << _srs_config->get_rtc_listen() <<" typ host generation 0\\r\\n"; + os << "a=candidate:10 1 udp 2115783679 " << candidate_ips[i] << " " << _srs_config->get_rtc_server_listen() <<" typ host generation 0\\r\\n"; candidate_lines += os.str(); } @@ -1179,11 +1179,11 @@ srs_error_t SrsRtcServer::listen_udp() { srs_error_t err = srs_success; - if (!_srs_config->get_rtc_enabled()) { + if (!_srs_config->get_rtc_server_enabled()) { return err; } - int port = _srs_config->get_rtc_listen(); + int port = _srs_config->get_rtc_server_listen(); if (port <= 0) { return srs_error_new(ERROR_RTC_PORT, "invalid port=%d", port); } diff --git a/trunk/src/app/srs_app_source.cpp b/trunk/src/app/srs_app_source.cpp index bccf5aae7..2d26c9e33 100755 --- a/trunk/src/app/srs_app_source.cpp +++ b/trunk/src/app/srs_app_source.cpp @@ -33,7 +33,7 @@ using namespace std; #include #include #include -#include +#include #include #include #include @@ -875,7 +875,7 @@ SrsOriginHub::SrsOriginHub() dash = new SrsDash(); dvr = new SrsDvr(); encoder = new SrsEncoder(); - rtp = new SrsRtp(); + rtc = new SrsRtc(); #ifdef SRS_AUTO_HDS hds = new SrsHds(); #endif @@ -920,8 +920,8 @@ srs_error_t SrsOriginHub::initialize(SrsSource* s, SrsRequest* r) return srs_error_wrap(err, "format initialize"); } - if ((err = rtp->initialize(this, req)) != srs_success) { - return srs_error_wrap(err, "rtp initialize"); + if ((err = rtc->initialize(this, req)) != srs_success) { + return srs_error_wrap(err, "rtc initialize"); } if ((err = hls->initialize(this, req)) != srs_success) { @@ -1022,10 +1022,10 @@ srs_error_t SrsOriginHub::on_audio(SrsSharedPtrMessage* shared_audio) srs_flv_srates[c->sound_rate]); } - if ((err = rtp->on_audio(msg, format)) != srs_success) { - srs_warn("rtp: ignore audio error %s", srs_error_desc(err).c_str()); + if ((err = rtc->on_audio(msg, format)) != srs_success) { + srs_warn("rtc: ignore audio error %s", srs_error_desc(err).c_str()); srs_error_reset(err); - rtp->on_unpublish(); + rtc->on_unpublish(); } if ((err = hls->on_audio(msg, format)) != srs_success) { @@ -1122,11 +1122,11 @@ srs_error_t SrsOriginHub::on_video(SrsSharedPtrMessage* shared_video, bool is_se } // Parse RTMP message to RTP packets, in FU-A if too large. - if ((err = rtp->on_video(msg, format)) != srs_success) { + if ((err = rtc->on_video(msg, format)) != srs_success) { // TODO: We should support more strategies. - srs_warn("rtp: ignore video error %s", srs_error_desc(err).c_str()); + srs_warn("rtc: ignore video error %s", srs_error_desc(err).c_str()); srs_error_reset(err); - rtp->on_unpublish(); + rtc->on_unpublish(); } // TODO: FIXME: Refactor to move to rtp? @@ -1201,8 +1201,8 @@ srs_error_t SrsOriginHub::on_publish() return srs_error_wrap(err, "encoder publish"); } - if ((err = rtp->on_publish()) != srs_success) { - return srs_error_wrap(err, "rtp publish"); + if ((err = rtc->on_publish()) != srs_success) { + return srs_error_wrap(err, "rtc publish"); } if ((err = hls->on_publish()) != srs_success) { @@ -1242,7 +1242,7 @@ void SrsOriginHub::on_unpublish() destroy_forwarders(); encoder->on_unpublish(); - rtp->on_unpublish(); + rtc->on_unpublish(); hls->on_unpublish(); dash->on_unpublish(); dvr->on_unpublish(); diff --git a/trunk/src/app/srs_app_source.hpp b/trunk/src/app/srs_app_source.hpp index 083bf3e02..01005d96b 100644 --- a/trunk/src/app/srs_app_source.hpp +++ b/trunk/src/app/srs_app_source.hpp @@ -54,7 +54,7 @@ class SrsNgExec; class SrsConnection; class SrsMessageHeader; class SrsHls; -class SrsRtp; +class SrsRtc; class SrsDvr; class SrsDash; class SrsEncoder; @@ -360,8 +360,8 @@ private: private: // The format, codec information. SrsRtmpFormat* format; - // rtp handler - SrsRtp* rtp; + // rtc handler + SrsRtc* rtc; // hls handler. SrsHls* hls; // The DASH encoder.