Add RTCStats for keyFramesEncoded, keyFramesDecoded.
This implements the correspondingly named JavaScript fields defined in https://w3c.github.io/webrtc-stats/#inboundrtpstats-dict* and https://w3c.github.io/webrtc-stats/#outboundrtpstats-dict*. Bug: webrtc:7066 Change-Id: I431045bca80bf5faf27132c54f59c1f723c92952 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/143683 Commit-Queue: Rasmus Brandt <brandtr@webrtc.org> Reviewed-by: Henrik Boström <hbos@webrtc.org> Reviewed-by: Niels Moller <nisse@webrtc.org> Cr-Commit-Position: refs/heads/master@{#28404}
This commit is contained in:
parent
478cb46435
commit
2efae7786e
@ -442,6 +442,7 @@ class RTC_EXPORT RTCInboundRTPStreamStats final : public RTCRTPStreamStats {
|
||||
// TODO(hbos): Collect and populate this value. https://bugs.webrtc.org/7065
|
||||
RTCStatsMember<double> gap_discard_rate;
|
||||
RTCStatsMember<uint32_t> frames_decoded;
|
||||
RTCStatsMember<uint32_t> key_frames_decoded;
|
||||
// https://henbos.github.io/webrtc-provisional-stats/#dom-rtcinboundrtpstreamstats-contenttype
|
||||
RTCStatsMember<std::string> content_type;
|
||||
};
|
||||
@ -466,6 +467,7 @@ class RTC_EXPORT RTCOutboundRTPStreamStats final : public RTCRTPStreamStats {
|
||||
// TODO(hbos): Collect and populate this value. https://bugs.webrtc.org/7066
|
||||
RTCStatsMember<double> target_bitrate;
|
||||
RTCStatsMember<uint32_t> frames_encoded;
|
||||
RTCStatsMember<uint32_t> key_frames_encoded;
|
||||
RTCStatsMember<double> total_encode_time;
|
||||
RTCStatsMember<uint64_t> total_encoded_bytes_target;
|
||||
// TODO(https://crbug.com/webrtc/10635): This is only implemented for video;
|
||||
|
||||
@ -564,6 +564,7 @@ struct VideoSenderInfo : public MediaSenderInfo {
|
||||
int avg_encode_ms = 0;
|
||||
int encode_usage_percent = 0;
|
||||
uint32_t frames_encoded = 0;
|
||||
uint32_t key_frames_encoded = 0;
|
||||
// https://w3c.github.io/webrtc-stats/#dom-rtcoutboundrtpstreamstats-totalencodetime
|
||||
uint64_t total_encode_time_ms = 0;
|
||||
// https://w3c.github.io/webrtc-stats/#dom-rtcoutboundrtpstreamstats-totalencodedbytestarget
|
||||
@ -597,6 +598,7 @@ struct VideoReceiverInfo : public MediaReceiverInfo {
|
||||
int framerate_render_output = 0;
|
||||
uint32_t frames_received = 0;
|
||||
uint32_t frames_decoded = 0;
|
||||
uint32_t key_frames_decoded = 0;
|
||||
uint32_t frames_rendered = 0;
|
||||
absl::optional<uint64_t> qp_sum;
|
||||
int64_t interframe_delay_max_ms = -1;
|
||||
|
||||
@ -2280,6 +2280,13 @@ VideoSenderInfo WebRtcVideoChannel::WebRtcVideoSendStream::GetVideoSenderInfo(
|
||||
info.avg_encode_ms = stats.avg_encode_time_ms;
|
||||
info.encode_usage_percent = stats.encode_usage_percent;
|
||||
info.frames_encoded = stats.frames_encoded;
|
||||
// TODO(bugs.webrtc.org/9547): Populate individual outbound-rtp stats objects
|
||||
// for each simulcast stream, instead of accumulating all keyframes encoded
|
||||
// over all simulcast streams in the same outbound-rtp stats object.
|
||||
info.key_frames_encoded = 0;
|
||||
for (const auto& kv : stats.substreams) {
|
||||
info.key_frames_encoded += kv.second.frame_counts.key_frames;
|
||||
}
|
||||
info.total_encode_time_ms = stats.total_encode_time_ms;
|
||||
info.total_encoded_bytes_target = stats.total_encoded_bytes_target;
|
||||
info.qp_sum = stats.qp_sum;
|
||||
@ -2747,6 +2754,7 @@ WebRtcVideoChannel::WebRtcVideoReceiveStream::GetVideoReceiverInfo(
|
||||
info.frames_received =
|
||||
stats.frame_counts.key_frames + stats.frame_counts.delta_frames;
|
||||
info.frames_decoded = stats.frames_decoded;
|
||||
info.key_frames_decoded = stats.frame_counts.key_frames;
|
||||
info.frames_rendered = stats.frames_rendered;
|
||||
info.qp_sum = stats.qp_sum;
|
||||
info.last_packet_received_timestamp_ms =
|
||||
|
||||
@ -4938,6 +4938,21 @@ TEST_F(WebRtcVideoChannelTest, GetStatsReportsFramesEncoded) {
|
||||
EXPECT_EQ(stats.frames_encoded, info.senders[0].frames_encoded);
|
||||
}
|
||||
|
||||
TEST_F(WebRtcVideoChannelTest, GetStatsReportsKeyFramesEncoded) {
|
||||
FakeVideoSendStream* stream = AddSendStream();
|
||||
webrtc::VideoSendStream::Stats stats;
|
||||
stats.substreams[123].frame_counts.key_frames = 10;
|
||||
stats.substreams[456].frame_counts.key_frames = 87;
|
||||
stream->SetStats(stats);
|
||||
|
||||
cricket::VideoMediaInfo info;
|
||||
ASSERT_TRUE(channel_->GetStats(&info));
|
||||
// TODO(bugs.webrtc.org/9547): Populate individual outbound-rtp stats objects
|
||||
// for each simulcast stream, instead of accumulating all keyframes encoded
|
||||
// over all simulcast streams in the same outbound-rtp stats object.
|
||||
EXPECT_EQ(97u, info.senders[0].key_frames_encoded);
|
||||
}
|
||||
|
||||
TEST_F(WebRtcVideoChannelTest, GetStatsReportsQpSum) {
|
||||
FakeVideoSendStream* stream = AddSendStream();
|
||||
webrtc::VideoSendStream::Stats stats;
|
||||
@ -5095,6 +5110,8 @@ TEST_F(WebRtcVideoChannelTest, GetStatsTranslatesDecodeStatsCorrectly) {
|
||||
info.receivers[0].frames_received);
|
||||
EXPECT_EQ(stats.frames_rendered, info.receivers[0].frames_rendered);
|
||||
EXPECT_EQ(stats.frames_decoded, info.receivers[0].frames_decoded);
|
||||
EXPECT_EQ(rtc::checked_cast<unsigned int>(stats.frame_counts.key_frames),
|
||||
info.receivers[0].key_frames_decoded);
|
||||
EXPECT_EQ(stats.qp_sum, info.receivers[0].qp_sum);
|
||||
}
|
||||
|
||||
|
||||
@ -2708,6 +2708,12 @@ TEST_P(PeerConnectionIntegrationTest, NewGetStatsManyAudioAndManyVideoStreams) {
|
||||
for (const auto& stat : outbound_stream_stats) {
|
||||
ASSERT_TRUE(stat->bytes_sent.is_defined());
|
||||
EXPECT_LT(0u, *stat->bytes_sent);
|
||||
if (*stat->kind == "video") {
|
||||
ASSERT_TRUE(stat->key_frames_encoded.is_defined());
|
||||
EXPECT_GT(*stat->key_frames_encoded, 0u);
|
||||
ASSERT_TRUE(stat->frames_encoded.is_defined());
|
||||
EXPECT_GE(*stat->frames_encoded, *stat->key_frames_encoded);
|
||||
}
|
||||
ASSERT_TRUE(stat->track_id.is_defined());
|
||||
const auto* track_stat =
|
||||
caller_report->GetAs<webrtc::RTCMediaStreamTrackStats>(*stat->track_id);
|
||||
@ -2726,6 +2732,12 @@ TEST_P(PeerConnectionIntegrationTest, NewGetStatsManyAudioAndManyVideoStreams) {
|
||||
for (const auto& stat : inbound_stream_stats) {
|
||||
ASSERT_TRUE(stat->bytes_received.is_defined());
|
||||
EXPECT_LT(0u, *stat->bytes_received);
|
||||
if (*stat->kind == "video") {
|
||||
ASSERT_TRUE(stat->key_frames_decoded.is_defined());
|
||||
EXPECT_GT(*stat->key_frames_decoded, 0u);
|
||||
ASSERT_TRUE(stat->frames_decoded.is_defined());
|
||||
EXPECT_GE(*stat->frames_decoded, *stat->key_frames_decoded);
|
||||
}
|
||||
ASSERT_TRUE(stat->track_id.is_defined());
|
||||
const auto* track_stat =
|
||||
callee_report->GetAs<webrtc::RTCMediaStreamTrackStats>(*stat->track_id);
|
||||
|
||||
@ -309,6 +309,7 @@ void SetInboundRTPStreamStatsFromVideoReceiverInfo(
|
||||
inbound_video->nack_count =
|
||||
static_cast<uint32_t>(video_receiver_info.nacks_sent);
|
||||
inbound_video->frames_decoded = video_receiver_info.frames_decoded;
|
||||
inbound_video->key_frames_decoded = video_receiver_info.key_frames_decoded;
|
||||
if (video_receiver_info.qp_sum)
|
||||
inbound_video->qp_sum = *video_receiver_info.qp_sum;
|
||||
if (video_receiver_info.last_packet_received_timestamp_ms) {
|
||||
@ -378,6 +379,7 @@ void SetOutboundRTPStreamStatsFromVideoSenderInfo(
|
||||
if (video_sender_info.qp_sum)
|
||||
outbound_video->qp_sum = *video_sender_info.qp_sum;
|
||||
outbound_video->frames_encoded = video_sender_info.frames_encoded;
|
||||
outbound_video->key_frames_encoded = video_sender_info.key_frames_encoded;
|
||||
outbound_video->total_encode_time =
|
||||
static_cast<double>(video_sender_info.total_encode_time_ms) /
|
||||
rtc::kNumMillisecsPerSec;
|
||||
|
||||
@ -1801,6 +1801,7 @@ TEST_F(RTCStatsCollectorTest, CollectRTCInboundRTPStreamStats_Video) {
|
||||
video_media_info.receivers[0].plis_sent = 6;
|
||||
video_media_info.receivers[0].nacks_sent = 7;
|
||||
video_media_info.receivers[0].frames_decoded = 8;
|
||||
video_media_info.receivers[0].key_frames_decoded = 3;
|
||||
video_media_info.receivers[0].qp_sum = absl::nullopt;
|
||||
video_media_info.receivers[0].last_packet_received_timestamp_ms =
|
||||
absl::nullopt;
|
||||
@ -1837,6 +1838,7 @@ TEST_F(RTCStatsCollectorTest, CollectRTCInboundRTPStreamStats_Video) {
|
||||
expected_video.bytes_received = 3;
|
||||
expected_video.packets_lost = 42;
|
||||
expected_video.frames_decoded = 8;
|
||||
expected_video.key_frames_decoded = 3;
|
||||
// |expected_video.qp_sum| should be undefined.
|
||||
// |expected_video.last_packet_received_timestamp| should be undefined.
|
||||
// |expected_video.content_type| should be undefined.
|
||||
@ -1938,6 +1940,7 @@ TEST_F(RTCStatsCollectorTest, CollectRTCOutboundRTPStreamStats_Video) {
|
||||
video_media_info.senders[0].retransmitted_bytes_sent = 60;
|
||||
video_media_info.senders[0].codec_payload_type = 42;
|
||||
video_media_info.senders[0].frames_encoded = 8;
|
||||
video_media_info.senders[0].key_frames_encoded = 3;
|
||||
video_media_info.senders[0].total_encode_time_ms = 9000;
|
||||
video_media_info.senders[0].total_encoded_bytes_target = 1234;
|
||||
video_media_info.senders[0].total_packet_send_delay_ms = 10000;
|
||||
@ -1985,6 +1988,7 @@ TEST_F(RTCStatsCollectorTest, CollectRTCOutboundRTPStreamStats_Video) {
|
||||
expected_video.bytes_sent = 6;
|
||||
expected_video.retransmitted_bytes_sent = 60;
|
||||
expected_video.frames_encoded = 8;
|
||||
expected_video.key_frames_encoded = 3;
|
||||
expected_video.total_encode_time = 9.0;
|
||||
expected_video.total_encoded_bytes_target = 1234;
|
||||
expected_video.total_packet_send_delay = 10.0;
|
||||
|
||||
@ -804,11 +804,13 @@ class RTCStatsReportVerifier {
|
||||
if (inbound_stream.media_type.is_defined() &&
|
||||
*inbound_stream.media_type == "video") {
|
||||
verifier.TestMemberIsDefined(inbound_stream.frames_decoded);
|
||||
verifier.TestMemberIsDefined(inbound_stream.key_frames_decoded);
|
||||
// The integration test is not set up to test screen share; don't require
|
||||
// this to be present.
|
||||
verifier.MarkMemberTested(inbound_stream.content_type, true);
|
||||
} else {
|
||||
verifier.TestMemberIsUndefined(inbound_stream.frames_decoded);
|
||||
verifier.TestMemberIsUndefined(inbound_stream.key_frames_decoded);
|
||||
verifier.TestMemberIsUndefined(inbound_stream.content_type);
|
||||
}
|
||||
return verifier.ExpectAllMembersSuccessfullyTested();
|
||||
@ -838,6 +840,7 @@ class RTCStatsReportVerifier {
|
||||
if (outbound_stream.media_type.is_defined() &&
|
||||
*outbound_stream.media_type == "video") {
|
||||
verifier.TestMemberIsDefined(outbound_stream.frames_encoded);
|
||||
verifier.TestMemberIsDefined(outbound_stream.key_frames_encoded);
|
||||
verifier.TestMemberIsNonNegative<double>(
|
||||
outbound_stream.total_encode_time);
|
||||
verifier.TestMemberIsNonNegative<uint64_t>(
|
||||
@ -850,6 +853,7 @@ class RTCStatsReportVerifier {
|
||||
verifier.MarkMemberTested(outbound_stream.content_type, true);
|
||||
} else {
|
||||
verifier.TestMemberIsUndefined(outbound_stream.frames_encoded);
|
||||
verifier.TestMemberIsUndefined(outbound_stream.key_frames_encoded);
|
||||
verifier.TestMemberIsUndefined(outbound_stream.total_encode_time);
|
||||
verifier.TestMemberIsUndefined(
|
||||
outbound_stream.total_encoded_bytes_target);
|
||||
|
||||
@ -614,6 +614,7 @@ WEBRTC_RTCSTATS_IMPL(
|
||||
&gap_loss_rate,
|
||||
&gap_discard_rate,
|
||||
&frames_decoded,
|
||||
&key_frames_decoded,
|
||||
&content_type)
|
||||
// clang-format on
|
||||
|
||||
@ -643,6 +644,7 @@ RTCInboundRTPStreamStats::RTCInboundRTPStreamStats(std::string&& id,
|
||||
gap_loss_rate("gapLossRate"),
|
||||
gap_discard_rate("gapDiscardRate"),
|
||||
frames_decoded("framesDecoded"),
|
||||
key_frames_decoded("keyFramesDecoded"),
|
||||
content_type("contentType") {}
|
||||
|
||||
RTCInboundRTPStreamStats::RTCInboundRTPStreamStats(
|
||||
@ -667,6 +669,7 @@ RTCInboundRTPStreamStats::RTCInboundRTPStreamStats(
|
||||
gap_loss_rate(other.gap_loss_rate),
|
||||
gap_discard_rate(other.gap_discard_rate),
|
||||
frames_decoded(other.frames_decoded),
|
||||
key_frames_decoded(other.key_frames_decoded),
|
||||
content_type(other.content_type) {}
|
||||
|
||||
RTCInboundRTPStreamStats::~RTCInboundRTPStreamStats() {}
|
||||
@ -681,6 +684,7 @@ WEBRTC_RTCSTATS_IMPL(
|
||||
&retransmitted_bytes_sent,
|
||||
&target_bitrate,
|
||||
&frames_encoded,
|
||||
&key_frames_encoded,
|
||||
&total_encode_time,
|
||||
&total_encoded_bytes_target,
|
||||
&total_packet_send_delay,
|
||||
@ -702,6 +706,7 @@ RTCOutboundRTPStreamStats::RTCOutboundRTPStreamStats(std::string&& id,
|
||||
retransmitted_bytes_sent("retransmittedBytesSent"),
|
||||
target_bitrate("targetBitrate"),
|
||||
frames_encoded("framesEncoded"),
|
||||
key_frames_encoded("keyFramesEncoded"),
|
||||
total_encode_time("totalEncodeTime"),
|
||||
total_encoded_bytes_target("totalEncodedBytesTarget"),
|
||||
total_packet_send_delay("totalPacketSendDelay"),
|
||||
@ -718,6 +723,7 @@ RTCOutboundRTPStreamStats::RTCOutboundRTPStreamStats(
|
||||
retransmitted_bytes_sent(other.retransmitted_bytes_sent),
|
||||
target_bitrate(other.target_bitrate),
|
||||
frames_encoded(other.frames_encoded),
|
||||
key_frames_encoded(other.key_frames_encoded),
|
||||
total_encode_time(other.total_encode_time),
|
||||
total_encoded_bytes_target(other.total_encoded_bytes_target),
|
||||
total_packet_send_delay(other.total_packet_send_delay),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user