diff --git a/trunk/src/app/srs_app_http_api.cpp b/trunk/src/app/srs_app_http_api.cpp index 388420374..81e45183c 100644 --- a/trunk/src/app/srs_app_http_api.cpp +++ b/trunk/src/app/srs_app_http_api.cpp @@ -1086,11 +1086,13 @@ 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; - SrsSSRCInfo ssrc_info; - ssrc_info.ssrc_ = ++ssrc_num; - // TODO:use formated cname - ssrc_info.cname_ = "test_sdp_cname"; - local_media_desc.ssrc_infos_.push_back(ssrc_info); + if (local_media_desc.recvonly_ || local_media_desc.sendrecv_) { + SrsSSRCInfo ssrc_info; + ssrc_info.ssrc_ = ++ssrc_num; + // TODO:use formated cname + ssrc_info.cname_ = "test_sdp_cname"; + local_media_desc.ssrc_infos_.push_back(ssrc_info); + } } return err; @@ -1381,10 +1383,12 @@ srs_error_t SrsGoApiRtcPublish::exchange_sdp(const std::string& app, const std:: local_media_desc.rtcp_mux_ = true; - SrsSSRCInfo ssrc_info; - ssrc_info.ssrc_ = ++ssrc_num; - ssrc_info.cname_ = "test_sdp_cname"; - local_media_desc.ssrc_infos_.push_back(ssrc_info); + 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); + } } return err; diff --git a/trunk/src/app/srs_app_rtc_conn.cpp b/trunk/src/app/srs_app_rtc_conn.cpp index e228a2464..21e749c48 100644 --- a/trunk/src/app/srs_app_rtc_conn.cpp +++ b/trunk/src/app/srs_app_rtc_conn.cpp @@ -1614,6 +1614,10 @@ srs_error_t SrsRtcPublisher::on_rtcp_sender_report(char* buf, int nb_buf, SrsUdp { srs_error_t err = srs_success; + if (nb_buf < 28) { + return srs_error_new(ERROR_RTC_RTCP_CHECK, "invalid rtp sender report packet, nb_buf=%d", nb_buf); + } + SrsBuffer* stream = new SrsBuffer(buf, nb_buf); SrsAutoFree(SrsBuffer, stream); @@ -2100,7 +2104,7 @@ SrsRtcSession::SrsRtcSession(SrsRtcServer* rtc_svr, const SrsRequest& req, const // TODO: FIXME: Support reload. sessionStunTimeout = _srs_config->get_rtc_stun_timeout(req.vhost); - rtc_publisher = new SrsRtcPublisher(this); + rtc_publisher = NULL; } SrsRtcSession::~SrsRtcSession() @@ -2362,6 +2366,10 @@ srs_error_t SrsRtcSession::on_rtcp_ps_feedback(char* buf, int nb_buf, SrsUdpMuxS srs_error_t SrsRtcSession::on_rtcp_xr(char* buf, int nb_buf, SrsUdpMuxSocket* skt) { + if (rtc_publisher == NULL) { + return srs_error_new(ERROR_RTC_RTCP, "rtc publisher null"); + } + return rtc_publisher->on_rtcp_xr(buf, nb_buf, skt); } @@ -2369,8 +2377,8 @@ srs_error_t SrsRtcSession::on_rtcp_sender_report(char* buf, int nb_buf, SrsUdpMu { srs_error_t err = srs_success; - if (nb_buf < 28) { - return srs_error_new(ERROR_RTC_RTCP_CHECK, "invalid rtp sender report packet, nb_buf=%d", nb_buf); + if (rtc_publisher == NULL) { + return srs_error_new(ERROR_RTC_RTCP, "rtc publisher null"); } return rtc_publisher->on_rtcp_sender_report(buf, nb_buf, skt); @@ -2447,34 +2455,25 @@ block +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ srs_error_t SrsRtcSession::on_connection_established(SrsUdpMuxSocket* skt) { - // FIXME: - if (true) - { - uint32_t video_ssrc = 0; - uint32_t audio_ssrc = 0; - uint16_t video_payload_type = 0; - uint16_t audio_payload_type = 0; - for (size_t i = 0; i < remote_sdp.media_descs_.size(); ++i) { - const SrsMediaDesc& media_desc = remote_sdp.media_descs_[i]; - if (media_desc.is_audio()) { - if (! media_desc.ssrc_infos_.empty()) { - audio_ssrc = media_desc.ssrc_infos_[0].ssrc_; - audio_payload_type = media_desc.payload_types_[0].payload_type_; - } - } else if (media_desc.is_video()) { - if (! media_desc.ssrc_infos_.empty()) { - video_ssrc = media_desc.ssrc_infos_[0].ssrc_; - video_payload_type = media_desc.payload_types_[0].payload_type_; - } - } - } - - // FIXME: err process. - rtc_publisher->initialize(skt, video_ssrc, audio_ssrc, request); - } + srs_error_t err = srs_success; srs_trace("rtc session=%s, to=%dms connection established", id().c_str(), srsu2msi(sessionStunTimeout)); - return start_play(skt); + + if (! local_sdp.media_descs_.empty() && + (local_sdp.media_descs_.back().recvonly_ || local_sdp.media_descs_.back().sendrecv_)) { + if ((err = start_publish(skt)) != 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_)) { + if ((err = start_play(skt)) != srs_success) { + return srs_error_wrap(err, "start play"); + } + } + + return err; } srs_error_t SrsRtcSession::start_play(SrsUdpMuxSocket* skt) @@ -2510,6 +2509,39 @@ srs_error_t SrsRtcSession::start_play(SrsUdpMuxSocket* skt) return err; } +srs_error_t SrsRtcSession::start_publish(SrsUdpMuxSocket* skt) +{ + srs_error_t err = srs_success; + + rtc_publisher = new SrsRtcPublisher(this); + + uint32_t video_ssrc = 0; + uint32_t audio_ssrc = 0; + uint16_t video_payload_type = 0; + uint16_t audio_payload_type = 0; + for (size_t i = 0; i < remote_sdp.media_descs_.size(); ++i) { + const SrsMediaDesc& media_desc = remote_sdp.media_descs_[i]; + if (media_desc.is_audio()) { + if (! media_desc.ssrc_infos_.empty()) { + audio_ssrc = media_desc.ssrc_infos_[0].ssrc_; + audio_payload_type = media_desc.payload_types_[0].payload_type_; + } + } else if (media_desc.is_video()) { + if (! media_desc.ssrc_infos_.empty()) { + video_ssrc = media_desc.ssrc_infos_[0].ssrc_; + video_payload_type = media_desc.payload_types_[0].payload_type_; + } + } + } + + // FIXME: err process. + if ((err = rtc_publisher->initialize(skt, video_ssrc, audio_ssrc, request)) != srs_success) { + return srs_error_wrap(err, "rtc publisher init"); + } + + return err; +} + bool SrsRtcSession::is_stun_timeout() { return last_stun_time + sessionStunTimeout < srs_get_system_time(); @@ -2599,6 +2631,10 @@ srs_error_t SrsRtcSession::on_rtp(SrsUdpMuxSocket* skt) { srs_error_t err = srs_success; + if (rtc_publisher == NULL) { + return srs_error_new(ERROR_RTC_RTCP, "rtc publisher null"); + } + if (dtls_session == NULL) { return srs_error_new(ERROR_RTC_RTCP, "recv unexpect rtp packet before dtls done"); } diff --git a/trunk/src/app/srs_app_rtc_conn.hpp b/trunk/src/app/srs_app_rtc_conn.hpp index ff697e650..718d62d9e 100644 --- a/trunk/src/app/srs_app_rtc_conn.hpp +++ b/trunk/src/app/srs_app_rtc_conn.hpp @@ -358,6 +358,7 @@ public: srs_error_t send_client_hello(SrsUdpMuxSocket* skt); srs_error_t on_connection_established(SrsUdpMuxSocket* skt); srs_error_t start_play(SrsUdpMuxSocket* skt); + srs_error_t start_publish(SrsUdpMuxSocket* skt); public: bool is_stun_timeout(); private: diff --git a/trunk/src/app/srs_app_rtp_queue.cpp b/trunk/src/app/srs_app_rtp_queue.cpp index 393c23263..74390314b 100644 --- a/trunk/src/app/srs_app_rtp_queue.cpp +++ b/trunk/src/app/srs_app_rtp_queue.cpp @@ -127,8 +127,8 @@ void SrsRtpNackList::get_nack_seqs(vector& seqs) void SrsRtpNackList::update_rtt(int rtt) { - rtt_ = rtt; - srs_verbose("NACK, update rtt from %ld to %d", opts_.nack_interval, rtt); + rtt_ = rtt * SRS_UTIME_MILLISECONDS; + srs_verbose("NACK, update rtt from %ld to %d", opts_.nack_interval, rtt_); // FIXME: limit min and max value. opts_.nack_interval = rtt_; } @@ -182,7 +182,9 @@ srs_error_t SrsRtpQueue::insert(SrsRtpSharedPacket* rtp_pkt) } else { SrsRtpNackInfo* nack_info = NULL; if ((nack_info = nack_.find(seq)) != NULL) { - srs_verbose("seq=%u, alive time=%d, nack count=%d, rtx success", seq, now - nack_info->generate_time_, nack_info->req_nack_count_); + int nack_rtt = nack_info->req_nack_count_ ? ((now - nack_info->pre_req_nack_time_) / SRS_UTIME_MILLISECONDS) : 0; + srs_verbose("seq=%u, alive time=%d, nack count=%d, rtx success, resend use %dms", + seq, now - nack_info->generate_time_, nack_info->req_nack_count_, nack_rtt); nack_.remove(seq); } else { // Calc jitter.