Add a default RTT to CallStats and use different values for buffered/real-time mode.

BUG=1613

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

git-svn-id: http://webrtc.googlecode.com/svn/trunk@3888 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
stefan@webrtc.org 2013-04-23 15:58:23 +00:00
parent d25b602dc0
commit ccd4b2aec8
11 changed files with 60 additions and 43 deletions

View File

@ -54,8 +54,7 @@ RTCPReceiver::RTCPReceiver(const int32_t id, Clock* clock,
_receivedInfoMap(),
_packetTimeOutMS(0),
_lastReceivedRrMs(0),
_lastIncreasedSequenceNumberMs(0),
_rtt(0) {
_lastIncreasedSequenceNumberMs(0) {
memset(&_remoteSenderInfo, 0, sizeof(_remoteSenderInfo));
WEBRTC_TRACE(kTraceMemory, kTraceRtpRtcp, id, "%s created", __FUNCTION__);
}
@ -211,23 +210,6 @@ int32_t RTCPReceiver::RTT(const uint32_t remoteSSRC,
return 0;
}
uint16_t RTCPReceiver::RTT() const {
CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
if (!_receivedReportBlockMap.empty()) {
return 0;
}
return _rtt;
}
int RTCPReceiver::SetRTT(uint16_t rtt) {
CriticalSectionScoped lock(_criticalSectionRTCPReceiver);
if (!_receivedReportBlockMap.empty()) {
return -1;
}
_rtt = rtt;
return 0;
}
int32_t
RTCPReceiver::NTP(uint32_t *ReceivedNTPsecs,
uint32_t *ReceivedNTPfrac,

View File

@ -237,11 +237,6 @@ protected:
// The time we last received an RTCP RR telling we have ssuccessfully
// delivered RTP packet to the remote side.
int64_t _lastIncreasedSequenceNumberMs;
// Externally set RTT. This value can only be used if there are no valid
// RTT estimates.
uint16_t _rtt;
};
} // namespace webrtc
#endif // WEBRTC_MODULES_RTP_RTCP_SOURCE_RTCP_RECEIVER_H_

View File

@ -95,7 +95,8 @@ RTPReceiver::RTPReceiver(const int32_t id,
max_reordering_threshold_(kDefaultMaxReorderingThreshold),
rtx_(false),
ssrc_rtx_(0),
payload_type_rtx_(-1) {
payload_type_rtx_(-1),
rtt_ms_(kInitialReceiveSideRtt) {
assert(incoming_audio_messages_callback &&
incoming_messages_callback &&
incoming_payload_callback);

View File

@ -158,6 +158,10 @@ class RTPReceiver : public Bitrate {
const uint16_t bytes,
const bool old_packet);
void set_rtt_ms(uint32_t rtt_ms) { rtt_ms_ = rtt_ms; }
uint32_t rtt_ms() const { return rtt_ms_; }
private:
// Returns whether RED is configured with payload_type.
bool REDPayloadType(const int8_t payload_type) const;
@ -237,6 +241,7 @@ class RTPReceiver : public Bitrate {
bool rtx_;
uint32_t ssrc_rtx_;
int payload_type_rtx_;
uint32_t rtt_ms_;
};
} // namespace webrtc

View File

@ -23,6 +23,7 @@ enum { NACK_BYTECOUNT_SIZE = 60}; // size of our NACK history
enum { kSendSideNackListSizeSanity = 20000 };
enum { kDefaultMaxReorderingThreshold = 50 }; // In sequence numbers.
enum { kRtcpMaxNackFields = 253 };
enum { kInitialReceiveSideRtt = 100 };
enum { RTCP_INTERVAL_VIDEO_MS = 1000 };
enum { RTCP_INTERVAL_AUDIO_MS = 5000 };

View File

@ -1224,9 +1224,9 @@ int32_t ModuleRtpRtcpImpl::ResetRTT(const uint32_t remote_ssrc) {
return rtcp_receiver_.ResetRTT(remote_ssrc);
}
void ModuleRtpRtcpImpl:: SetRtt(uint32_t rtt) {
void ModuleRtpRtcpImpl::SetRtt(uint32_t rtt) {
WEBRTC_TRACE(kTraceModuleCall, kTraceRtpRtcp, id_, "SetRtt(rtt: %u)", rtt);
rtcp_receiver_.SetRTT(static_cast<uint16_t>(rtt));
rtp_receiver_->set_rtt_ms(rtt);
}
// Reset RTP statistics.
@ -1545,13 +1545,8 @@ int32_t ModuleRtpRtcpImpl::SendNACK(const uint16_t* nack_list,
id_,
"SendNACK(size:%u)", size);
uint16_t avg_rtt = 0;
rtcp_receiver_.RTT(rtp_receiver_->SSRC(), NULL, &avg_rtt, NULL, NULL);
int64_t wait_time = 5 + ((avg_rtt * 3) >> 1); // 5 + RTT * 1.5.
if (wait_time == 5) {
wait_time = 100; // During startup we don't have an RTT.
}
// 5 + RTT * 1.5.
int64_t wait_time = 5 + ((rtp_receiver_->rtt_ms() * 3) / 2);
const int64_t now = clock_->TimeInMilliseconds();
const int64_t time_limit = now - wait_time;
uint16_t nackLength = size;

View File

@ -23,6 +23,7 @@ namespace webrtc {
const int kRttTimeoutMs = 1500;
// Time interval for updating the observers.
const int kUpdateIntervalMs = 1000;
const uint32_t kInitialRttMs = 200;
class RtcpObserver : public RtcpRttObserver {
public:
@ -42,7 +43,9 @@ class RtcpObserver : public RtcpRttObserver {
CallStats::CallStats()
: crit_(CriticalSectionWrapper::CreateCriticalSection()),
rtcp_rtt_observer_(new RtcpObserver(this)),
last_process_time_(TickTime::MillisecondTimestamp()) {
last_process_time_(TickTime::MillisecondTimestamp()),
last_reported_rtt_(kInitialRttMs),
rtt_report_received_(false) {
}
CallStats::~CallStats() {
@ -73,13 +76,13 @@ int32_t CallStats::Process() {
if (it->rtt > max_rtt)
max_rtt = it->rtt;
}
// If there is a valid rtt, update all observers.
if (max_rtt > 0) {
for (std::list<CallStatsObserver*>::iterator it = observers_.begin();
it != observers_.end(); ++it) {
(*it)->OnRttUpdate(max_rtt);
}
last_reported_rtt_ = max_rtt;
}
// If there is a valid rtt, update all observers.
for (std::list<CallStatsObserver*>::iterator it = observers_.begin();
it != observers_.end(); ++it) {
(*it)->OnRttUpdate(last_reported_rtt_);
}
last_process_time_ = time_now;
return 0;
@ -114,6 +117,7 @@ void CallStats::OnRttUpdate(uint32_t rtt) {
CriticalSectionScoped cs(crit_.get());
int64_t time_now = TickTime::MillisecondTimestamp();
reports_.push_back(RttTime(rtt, time_now));
rtt_report_received_ = true;
}
} // namespace webrtc

View File

@ -68,6 +68,9 @@ class CallStats : public Module {
// Observers getting stats reports.
std::list<CallStatsObserver*> observers_;
uint32_t last_reported_rtt_;
bool rtt_report_received_;
DISALLOW_COPY_AND_ASSIGN(CallStats);
};

View File

@ -22,6 +22,8 @@ using ::testing::Return;
namespace webrtc {
enum { kDefaultRttMs = 200 };
class MockStatsObserver : public CallStatsObserver {
public:
MockStatsObserver() {}
@ -176,4 +178,32 @@ TEST_F(CallStatsTest, ChangeRtt) {
call_stats_->DeregisterStatsObserver(&stats_observer);
}
TEST_F(CallStatsTest, NoRttUpdates) {
MockStatsObserver stats_observer;
call_stats_->RegisterStatsObserver(&stats_observer);
// Advance clock to be ready for an update.
TickTime::AdvanceFakeClock(1000);
EXPECT_CALL(stats_observer, OnRttUpdate(kDefaultRttMs))
.Times(1);
call_stats_->Process();
RtcpRttObserver* rtcp_observer = call_stats_->rtcp_rtt_observer();
const int kNewRtt = 50;
// Report an RTT and verify that it replaces the default.
rtcp_observer->OnRttUpdate(kNewRtt);
TickTime::AdvanceFakeClock(1000);
EXPECT_CALL(stats_observer, OnRttUpdate(kNewRtt))
.Times(1);
call_stats_->Process();
TickTime::AdvanceFakeClock(1500);
// The last reported RTT should still be reported when all reports have
// timed out.
EXPECT_CALL(stats_observer, OnRttUpdate(kNewRtt))
.Times(1);
call_stats_->Process();
call_stats_->DeregisterStatsObserver(&stats_observer);
}
} // namespace webrtc

View File

@ -76,6 +76,8 @@ enum { kViEDefaultRenderDelayMs = 10 };
// ViERTP_RTCP
enum { kSendSidePacketHistorySize = 600 };
enum { kDefaultBufferingRtt = 20 };
enum { kDefaultRealtimeRtt = 200 };
// NACK
enum { kMaxPacketAgeToNack = 450 }; // In sequence numbers.

View File

@ -631,7 +631,7 @@ int ViERTP_RTCPImpl::SetSenderBufferingMode(int video_channel,
}
int ViERTP_RTCPImpl::SetReceiverBufferingMode(int video_channel,
int target_delay_ms) {
int target_delay_ms) {
WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
ViEId(shared_data_->instance_id(), video_channel),
"%s(channel: %d, receiver target_delay: %d)",
@ -645,7 +645,6 @@ int ViERTP_RTCPImpl::SetReceiverBufferingMode(int video_channel,
shared_data_->SetLastError(kViERtpRtcpInvalidChannelId);
return -1;
}
// Update the channel with buffering mode settings.
if (vie_channel->SetReceiverBufferingMode(target_delay_ms) != 0) {
WEBRTC_TRACE(kTraceError, kTraceVideo,