diff --git a/trunk/src/app/srs_app_rtc_conn.cpp b/trunk/src/app/srs_app_rtc_conn.cpp index 2aff617d9..e05ec1dd6 100644 --- a/trunk/src/app/srs_app_rtc_conn.cpp +++ b/trunk/src/app/srs_app_rtc_conn.cpp @@ -257,6 +257,8 @@ srs_error_t SrsRtcPlayStream::initialize(SrsRequest* req, std::mapget_rtc_nack_enabled(req->vhost); srs_trace("RTC player nack=%d", nack_enabled_); + session_->stat_->nn_subscribers++; + return err; } @@ -385,6 +387,9 @@ srs_error_t SrsRtcPlayStream::cycle() continue; } + // Update stats for session. + session_->stat_->nn_out_rtp += msg_count; + // Send-out all RTP packets and do cleanup. // TODO: FIXME: Handle error. send_packets(source, pkts, info); @@ -448,8 +453,6 @@ srs_error_t SrsRtcPlayStream::send_packets(SrsRtcStream* source, const vectorheader.get_ssrc()]; // TODO: FIXME: Any simple solution? if ((err = video_track->on_rtp(pkt, info)) != srs_success) { @@ -562,14 +565,22 @@ srs_error_t SrsRtcPlayStream::on_rtcp(char* data, int nb_data) srs_error_t SrsRtcPlayStream::on_rtcp_sr(char* buf, int nb_buf) { srs_error_t err = srs_success; + // TODO: FIXME: Implements it. + + session_->stat_->nn_sr++; + return err; } srs_error_t SrsRtcPlayStream::on_rtcp_xr(char* buf, int nb_buf) { srs_error_t err = srs_success; + // TODO: FIXME: Implements it. + + session_->stat_->nn_xr++; + return err; } @@ -654,6 +665,8 @@ srs_error_t SrsRtcPlayStream::on_rtcp_feedback(char* buf, int nb_buf) return srs_error_wrap(err, "raw send"); } + session_->stat_->nn_nack++; + return err; } @@ -688,6 +701,8 @@ srs_error_t SrsRtcPlayStream::on_rtcp_ps_feedback(char* buf, int nb_buf) srs_trace("RTC request PLI"); } } + + session_->stat_->nn_pli++; break; } case kSLI: { @@ -713,7 +728,11 @@ srs_error_t SrsRtcPlayStream::on_rtcp_ps_feedback(char* buf, int nb_buf) srs_error_t SrsRtcPlayStream::on_rtcp_rr(char* data, int nb_data) { srs_error_t err = srs_success; + // TODO: FIXME: Implements it. + + session_->stat_->nn_rr++; + return err; } @@ -793,6 +812,8 @@ srs_error_t SrsRtcPublishStream::initialize(SrsRequest* r, SrsRtcStreamDescripti srs_trace("RTC publisher nack=%d, pt-drop=%u, twcc=%u/%d", nack_enabled_, pt_to_drop_, twcc_enabled, twcc_id); + session_->stat_->nn_publishers++; + return err; } @@ -848,6 +869,8 @@ srs_error_t SrsRtcPublishStream::send_rtcp_rr() track->send_rtcp_rr(); } + session_->stat_->nn_rr++; + return err; } @@ -865,18 +888,28 @@ srs_error_t SrsRtcPublishStream::send_rtcp_xr_rrtr() track->send_rtcp_xr_rrtr(); } + session_->stat_->nn_xr++; + return err; } srs_error_t SrsRtcPublishStream::on_twcc(uint16_t sn) { + srs_error_t err = srs_success; + srs_utime_t now = srs_get_system_time(); - return rtcp_twcc_.recv_packet(sn, now); + err = rtcp_twcc_.recv_packet(sn, now); + + session_->stat_->nn_in_twcc++; + + return err; } srs_error_t SrsRtcPublishStream::on_rtp(char* data, int nb_data) { srs_error_t err = srs_success; + session_->stat_->nn_in_rtp++; + // For NACK simulator, drop packet. if (nn_simulate_nack_drop) { SrsBuffer b(data, nb_data); SrsRtpHeader h; h.decode(&b); @@ -1376,6 +1409,8 @@ void SrsRtcPublishStream::request_keyframe(uint32_t ssrc) if (video_track) { video_track->request_keyframe(); } + + session_->stat_->nn_pli++; } srs_error_t SrsRtcPublishStream::notify(int type, srs_utime_t interval, srs_utime_t tick) @@ -1458,12 +1493,58 @@ void SrsRtcPublishStream::update_send_report_time(uint32_t ssrc, const SrsNtp& n } } +SrsRtcConnectionStat::SrsRtcConnectionStat() +{ + dead = born = srs_get_system_time(); + nn_publishers = nn_subscribers = 0; + nn_rr = nn_xr = 0; + nn_sr = nn_nack = nn_pli = 0; + nn_in_twcc = nn_in_rtp = nn_in_audios = nn_in_videos = 0; + nn_out_twcc = nn_out_rtp = nn_out_audios = nn_out_videos = 0; +} + +SrsRtcConnectionStat::~SrsRtcConnectionStat() +{ +} + +string SrsRtcConnectionStat::summary() +{ + dead = srs_get_system_time(); + + stringstream ss; + + ss << "alive=" << srsu2msi(dead - born) << "ms"; + + if (nn_publishers) ss << ", npub=" << nn_publishers; + if (nn_subscribers) ss << ", nsub=" << nn_subscribers; + + if (nn_rr) ss << ", nrr=" << nn_rr; + if (nn_xr) ss << ", nxr=" << nn_xr; + + if (nn_sr) ss << ", nsr=" << nn_sr; + if (nn_nack) ss << ", nnack=" << nn_nack; + if (nn_pli) ss << ", npli=" << nn_pli; + + if (nn_in_twcc) ss << ", in_ntwcc=" << nn_in_twcc; + if (nn_in_rtp) ss << ", in_nrtp=" << nn_in_rtp; + if (nn_in_audios) ss << ", in_naudio=" << nn_in_audios; + if (nn_in_videos) ss << ", in_nvideo=" << nn_in_videos; + + if (nn_out_twcc) ss << ", out_ntwcc=" << nn_out_twcc; + if (nn_out_rtp) ss << ", out_nrtp=" << nn_out_rtp; + if (nn_out_audios) ss << ", out_naudio=" << nn_out_audios; + if (nn_out_videos) ss << ", out_nvideo=" << nn_out_videos; + + return ss.str(); +} + SrsRtcConnection::SrsRtcConnection(SrsRtcServer* s, SrsContextId context_id) { req = NULL; is_publisher_ = false; encrypt = true; cid = context_id; + stat_ = new SrsRtcConnectionStat(); source_ = NULL; publisher_ = NULL; @@ -1488,6 +1569,7 @@ SrsRtcConnection::~SrsRtcConnection() srs_freep(transport_); srs_freep(req); srs_freep(sendonly_skt); + srs_freep(stat_); } SrsSdp* SrsRtcConnection::get_local_sdp() diff --git a/trunk/src/app/srs_app_rtc_conn.hpp b/trunk/src/app/srs_app_rtc_conn.hpp index 7da0001d0..de451ab7a 100644 --- a/trunk/src/app/srs_app_rtc_conn.hpp +++ b/trunk/src/app/srs_app_rtc_conn.hpp @@ -200,6 +200,7 @@ public: public: virtual srs_error_t start(); virtual void stop(); + // TODO: FIXME: Remove dead code. virtual void stop_loop(); public: virtual srs_error_t cycle(); @@ -287,6 +288,26 @@ private: void update_send_report_time(uint32_t ssrc, const SrsNtp& ntp); }; +// The statistics for RTC connection. +class SrsRtcConnectionStat +{ +public: + int nn_publishers; + int nn_subscribers; + int nn_rr; int nn_xr; + int nn_sr; int nn_nack; int nn_pli; + uint64_t nn_in_twcc; uint64_t nn_in_rtp; uint64_t nn_in_audios; uint64_t nn_in_videos; + uint64_t nn_out_twcc; uint64_t nn_out_rtp; uint64_t nn_out_audios; uint64_t nn_out_videos; +private: + srs_utime_t born; + srs_utime_t dead; +public: + SrsRtcConnectionStat(); + virtual ~SrsRtcConnectionStat(); +public: + std::string summary(); +}; + // A RTC Peer Connection, SDP level object. class SrsRtcConnection { @@ -295,6 +316,7 @@ class SrsRtcConnection friend class SrsRtcPublishStream; public: bool disposing_; + SrsRtcConnectionStat* stat_; private: SrsRtcServer* server_; SrsRtcConnectionStateType state_; diff --git a/trunk/src/app/srs_app_rtc_server.cpp b/trunk/src/app/srs_app_rtc_server.cpp index 218231af9..ce8412367 100644 --- a/trunk/src/app/srs_app_rtc_server.cpp +++ b/trunk/src/app/srs_app_rtc_server.cpp @@ -550,6 +550,10 @@ void SrsRtcServer::destroy(SrsRtcConnection* session) map_id_session.erase(it); } + SrsContextRestore(_srs_context->get_id()); + session->switch_to_context(); + srs_trace("RTC session=%s, destroy, summary: %s", session->id().c_str(), session->stat_->summary().c_str()); + zombies_.push_back(session); } @@ -581,7 +585,7 @@ void SrsRtcServer::check_and_clean_timeout_session() // Now, we got the RTC session to cleanup, switch to its context // to make all logs write to the "correct" pid+cid. session->switch_to_context(); - srs_trace("RTC session=%s, STUN timeout", session->id().c_str()); + srs_trace("RTC session=%s, STUN timeout, summary: %s", session->id().c_str(), session->stat_->summary().c_str()); session->disposing_ = true; zombies_.push_back(session); diff --git a/trunk/src/app/srs_app_rtc_source.cpp b/trunk/src/app/srs_app_rtc_source.cpp index a0fb8527d..9481331de 100644 --- a/trunk/src/app/srs_app_rtc_source.cpp +++ b/trunk/src/app/srs_app_rtc_source.cpp @@ -1632,6 +1632,8 @@ srs_error_t SrsRtcAudioRecvTrack::on_rtp(SrsRtcStream* source, SrsRtpPacket2* pk return srs_error_wrap(err, "on nack"); } + session_->stat_->nn_in_audios++; + return err; } @@ -1670,6 +1672,8 @@ srs_error_t SrsRtcVideoRecvTrack::on_rtp(SrsRtcStream* source, SrsRtpPacket2* pk return srs_error_wrap(err, "on nack"); } + session_->stat_->nn_in_videos++; + return err; } @@ -1713,6 +1717,7 @@ SrsRtpPacket2* SrsRtcSendTrack::fetch_rtp_packet(uint16_t seq) return NULL; } +// TODO: FIXME: Should refine logs, set tracks in a time. void SrsRtcSendTrack::set_track_status(bool active) { track_desc_->is_active_ = active; @@ -1764,6 +1769,7 @@ srs_error_t SrsRtcAudioSendTrack::on_rtp(SrsRtpPacket2* pkt, SrsRtcOutgoingInfo& // Update stats. info.nn_bytes += pkt->nb_bytes(); info.nn_audios++; + session_->stat_->nn_out_audios++; if ((err = session_->do_send_packets(pkts, info)) != srs_success) { return srs_error_wrap(err, "raw send"); @@ -1809,6 +1815,7 @@ srs_error_t SrsRtcVideoSendTrack::on_rtp(SrsRtpPacket2* pkt, SrsRtcOutgoingInfo& // Update stats. info.nn_bytes += pkt->nb_bytes(); info.nn_videos++; + session_->stat_->nn_out_videos++; if ((err = session_->do_send_packets(pkts, info)) != srs_success) { return srs_error_wrap(err, "raw send");