Add API to query video engine for the send-side delay.

R=mflodman@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/4559005

git-svn-id: http://webrtc.googlecode.com/svn/trunk@5225 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
stefan@webrtc.org
2013-12-05 14:05:07 +00:00
parent 07fcc4f2fa
commit 0a3c1471b8
12 changed files with 129 additions and 4 deletions

View File

@ -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()");

View File

@ -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.

View File

@ -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();

View File

@ -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_;