Implement RTC[In/Out]boundRtpStreamStats.contentType.

Spec: https://henbos.github.io/webrtc-provisional-stats/#dom-rtcinboundrtpstreamstats-contenttype

This already exists as a goog-stat. This CL only plumbs the value to the
new stats collector.

Note: There is currently no distinction between the extension being
missing and it being present but the value being "unspecified". Until
https://crbug.com/webrtc/10529 is fixed, this metric is only exposed if
SCREENSHARE was present.

Bug: webrtc:10452
Change-Id: Ic8723f4d0efb43ab72a560e954676facd3b90659
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/131946
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#27520}
This commit is contained in:
Henrik Boström
2019-04-09 13:59:31 +02:00
committed by Commit Bot
parent 7150d8c60f
commit 2e06926c95
5 changed files with 51 additions and 6 deletions

View File

@ -74,6 +74,12 @@ struct RTCNetworkType {
static const char* const kUnknown; static const char* const kUnknown;
}; };
// https://webrtc.org/experiments/rtp-hdrext/video-content-type/
struct RTCContentType {
static const char* const kUnspecified;
static const char* const kScreenshare;
};
// https://w3c.github.io/webrtc-stats/#certificatestats-dict* // https://w3c.github.io/webrtc-stats/#certificatestats-dict*
class RTC_EXPORT RTCCertificateStats final : public RTCStats { class RTC_EXPORT RTCCertificateStats final : public RTCStats {
public: public:
@ -418,6 +424,8 @@ class RTC_EXPORT RTCInboundRTPStreamStats final : public RTCRTPStreamStats {
// TODO(hbos): Collect and populate this value. https://bugs.webrtc.org/7065 // TODO(hbos): Collect and populate this value. https://bugs.webrtc.org/7065
RTCStatsMember<double> gap_discard_rate; RTCStatsMember<double> gap_discard_rate;
RTCStatsMember<uint32_t> frames_decoded; RTCStatsMember<uint32_t> frames_decoded;
// https://henbos.github.io/webrtc-provisional-stats/#dom-rtcinboundrtpstreamstats-contenttype
RTCStatsMember<std::string> content_type;
}; };
// https://w3c.github.io/webrtc-stats/#outboundrtpstats-dict* // https://w3c.github.io/webrtc-stats/#outboundrtpstats-dict*
@ -438,6 +446,8 @@ class RTC_EXPORT RTCOutboundRTPStreamStats final : public RTCRTPStreamStats {
RTCStatsMember<double> target_bitrate; RTCStatsMember<double> target_bitrate;
RTCStatsMember<uint32_t> frames_encoded; RTCStatsMember<uint32_t> frames_encoded;
RTCStatsMember<double> total_encode_time; RTCStatsMember<double> total_encode_time;
// https://henbos.github.io/webrtc-provisional-stats/#dom-rtcoutboundrtpstreamstats-contenttype
RTCStatsMember<std::string> content_type;
}; };
// https://w3c.github.io/webrtc-stats/#transportstats-dict* // https://w3c.github.io/webrtc-stats/#transportstats-dict*

View File

@ -19,6 +19,7 @@
#include "api/candidate.h" #include "api/candidate.h"
#include "api/media_stream_interface.h" #include "api/media_stream_interface.h"
#include "api/peer_connection_interface.h" #include "api/peer_connection_interface.h"
#include "api/video/video_content_type.h"
#include "media/base/media_channel.h" #include "media/base/media_channel.h"
#include "p2p/base/p2p_constants.h" #include "p2p/base/p2p_constants.h"
#include "p2p/base/port.h" #include "p2p/base/port.h"
@ -266,6 +267,10 @@ void SetInboundRTPStreamStatsFromVideoReceiverInfo(
inbound_video->frames_decoded = video_receiver_info.frames_decoded; inbound_video->frames_decoded = video_receiver_info.frames_decoded;
if (video_receiver_info.qp_sum) if (video_receiver_info.qp_sum)
inbound_video->qp_sum = *video_receiver_info.qp_sum; inbound_video->qp_sum = *video_receiver_info.qp_sum;
// TODO(https://crbug.com/webrtc/10529): When info's |content_info| is
// optional, support the "unspecified" value.
if (video_receiver_info.content_type == VideoContentType::SCREENSHARE)
inbound_video->content_type = RTCContentType::kScreenshare;
} }
// Provides the media independent counters (both audio and video). // Provides the media independent counters (both audio and video).
@ -322,6 +327,10 @@ void SetOutboundRTPStreamStatsFromVideoSenderInfo(
outbound_video->total_encode_time = outbound_video->total_encode_time =
static_cast<double>(video_sender_info.total_encode_time_ms) / static_cast<double>(video_sender_info.total_encode_time_ms) /
rtc::kNumMillisecsPerSec; rtc::kNumMillisecsPerSec;
// TODO(https://crbug.com/webrtc/10529): When info's |content_info| is
// optional, support the "unspecified" value.
if (video_sender_info.content_type == VideoContentType::SCREENSHARE)
outbound_video->content_type = RTCContentType::kScreenshare;
} }
void ProduceCertificateStatsFromSSLCertificateStats( void ProduceCertificateStatsFromSSLCertificateStats(

View File

@ -1684,6 +1684,7 @@ TEST_F(RTCStatsCollectorTest, CollectRTCInboundRTPStreamStats_Video) {
video_media_info.receivers[0].nacks_sent = 7; video_media_info.receivers[0].nacks_sent = 7;
video_media_info.receivers[0].frames_decoded = 8; video_media_info.receivers[0].frames_decoded = 8;
video_media_info.receivers[0].qp_sum = absl::nullopt; video_media_info.receivers[0].qp_sum = absl::nullopt;
video_media_info.receivers[0].content_type = VideoContentType::UNSPECIFIED;
RtpCodecParameters codec_parameters; RtpCodecParameters codec_parameters;
codec_parameters.payload_type = 42; codec_parameters.payload_type = 42;
@ -1718,6 +1719,7 @@ TEST_F(RTCStatsCollectorTest, CollectRTCInboundRTPStreamStats_Video) {
expected_video.fraction_lost = 4.5; expected_video.fraction_lost = 4.5;
expected_video.frames_decoded = 8; expected_video.frames_decoded = 8;
// |expected_video.qp_sum| should be undefined. // |expected_video.qp_sum| should be undefined.
// |expected_video.content_type| should be undefined.
ASSERT_TRUE(report->Get(expected_video.id())); ASSERT_TRUE(report->Get(expected_video.id()));
EXPECT_EQ( EXPECT_EQ(
@ -1727,6 +1729,8 @@ TEST_F(RTCStatsCollectorTest, CollectRTCInboundRTPStreamStats_Video) {
// Set previously undefined values and "GetStats" again. // Set previously undefined values and "GetStats" again.
video_media_info.receivers[0].qp_sum = 9; video_media_info.receivers[0].qp_sum = 9;
expected_video.qp_sum = 9; expected_video.qp_sum = 9;
video_media_info.receivers[0].content_type = VideoContentType::SCREENSHARE;
expected_video.content_type = "screenshare";
video_media_channel->SetStats(video_media_info); video_media_channel->SetStats(video_media_info);
report = stats_->GetFreshStatsReport(); report = stats_->GetFreshStatsReport();
@ -1806,6 +1810,7 @@ TEST_F(RTCStatsCollectorTest, CollectRTCOutboundRTPStreamStats_Video) {
video_media_info.senders[0].frames_encoded = 8; video_media_info.senders[0].frames_encoded = 8;
video_media_info.senders[0].total_encode_time_ms = 9000; video_media_info.senders[0].total_encode_time_ms = 9000;
video_media_info.senders[0].qp_sum = absl::nullopt; video_media_info.senders[0].qp_sum = absl::nullopt;
video_media_info.senders[0].content_type = VideoContentType::UNSPECIFIED;
RtpCodecParameters codec_parameters; RtpCodecParameters codec_parameters;
codec_parameters.payload_type = 42; codec_parameters.payload_type = 42;
@ -1843,6 +1848,7 @@ TEST_F(RTCStatsCollectorTest, CollectRTCOutboundRTPStreamStats_Video) {
expected_video.bytes_sent = 6; expected_video.bytes_sent = 6;
expected_video.frames_encoded = 8; expected_video.frames_encoded = 8;
expected_video.total_encode_time = 9.0; expected_video.total_encode_time = 9.0;
// |expected_video.content_type| should be undefined.
// |expected_video.qp_sum| should be undefined. // |expected_video.qp_sum| should be undefined.
ASSERT_TRUE(report->Get(expected_video.id())); ASSERT_TRUE(report->Get(expected_video.id()));
@ -1853,6 +1859,8 @@ TEST_F(RTCStatsCollectorTest, CollectRTCOutboundRTPStreamStats_Video) {
// Set previously undefined values and "GetStats" again. // Set previously undefined values and "GetStats" again.
video_media_info.senders[0].qp_sum = 9; video_media_info.senders[0].qp_sum = 9;
expected_video.qp_sum = 9; expected_video.qp_sum = 9;
video_media_info.senders[0].content_type = VideoContentType::SCREENSHARE;
expected_video.content_type = "screenshare";
video_media_channel->SetStats(video_media_info); video_media_channel->SetStats(video_media_info);
report = stats_->GetFreshStatsReport(); report = stats_->GetFreshStatsReport();

View File

@ -740,8 +740,12 @@ class RTCStatsReportVerifier {
if (inbound_stream.media_type.is_defined() && if (inbound_stream.media_type.is_defined() &&
*inbound_stream.media_type == "video") { *inbound_stream.media_type == "video") {
verifier.TestMemberIsDefined(inbound_stream.frames_decoded); verifier.TestMemberIsDefined(inbound_stream.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 { } else {
verifier.TestMemberIsUndefined(inbound_stream.frames_decoded); verifier.TestMemberIsUndefined(inbound_stream.frames_decoded);
verifier.TestMemberIsUndefined(inbound_stream.content_type);
} }
return verifier.ExpectAllMembersSuccessfullyTested(); return verifier.ExpectAllMembersSuccessfullyTested();
} }
@ -764,9 +768,13 @@ class RTCStatsReportVerifier {
verifier.TestMemberIsDefined(outbound_stream.frames_encoded); verifier.TestMemberIsDefined(outbound_stream.frames_encoded);
verifier.TestMemberIsNonNegative<double>( verifier.TestMemberIsNonNegative<double>(
outbound_stream.total_encode_time); outbound_stream.total_encode_time);
// The integration test is not set up to test screen share; don't require
// this to be present.
verifier.MarkMemberTested(outbound_stream.content_type, true);
} else { } else {
verifier.TestMemberIsUndefined(outbound_stream.frames_encoded); verifier.TestMemberIsUndefined(outbound_stream.frames_encoded);
verifier.TestMemberIsUndefined(outbound_stream.total_encode_time); verifier.TestMemberIsUndefined(outbound_stream.total_encode_time);
verifier.TestMemberIsUndefined(outbound_stream.content_type);
} }
return verifier.ExpectAllMembersSuccessfullyTested(); return verifier.ExpectAllMembersSuccessfullyTested();
} }

View File

@ -53,6 +53,10 @@ const char* const RTCNetworkType::kWimax = "wimax";
const char* const RTCNetworkType::kVpn = "vpn"; const char* const RTCNetworkType::kVpn = "vpn";
const char* const RTCNetworkType::kUnknown = "unknown"; const char* const RTCNetworkType::kUnknown = "unknown";
// https://webrtc.org/experiments/rtp-hdrext/video-content-type/
const char* const RTCContentType::kUnspecified = "unspecified";
const char* const RTCContentType::kScreenshare = "screenshare";
// clang-format off // clang-format off
WEBRTC_RTCSTATS_IMPL(RTCCertificateStats, RTCStats, "certificate", WEBRTC_RTCSTATS_IMPL(RTCCertificateStats, RTCStats, "certificate",
&fingerprint, &fingerprint,
@ -587,7 +591,8 @@ WEBRTC_RTCSTATS_IMPL(
&burst_discard_rate, &burst_discard_rate,
&gap_loss_rate, &gap_loss_rate,
&gap_discard_rate, &gap_discard_rate,
&frames_decoded) &frames_decoded,
&content_type)
// clang-format on // clang-format on
RTCInboundRTPStreamStats::RTCInboundRTPStreamStats(const std::string& id, RTCInboundRTPStreamStats::RTCInboundRTPStreamStats(const std::string& id,
@ -613,7 +618,8 @@ RTCInboundRTPStreamStats::RTCInboundRTPStreamStats(std::string&& id,
burst_discard_rate("burstDiscardRate"), burst_discard_rate("burstDiscardRate"),
gap_loss_rate("gapLossRate"), gap_loss_rate("gapLossRate"),
gap_discard_rate("gapDiscardRate"), gap_discard_rate("gapDiscardRate"),
frames_decoded("framesDecoded") {} frames_decoded("framesDecoded"),
content_type("contentType") {}
RTCInboundRTPStreamStats::RTCInboundRTPStreamStats( RTCInboundRTPStreamStats::RTCInboundRTPStreamStats(
const RTCInboundRTPStreamStats& other) const RTCInboundRTPStreamStats& other)
@ -634,7 +640,8 @@ RTCInboundRTPStreamStats::RTCInboundRTPStreamStats(
burst_discard_rate(other.burst_discard_rate), burst_discard_rate(other.burst_discard_rate),
gap_loss_rate(other.gap_loss_rate), gap_loss_rate(other.gap_loss_rate),
gap_discard_rate(other.gap_discard_rate), gap_discard_rate(other.gap_discard_rate),
frames_decoded(other.frames_decoded) {} frames_decoded(other.frames_decoded),
content_type(other.content_type) {}
RTCInboundRTPStreamStats::~RTCInboundRTPStreamStats() {} RTCInboundRTPStreamStats::~RTCInboundRTPStreamStats() {}
@ -645,7 +652,8 @@ WEBRTC_RTCSTATS_IMPL(
&bytes_sent, &bytes_sent,
&target_bitrate, &target_bitrate,
&frames_encoded, &frames_encoded,
&total_encode_time) &total_encode_time,
&content_type)
// clang-format on // clang-format on
RTCOutboundRTPStreamStats::RTCOutboundRTPStreamStats(const std::string& id, RTCOutboundRTPStreamStats::RTCOutboundRTPStreamStats(const std::string& id,
@ -659,7 +667,8 @@ RTCOutboundRTPStreamStats::RTCOutboundRTPStreamStats(std::string&& id,
bytes_sent("bytesSent"), bytes_sent("bytesSent"),
target_bitrate("targetBitrate"), target_bitrate("targetBitrate"),
frames_encoded("framesEncoded"), frames_encoded("framesEncoded"),
total_encode_time("totalEncodeTime") {} total_encode_time("totalEncodeTime"),
content_type("contentType") {}
RTCOutboundRTPStreamStats::RTCOutboundRTPStreamStats( RTCOutboundRTPStreamStats::RTCOutboundRTPStreamStats(
const RTCOutboundRTPStreamStats& other) const RTCOutboundRTPStreamStats& other)
@ -668,7 +677,8 @@ RTCOutboundRTPStreamStats::RTCOutboundRTPStreamStats(
bytes_sent(other.bytes_sent), bytes_sent(other.bytes_sent),
target_bitrate(other.target_bitrate), target_bitrate(other.target_bitrate),
frames_encoded(other.frames_encoded), frames_encoded(other.frames_encoded),
total_encode_time(other.total_encode_time) {} total_encode_time(other.total_encode_time),
content_type(other.content_type) {}
RTCOutboundRTPStreamStats::~RTCOutboundRTPStreamStats() {} RTCOutboundRTPStreamStats::~RTCOutboundRTPStreamStats() {}