Commit 8905ee14 authored by Takumi Fujimoto's avatar Takumi Fujimoto Committed by Chromium LUCI CQ

Add media remoting metrics

Media.Remoting.VideoPixelRateSupport
- How big the video resolution is and whether it's supported
Media.Remoting.Compatibility
- Record various reasons why the media may not be compatible with
  remoting

Bug: 1163944
Change-Id: I3c46662b71a7a860d6e63f6db3218c9c576d4305
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2605289Reviewed-by: default avatarJordan Bayles <jophba@chromium.org>
Reviewed-by: default avatarCaitlin Fischer <caitlinfischer@google.com>
Commit-Queue: Takumi Fujimoto <takumif@chromium.org>
Cr-Commit-Position: refs/heads/master@{#842631}
parent 2d53d1ab
...@@ -125,6 +125,7 @@ source_set("media_remoting_tests") { ...@@ -125,6 +125,7 @@ source_set("media_remoting_tests") {
"fake_media_resource.cc", "fake_media_resource.cc",
"fake_media_resource.h", "fake_media_resource.h",
"integration_test.cc", "integration_test.cc",
"metrics_unittest.cc",
"proto_utils_unittest.cc", "proto_utils_unittest.cc",
"rpc_broker_unittest.cc", "rpc_broker_unittest.cc",
] ]
......
...@@ -46,8 +46,7 @@ SessionMetricsRecorder::SessionMetricsRecorder() ...@@ -46,8 +46,7 @@ SessionMetricsRecorder::SessionMetricsRecorder()
last_channel_layout_(CHANNEL_LAYOUT_NONE), last_channel_layout_(CHANNEL_LAYOUT_NONE),
last_sample_rate_(0), last_sample_rate_(0),
last_video_codec_(kUnknownVideoCodec), last_video_codec_(kUnknownVideoCodec),
last_video_profile_(VIDEO_CODEC_PROFILE_UNKNOWN), last_video_profile_(VIDEO_CODEC_PROFILE_UNKNOWN) {}
remote_playback_is_disabled_(false) {}
SessionMetricsRecorder::~SessionMetricsRecorder() = default; SessionMetricsRecorder::~SessionMetricsRecorder() = default;
...@@ -171,6 +170,21 @@ void SessionMetricsRecorder::OnRemotePlaybackDisabled(bool disabled) { ...@@ -171,6 +170,21 @@ void SessionMetricsRecorder::OnRemotePlaybackDisabled(bool disabled) {
remote_playback_is_disabled_ = disabled; remote_playback_is_disabled_ = disabled;
} }
void SessionMetricsRecorder::RecordVideoPixelRateSupport(
PixelRateSupport support) {
if (did_record_pixel_rate_support_) {
return;
}
did_record_pixel_rate_support_ = true;
base::UmaHistogramEnumeration("Media.Remoting.VideoPixelRateSupport",
support);
}
void SessionMetricsRecorder::RecordCompatibility(
RemotingCompatibility compatibility) {
base::UmaHistogramEnumeration("Media.Remoting.Compatibility", compatibility);
}
void SessionMetricsRecorder::RecordAudioConfiguration() { void SessionMetricsRecorder::RecordAudioConfiguration() {
UMA_HISTOGRAM_ENUMERATION("Media.Remoting.AudioCodec", last_audio_codec_, UMA_HISTOGRAM_ENUMERATION("Media.Remoting.AudioCodec", last_audio_codec_,
kAudioCodecMax + 1); kAudioCodecMax + 1);
...@@ -219,7 +233,7 @@ void SessionMetricsRecorder::RecordTrackConfiguration() { ...@@ -219,7 +233,7 @@ void SessionMetricsRecorder::RecordTrackConfiguration() {
} }
RendererMetricsRecorder::RendererMetricsRecorder() RendererMetricsRecorder::RendererMetricsRecorder()
: start_time_(base::TimeTicks::Now()), did_record_first_playout_(false) {} : start_time_(base::TimeTicks::Now()) {}
RendererMetricsRecorder::~RendererMetricsRecorder() = default; RendererMetricsRecorder::~RendererMetricsRecorder() = default;
......
...@@ -15,6 +15,39 @@ ...@@ -15,6 +15,39 @@
namespace media { namespace media {
namespace remoting { namespace remoting {
// The compatibility of a media content with remoting, and the reasons for
// incompatibilities.
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
enum class RemotingCompatibility {
kCompatible = 0,
kNoAudioNorVideo = 1,
kEncryptedVideo = 2,
kIncompatibleVideoCodec = 3,
kEncryptedAudio = 4,
kIncompatibleAudioCodec = 5,
kDisabledByPage = 6,
kDurationBelowThreshold = 7,
// Add new values here. Don't re-number existing values.
kMaxValue = kDurationBelowThreshold,
};
// The rate of pixels in a video and whether the receiver supports its playback.
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
enum class PixelRateSupport {
// Pixels per second is at most the equivalent of 1080p 30fps.
k2kSupported = 0,
// More than 1080p 30fps and at most 2160p 30fps.
k4kSupported = 1,
k4kNotSupported = 2,
kOver4kNotSupported = 3,
// Add new values here. Don't re-number existing values.
kMaxValue = kOver4kNotSupported,
};
class SessionMetricsRecorder { class SessionMetricsRecorder {
public: public:
SessionMetricsRecorder(); SessionMetricsRecorder();
...@@ -32,6 +65,14 @@ class SessionMetricsRecorder { ...@@ -32,6 +65,14 @@ class SessionMetricsRecorder {
void OnPipelineMetadataChanged(const PipelineMetadata& metadata); void OnPipelineMetadataChanged(const PipelineMetadata& metadata);
void OnRemotePlaybackDisabled(bool disabled); void OnRemotePlaybackDisabled(bool disabled);
// Records the rate of pixels in a video (bucketed into FHD, 4K, etc.) and
// whether the receiver supports its playback. Records only on the first call
// for the recorder instance.
void RecordVideoPixelRateSupport(PixelRateSupport support);
// Records the compatibility of a media content with remoting.
void RecordCompatibility(RemotingCompatibility compatibility);
private: private:
// Whether audio only, video only, or both were played during the session. // Whether audio only, video only, or both were played during the session.
// //
...@@ -70,7 +111,9 @@ class SessionMetricsRecorder { ...@@ -70,7 +111,9 @@ class SessionMetricsRecorder {
// Last known disabled playback state. This can change before/after a remoting // Last known disabled playback state. This can change before/after a remoting
// session as well as during one. // session as well as during one.
bool remote_playback_is_disabled_; bool remote_playback_is_disabled_ = false;
bool did_record_pixel_rate_support_ = false;
DISALLOW_COPY_AND_ASSIGN(SessionMetricsRecorder); DISALLOW_COPY_AND_ASSIGN(SessionMetricsRecorder);
}; };
...@@ -94,7 +137,7 @@ class RendererMetricsRecorder { ...@@ -94,7 +137,7 @@ class RendererMetricsRecorder {
private: private:
const base::TimeTicks start_time_; const base::TimeTicks start_time_;
bool did_record_first_playout_; bool did_record_first_playout_ = false;
DISALLOW_COPY_AND_ASSIGN(RendererMetricsRecorder); DISALLOW_COPY_AND_ASSIGN(RendererMetricsRecorder);
}; };
......
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "media/remoting/metrics.h"
#include <string>
#include "base/test/metrics/histogram_tester.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
using base::Bucket;
using testing::ElementsAre;
namespace media {
namespace remoting {
namespace {
class MediaRemotingMetricsTest : public testing::Test {
protected:
media::remoting::SessionMetricsRecorder recorder_;
};
} // namespace
TEST_F(MediaRemotingMetricsTest, RecordVideoPixelRateSupport) {
constexpr char kPixelRateSupportHistogramName[] =
"Media.Remoting.VideoPixelRateSupport";
base::HistogramTester tester;
tester.ExpectTotalCount(kPixelRateSupportHistogramName, 0);
recorder_.RecordVideoPixelRateSupport(PixelRateSupport::k4kNotSupported);
recorder_.RecordVideoPixelRateSupport(PixelRateSupport::k2kSupported);
recorder_.RecordVideoPixelRateSupport(PixelRateSupport::k4kNotSupported);
// We record only for the first RecordVideoPixelRateSupport() call for the
// given SessionMetricsRecorder instance.
EXPECT_THAT(tester.GetAllSamples(kPixelRateSupportHistogramName),
ElementsAre(Bucket(
static_cast<int>(PixelRateSupport::k4kNotSupported), 1)));
}
TEST_F(MediaRemotingMetricsTest, RecordCompatibility) {
constexpr char kCompatibilityHistogramName[] = "Media.Remoting.Compatibility";
base::HistogramTester tester;
tester.ExpectTotalCount(kCompatibilityHistogramName, 0);
recorder_.RecordCompatibility(RemotingCompatibility::kIncompatibleVideoCodec);
recorder_.RecordCompatibility(RemotingCompatibility::kCompatible);
recorder_.RecordCompatibility(RemotingCompatibility::kIncompatibleVideoCodec);
EXPECT_THAT(
tester.GetAllSamples(kCompatibilityHistogramName),
ElementsAre(
Bucket(static_cast<int>(RemotingCompatibility::kCompatible), 1),
Bucket(
static_cast<int>(RemotingCompatibility::kIncompatibleVideoCodec),
2)));
}
} // namespace remoting
} // namespace media
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "base/time/default_tick_clock.h" #include "base/time/default_tick_clock.h"
#include "base/time/tick_clock.h" #include "base/time/tick_clock.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "media/remoting/metrics.h"
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
#include "media/base/android/media_codec_util.h" #include "media/base/android/media_codec_util.h"
...@@ -17,14 +18,17 @@ ...@@ -17,14 +18,17 @@
namespace media { namespace media {
namespace remoting { namespace remoting {
using mojom::RemotingSinkAudioCapability;
using mojom::RemotingSinkVideoCapability;
namespace { namespace {
// The duration to delay the start of media remoting to ensure all preconditions // The duration to delay the start of media remoting to ensure all preconditions
// are held stable before switching to media remoting. // are held stable before switching to media remoting.
constexpr base::TimeDelta kDelayedStart = base::TimeDelta::FromSeconds(5); constexpr base::TimeDelta kDelayedStart = base::TimeDelta::FromSeconds(5);
constexpr int kPixelPerSec4K = 3840 * 2160 * 30; // 4k 30fps. constexpr int kPixelsPerSec4k = 3840 * 2160 * 30; // 4k 30fps.
constexpr int kPixelPerSec2K = 1920 * 1080 * 30; // 1080p 30fps. constexpr int kPixelsPerSec2k = 1920 * 1080 * 30; // 1080p 30fps.
// The minimum media element duration that is allowed for media remoting. // The minimum media element duration that is allowed for media remoting.
// Frequent switching into and out of media remoting for short-duration media // Frequent switching into and out of media remoting for short-duration media
...@@ -326,42 +330,76 @@ void RendererController::UpdateRemotePlaybackAvailabilityMonitoringState() { ...@@ -326,42 +330,76 @@ void RendererController::UpdateRemotePlaybackAvailabilityMonitoringState() {
} }
bool RendererController::IsVideoCodecSupported() const { bool RendererController::IsVideoCodecSupported() const {
DCHECK(thread_checker_.CalledOnValidThread());
return GetVideoCompatibility() == RemotingCompatibility::kCompatible;
}
bool RendererController::IsAudioCodecSupported() const {
DCHECK(thread_checker_.CalledOnValidThread());
return GetAudioCompatibility() == RemotingCompatibility::kCompatible;
}
void RendererController::OnPlaying() {
DCHECK(thread_checker_.CalledOnValidThread());
is_paused_ = false;
UpdateAndMaybeSwitch(PLAY_COMMAND, UNKNOWN_STOP_TRIGGER);
}
void RendererController::OnPaused() {
DCHECK(thread_checker_.CalledOnValidThread());
is_paused_ = true;
// Cancel the start if in the middle of delayed start.
CancelDelayedStart();
}
RemotingCompatibility RendererController::GetVideoCompatibility() const {
DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(has_video()); DCHECK(has_video());
// Media Remoting doesn't support encrypted media. // Media Remoting doesn't support encrypted media.
if (pipeline_metadata_.video_decoder_config.is_encrypted()) if (pipeline_metadata_.video_decoder_config.is_encrypted())
return false; return RemotingCompatibility::kEncryptedVideo;
bool compatible = false;
switch (pipeline_metadata_.video_decoder_config.codec()) { switch (pipeline_metadata_.video_decoder_config.codec()) {
case VideoCodec::kCodecH264: case VideoCodec::kCodecH264:
return HasVideoCapability(mojom::RemotingSinkVideoCapability::CODEC_H264); compatible = HasVideoCapability(RemotingSinkVideoCapability::CODEC_H264);
break;
case VideoCodec::kCodecVP8: case VideoCodec::kCodecVP8:
return HasVideoCapability(mojom::RemotingSinkVideoCapability::CODEC_VP8); compatible = HasVideoCapability(RemotingSinkVideoCapability::CODEC_VP8);
break;
case VideoCodec::kCodecVP9: case VideoCodec::kCodecVP9:
return HasVideoCapability(mojom::RemotingSinkVideoCapability::CODEC_VP9); compatible = HasVideoCapability(RemotingSinkVideoCapability::CODEC_VP9);
break;
case VideoCodec::kCodecHEVC: case VideoCodec::kCodecHEVC:
return HasVideoCapability(mojom::RemotingSinkVideoCapability::CODEC_HEVC); compatible = HasVideoCapability(RemotingSinkVideoCapability::CODEC_HEVC);
break;
default: default:
VLOG(2) << "Remoting does not support video codec: " VLOG(2) << "Remoting does not support video codec: "
<< pipeline_metadata_.video_decoder_config.codec(); << pipeline_metadata_.video_decoder_config.codec();
return false;
} }
return compatible ? RemotingCompatibility::kCompatible
: RemotingCompatibility::kIncompatibleVideoCodec;
} }
bool RendererController::IsAudioCodecSupported() const { RemotingCompatibility RendererController::GetAudioCompatibility() const {
DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(has_audio()); DCHECK(has_audio());
// Media Remoting doesn't support encrypted media. // Media Remoting doesn't support encrypted media.
if (pipeline_metadata_.audio_decoder_config.is_encrypted()) if (pipeline_metadata_.audio_decoder_config.is_encrypted())
return false; return RemotingCompatibility::kEncryptedAudio;
bool compatible = false;
switch (pipeline_metadata_.audio_decoder_config.codec()) { switch (pipeline_metadata_.audio_decoder_config.codec()) {
case AudioCodec::kCodecAAC: case AudioCodec::kCodecAAC:
return HasAudioCapability(mojom::RemotingSinkAudioCapability::CODEC_AAC); compatible = HasAudioCapability(RemotingSinkAudioCapability::CODEC_AAC);
break;
case AudioCodec::kCodecOpus: case AudioCodec::kCodecOpus:
return HasAudioCapability(mojom::RemotingSinkAudioCapability::CODEC_OPUS); compatible = HasAudioCapability(RemotingSinkAudioCapability::CODEC_OPUS);
break;
case AudioCodec::kCodecMP3: case AudioCodec::kCodecMP3:
case AudioCodec::kCodecPCM: case AudioCodec::kCodecPCM:
case AudioCodec::kCodecVorbis: case AudioCodec::kCodecVorbis:
...@@ -376,49 +414,43 @@ bool RendererController::IsAudioCodecSupported() const { ...@@ -376,49 +414,43 @@ bool RendererController::IsAudioCodecSupported() const {
case AudioCodec::kCodecPCM_ALAW: case AudioCodec::kCodecPCM_ALAW:
case AudioCodec::kCodecALAC: case AudioCodec::kCodecALAC:
case AudioCodec::kCodecAC3: case AudioCodec::kCodecAC3:
return HasAudioCapability( compatible =
mojom::RemotingSinkAudioCapability::CODEC_BASELINE_SET); HasAudioCapability(RemotingSinkAudioCapability::CODEC_BASELINE_SET);
break;
default: default:
VLOG(2) << "Remoting does not support audio codec: " VLOG(2) << "Remoting does not support audio codec: "
<< pipeline_metadata_.audio_decoder_config.codec(); << pipeline_metadata_.audio_decoder_config.codec();
return false;
} }
return compatible ? RemotingCompatibility::kCompatible
: RemotingCompatibility::kIncompatibleAudioCodec;
} }
void RendererController::OnPlaying() { RemotingCompatibility RendererController::GetCompatibility() const {
DCHECK(thread_checker_.CalledOnValidThread());
is_paused_ = false;
UpdateAndMaybeSwitch(PLAY_COMMAND, UNKNOWN_STOP_TRIGGER);
}
void RendererController::OnPaused() {
DCHECK(thread_checker_.CalledOnValidThread());
is_paused_ = true;
// Cancel the start if in the middle of delayed start.
CancelDelayedStart();
}
bool RendererController::CanBeRemoting() const {
DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(client_);
if (!client_) if (is_remote_playback_disabled_)
return false; // No way to switch to the remoting renderer. return RemotingCompatibility::kDisabledByPage;
if (permanently_disable_remoting_) if (!has_video() && !has_audio())
return false; return RemotingCompatibility::kNoAudioNorVideo;
if (!IsAudioOrVideoSupported()) if (has_video()) {
return false; RemotingCompatibility compatibility = GetVideoCompatibility();
if (compatibility != RemotingCompatibility::kCompatible)
return compatibility;
}
if (is_remote_playback_disabled_) if (has_audio()) {
return false; RemotingCompatibility compatibility = GetAudioCompatibility();
if (compatibility != RemotingCompatibility::kCompatible)
return compatibility;
}
if (client_->Duration() <= kMinRemotingMediaDurationInSec) if (client_->Duration() <= kMinRemotingMediaDurationInSec)
return false; return RemotingCompatibility::kDurationBelowThreshold;
return true; return RemotingCompatibility::kCompatible;
} }
bool RendererController::IsAudioOrVideoSupported() const { bool RendererController::IsAudioOrVideoSupported() const {
...@@ -431,26 +463,25 @@ void RendererController::UpdateAndMaybeSwitch(StartTrigger start_trigger, ...@@ -431,26 +463,25 @@ void RendererController::UpdateAndMaybeSwitch(StartTrigger start_trigger,
StopTrigger stop_trigger) { StopTrigger stop_trigger) {
DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(thread_checker_.CalledOnValidThread());
bool should_be_remoting = CanBeRemoting();
// Being the dominant visible content is the signal that starts remote // Being the dominant visible content is the signal that starts remote
// rendering. // rendering.
should_be_remoting &= // Also, only switch to remoting when media is playing. Since the renderer is
(is_dominant_content_ && !encountered_renderer_fatal_error_); // created when video starts loading, the receiver would display a black
// screen if switching to remoting while paused. Thus, the user experience is
// improved by not starting remoting until playback resumes.
bool should_be_remoting = client_ && !encountered_renderer_fatal_error_ &&
is_dominant_content_ && !is_paused_;
if (should_be_remoting) {
const RemotingCompatibility compatibility = GetCompatibility();
metrics_recorder_.RecordCompatibility(compatibility);
should_be_remoting = compatibility == RemotingCompatibility::kCompatible;
}
if ((remote_rendering_started_ || if ((remote_rendering_started_ ||
delayed_start_stability_timer_.IsRunning()) == should_be_remoting) { delayed_start_stability_timer_.IsRunning()) == should_be_remoting) {
return; return;
} }
// Only switch to remoting when media is playing. Since the renderer is
// created when video starts loading/playing, receiver will display a black
// screen before video starts playing if switching to remoting when paused.
// Thus, the user experience is improved by not starting remoting until
// playback resumes.
if (should_be_remoting && is_paused_)
return;
if (should_be_remoting) { if (should_be_remoting) {
WaitForStabilityBeforeStart(start_trigger); WaitForStabilityBeforeStart(start_trigger);
} else if (delayed_start_stability_timer_.IsRunning()) { } else if (delayed_start_stability_timer_.IsRunning()) {
...@@ -498,13 +529,10 @@ void RendererController::OnDelayedStartTimerFired( ...@@ -498,13 +529,10 @@ void RendererController::OnDelayedStartTimerFired(
const double frame_rate = const double frame_rate =
(client_->DecodedFrameCount() - decoded_frame_count_before_delay) / (client_->DecodedFrameCount() - decoded_frame_count_before_delay) /
elapsed.InSecondsF(); elapsed.InSecondsF();
const double pixel_per_sec = const double pixels_per_second =
frame_rate * pipeline_metadata_.natural_size.GetArea(); frame_rate * pipeline_metadata_.natural_size.GetArea();
if ((pixel_per_sec > kPixelPerSec4K) || const bool supported = RecordPixelRateSupport(pixels_per_second);
((pixel_per_sec > kPixelPerSec2K) && if (!supported) {
!HasVideoCapability(mojom::RemotingSinkVideoCapability::SUPPORT_4K))) {
VLOG(1) << "Media remoting is not supported: frame_rate = " << frame_rate
<< " resolution = " << pipeline_metadata_.natural_size.ToString();
permanently_disable_remoting_ = true; permanently_disable_remoting_ = true;
return; return;
} }
...@@ -518,6 +546,28 @@ void RendererController::OnDelayedStartTimerFired( ...@@ -518,6 +546,28 @@ void RendererController::OnDelayedStartTimerFired(
remoter_->Start(); remoter_->Start();
} }
bool RendererController::RecordPixelRateSupport(double pixels_per_second) {
if (pixels_per_second <= kPixelsPerSec2k) {
metrics_recorder_.RecordVideoPixelRateSupport(
PixelRateSupport::k2kSupported);
return true;
}
if (pixels_per_second <= kPixelsPerSec4k) {
if (HasVideoCapability(mojom::RemotingSinkVideoCapability::SUPPORT_4K)) {
metrics_recorder_.RecordVideoPixelRateSupport(
PixelRateSupport::k4kSupported);
return true;
} else {
metrics_recorder_.RecordVideoPixelRateSupport(
PixelRateSupport::k4kNotSupported);
return false;
}
}
metrics_recorder_.RecordVideoPixelRateSupport(
PixelRateSupport::kOver4kNotSupported);
return false;
}
void RendererController::OnRendererFatalError(StopTrigger stop_trigger) { void RendererController::OnRendererFatalError(StopTrigger stop_trigger) {
DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(thread_checker_.CalledOnValidThread());
......
...@@ -117,11 +117,14 @@ class RendererController final : public mojom::RemotingSource, ...@@ -117,11 +117,14 @@ class RendererController final : public mojom::RemotingSource,
bool IsAudioCodecSupported() const; bool IsAudioCodecSupported() const;
bool IsAudioOrVideoSupported() const; bool IsAudioOrVideoSupported() const;
// Returns true if all of the technical requirements for the media pipeline // Returns |kCompatible| if all of the technical requirements for the media
// and remote rendering are being met. This does not include environmental // pipeline and remote rendering are being met, and the first detected
// conditions, such as the content being dominant in the viewport, available // reason if incompatible. This does not include environmental conditions,
// network bandwidth, etc. // such as the content being dominant in the viewport, available network
bool CanBeRemoting() const; // bandwidth, etc.
RemotingCompatibility GetVideoCompatibility() const;
RemotingCompatibility GetAudioCompatibility() const;
RemotingCompatibility GetCompatibility() const;
// Determines whether to enter or leave Remoting mode and switches if // Determines whether to enter or leave Remoting mode and switches if
// necessary. Each call to this method could cause a remoting session to be // necessary. Each call to this method could cause a remoting session to be
...@@ -146,6 +149,10 @@ class RendererController final : public mojom::RemotingSource, ...@@ -146,6 +149,10 @@ class RendererController final : public mojom::RemotingSource,
unsigned decoded_frame_count_before_delay, unsigned decoded_frame_count_before_delay,
base::TimeTicks delayed_start_time); base::TimeTicks delayed_start_time);
// Records in a histogram and returns whether the receiver supports the given
// pixel rate.
bool RecordPixelRateSupport(double pixels_per_second);
// Queries on remoting sink capabilities. // Queries on remoting sink capabilities.
bool HasVideoCapability(mojom::RemotingSinkVideoCapability capability) const; bool HasVideoCapability(mojom::RemotingSinkVideoCapability capability) const;
bool HasAudioCapability(mojom::RemotingSinkAudioCapability capability) const; bool HasAudioCapability(mojom::RemotingSinkAudioCapability capability) const;
......
...@@ -64109,6 +64109,17 @@ https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_2.7.1.pdf ...@@ -64109,6 +64109,17 @@ https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_2.7.1.pdf
<int value="14" label="User refused to terminate process"/> <int value="14" label="User refused to terminate process"/>
</enum> </enum>
<enum name="RemotingCompatibility">
<int value="0" label="Compatible"/>
<int value="1" label="Incompatible, no audio nor video"/>
<int value="2" label="Incompatible, encrypted video"/>
<int value="3" label="Incompatible video codec"/>
<int value="4" label="Incompatible, encrypted audio"/>
<int value="5" label="Incompatible audio codec"/>
<int value="6" label="Incompatible, disabled by page"/>
<int value="7" label="Incompatible, duration below threshold"/>
</enum>
<enum name="RemotingStartTrigger"> <enum name="RemotingStartTrigger">
<int value="0" label="Unknown start trigger"/> <int value="0" label="Unknown start trigger"/>
<int value="1" label="Entered fullscreen"/> <int value="1" label="Entered fullscreen"/>
...@@ -64151,6 +64162,19 @@ https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_2.7.1.pdf ...@@ -64151,6 +64162,19 @@ https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_2.7.1.pdf
<int value="3" label="Audio and video"/> <int value="3" label="Audio and video"/>
</enum> </enum>
<enum name="RemotingVideoPixelRateSupport">
<int value="0"
label="Supported; pixels-per-second is equivalent to at most 1080p
30fps"/>
<int value="1"
label="Supported; equivalent to more than 1080p 30fps and at most 2160p
30fps"/>
<int value="2"
label="Not supported; equivalent to more than 1080p 30fps and at most
2160p 30fps"/>
<int value="3" label="Not supported; equivalent to more than 2160p 30fps"/>
</enum>
<enum name="RemoveCompromisedCredentialsReason"> <enum name="RemoveCompromisedCredentialsReason">
<int value="0" label="Update - If the credentials was updated."/> <int value="0" label="Update - If the credentials was updated."/>
<int value="1" label="Remove - If the credentials was removed."/> <int value="1" label="Remove - If the credentials was removed."/>
...@@ -2993,6 +2993,17 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. ...@@ -2993,6 +2993,17 @@ reviews. Googlers can read more about this at go/gwsq-gerrit.
</summary> </summary>
</histogram> </histogram>
<histogram name="Media.Remoting.Compatibility" enum="RemotingCompatibility"
expires_after="2022-02-01">
<owner>takumif@chromium.org</owner>
<owner>openscreen-eng@google.com</owner>
<summary>
Whether the given media is compatible with media remoting. Recorded whenever
the conditions are met to start remoting (e.g. the media element is the
dominant page content and is not paused).
</summary>
</histogram>
<histogram name="Media.Remoting.SessionDuration" units="ms" <histogram name="Media.Remoting.SessionDuration" units="ms"
expires_after="2021-07-01"> expires_after="2021-07-01">
<owner>miu@chromium.org</owner> <owner>miu@chromium.org</owner>
...@@ -3101,6 +3112,16 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. ...@@ -3101,6 +3112,16 @@ reviews. Googlers can read more about this at go/gwsq-gerrit.
<summary>Video width while remoting content.</summary> <summary>Video width while remoting content.</summary>
</histogram> </histogram>
<histogram name="Media.Remoting.VideoPixelRateSupport"
enum="RemotingVideoPixelRateSupport" expires_after="2022-02-01">
<owner>takumif@chromium.org</owner>
<owner>openscreen-eng@google.com</owner>
<summary>
Pixels-per-second in a video and whether the receiver supports its playback.
Recorded whenever we are about to start media remoting a video.
</summary>
</histogram>
<histogram name="Media.RtcLowLatencyVideoRenderer.AverageQueueLengthX10" <histogram name="Media.RtcLowLatencyVideoRenderer.AverageQueueLengthX10"
units="frames" expires_after="2021-05-31"> units="frames" expires_after="2021-05-31">
<owner>kron@chromium.org</owner> <owner>kron@chromium.org</owner>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment