summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/rtp_rtcp/interface/rtp_rtcp.h3
-rw-r--r--modules/rtp_rtcp/mocks/mock_rtp_rtcp.h2
-rw-r--r--modules/rtp_rtcp/source/rtp_rtcp_impl.cc12
-rw-r--r--modules/rtp_rtcp/source/rtp_rtcp_impl.h4
-rw-r--r--modules/rtp_rtcp/source/rtp_sender.cc31
-rw-r--r--modules/rtp_rtcp/source/rtp_sender.h12
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_;