diff --git a/api/stats/rtcstats_objects.h b/api/stats/rtcstats_objects.h index 46bc018372..7590a620c2 100644 --- a/api/stats/rtcstats_objects.h +++ b/api/stats/rtcstats_objects.h @@ -603,7 +603,6 @@ class RTC_EXPORT RTCVideoSourceStats final : public RTCMediaSourceStats { RTCStatsMember width; RTCStatsMember height; - // TODO(hbos): Implement this metric. RTCStatsMember frames; RTCStatsMember frames_per_second; }; diff --git a/call/video_send_stream.h b/call/video_send_stream.h index 0df9e6ce05..5c8906fbaf 100644 --- a/call/video_send_stream.h +++ b/call/video_send_stream.h @@ -108,6 +108,7 @@ class VideoSendStream { uint64_t total_encode_time_ms = 0; // https://w3c.github.io/webrtc-stats/#dom-rtcoutboundrtpstreamstats-totalencodedbytestarget uint64_t total_encoded_bytes_target = 0; + uint32_t frames = 0; uint32_t frames_dropped_by_capturer = 0; uint32_t frames_dropped_by_encoder_queue = 0; uint32_t frames_dropped_by_rate_limiter = 0; diff --git a/media/base/media_channel.h b/media/base/media_channel.h index fbe2df99a4..c964ce1d2f 100644 --- a/media/base/media_channel.h +++ b/media/base/media_channel.h @@ -548,6 +548,7 @@ struct VideoSenderInfo : public MediaSenderInfo { int nacks_rcvd = 0; int send_frame_width = 0; int send_frame_height = 0; + int frames = 0; int framerate_input = 0; int framerate_sent = 0; int aggregated_framerate_sent = 0; diff --git a/media/engine/webrtc_video_engine.cc b/media/engine/webrtc_video_engine.cc index d5b0f40235..5808e6fbb2 100644 --- a/media/engine/webrtc_video_engine.cc +++ b/media/engine/webrtc_video_engine.cc @@ -2574,6 +2574,7 @@ WebRtcVideoChannel::WebRtcVideoSendStream::GetPerLayerVideoSenderInfos( stats.quality_limitation_resolution_changes; common_info.encoder_implementation_name = stats.encoder_implementation_name; common_info.ssrc_groups = ssrc_groups_; + common_info.frames = stats.frames; common_info.framerate_input = stats.input_frame_rate; common_info.avg_encode_ms = stats.avg_encode_time_ms; common_info.encode_usage_percent = stats.encode_usage_percent; diff --git a/pc/rtc_stats_collector.cc b/pc/rtc_stats_collector.cc index 6cb1dcc7a9..122ae9ff5f 100644 --- a/pc/rtc_stats_collector.cc +++ b/pc/rtc_stats_collector.cc @@ -1620,6 +1620,7 @@ void RTCStatsCollector::ProduceMediaSourceStats_s( if (video_sender_info) { video_source_stats->frames_per_second = video_sender_info->framerate_input; + video_source_stats->frames = video_sender_info->frames; } } media_source_stats = std::move(video_source_stats); diff --git a/pc/rtc_stats_collector_unittest.cc b/pc/rtc_stats_collector_unittest.cc index aa8bff0a54..58a60c1a8c 100644 --- a/pc/rtc_stats_collector_unittest.cc +++ b/pc/rtc_stats_collector_unittest.cc @@ -2474,6 +2474,7 @@ TEST_F(RTCStatsCollectorTest, RTCVideoSourceStatsCollectedForSenderWithTrack) { cricket::SsrcSenderInfo()); 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].frames = 10001; auto* video_media_channel = pc_->AddVideoChannel("VideoMid", "TransportName"); video_media_channel->SetStats(video_media_info); @@ -2493,9 +2494,8 @@ TEST_F(RTCStatsCollectorTest, RTCVideoSourceStatsCollectedForSenderWithTrack) { expected_video.kind = "video"; expected_video.width = kVideoSourceWidth; 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 = 10001; ASSERT_TRUE(report->Get(expected_video.id())); EXPECT_EQ(report->Get(expected_video.id())->cast_to(), @@ -2535,6 +2535,7 @@ TEST_F(RTCStatsCollectorTest, auto video_stats = report->Get("RTCVideoSource_42")->cast_to(); 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 diff --git a/pc/rtc_stats_integrationtest.cc b/pc/rtc_stats_integrationtest.cc index 63426673d8..a6044ba975 100644 --- a/pc/rtc_stats_integrationtest.cc +++ b/pc/rtc_stats_integrationtest.cc @@ -1062,9 +1062,7 @@ class RTCStatsReportVerifier { // reflect real code. verifier.TestMemberIsUndefined(video_source.width); verifier.TestMemberIsUndefined(video_source.height); - // TODO(hbos): When |frames| is implemented test that this member should be - // expected to be non-negative. - verifier.TestMemberIsUndefined(video_source.frames); + verifier.TestMemberIsNonNegative(video_source.frames); verifier.TestMemberIsNonNegative(video_source.frames_per_second); return verifier.ExpectAllMembersSuccessfullyTested(); } diff --git a/video/send_statistics_proxy.cc b/video/send_statistics_proxy.cc index 3b3f69d4e2..686b756776 100644 --- a/video/send_statistics_proxy.cc +++ b/video/send_statistics_proxy.cc @@ -737,6 +737,8 @@ VideoSendStream::Stats SendStatisticsProxy::GetStats() { PurgeOldStats(); stats_.input_frame_rate = round(uma_container_->input_frame_rate_tracker_.ComputeRate()); + stats_.frames = + uma_container_->input_frame_rate_tracker_.TotalSampleCount(); stats_.content_type = content_type_ == VideoEncoderConfig::ContentType::kRealtimeVideo ? VideoContentType::UNSPECIFIED diff --git a/video/send_statistics_proxy_unittest.cc b/video/send_statistics_proxy_unittest.cc index 33107d4c2f..bce79a5c97 100644 --- a/video/send_statistics_proxy_unittest.cc +++ b/video/send_statistics_proxy_unittest.cc @@ -126,6 +126,7 @@ class SendStatisticsProxyTest : public ::testing::Test { } 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.encode_frame_rate, other.encode_frame_rate); EXPECT_EQ(one.media_bitrate_bps, other.media_bitrate_bps);