diff --git a/trunk/src/app/srs_app_rtc_conn.cpp b/trunk/src/app/srs_app_rtc_conn.cpp index 8c448a4fa..347a34cf7 100644 --- a/trunk/src/app/srs_app_rtc_conn.cpp +++ b/trunk/src/app/srs_app_rtc_conn.cpp @@ -313,6 +313,8 @@ SrsRtcPlayStream::SrsRtcPlayStream(SrsRtcConnection* s, SrsContextId parent_cid) _srs_config->subscribe(this); timer_ = new SrsHourGlass(this, 1000 * SRS_UTIME_MILLISECONDS); + + nack_epp = new SrsErrorPithyPrint(); } SrsRtcPlayStream::~SrsRtcPlayStream() @@ -336,6 +338,8 @@ SrsRtcPlayStream::~SrsRtcPlayStream() srs_freep(it->second); } } + + srs_freep(nack_epp); } srs_error_t SrsRtcPlayStream::initialize(SrsRequest* req, std::map sub_relations) @@ -731,8 +735,12 @@ srs_error_t SrsRtcPlayStream::on_rtcp_nack(SrsRtcpNack* rtcp) for (int i = 0; i < (int)resend_pkts.size(); ++i) { SrsRtpPacket2* pkt = resend_pkts[i]; info.nn_bytes += pkt->nb_bytes(); - srs_trace("RTC NACK ARQ seq=%u, ssrc=%u, ts=%u, %d bytes", pkt->header.get_sequence(), - pkt->header.get_ssrc(), pkt->header.get_timestamp(), pkt->nb_bytes()); + + uint32_t nn = 0; + if (nack_epp->can_print(pkt->header.get_ssrc(), &nn)) { + srs_trace("RTC NACK ARQ seq=%u, ssrc=%u, ts=%u, count=%u/%u, %d bytes", pkt->header.get_sequence(), + pkt->header.get_ssrc(), pkt->header.get_timestamp(), nn, nack_epp->nn_count, pkt->nb_bytes()); + } } // By default, we send packets by sendmmsg. diff --git a/trunk/src/app/srs_app_rtc_conn.hpp b/trunk/src/app/srs_app_rtc_conn.hpp index e366d37b9..fd17471cd 100644 --- a/trunk/src/app/srs_app_rtc_conn.hpp +++ b/trunk/src/app/srs_app_rtc_conn.hpp @@ -221,6 +221,8 @@ private: // key: publish_ssrc, value: send track to process rtp/rtcp std::map audio_tracks_; std::map video_tracks_; + // The pithy print for special stage. + SrsErrorPithyPrint* nack_epp; private: // For merged-write messages. int mw_msgs; diff --git a/trunk/src/app/srs_app_rtc_source.cpp b/trunk/src/app/srs_app_rtc_source.cpp index c88e09e32..9bbdbc2c7 100644 --- a/trunk/src/app/srs_app_rtc_source.cpp +++ b/trunk/src/app/srs_app_rtc_source.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #ifdef SRS_FFMPEG_FIT #include @@ -1813,6 +1814,8 @@ SrsRtcSendTrack::SrsRtcSendTrack(SrsRtcConnection* session, SrsRtcTrackDescripti } else { rtp_queue_ = new SrsRtpRingBuffer(1000); } + + nack_epp = new SrsErrorPithyPrint(); } SrsRtcSendTrack::~SrsRtcSendTrack() @@ -1820,6 +1823,7 @@ SrsRtcSendTrack::~SrsRtcSendTrack() srs_freep(rtp_queue_); srs_freep(track_desc_); srs_freep(statistic_); + srs_freep(nack_epp); } bool SrsRtcSendTrack::has_ssrc(uint32_t ssrc) @@ -1836,12 +1840,18 @@ SrsRtpPacket2* SrsRtcSendTrack::fetch_rtp_packet(uint16_t seq) } // For NACK, it sequence must match exactly, or it cause SRTP fail. - if (pkt->header.get_sequence() != seq) { - srs_trace("miss match seq=%u, pkt seq=%u", seq, pkt->header.get_sequence()); - return NULL; + // Return packet only when sequence is equal. + if (pkt->header.get_sequence() == seq) { + return pkt; } - return pkt; + // Ignore if sequence not match. + uint32_t nn = 0; + if (nack_epp->can_print(pkt->header.get_ssrc(), &nn)) { + srs_trace("RTC NACK miss seq=%u, require_seq=%u, ssrc=%u, ts=%u, count=%u/%u, %d bytes", seq, pkt->header.get_sequence(), + pkt->header.get_ssrc(), pkt->header.get_timestamp(), nn, nack_epp->nn_count, pkt->nb_bytes()); + } + return NULL; } // TODO: FIXME: Should refine logs, set tracks in a time. diff --git a/trunk/src/app/srs_app_rtc_source.hpp b/trunk/src/app/srs_app_rtc_source.hpp index abd1d072d..cd292b767 100644 --- a/trunk/src/app/srs_app_rtc_source.hpp +++ b/trunk/src/app/srs_app_rtc_source.hpp @@ -55,6 +55,7 @@ class SrsRtpRingBuffer; class SrsRtpNackForReceiver; class SrsJsonObject; class SrsRtcPlayStreamStatistic; +class SrsErrorPithyPrint; class SrsNtp { @@ -530,11 +531,14 @@ protected: // send track description SrsRtcTrackDescription* track_desc_; SrsRtcTrackStatistic* statistic_; - +protected: // The owner connection for this track. SrsRtcConnection* session_; // NACK ARQ ring buffer. SrsRtpRingBuffer* rtp_queue_; +private: + // The pithy print for special stage. + SrsErrorPithyPrint* nack_epp; public: SrsRtcSendTrack(SrsRtcConnection* session, SrsRtcTrackDescription* track_desc, bool is_audio); virtual ~SrsRtcSendTrack();