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:
@ -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()");
|
||||
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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_;
|
||||
|
||||
Reference in New Issue
Block a user