[Stats] Populate "frames" stats for video source.

Spec: https://www.w3.org/TR/webrtc-stats/#dom-rtcvideosourcestats-frames

Wiring up the "frames" stats with the cumulative fps counter on the video source.

Tests:
./out/Default/peerconnection_unittests
./out/Default/video_engine_tests

Bug: webrtc:12499
Change-Id: I4103f56ed04cb464f5f7e70fbf2d77c25a867a68
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/208782
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#33404}
This commit is contained in:
Di Wu 2021-02-27 00:29:15 -08:00 committed by Commit Bot
parent 5ab9b32ee6
commit 668dbf66ce
9 changed files with 11 additions and 6 deletions

View File

@ -603,7 +603,6 @@ class RTC_EXPORT RTCVideoSourceStats final : public RTCMediaSourceStats {
RTCStatsMember<uint32_t> width; RTCStatsMember<uint32_t> width;
RTCStatsMember<uint32_t> height; RTCStatsMember<uint32_t> height;
// TODO(hbos): Implement this metric.
RTCStatsMember<uint32_t> frames; RTCStatsMember<uint32_t> frames;
RTCStatsMember<uint32_t> frames_per_second; RTCStatsMember<uint32_t> frames_per_second;
}; };

View File

@ -108,6 +108,7 @@ class VideoSendStream {
uint64_t total_encode_time_ms = 0; uint64_t total_encode_time_ms = 0;
// https://w3c.github.io/webrtc-stats/#dom-rtcoutboundrtpstreamstats-totalencodedbytestarget // https://w3c.github.io/webrtc-stats/#dom-rtcoutboundrtpstreamstats-totalencodedbytestarget
uint64_t total_encoded_bytes_target = 0; uint64_t total_encoded_bytes_target = 0;
uint32_t frames = 0;
uint32_t frames_dropped_by_capturer = 0; uint32_t frames_dropped_by_capturer = 0;
uint32_t frames_dropped_by_encoder_queue = 0; uint32_t frames_dropped_by_encoder_queue = 0;
uint32_t frames_dropped_by_rate_limiter = 0; uint32_t frames_dropped_by_rate_limiter = 0;

View File

@ -548,6 +548,7 @@ struct VideoSenderInfo : public MediaSenderInfo {
int nacks_rcvd = 0; int nacks_rcvd = 0;
int send_frame_width = 0; int send_frame_width = 0;
int send_frame_height = 0; int send_frame_height = 0;
int frames = 0;
int framerate_input = 0; int framerate_input = 0;
int framerate_sent = 0; int framerate_sent = 0;
int aggregated_framerate_sent = 0; int aggregated_framerate_sent = 0;

View File

@ -2574,6 +2574,7 @@ WebRtcVideoChannel::WebRtcVideoSendStream::GetPerLayerVideoSenderInfos(
stats.quality_limitation_resolution_changes; stats.quality_limitation_resolution_changes;
common_info.encoder_implementation_name = stats.encoder_implementation_name; common_info.encoder_implementation_name = stats.encoder_implementation_name;
common_info.ssrc_groups = ssrc_groups_; common_info.ssrc_groups = ssrc_groups_;
common_info.frames = stats.frames;
common_info.framerate_input = stats.input_frame_rate; common_info.framerate_input = stats.input_frame_rate;
common_info.avg_encode_ms = stats.avg_encode_time_ms; common_info.avg_encode_ms = stats.avg_encode_time_ms;
common_info.encode_usage_percent = stats.encode_usage_percent; common_info.encode_usage_percent = stats.encode_usage_percent;

View File

@ -1620,6 +1620,7 @@ void RTCStatsCollector::ProduceMediaSourceStats_s(
if (video_sender_info) { if (video_sender_info) {
video_source_stats->frames_per_second = video_source_stats->frames_per_second =
video_sender_info->framerate_input; video_sender_info->framerate_input;
video_source_stats->frames = video_sender_info->frames;
} }
} }
media_source_stats = std::move(video_source_stats); media_source_stats = std::move(video_source_stats);

View File

@ -2474,6 +2474,7 @@ TEST_F(RTCStatsCollectorTest, RTCVideoSourceStatsCollectedForSenderWithTrack) {
cricket::SsrcSenderInfo()); cricket::SsrcSenderInfo());
video_media_info.aggregated_senders[0].local_stats[0].ssrc = kSsrc; video_media_info.aggregated_senders[0].local_stats[0].ssrc = kSsrc;
video_media_info.aggregated_senders[0].framerate_input = 29; video_media_info.aggregated_senders[0].framerate_input = 29;
video_media_info.aggregated_senders[0].frames = 10001;
auto* video_media_channel = pc_->AddVideoChannel("VideoMid", "TransportName"); auto* video_media_channel = pc_->AddVideoChannel("VideoMid", "TransportName");
video_media_channel->SetStats(video_media_info); video_media_channel->SetStats(video_media_info);
@ -2493,9 +2494,8 @@ TEST_F(RTCStatsCollectorTest, RTCVideoSourceStatsCollectedForSenderWithTrack) {
expected_video.kind = "video"; expected_video.kind = "video";
expected_video.width = kVideoSourceWidth; expected_video.width = kVideoSourceWidth;
expected_video.height = kVideoSourceHeight; expected_video.height = kVideoSourceHeight;
// |expected_video.frames| is expected to be undefined because it is not set.
// TODO(hbos): When implemented, set its expected value here.
expected_video.frames_per_second = 29; expected_video.frames_per_second = 29;
expected_video.frames = 10001;
ASSERT_TRUE(report->Get(expected_video.id())); ASSERT_TRUE(report->Get(expected_video.id()));
EXPECT_EQ(report->Get(expected_video.id())->cast_to<RTCVideoSourceStats>(), EXPECT_EQ(report->Get(expected_video.id())->cast_to<RTCVideoSourceStats>(),
@ -2535,6 +2535,7 @@ TEST_F(RTCStatsCollectorTest,
auto video_stats = auto video_stats =
report->Get("RTCVideoSource_42")->cast_to<RTCVideoSourceStats>(); report->Get("RTCVideoSource_42")->cast_to<RTCVideoSourceStats>();
EXPECT_FALSE(video_stats.frames_per_second.is_defined()); EXPECT_FALSE(video_stats.frames_per_second.is_defined());
EXPECT_FALSE(video_stats.frames.is_defined());
} }
// The track not having a source is not expected to be true in practise, but // The track not having a source is not expected to be true in practise, but

View File

@ -1062,9 +1062,7 @@ class RTCStatsReportVerifier {
// reflect real code. // reflect real code.
verifier.TestMemberIsUndefined(video_source.width); verifier.TestMemberIsUndefined(video_source.width);
verifier.TestMemberIsUndefined(video_source.height); verifier.TestMemberIsUndefined(video_source.height);
// TODO(hbos): When |frames| is implemented test that this member should be verifier.TestMemberIsNonNegative<uint32_t>(video_source.frames);
// expected to be non-negative.
verifier.TestMemberIsUndefined(video_source.frames);
verifier.TestMemberIsNonNegative<uint32_t>(video_source.frames_per_second); verifier.TestMemberIsNonNegative<uint32_t>(video_source.frames_per_second);
return verifier.ExpectAllMembersSuccessfullyTested(); return verifier.ExpectAllMembersSuccessfullyTested();
} }

View File

@ -737,6 +737,8 @@ VideoSendStream::Stats SendStatisticsProxy::GetStats() {
PurgeOldStats(); PurgeOldStats();
stats_.input_frame_rate = stats_.input_frame_rate =
round(uma_container_->input_frame_rate_tracker_.ComputeRate()); round(uma_container_->input_frame_rate_tracker_.ComputeRate());
stats_.frames =
uma_container_->input_frame_rate_tracker_.TotalSampleCount();
stats_.content_type = stats_.content_type =
content_type_ == VideoEncoderConfig::ContentType::kRealtimeVideo content_type_ == VideoEncoderConfig::ContentType::kRealtimeVideo
? VideoContentType::UNSPECIFIED ? VideoContentType::UNSPECIFIED

View File

@ -126,6 +126,7 @@ class SendStatisticsProxyTest : public ::testing::Test {
} }
void ExpectEqual(VideoSendStream::Stats one, VideoSendStream::Stats other) { void ExpectEqual(VideoSendStream::Stats one, VideoSendStream::Stats other) {
EXPECT_EQ(one.frames, other.frames);
EXPECT_EQ(one.input_frame_rate, other.input_frame_rate); EXPECT_EQ(one.input_frame_rate, other.input_frame_rate);
EXPECT_EQ(one.encode_frame_rate, other.encode_frame_rate); EXPECT_EQ(one.encode_frame_rate, other.encode_frame_rate);
EXPECT_EQ(one.media_bitrate_bps, other.media_bitrate_bps); EXPECT_EQ(one.media_bitrate_bps, other.media_bitrate_bps);