diff options
Diffstat (limited to 'modules')
-rw-r--r-- | modules/rtp_rtcp/interface/rtp_rtcp.h | 3 | ||||
-rw-r--r-- | modules/rtp_rtcp/mocks/mock_rtp_rtcp.h | 2 | ||||
-rw-r--r-- | modules/rtp_rtcp/source/rtp_rtcp_impl.cc | 12 | ||||
-rw-r--r-- | modules/rtp_rtcp/source/rtp_rtcp_impl.h | 4 | ||||
-rw-r--r-- | modules/rtp_rtcp/source/rtp_sender.cc | 31 | ||||
-rw-r--r-- | modules/rtp_rtcp/source/rtp_sender.h | 12 |
6 files changed, 64 insertions, 0 deletions
diff --git a/modules/rtp_rtcp/interface/rtp_rtcp.h b/modules/rtp_rtcp/interface/rtp_rtcp.h index 51471ba3..f8687a55 100644 --- a/modules/rtp_rtcp/interface/rtp_rtcp.h +++ b/modules/rtp_rtcp/interface/rtp_rtcp.h @@ -335,6 +335,9 @@ class RtpRtcp : public Module { FrameCountObserver* observer) = 0; virtual FrameCountObserver* GetSendFrameCountObserver() const = 0; + virtual bool GetSendSideDelay(int* avg_send_delay_ms, + int* max_send_delay_ms) const = 0; + /************************************************************************** * * RTCP diff --git a/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h b/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h index 9ca48975..293412b6 100644 --- a/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h +++ b/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h @@ -116,6 +116,8 @@ class MockRtpRtcp : public RtpRtcp { bool retransmission)); MOCK_METHOD1(TimeToSendPadding, int(int bytes)); + MOCK_CONST_METHOD2(GetSendSideDelay, + bool(int* avg_send_delay_ms, int* max_send_delay_ms)); MOCK_METHOD3(RegisterRtcpObservers, void(RtcpIntraFrameObserver* intraFrameCallback, RtcpBandwidthObserver* bandwidthCallback, diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl.cc b/modules/rtp_rtcp/source/rtp_rtcp_impl.cc index 4af8cde5..00e34125 100644 --- a/modules/rtp_rtcp/source/rtp_rtcp_impl.cc +++ b/modules/rtp_rtcp/source/rtp_rtcp_impl.cc @@ -732,6 +732,18 @@ int ModuleRtpRtcpImpl::TimeToSendPadding(int bytes) { return 0; } +bool ModuleRtpRtcpImpl::GetSendSideDelay(int* avg_send_delay_ms, + int* max_send_delay_ms) const { + assert(avg_send_delay_ms); + assert(max_send_delay_ms); + + if (!child_modules_.empty()) { + // This API is only supported for child modules. + return false; + } + return rtp_sender_.GetSendSideDelay(avg_send_delay_ms, max_send_delay_ms); +} + uint16_t ModuleRtpRtcpImpl::MaxPayloadLength() const { WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_, "MaxPayloadLength()"); diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl.h b/modules/rtp_rtcp/source/rtp_rtcp_impl.h index 0dd25492..ae070f92 100644 --- a/modules/rtp_rtcp/source/rtp_rtcp_impl.h +++ b/modules/rtp_rtcp/source/rtp_rtcp_impl.h @@ -134,6 +134,10 @@ class ModuleRtpRtcpImpl : public RtpRtcp { // Returns the number of padding bytes actually sent, which can be more or // less than |bytes|. virtual int TimeToSendPadding(int bytes) OVERRIDE; + + virtual bool GetSendSideDelay(int* avg_send_delay_ms, + int* max_send_delay_ms) const OVERRIDE; + // RTCP part. // Get RTCP status. diff --git a/modules/rtp_rtcp/source/rtp_sender.cc b/modules/rtp_rtcp/source/rtp_sender.cc index c7179646..787f8717 100644 --- a/modules/rtp_rtcp/source/rtp_sender.cc +++ b/modules/rtp_rtcp/source/rtp_sender.cc @@ -22,6 +22,7 @@ namespace webrtc { // Max in the RFC 3550 is 255 bytes, we limit it to be modulus 32 for SRTP. const int kMaxPaddingLength = 224; +const int kSendSideDelayWindowMs = 1000; namespace { @@ -127,6 +128,23 @@ uint32_t RTPSender::NackOverheadRate() const { return nack_bitrate_.BitrateLast(); } +bool RTPSender::GetSendSideDelay(int* avg_send_delay_ms, + int* max_send_delay_ms) const { + CriticalSectionScoped cs(statistics_crit_.get()); + SendDelayMap::const_iterator it = send_delays_.upper_bound( + clock_->TimeInMilliseconds() - kSendSideDelayWindowMs); + if (!sending_media_ || it == send_delays_.end()) + return false; + int num_delays = 0; + for (; it != send_delays_.end(); ++it) { + *max_send_delay_ms = std::max(*max_send_delay_ms, it->second); + *avg_send_delay_ms += it->second; + ++num_delays; + } + *avg_send_delay_ms = (*avg_send_delay_ms + num_delays / 2) / num_delays; + return true; +} + int32_t RTPSender::SetTransmissionTimeOffset( const int32_t transmission_time_offset) { if (transmission_time_offset > (0x800000 - 1) || @@ -756,6 +774,9 @@ bool RTPSender::TimeToSendPacket(uint16_t sequence_number, // Packet cannot be found. Allow sending to continue. return true; } + if (!retransmission && capture_time_ms > 0) { + UpdateDelayStatistics(capture_time_ms, clock_->TimeInMilliseconds()); + } return PrepareAndSendPacket(data_buffer, length, capture_time_ms, retransmission && (rtx_ & kRtxRetransmitted) > 0); } @@ -871,12 +892,22 @@ int32_t RTPSender::SendToNetwork( return 0; } } + if (capture_time_ms > 0) { + UpdateDelayStatistics(capture_time_ms, now_ms); + } if (SendPacketToNetwork(buffer, payload_length + rtp_header_length)) { return 0; } return -1; } +void RTPSender::UpdateDelayStatistics(int64_t capture_time_ms, int64_t now_ms) { + CriticalSectionScoped cs(statistics_crit_.get()); + send_delays_[now_ms] = now_ms - capture_time_ms; + send_delays_.erase(send_delays_.begin(), + send_delays_.lower_bound(now_ms - kSendSideDelayWindowMs)); +} + void RTPSender::ProcessBitrate() { CriticalSectionScoped cs(send_critsect_); Bitrate::Process(); diff --git a/modules/rtp_rtcp/source/rtp_sender.h b/modules/rtp_rtcp/source/rtp_sender.h index cd8cd218..becd22ad 100644 --- a/modules/rtp_rtcp/source/rtp_sender.h +++ b/modules/rtp_rtcp/source/rtp_sender.h @@ -78,6 +78,10 @@ class RTPSender : public Bitrate, public RTPSenderInterface { uint32_t FecOverheadRate() const; uint32_t NackOverheadRate() const; + // Returns true if the statistics have been calculated, and false if no frame + // was sent within the statistics window. + bool GetSendSideDelay(int* avg_send_delay_ms, int* max_send_delay_ms) const; + void SetTargetSendBitrate(const uint32_t bits); virtual uint16_t MaxDataPayloadLength() const @@ -272,6 +276,11 @@ class RTPSender : public Bitrate, public RTPSenderInterface { RtpVideoCodecTypes *video_type); private: + // Maps capture time in milliseconds to send-side delay in milliseconds. + // Send-side delay is the difference between transmission time and capture + // time. + typedef std::map<int64_t, int> SendDelayMap; + int CreateRTPHeader(uint8_t* header, int8_t payload_type, uint32_t ssrc, bool marker_bit, uint32_t timestamp, uint16_t sequence_number, @@ -296,6 +305,8 @@ class RTPSender : public Bitrate, public RTPSenderInterface { bool SendPacketToNetwork(const uint8_t *packet, uint32_t size); + void UpdateDelayStatistics(int64_t capture_time_ms, int64_t now_ms); + int32_t id_; const bool audio_configured_; RTPSenderAudio *audio_; @@ -329,6 +340,7 @@ class RTPSender : public Bitrate, public RTPSenderInterface { scoped_ptr<CriticalSectionWrapper> statistics_crit_; uint32_t packets_sent_; uint32_t payload_bytes_sent_; + SendDelayMap send_delays_; // RTP variables bool start_time_stamp_forced_; |