Add decoder-timing stats to VideoReceiveStream.
Also breaks out SsrcStats from VideoReceiveStream::Stats as they don't have that much overlap. R=mflodman@webrtc.org, stefan@webrtc.org BUG=1667, 1788 Review URL: https://webrtc-codereview.appspot.com/40819004 Cr-Commit-Position: refs/heads/master@{#8501} git-svn-id: http://webrtc.googlecode.com/svn/trunk@8501 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
c5558b7021
commit
09c77b95bb
@ -1766,21 +1766,20 @@ WebRtcVideoChannel2::WebRtcVideoSendStream::GetVideoSenderInfo() {
|
|||||||
|
|
||||||
info.send_frame_width = 0;
|
info.send_frame_width = 0;
|
||||||
info.send_frame_height = 0;
|
info.send_frame_height = 0;
|
||||||
for (std::map<uint32_t, webrtc::SsrcStats>::iterator it =
|
for (std::map<uint32_t, webrtc::VideoSendStream::StreamStats>::iterator it =
|
||||||
stats.substreams.begin();
|
stats.substreams.begin();
|
||||||
it != stats.substreams.end();
|
it != stats.substreams.end(); ++it) {
|
||||||
++it) {
|
|
||||||
// TODO(pbos): Wire up additional stats, such as padding bytes.
|
// TODO(pbos): Wire up additional stats, such as padding bytes.
|
||||||
webrtc::SsrcStats stream_stats = it->second;
|
webrtc::VideoSendStream::StreamStats stream_stats = it->second;
|
||||||
info.bytes_sent += stream_stats.rtp_stats.transmitted.payload_bytes +
|
info.bytes_sent += stream_stats.rtp_stats.transmitted.payload_bytes +
|
||||||
stream_stats.rtp_stats.transmitted.header_bytes +
|
stream_stats.rtp_stats.transmitted.header_bytes +
|
||||||
stream_stats.rtp_stats.transmitted.padding_bytes;
|
stream_stats.rtp_stats.transmitted.padding_bytes;
|
||||||
info.packets_sent += stream_stats.rtp_stats.transmitted.packets;
|
info.packets_sent += stream_stats.rtp_stats.transmitted.packets;
|
||||||
info.packets_lost += stream_stats.rtcp_stats.cumulative_lost;
|
info.packets_lost += stream_stats.rtcp_stats.cumulative_lost;
|
||||||
if (stream_stats.sent_width > info.send_frame_width)
|
if (stream_stats.width > info.send_frame_width)
|
||||||
info.send_frame_width = stream_stats.sent_width;
|
info.send_frame_width = stream_stats.width;
|
||||||
if (stream_stats.sent_height > info.send_frame_height)
|
if (stream_stats.height > info.send_frame_height)
|
||||||
info.send_frame_height = stream_stats.sent_height;
|
info.send_frame_height = stream_stats.height;
|
||||||
info.firs_rcvd += stream_stats.rtcp_packet_type_counts.fir_packets;
|
info.firs_rcvd += stream_stats.rtcp_packet_type_counts.fir_packets;
|
||||||
info.nacks_rcvd += stream_stats.rtcp_packet_type_counts.nack_packets;
|
info.nacks_rcvd += stream_stats.rtcp_packet_type_counts.nack_packets;
|
||||||
info.plis_rcvd += stream_stats.rtcp_packet_type_counts.pli_packets;
|
info.plis_rcvd += stream_stats.rtcp_packet_type_counts.pli_packets;
|
||||||
@ -1788,7 +1787,8 @@ WebRtcVideoChannel2::WebRtcVideoSendStream::GetVideoSenderInfo() {
|
|||||||
|
|
||||||
if (!stats.substreams.empty()) {
|
if (!stats.substreams.empty()) {
|
||||||
// TODO(pbos): Report fraction lost per SSRC.
|
// TODO(pbos): Report fraction lost per SSRC.
|
||||||
webrtc::SsrcStats first_stream_stats = stats.substreams.begin()->second;
|
webrtc::VideoSendStream::StreamStats first_stream_stats =
|
||||||
|
stats.substreams.begin()->second;
|
||||||
info.fraction_lost =
|
info.fraction_lost =
|
||||||
static_cast<float>(first_stream_stats.rtcp_stats.fraction_lost) /
|
static_cast<float>(first_stream_stats.rtcp_stats.fraction_lost) /
|
||||||
(1 << 8);
|
(1 << 8);
|
||||||
@ -1804,10 +1804,9 @@ void WebRtcVideoChannel2::WebRtcVideoSendStream::FillBandwidthEstimationInfo(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
webrtc::VideoSendStream::Stats stats = stream_->GetStats();
|
webrtc::VideoSendStream::Stats stats = stream_->GetStats();
|
||||||
for (std::map<uint32_t, webrtc::SsrcStats>::iterator it =
|
for (std::map<uint32_t, webrtc::VideoSendStream::StreamStats>::iterator it =
|
||||||
stats.substreams.begin();
|
stats.substreams.begin();
|
||||||
it != stats.substreams.end();
|
it != stats.substreams.end(); ++it) {
|
||||||
++it) {
|
|
||||||
bwe_info->transmit_bitrate += it->second.total_bitrate_bps;
|
bwe_info->transmit_bitrate += it->second.total_bitrate_bps;
|
||||||
bwe_info->retransmit_bitrate += it->second.retransmit_bitrate_bps;
|
bwe_info->retransmit_bitrate += it->second.retransmit_bitrate_bps;
|
||||||
}
|
}
|
||||||
@ -2043,6 +2042,14 @@ WebRtcVideoChannel2::WebRtcVideoReceiveStream::GetVideoReceiverInfo() {
|
|||||||
info.capture_start_ntp_time_ms = estimated_remote_start_ntp_time_ms_;
|
info.capture_start_ntp_time_ms = estimated_remote_start_ntp_time_ms_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
info.decode_ms = stats.decode_ms;
|
||||||
|
info.max_decode_ms = stats.max_decode_ms;
|
||||||
|
info.current_delay_ms = stats.current_delay_ms;
|
||||||
|
info.target_delay_ms = stats.target_delay_ms;
|
||||||
|
info.jitter_buffer_ms = stats.jitter_buffer_ms;
|
||||||
|
info.min_playout_delay_ms = stats.min_playout_delay_ms;
|
||||||
|
info.render_delay_ms = stats.render_delay_ms;
|
||||||
|
|
||||||
info.firs_sent = stats.rtcp_packet_type_counts.fir_packets;
|
info.firs_sent = stats.rtcp_packet_type_counts.fir_packets;
|
||||||
info.plis_sent = stats.rtcp_packet_type_counts.pli_packets;
|
info.plis_sent = stats.rtcp_packet_type_counts.pli_packets;
|
||||||
info.nacks_sent = stats.rtcp_packet_type_counts.nack_packets;
|
info.nacks_sent = stats.rtcp_packet_type_counts.nack_packets;
|
||||||
|
@ -2041,12 +2041,12 @@ TEST_F(WebRtcVideoChannel2Test, OnReadyToSendSignalsNetworkState) {
|
|||||||
TEST_F(WebRtcVideoChannel2Test, GetStatsReportsUpperResolution) {
|
TEST_F(WebRtcVideoChannel2Test, GetStatsReportsUpperResolution) {
|
||||||
FakeVideoSendStream* stream = AddSendStream();
|
FakeVideoSendStream* stream = AddSendStream();
|
||||||
webrtc::VideoSendStream::Stats stats;
|
webrtc::VideoSendStream::Stats stats;
|
||||||
stats.substreams[17].sent_width = 123;
|
stats.substreams[17].width = 123;
|
||||||
stats.substreams[17].sent_height = 40;
|
stats.substreams[17].height = 40;
|
||||||
stats.substreams[42].sent_width = 80;
|
stats.substreams[42].width = 80;
|
||||||
stats.substreams[42].sent_height = 31;
|
stats.substreams[42].height = 31;
|
||||||
stats.substreams[11].sent_width = 20;
|
stats.substreams[11].width = 20;
|
||||||
stats.substreams[11].sent_height = 90;
|
stats.substreams[11].height = 90;
|
||||||
stream->SetStats(stats);
|
stream->SetStats(stats);
|
||||||
|
|
||||||
cricket::VideoMediaInfo info;
|
cricket::VideoMediaInfo info;
|
||||||
@ -2096,6 +2096,29 @@ TEST_F(WebRtcVideoChannel2Test,
|
|||||||
info.receivers[0].plis_sent);
|
info.receivers[0].plis_sent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(WebRtcVideoChannel2Test, GetStatsTranslatesDecodeStatsCorrectly) {
|
||||||
|
FakeVideoReceiveStream* stream = AddRecvStream();
|
||||||
|
webrtc::VideoReceiveStream::Stats stats;
|
||||||
|
stats.decode_ms = 2;
|
||||||
|
stats.max_decode_ms = 3;
|
||||||
|
stats.current_delay_ms = 4;
|
||||||
|
stats.target_delay_ms = 5;
|
||||||
|
stats.jitter_buffer_ms = 6;
|
||||||
|
stats.min_playout_delay_ms = 7;
|
||||||
|
stats.render_delay_ms = 8;
|
||||||
|
stream->SetStats(stats);
|
||||||
|
|
||||||
|
cricket::VideoMediaInfo info;
|
||||||
|
ASSERT_TRUE(channel_->GetStats(cricket::StatsOptions(), &info));
|
||||||
|
EXPECT_EQ(stats.decode_ms, info.receivers[0].decode_ms);
|
||||||
|
EXPECT_EQ(stats.max_decode_ms, info.receivers[0].max_decode_ms);
|
||||||
|
EXPECT_EQ(stats.current_delay_ms, info.receivers[0].current_delay_ms);
|
||||||
|
EXPECT_EQ(stats.target_delay_ms, info.receivers[0].target_delay_ms);
|
||||||
|
EXPECT_EQ(stats.jitter_buffer_ms, info.receivers[0].jitter_buffer_ms);
|
||||||
|
EXPECT_EQ(stats.min_playout_delay_ms, info.receivers[0].min_playout_delay_ms);
|
||||||
|
EXPECT_EQ(stats.render_delay_ms, info.receivers[0].render_delay_ms);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(WebRtcVideoChannel2Test, TranslatesCallStatsCorrectly) {
|
TEST_F(WebRtcVideoChannel2Test, TranslatesCallStatsCorrectly) {
|
||||||
AddSendStream();
|
AddSendStream();
|
||||||
AddSendStream();
|
AddSendStream();
|
||||||
|
@ -21,27 +21,6 @@
|
|||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
struct SsrcStats {
|
|
||||||
SsrcStats()
|
|
||||||
: sent_width(0),
|
|
||||||
sent_height(0),
|
|
||||||
total_bitrate_bps(0),
|
|
||||||
retransmit_bitrate_bps(0),
|
|
||||||
avg_delay_ms(0),
|
|
||||||
max_delay_ms(0) {}
|
|
||||||
FrameCounts frame_counts;
|
|
||||||
int sent_width;
|
|
||||||
int sent_height;
|
|
||||||
// TODO(holmer): Move bitrate_bps out to the webrtc::Call layer.
|
|
||||||
int total_bitrate_bps;
|
|
||||||
int retransmit_bitrate_bps;
|
|
||||||
int avg_delay_ms;
|
|
||||||
int max_delay_ms;
|
|
||||||
StreamDataCounters rtp_stats;
|
|
||||||
RtcpPacketTypeCounter rtcp_packet_type_counts;
|
|
||||||
RtcpStatistics rtcp_stats;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Settings for NACK, see RFC 4585 for details.
|
// Settings for NACK, see RFC 4585 for details.
|
||||||
struct NackConfig {
|
struct NackConfig {
|
||||||
NackConfig() : rtp_history_ms(0) {}
|
NackConfig() : rtp_history_ms(0) {}
|
||||||
|
@ -1630,7 +1630,7 @@ TEST_F(EndToEndTest, GetStats) {
|
|||||||
stats.rtp_stats.retransmitted.packets != 0;
|
stats.rtp_stats.retransmitted.packets != 0;
|
||||||
|
|
||||||
receive_stats_filled_["CodecStats"] |=
|
receive_stats_filled_["CodecStats"] |=
|
||||||
stats.avg_delay_ms != 0 || stats.discarded_packets != 0;
|
stats.target_delay_ms != 0 || stats.discarded_packets != 0;
|
||||||
|
|
||||||
receive_stats_filled_["FrameCounts"] |=
|
receive_stats_filled_["FrameCounts"] |=
|
||||||
stats.frame_counts.key_frames != 0 ||
|
stats.frame_counts.key_frames != 0 ||
|
||||||
@ -1656,17 +1656,16 @@ TEST_F(EndToEndTest, GetStats) {
|
|||||||
send_stats_filled_["NumStreams"] |=
|
send_stats_filled_["NumStreams"] |=
|
||||||
stats.substreams.size() == expected_send_ssrcs_.size();
|
stats.substreams.size() == expected_send_ssrcs_.size();
|
||||||
|
|
||||||
for (std::map<uint32_t, SsrcStats>::const_iterator it =
|
for (std::map<uint32_t, VideoSendStream::StreamStats>::const_iterator it =
|
||||||
stats.substreams.begin();
|
stats.substreams.begin();
|
||||||
it != stats.substreams.end();
|
it != stats.substreams.end(); ++it) {
|
||||||
++it) {
|
|
||||||
EXPECT_TRUE(expected_send_ssrcs_.find(it->first) !=
|
EXPECT_TRUE(expected_send_ssrcs_.find(it->first) !=
|
||||||
expected_send_ssrcs_.end());
|
expected_send_ssrcs_.end());
|
||||||
|
|
||||||
send_stats_filled_[CompoundKey("CapturedFrameRate", it->first)] |=
|
send_stats_filled_[CompoundKey("CapturedFrameRate", it->first)] |=
|
||||||
stats.input_frame_rate != 0;
|
stats.input_frame_rate != 0;
|
||||||
|
|
||||||
const SsrcStats& stream_stats = it->second;
|
const VideoSendStream::StreamStats& stream_stats = it->second;
|
||||||
|
|
||||||
send_stats_filled_[CompoundKey("StatisticsUpdated", it->first)] |=
|
send_stats_filled_[CompoundKey("StatisticsUpdated", it->first)] |=
|
||||||
stream_stats.rtcp_stats.cumulative_lost != 0 ||
|
stream_stats.rtcp_stats.cumulative_lost != 0 ||
|
||||||
|
@ -47,7 +47,13 @@ void ReceiveStatisticsProxy::DecoderTiming(int decode_ms,
|
|||||||
int min_playout_delay_ms,
|
int min_playout_delay_ms,
|
||||||
int render_delay_ms) {
|
int render_delay_ms) {
|
||||||
CriticalSectionScoped lock(crit_.get());
|
CriticalSectionScoped lock(crit_.get());
|
||||||
stats_.avg_delay_ms = target_delay_ms;
|
stats_.decode_ms = decode_ms;
|
||||||
|
stats_.max_decode_ms = max_decode_ms;
|
||||||
|
stats_.current_delay_ms = current_delay_ms;
|
||||||
|
stats_.target_delay_ms = target_delay_ms;
|
||||||
|
stats_.jitter_buffer_ms = jitter_buffer_ms;
|
||||||
|
stats_.min_playout_delay_ms = min_playout_delay_ms;
|
||||||
|
stats_.render_delay_ms = render_delay_ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReceiveStatisticsProxy::RtcpPacketTypesCounterUpdated(
|
void ReceiveStatisticsProxy::RtcpPacketTypesCounterUpdated(
|
||||||
|
@ -57,20 +57,23 @@ VideoSendStream::Stats SendStatisticsProxy::GetStats() {
|
|||||||
|
|
||||||
void SendStatisticsProxy::PurgeOldStats() {
|
void SendStatisticsProxy::PurgeOldStats() {
|
||||||
int64_t current_time_ms = clock_->TimeInMilliseconds();
|
int64_t current_time_ms = clock_->TimeInMilliseconds();
|
||||||
for (std::map<uint32_t, SsrcStats>::iterator it = stats_.substreams.begin();
|
for (std::map<uint32_t, VideoSendStream::StreamStats>::iterator it =
|
||||||
|
stats_.substreams.begin();
|
||||||
it != stats_.substreams.end(); ++it) {
|
it != stats_.substreams.end(); ++it) {
|
||||||
uint32_t ssrc = it->first;
|
uint32_t ssrc = it->first;
|
||||||
if (update_times_[ssrc].resolution_update_ms + kStatsTimeoutMs >
|
if (update_times_[ssrc].resolution_update_ms + kStatsTimeoutMs >
|
||||||
current_time_ms)
|
current_time_ms)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
it->second.sent_width = 0;
|
it->second.width = 0;
|
||||||
it->second.sent_height = 0;
|
it->second.height = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SsrcStats* SendStatisticsProxy::GetStatsEntry(uint32_t ssrc) {
|
VideoSendStream::StreamStats* SendStatisticsProxy::GetStatsEntry(
|
||||||
std::map<uint32_t, SsrcStats>::iterator it = stats_.substreams.find(ssrc);
|
uint32_t ssrc) {
|
||||||
|
std::map<uint32_t, VideoSendStream::StreamStats>::iterator it =
|
||||||
|
stats_.substreams.find(ssrc);
|
||||||
if (it != stats_.substreams.end())
|
if (it != stats_.substreams.end())
|
||||||
return &it->second;
|
return &it->second;
|
||||||
|
|
||||||
@ -98,12 +101,12 @@ void SendStatisticsProxy::OnSendEncodedImage(
|
|||||||
uint32_t ssrc = config_.rtp.ssrcs[simulcast_idx];
|
uint32_t ssrc = config_.rtp.ssrcs[simulcast_idx];
|
||||||
|
|
||||||
CriticalSectionScoped lock(crit_.get());
|
CriticalSectionScoped lock(crit_.get());
|
||||||
SsrcStats* stats = GetStatsEntry(ssrc);
|
VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
|
||||||
if (stats == NULL)
|
if (stats == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
stats->sent_width = encoded_image._encodedWidth;
|
stats->width = encoded_image._encodedWidth;
|
||||||
stats->sent_height = encoded_image._encodedHeight;
|
stats->height = encoded_image._encodedHeight;
|
||||||
update_times_[ssrc].resolution_update_ms = clock_->TimeInMilliseconds();
|
update_times_[ssrc].resolution_update_ms = clock_->TimeInMilliseconds();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,7 +114,7 @@ void SendStatisticsProxy::RtcpPacketTypesCounterUpdated(
|
|||||||
uint32_t ssrc,
|
uint32_t ssrc,
|
||||||
const RtcpPacketTypeCounter& packet_counter) {
|
const RtcpPacketTypeCounter& packet_counter) {
|
||||||
CriticalSectionScoped lock(crit_.get());
|
CriticalSectionScoped lock(crit_.get());
|
||||||
SsrcStats* stats = GetStatsEntry(ssrc);
|
VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
|
||||||
if (stats == NULL)
|
if (stats == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -121,7 +124,7 @@ void SendStatisticsProxy::RtcpPacketTypesCounterUpdated(
|
|||||||
void SendStatisticsProxy::StatisticsUpdated(const RtcpStatistics& statistics,
|
void SendStatisticsProxy::StatisticsUpdated(const RtcpStatistics& statistics,
|
||||||
uint32_t ssrc) {
|
uint32_t ssrc) {
|
||||||
CriticalSectionScoped lock(crit_.get());
|
CriticalSectionScoped lock(crit_.get());
|
||||||
SsrcStats* stats = GetStatsEntry(ssrc);
|
VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
|
||||||
if (stats == NULL)
|
if (stats == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -135,11 +138,9 @@ void SendStatisticsProxy::DataCountersUpdated(
|
|||||||
const StreamDataCounters& counters,
|
const StreamDataCounters& counters,
|
||||||
uint32_t ssrc) {
|
uint32_t ssrc) {
|
||||||
CriticalSectionScoped lock(crit_.get());
|
CriticalSectionScoped lock(crit_.get());
|
||||||
SsrcStats* stats = GetStatsEntry(ssrc);
|
VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
|
||||||
DCHECK(stats != NULL) << "DataCountersUpdated reported for unknown ssrc: "
|
DCHECK(stats != NULL) << "DataCountersUpdated reported for unknown ssrc: "
|
||||||
<< ssrc;
|
<< ssrc;
|
||||||
if (stats == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
stats->rtp_stats = counters;
|
stats->rtp_stats = counters;
|
||||||
}
|
}
|
||||||
@ -148,7 +149,7 @@ void SendStatisticsProxy::Notify(const BitrateStatistics& total_stats,
|
|||||||
const BitrateStatistics& retransmit_stats,
|
const BitrateStatistics& retransmit_stats,
|
||||||
uint32_t ssrc) {
|
uint32_t ssrc) {
|
||||||
CriticalSectionScoped lock(crit_.get());
|
CriticalSectionScoped lock(crit_.get());
|
||||||
SsrcStats* stats = GetStatsEntry(ssrc);
|
VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
|
||||||
if (stats == NULL)
|
if (stats == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -159,7 +160,7 @@ void SendStatisticsProxy::Notify(const BitrateStatistics& total_stats,
|
|||||||
void SendStatisticsProxy::FrameCountUpdated(const FrameCounts& frame_counts,
|
void SendStatisticsProxy::FrameCountUpdated(const FrameCounts& frame_counts,
|
||||||
uint32_t ssrc) {
|
uint32_t ssrc) {
|
||||||
CriticalSectionScoped lock(crit_.get());
|
CriticalSectionScoped lock(crit_.get());
|
||||||
SsrcStats* stats = GetStatsEntry(ssrc);
|
VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
|
||||||
if (stats == NULL)
|
if (stats == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -170,7 +171,7 @@ void SendStatisticsProxy::SendSideDelayUpdated(int avg_delay_ms,
|
|||||||
int max_delay_ms,
|
int max_delay_ms,
|
||||||
uint32_t ssrc) {
|
uint32_t ssrc) {
|
||||||
CriticalSectionScoped lock(crit_.get());
|
CriticalSectionScoped lock(crit_.get());
|
||||||
SsrcStats* stats = GetStatsEntry(ssrc);
|
VideoSendStream::StreamStats* stats = GetStatsEntry(ssrc);
|
||||||
if (stats == NULL)
|
if (stats == NULL)
|
||||||
return;
|
return;
|
||||||
stats->avg_delay_ms = avg_delay_ms;
|
stats->avg_delay_ms = avg_delay_ms;
|
||||||
|
@ -94,7 +94,8 @@ class SendStatisticsProxy : public RtcpStatisticsCallback,
|
|||||||
int64_t resolution_update_ms;
|
int64_t resolution_update_ms;
|
||||||
};
|
};
|
||||||
void PurgeOldStats() EXCLUSIVE_LOCKS_REQUIRED(crit_);
|
void PurgeOldStats() EXCLUSIVE_LOCKS_REQUIRED(crit_);
|
||||||
SsrcStats* GetStatsEntry(uint32_t ssrc) EXCLUSIVE_LOCKS_REQUIRED(crit_);
|
VideoSendStream::StreamStats* GetStatsEntry(uint32_t ssrc)
|
||||||
|
EXCLUSIVE_LOCKS_REQUIRED(crit_);
|
||||||
|
|
||||||
Clock* const clock_;
|
Clock* const clock_;
|
||||||
const VideoSendStream::Config config_;
|
const VideoSendStream::Config config_;
|
||||||
|
@ -49,15 +49,14 @@ class SendStatisticsProxyTest : public ::testing::Test {
|
|||||||
EXPECT_EQ(one.suspended, other.suspended);
|
EXPECT_EQ(one.suspended, other.suspended);
|
||||||
|
|
||||||
EXPECT_EQ(one.substreams.size(), other.substreams.size());
|
EXPECT_EQ(one.substreams.size(), other.substreams.size());
|
||||||
for (std::map<uint32_t, SsrcStats>::const_iterator it =
|
for (std::map<uint32_t, VideoSendStream::StreamStats>::const_iterator it =
|
||||||
one.substreams.begin();
|
one.substreams.begin();
|
||||||
it != one.substreams.end();
|
it != one.substreams.end(); ++it) {
|
||||||
++it) {
|
std::map<uint32_t, VideoSendStream::StreamStats>::const_iterator
|
||||||
std::map<uint32_t, SsrcStats>::const_iterator corresponding_it =
|
corresponding_it = other.substreams.find(it->first);
|
||||||
other.substreams.find(it->first);
|
|
||||||
ASSERT_TRUE(corresponding_it != other.substreams.end());
|
ASSERT_TRUE(corresponding_it != other.substreams.end());
|
||||||
const SsrcStats& a = it->second;
|
const VideoSendStream::StreamStats& a = it->second;
|
||||||
const SsrcStats& b = corresponding_it->second;
|
const VideoSendStream::StreamStats& b = corresponding_it->second;
|
||||||
|
|
||||||
EXPECT_EQ(a.frame_counts.key_frames, b.frame_counts.key_frames);
|
EXPECT_EQ(a.frame_counts.key_frames, b.frame_counts.key_frames);
|
||||||
EXPECT_EQ(a.frame_counts.delta_frames, b.frame_counts.delta_frames);
|
EXPECT_EQ(a.frame_counts.delta_frames, b.frame_counts.delta_frames);
|
||||||
@ -91,7 +90,8 @@ class SendStatisticsProxyTest : public ::testing::Test {
|
|||||||
int avg_delay_ms_;
|
int avg_delay_ms_;
|
||||||
int max_delay_ms_;
|
int max_delay_ms_;
|
||||||
VideoSendStream::Stats expected_;
|
VideoSendStream::Stats expected_;
|
||||||
typedef std::map<uint32_t, SsrcStats>::const_iterator StreamIterator;
|
typedef std::map<uint32_t, VideoSendStream::StreamStats>::const_iterator
|
||||||
|
StreamIterator;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(SendStatisticsProxyTest, RtcpStatistics) {
|
TEST_F(SendStatisticsProxyTest, RtcpStatistics) {
|
||||||
@ -100,7 +100,7 @@ TEST_F(SendStatisticsProxyTest, RtcpStatistics) {
|
|||||||
it != config_.rtp.ssrcs.end();
|
it != config_.rtp.ssrcs.end();
|
||||||
++it) {
|
++it) {
|
||||||
const uint32_t ssrc = *it;
|
const uint32_t ssrc = *it;
|
||||||
SsrcStats& ssrc_stats = expected_.substreams[ssrc];
|
VideoSendStream::StreamStats& ssrc_stats = expected_.substreams[ssrc];
|
||||||
|
|
||||||
// Add statistics with some arbitrary, but unique, numbers.
|
// Add statistics with some arbitrary, but unique, numbers.
|
||||||
uint32_t offset = ssrc * sizeof(RtcpStatistics);
|
uint32_t offset = ssrc * sizeof(RtcpStatistics);
|
||||||
@ -114,7 +114,7 @@ TEST_F(SendStatisticsProxyTest, RtcpStatistics) {
|
|||||||
it != config_.rtp.rtx.ssrcs.end();
|
it != config_.rtp.rtx.ssrcs.end();
|
||||||
++it) {
|
++it) {
|
||||||
const uint32_t ssrc = *it;
|
const uint32_t ssrc = *it;
|
||||||
SsrcStats& ssrc_stats = expected_.substreams[ssrc];
|
VideoSendStream::StreamStats& ssrc_stats = expected_.substreams[ssrc];
|
||||||
|
|
||||||
// Add statistics with some arbitrary, but unique, numbers.
|
// Add statistics with some arbitrary, but unique, numbers.
|
||||||
uint32_t offset = ssrc * sizeof(RtcpStatistics);
|
uint32_t offset = ssrc * sizeof(RtcpStatistics);
|
||||||
@ -171,8 +171,8 @@ TEST_F(SendStatisticsProxyTest, FrameCounts) {
|
|||||||
++it) {
|
++it) {
|
||||||
const uint32_t ssrc = *it;
|
const uint32_t ssrc = *it;
|
||||||
// Add statistics with some arbitrary, but unique, numbers.
|
// Add statistics with some arbitrary, but unique, numbers.
|
||||||
SsrcStats& stats = expected_.substreams[ssrc];
|
VideoSendStream::StreamStats& stats = expected_.substreams[ssrc];
|
||||||
uint32_t offset = ssrc * sizeof(SsrcStats);
|
uint32_t offset = ssrc * sizeof(VideoSendStream::StreamStats);
|
||||||
FrameCounts frame_counts;
|
FrameCounts frame_counts;
|
||||||
frame_counts.key_frames = offset;
|
frame_counts.key_frames = offset;
|
||||||
frame_counts.delta_frames = offset + 1;
|
frame_counts.delta_frames = offset + 1;
|
||||||
@ -184,8 +184,8 @@ TEST_F(SendStatisticsProxyTest, FrameCounts) {
|
|||||||
++it) {
|
++it) {
|
||||||
const uint32_t ssrc = *it;
|
const uint32_t ssrc = *it;
|
||||||
// Add statistics with some arbitrary, but unique, numbers.
|
// Add statistics with some arbitrary, but unique, numbers.
|
||||||
SsrcStats& stats = expected_.substreams[ssrc];
|
VideoSendStream::StreamStats& stats = expected_.substreams[ssrc];
|
||||||
uint32_t offset = ssrc * sizeof(SsrcStats);
|
uint32_t offset = ssrc * sizeof(VideoSendStream::StreamStats);
|
||||||
FrameCounts frame_counts;
|
FrameCounts frame_counts;
|
||||||
frame_counts.key_frames = offset;
|
frame_counts.key_frames = offset;
|
||||||
frame_counts.delta_frames = offset + 1;
|
frame_counts.delta_frames = offset + 1;
|
||||||
@ -342,16 +342,16 @@ TEST_F(SendStatisticsProxyTest, EncodedResolutionTimesOut) {
|
|||||||
statistics_proxy_->OnSendEncodedImage(encoded_image, &rtp_video_header);
|
statistics_proxy_->OnSendEncodedImage(encoded_image, &rtp_video_header);
|
||||||
|
|
||||||
VideoSendStream::Stats stats = statistics_proxy_->GetStats();
|
VideoSendStream::Stats stats = statistics_proxy_->GetStats();
|
||||||
EXPECT_EQ(kEncodedWidth, stats.substreams[config_.rtp.ssrcs[0]].sent_width);
|
EXPECT_EQ(kEncodedWidth, stats.substreams[config_.rtp.ssrcs[0]].width);
|
||||||
EXPECT_EQ(kEncodedHeight, stats.substreams[config_.rtp.ssrcs[0]].sent_height);
|
EXPECT_EQ(kEncodedHeight, stats.substreams[config_.rtp.ssrcs[0]].height);
|
||||||
EXPECT_EQ(kEncodedWidth, stats.substreams[config_.rtp.ssrcs[1]].sent_width);
|
EXPECT_EQ(kEncodedWidth, stats.substreams[config_.rtp.ssrcs[1]].width);
|
||||||
EXPECT_EQ(kEncodedHeight, stats.substreams[config_.rtp.ssrcs[1]].sent_height);
|
EXPECT_EQ(kEncodedHeight, stats.substreams[config_.rtp.ssrcs[1]].height);
|
||||||
|
|
||||||
// Forward almost to timeout, this should not have removed stats.
|
// Forward almost to timeout, this should not have removed stats.
|
||||||
fake_clock_.AdvanceTimeMilliseconds(SendStatisticsProxy::kStatsTimeoutMs - 1);
|
fake_clock_.AdvanceTimeMilliseconds(SendStatisticsProxy::kStatsTimeoutMs - 1);
|
||||||
stats = statistics_proxy_->GetStats();
|
stats = statistics_proxy_->GetStats();
|
||||||
EXPECT_EQ(kEncodedWidth, stats.substreams[config_.rtp.ssrcs[0]].sent_width);
|
EXPECT_EQ(kEncodedWidth, stats.substreams[config_.rtp.ssrcs[0]].width);
|
||||||
EXPECT_EQ(kEncodedHeight, stats.substreams[config_.rtp.ssrcs[0]].sent_height);
|
EXPECT_EQ(kEncodedHeight, stats.substreams[config_.rtp.ssrcs[0]].height);
|
||||||
|
|
||||||
// Update the first SSRC with bogus RTCP stats to make sure that encoded
|
// Update the first SSRC with bogus RTCP stats to make sure that encoded
|
||||||
// resolution still times out (no global timeout for all stats).
|
// resolution still times out (no global timeout for all stats).
|
||||||
@ -368,10 +368,10 @@ TEST_F(SendStatisticsProxyTest, EncodedResolutionTimesOut) {
|
|||||||
// reported, but substream 1 should.
|
// reported, but substream 1 should.
|
||||||
fake_clock_.AdvanceTimeMilliseconds(1);
|
fake_clock_.AdvanceTimeMilliseconds(1);
|
||||||
stats = statistics_proxy_->GetStats();
|
stats = statistics_proxy_->GetStats();
|
||||||
EXPECT_EQ(0, stats.substreams[config_.rtp.ssrcs[0]].sent_width);
|
EXPECT_EQ(0, stats.substreams[config_.rtp.ssrcs[0]].width);
|
||||||
EXPECT_EQ(0, stats.substreams[config_.rtp.ssrcs[0]].sent_height);
|
EXPECT_EQ(0, stats.substreams[config_.rtp.ssrcs[0]].height);
|
||||||
EXPECT_EQ(kEncodedWidth, stats.substreams[config_.rtp.ssrcs[1]].sent_width);
|
EXPECT_EQ(kEncodedWidth, stats.substreams[config_.rtp.ssrcs[1]].width);
|
||||||
EXPECT_EQ(kEncodedHeight, stats.substreams[config_.rtp.ssrcs[1]].sent_height);
|
EXPECT_EQ(kEncodedHeight, stats.substreams[config_.rtp.ssrcs[1]].height);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
@ -1673,9 +1673,10 @@ TEST_F(VideoSendStreamTest, ReportsSentResolution) {
|
|||||||
stats.substreams.end())
|
stats.substreams.end())
|
||||||
<< "No stats for SSRC: " << kSendSsrcs[i]
|
<< "No stats for SSRC: " << kSendSsrcs[i]
|
||||||
<< ", stats should exist as soon as frames have been encoded.";
|
<< ", stats should exist as soon as frames have been encoded.";
|
||||||
SsrcStats ssrc_stats = stats.substreams[kSendSsrcs[i]];
|
VideoSendStream::StreamStats ssrc_stats =
|
||||||
EXPECT_EQ(kEncodedResolution[i].width, ssrc_stats.sent_width);
|
stats.substreams[kSendSsrcs[i]];
|
||||||
EXPECT_EQ(kEncodedResolution[i].height, ssrc_stats.sent_height);
|
EXPECT_EQ(kEncodedResolution[i].width, ssrc_stats.width);
|
||||||
|
EXPECT_EQ(kEncodedResolution[i].height, ssrc_stats.height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,22 +64,29 @@ class VideoReceiveStream {
|
|||||||
int expected_delay_ms;
|
int expected_delay_ms;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Stats : public SsrcStats {
|
struct Stats {
|
||||||
Stats()
|
int network_frame_rate = 0;
|
||||||
: network_frame_rate(0),
|
int decode_frame_rate = 0;
|
||||||
decode_frame_rate(0),
|
int render_frame_rate = 0;
|
||||||
render_frame_rate(0),
|
|
||||||
avg_delay_ms(0),
|
|
||||||
discarded_packets(0),
|
|
||||||
ssrc(0) {}
|
|
||||||
|
|
||||||
int network_frame_rate;
|
// Decoder stats.
|
||||||
int decode_frame_rate;
|
FrameCounts frame_counts;
|
||||||
int render_frame_rate;
|
int decode_ms = 0;
|
||||||
int avg_delay_ms;
|
int max_decode_ms = 0;
|
||||||
int discarded_packets;
|
int current_delay_ms = 0;
|
||||||
uint32_t ssrc;
|
int target_delay_ms = 0;
|
||||||
|
int jitter_buffer_ms = 0;
|
||||||
|
int min_playout_delay_ms = 0;
|
||||||
|
int render_delay_ms = 0;
|
||||||
|
|
||||||
|
int total_bitrate_bps = 0;
|
||||||
|
int discarded_packets = 0;
|
||||||
|
|
||||||
|
uint32_t ssrc = 0;
|
||||||
std::string c_name;
|
std::string c_name;
|
||||||
|
StreamDataCounters rtp_stats;
|
||||||
|
RtcpPacketTypeCounter rtcp_packet_type_counts;
|
||||||
|
RtcpStatistics rtcp_stats;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Config {
|
struct Config {
|
||||||
|
@ -37,6 +37,20 @@ class VideoSendStreamInput {
|
|||||||
|
|
||||||
class VideoSendStream {
|
class VideoSendStream {
|
||||||
public:
|
public:
|
||||||
|
struct StreamStats {
|
||||||
|
FrameCounts frame_counts;
|
||||||
|
int width = 0;
|
||||||
|
int height = 0;
|
||||||
|
// TODO(holmer): Move bitrate_bps out to the webrtc::Call layer.
|
||||||
|
int total_bitrate_bps = 0;
|
||||||
|
int retransmit_bitrate_bps = 0;
|
||||||
|
int avg_delay_ms = 0;
|
||||||
|
int max_delay_ms = 0;
|
||||||
|
StreamDataCounters rtp_stats;
|
||||||
|
RtcpPacketTypeCounter rtcp_packet_type_counts;
|
||||||
|
RtcpStatistics rtcp_stats;
|
||||||
|
};
|
||||||
|
|
||||||
struct Stats {
|
struct Stats {
|
||||||
Stats()
|
Stats()
|
||||||
: input_frame_rate(0),
|
: input_frame_rate(0),
|
||||||
@ -47,7 +61,7 @@ class VideoSendStream {
|
|||||||
int encode_frame_rate;
|
int encode_frame_rate;
|
||||||
int media_bitrate_bps;
|
int media_bitrate_bps;
|
||||||
bool suspended;
|
bool suspended;
|
||||||
std::map<uint32_t, SsrcStats> substreams;
|
std::map<uint32_t, StreamStats> substreams;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Config {
|
struct Config {
|
||||||
|
Loading…
Reference in New Issue
Block a user