From 415bc95dda5aff3c7dfb34d0b921af9e13c94f3b Mon Sep 17 00:00:00 2001 From: ziyue <1213642868@qq.com> Date: Thu, 2 Sep 2021 21:17:59 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84ntp=E6=97=B6=E9=97=B4?= =?UTF-8?q?=E6=88=B3=E8=AE=A1=E7=AE=97=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Common/Stamp.cpp | 40 ++++++++++++++++++++++---------------- src/Common/Stamp.h | 5 ++--- src/Rtp/GB28181Process.cpp | 2 +- src/Rtsp/RtpReceiver.cpp | 8 ++++---- src/Rtsp/RtpReceiver.h | 7 +++---- src/Rtsp/RtspPlayer.cpp | 2 +- src/Rtsp/RtspSession.cpp | 2 +- webrtc/WebRtcTransport.cpp | 2 +- 8 files changed, 36 insertions(+), 32 deletions(-) diff --git a/src/Common/Stamp.cpp b/src/Common/Stamp.cpp index d4d22929..102d1e16 100644 --- a/src/Common/Stamp.cpp +++ b/src/Common/Stamp.cpp @@ -218,13 +218,12 @@ bool DtsGenerator::getDts_l(uint32_t pts, uint32_t &dts){ return false; } -void NtpStamp::setNtpStamp(uint32_t rtp_stamp, uint32_t sample_rate, uint64_t ntp_stamp_ms) { - assert(sample_rate); - update(uint64_t(rtp_stamp) * 1000 / sample_rate, ntp_stamp_ms); +void NtpStamp::setNtpStamp(uint32_t rtp_stamp, uint64_t ntp_stamp_ms) { + update(rtp_stamp, ntp_stamp_ms); } -void NtpStamp::update(uint32_t rtp_stamp_ms, uint64_t ntp_stamp_ms) { - _last_rtp_stamp_ms = rtp_stamp_ms; +void NtpStamp::update(uint32_t rtp_stamp, uint64_t ntp_stamp_ms) { + _last_rtp_stamp = rtp_stamp; _last_ntp_stamp_ms = ntp_stamp_ms; } @@ -238,38 +237,45 @@ uint64_t NtpStamp::getNtpStamp(uint32_t rtp_stamp, uint32_t sample_rate) { } uint64_t NtpStamp::getNtpStamp_l(uint32_t rtp_stamp, uint32_t sample_rate) { - uint64_t rtp_stamp_ms = uint64_t(rtp_stamp) * 1000 / sample_rate; - if (!_last_rtp_stamp_ms && !_last_ntp_stamp_ms) { + if (!_last_ntp_stamp_ms) { //尚未收到sender report rtcp包,那么赋值为本地系统时间戳吧 - update(rtp_stamp_ms, getCurrentMillisecond(true)); + update(rtp_stamp, getCurrentMillisecond(true)); } - if (rtp_stamp_ms >= _last_rtp_stamp_ms) { - auto diff = rtp_stamp_ms - _last_rtp_stamp_ms; + //rtp时间戳正增长 + if (rtp_stamp >= _last_rtp_stamp) { + auto diff = (rtp_stamp - _last_rtp_stamp) / (sample_rate / 1000.0f); if (diff < MAX_DELTA_STAMP) { //时间戳正常增长 - update(rtp_stamp_ms, _last_ntp_stamp_ms + diff); + update(rtp_stamp, _last_ntp_stamp_ms + diff); return _last_ntp_stamp_ms; } - uint64_t max_rtp_ms = uint64_t(UINT32_MAX) * 1000 / sample_rate; + //时间戳大幅跳跃 - if (_last_rtp_stamp_ms < STAMP_LOOP_DELTA && rtp_stamp_ms > max_rtp_ms - STAMP_LOOP_DELTA) { + uint64_t loop_delta = STAMP_LOOP_DELTA * sample_rate / 1000; + if (_last_rtp_stamp < loop_delta && rtp_stamp > UINT32_MAX - loop_delta) { //应该是rtp时间戳溢出+乱序 + uint64_t max_rtp_ms = uint64_t(UINT32_MAX) * 1000 / sample_rate; return _last_ntp_stamp_ms + diff - max_rtp_ms; } //不明原因的时间戳大幅跳跃,直接返回上次值 WarnL << "rtp stamp abnormal increased:" << _last_rtp_stamp << " -> " << rtp_stamp; return _last_ntp_stamp_ms; } - auto diff = _last_rtp_stamp_ms - rtp_stamp_ms; + + //rtp时间戳负增长 + auto diff = (_last_rtp_stamp - rtp_stamp) / (sample_rate / 1000.0f); if (diff < MAX_DELTA_STAMP) { //正常范围的时间戳回退,说明收到rtp乱序了 return _last_ntp_stamp_ms - diff; } - uint64_t max_rtp_ms = uint64_t(UINT32_MAX) * 1000 / sample_rate; - if (rtp_stamp_ms < STAMP_LOOP_DELTA && _last_rtp_stamp_ms > max_rtp_ms - STAMP_LOOP_DELTA) { + + //时间戳大幅度回退 + uint64_t loop_delta = STAMP_LOOP_DELTA * sample_rate / 1000; + if (rtp_stamp < loop_delta && _last_rtp_stamp > UINT32_MAX - loop_delta) { //确定是时间戳溢出 - update(rtp_stamp_ms, _last_ntp_stamp_ms + (max_rtp_ms - diff)); + uint64_t max_rtp_ms = uint64_t(UINT32_MAX) * 1000 / sample_rate; + update(rtp_stamp, _last_ntp_stamp_ms + (max_rtp_ms - diff)); return _last_ntp_stamp_ms; } //不明原因的时间戳回退,直接返回上次值 diff --git a/src/Common/Stamp.h b/src/Common/Stamp.h index 0bca9f1b..1f91b596 100644 --- a/src/Common/Stamp.h +++ b/src/Common/Stamp.h @@ -119,16 +119,15 @@ public: NtpStamp() = default; ~NtpStamp() = default; - void setNtpStamp(uint32_t rtp_stamp, uint32_t sample_rate, uint64_t ntp_stamp_ms); + void setNtpStamp(uint32_t rtp_stamp, uint64_t ntp_stamp_ms); uint64_t getNtpStamp(uint32_t rtp_stamp, uint32_t sample_rate); private: - void update(uint32_t rtp_stamp_ms, uint64_t ntp_stamp_ms); + void update(uint32_t rtp_stamp, uint64_t ntp_stamp_ms); uint64_t getNtpStamp_l(uint32_t rtp_stamp, uint32_t sample_rate); private: uint32_t _last_rtp_stamp = 0; - uint64_t _last_rtp_stamp_ms = 0; uint64_t _last_ntp_stamp_ms = 0; }; diff --git a/src/Rtp/GB28181Process.cpp b/src/Rtp/GB28181Process.cpp index 82f7a6f3..cff3b4e5 100644 --- a/src/Rtp/GB28181Process.cpp +++ b/src/Rtp/GB28181Process.cpp @@ -33,7 +33,7 @@ public: setOnSorted(std::move(cb)); setBeforeSorted(std::move(cb_before)); //GB28181推流不支持ntp时间戳 - setNtpStamp(0, 0, 0); + setNtpStamp(0, 0); } ~RtpReceiverImp() override = default; diff --git a/src/Rtsp/RtpReceiver.cpp b/src/Rtsp/RtpReceiver.cpp index 630805cd..37364bab 100644 --- a/src/Rtsp/RtpReceiver.cpp +++ b/src/Rtsp/RtpReceiver.cpp @@ -101,10 +101,10 @@ RtpPacket::Ptr RtpTrack::inputRtp(TrackType type, int sample_rate, uint8_t *ptr, return rtp; } -void RtpTrack::setNtpStamp(uint32_t rtp_stamp, uint32_t sample_rate, uint64_t ntp_stamp_ms) { - _disable_ntp = rtp_stamp == 0 && sample_rate == 0 && ntp_stamp_ms == 0; - if (sample_rate) { - _ntp_stamp.setNtpStamp(rtp_stamp, sample_rate, ntp_stamp_ms); +void RtpTrack::setNtpStamp(uint32_t rtp_stamp, uint64_t ntp_stamp_ms) { + _disable_ntp = rtp_stamp == 0 && ntp_stamp_ms == 0; + if (!_disable_ntp) { + _ntp_stamp.setNtpStamp(rtp_stamp, ntp_stamp_ms); } } diff --git a/src/Rtsp/RtpReceiver.h b/src/Rtsp/RtpReceiver.h index 3862fea2..8b6f7fed 100644 --- a/src/Rtsp/RtpReceiver.h +++ b/src/Rtsp/RtpReceiver.h @@ -176,7 +176,7 @@ public: void clear(); uint32_t getSSRC() const; RtpPacket::Ptr inputRtp(TrackType type, int sample_rate, uint8_t *ptr, size_t len); - void setNtpStamp(uint32_t rtp_stamp, uint32_t sample_rate, uint64_t ntp_stamp_ms); + void setNtpStamp(uint32_t rtp_stamp, uint64_t ntp_stamp_ms); protected: virtual void onRtpSorted(RtpPacket::Ptr rtp) {} @@ -245,11 +245,10 @@ public: * 如果rtp_stamp/sample_rate/ntp_stamp_ms都为0,那么采用rtp时间戳为ntp时间戳 * @param index track下标索引 * @param rtp_stamp rtp时间戳 - * @param sample_rate 时间戳采样率 * @param ntp_stamp_ms ntp时间戳 */ - void setNtpStamp(int index, uint32_t rtp_stamp, uint32_t sample_rate, uint64_t ntp_stamp_ms){ - _track[index].setNtpStamp(rtp_stamp, sample_rate, ntp_stamp_ms); + void setNtpStamp(int index, uint32_t rtp_stamp, uint64_t ntp_stamp_ms){ + _track[index].setNtpStamp(rtp_stamp, ntp_stamp_ms); } void clear() { diff --git a/src/Rtsp/RtspPlayer.cpp b/src/Rtsp/RtspPlayer.cpp index eadbd642..ceb74061 100644 --- a/src/Rtsp/RtspPlayer.cpp +++ b/src/Rtsp/RtspPlayer.cpp @@ -496,7 +496,7 @@ void RtspPlayer::onRtcpPacket(int track_idx, SdpTrack::Ptr &track, uint8_t *data if ((RtcpType) rtcp->pt == RtcpType::RTCP_SR) { auto sr = (RtcpSR *) (rtcp); //设置rtp时间戳与ntp时间戳的对应关系 - setNtpStamp(track_idx, sr->rtpts, track->_samplerate, sr->getNtpUnixStampMS()); + setNtpStamp(track_idx, sr->rtpts, sr->getNtpUnixStampMS()); } } } diff --git a/src/Rtsp/RtspSession.cpp b/src/Rtsp/RtspSession.cpp index 38b9a49e..597e1964 100644 --- a/src/Rtsp/RtspSession.cpp +++ b/src/Rtsp/RtspSession.cpp @@ -189,7 +189,7 @@ void RtspSession::onRtcpPacket(int track_idx, SdpTrack::Ptr &track, const char * if ((RtcpType) rtcp->pt == RtcpType::RTCP_SR) { auto sr = (RtcpSR *) (rtcp); //设置rtp时间戳与ntp时间戳的对应关系 - setNtpStamp(track_idx, sr->rtpts, track->_samplerate, sr->getNtpUnixStampMS()); + setNtpStamp(track_idx, sr->rtpts, sr->getNtpUnixStampMS()); } } } diff --git a/webrtc/WebRtcTransport.cpp b/webrtc/WebRtcTransport.cpp index 845231e2..dd5a61fa 100644 --- a/webrtc/WebRtcTransport.cpp +++ b/webrtc/WebRtcTransport.cpp @@ -674,7 +674,7 @@ void WebRtcTransportImp::onRtcp(const char *buf, size_t len) { } else { //InfoL << "接收丢包率,ssrc:" << sr->ssrc << ",loss rate(%):" << rtp_chn->getLossRate(); //设置rtp时间戳与ntp时间戳的对应关系 - rtp_chn->setNtpStamp(sr->rtpts, track->plan_rtp->sample_rate, sr->getNtpUnixStampMS()); + rtp_chn->setNtpStamp(sr->rtpts, sr->getNtpUnixStampMS()); auto rr = rtp_chn->createRtcpRR(sr, track->answer_ssrc_rtp); sendRtcpPacket(rr->data(), rr->size(), true); }