OLD | NEW |
(Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "media/remoting/metrics.h" |
| 6 |
| 7 #include "base/metrics/histogram_functions.h" |
| 8 #include "base/metrics/histogram_macros.h" |
| 9 #include "media/audio/sample_rates.h" |
| 10 |
| 11 namespace media { |
| 12 namespace remoting { |
| 13 |
| 14 namespace { |
| 15 |
| 16 //////////////////////////////////////////////////////////////////////////////// |
| 17 // BEGIN: These were all borrowed from src/media/filters/ffmpeg_demuxer.cc. |
| 18 // TODO(miu): This code will be de-duped in a soon-upcoming change. |
| 19 |
| 20 // Some videos just want to watch the world burn, with a height of 0; cap the |
| 21 // "infinite" aspect ratio resulting. |
| 22 constexpr int kInfiniteRatio = 99999; |
| 23 |
| 24 // Common aspect ratios (multiplied by 100 and truncated) used for histogramming |
| 25 // video sizes. These were taken on 20111103 from |
| 26 // http://wikipedia.org/wiki/Aspect_ratio_(image)#Previous_and_currently_used_as
pect_ratios |
| 27 constexpr int kCommonAspectRatios100[] = { |
| 28 100, 115, 133, 137, 143, 150, 155, 160, 166, |
| 29 175, 177, 185, 200, 210, 220, 221, 235, 237, |
| 30 240, 255, 259, 266, 276, 293, 400, 1200, kInfiniteRatio, |
| 31 }; |
| 32 |
| 33 // END: Code borrowed from src/media/filter/ffmpeg_demuxer.cc. |
| 34 //////////////////////////////////////////////////////////////////////////////// |
| 35 |
| 36 // Buckets for video width histograms. |
| 37 constexpr int kVideoWidthBuckets[] = { |
| 38 180, 240, 320, 480, 640, 720, 872, 940, 1280, |
| 39 1440, 1600, 1760, 1920, 2560, 3840, 7680, 16384, |
| 40 }; |
| 41 |
| 42 } // namespace |
| 43 |
| 44 SessionMetricsRecorder::SessionMetricsRecorder() |
| 45 : last_audio_codec_(kUnknownAudioCodec), |
| 46 last_channel_layout_(CHANNEL_LAYOUT_NONE), |
| 47 last_sample_rate_(0), |
| 48 last_video_codec_(kUnknownVideoCodec), |
| 49 last_video_profile_(VIDEO_CODEC_PROFILE_UNKNOWN), |
| 50 remote_playback_is_disabled_(false) {} |
| 51 |
| 52 SessionMetricsRecorder::~SessionMetricsRecorder() = default; |
| 53 |
| 54 void SessionMetricsRecorder::WillStartSession(StartTrigger trigger) { |
| 55 DCHECK(!start_trigger_); |
| 56 start_trigger_ = trigger; |
| 57 start_time_ = base::TimeTicks::Now(); |
| 58 } |
| 59 |
| 60 void SessionMetricsRecorder::DidStartSession() { |
| 61 UMA_HISTOGRAM_ENUMERATION("Media.Remoting.SessionStartTrigger", |
| 62 *start_trigger_, START_TRIGGER_MAX + 1); |
| 63 if (last_audio_codec_ != kUnknownAudioCodec) |
| 64 RecordAudioConfiguration(); |
| 65 if (last_video_codec_ != kUnknownVideoCodec) |
| 66 RecordVideoConfiguration(); |
| 67 RecordTrackConfiguration(); |
| 68 } |
| 69 |
| 70 void SessionMetricsRecorder::WillStopSession(StopTrigger trigger) { |
| 71 if (!start_trigger_) |
| 72 return; |
| 73 |
| 74 // Record what triggered the end of the session. |
| 75 UMA_HISTOGRAM_ENUMERATION("Media.Remoting.SessionStopTrigger", trigger, |
| 76 STOP_TRIGGER_MAX + 1); |
| 77 |
| 78 // Record the session duration. |
| 79 const base::TimeDelta session_duration = base::TimeTicks::Now() - start_time_; |
| 80 UMA_HISTOGRAM_CUSTOM_TIMES("Media.Remoting.SessionDuration", session_duration, |
| 81 base::TimeDelta::FromSeconds(15), |
| 82 base::TimeDelta::FromHours(12), 50); |
| 83 |
| 84 // Reset |start_trigger_| since metrics recording of the current remoting |
| 85 // session has now completed. |
| 86 start_trigger_ = base::nullopt; |
| 87 } |
| 88 |
| 89 void SessionMetricsRecorder::OnPipelineMetadataChanged( |
| 90 const PipelineMetadata& metadata) { |
| 91 if (metadata.has_audio && metadata.audio_decoder_config.IsValidConfig()) { |
| 92 const auto& config = metadata.audio_decoder_config; |
| 93 // While in a remoting session, record audio configuration changes. |
| 94 const bool need_to_record_audio_configuration = |
| 95 start_trigger_ && (config.codec() != last_audio_codec_ || |
| 96 config.channel_layout() != last_channel_layout_ || |
| 97 config.samples_per_second() != last_sample_rate_); |
| 98 last_audio_codec_ = config.codec(); |
| 99 last_channel_layout_ = config.channel_layout(); |
| 100 last_sample_rate_ = config.samples_per_second(); |
| 101 if (need_to_record_audio_configuration) |
| 102 RecordAudioConfiguration(); |
| 103 } else { |
| 104 last_audio_codec_ = kUnknownAudioCodec; |
| 105 last_channel_layout_ = CHANNEL_LAYOUT_NONE; |
| 106 last_sample_rate_ = 0; |
| 107 } |
| 108 |
| 109 if (metadata.has_video && metadata.video_decoder_config.IsValidConfig()) { |
| 110 const auto& config = metadata.video_decoder_config; |
| 111 // While in a remoting session, record video configuration changes. |
| 112 const bool need_to_record_video_configuration = |
| 113 start_trigger_ && (config.codec() != last_video_codec_ || |
| 114 config.profile() != last_video_profile_ || |
| 115 metadata.natural_size != last_natural_size_); |
| 116 last_video_codec_ = config.codec(); |
| 117 last_video_profile_ = config.profile(); |
| 118 last_natural_size_ = metadata.natural_size; |
| 119 if (need_to_record_video_configuration) |
| 120 RecordVideoConfiguration(); |
| 121 } else { |
| 122 last_video_codec_ = kUnknownVideoCodec; |
| 123 last_video_profile_ = VIDEO_CODEC_PROFILE_UNKNOWN; |
| 124 last_natural_size_ = gfx::Size(); |
| 125 } |
| 126 |
| 127 // While in a remoting session, record whether audio or video media streams |
| 128 // started or ended. |
| 129 if (start_trigger_) |
| 130 RecordTrackConfiguration(); |
| 131 } |
| 132 |
| 133 void SessionMetricsRecorder::OnRemotePlaybackDisabled(bool disabled) { |
| 134 if (disabled == remote_playback_is_disabled_) |
| 135 return; // De-dupe redundant notifications. |
| 136 UMA_HISTOGRAM_BOOLEAN("Media.Remoting.AllowedByPage", !disabled); |
| 137 remote_playback_is_disabled_ = disabled; |
| 138 } |
| 139 |
| 140 void SessionMetricsRecorder::OnPosterImageDownloaded( |
| 141 base::TimeDelta download_duration, |
| 142 bool success) { |
| 143 const std::string name = success |
| 144 ? "Media.Remoting.PosterDownloadDuration.Success" |
| 145 : "Media.Remoting.PosterDownloadDuration.Fail"; |
| 146 // Note: Not using UMA_HISTOGRAM_CUSTOM_TIMES because |name| is a variable in |
| 147 // in this instance; and so the "one histogram" static local should not be |
| 148 // created. |
| 149 base::UmaHistogramCustomTimes(name, download_duration, |
| 150 base::TimeDelta::FromMilliseconds(10), |
| 151 base::TimeDelta::FromSeconds(30), 50); |
| 152 } |
| 153 |
| 154 void SessionMetricsRecorder::RecordAudioConfiguration() { |
| 155 UMA_HISTOGRAM_ENUMERATION("Media.Remoting.AudioCodec", last_audio_codec_, |
| 156 kAudioCodecMax + 1); |
| 157 UMA_HISTOGRAM_ENUMERATION("Media.Remoting.AudioChannelLayout", |
| 158 last_channel_layout_, CHANNEL_LAYOUT_MAX + 1); |
| 159 AudioSampleRate asr; |
| 160 if (ToAudioSampleRate(last_sample_rate_, &asr)) { |
| 161 UMA_HISTOGRAM_ENUMERATION("Media.Remoting.AudioSamplesPerSecond", asr, |
| 162 kAudioSampleRateMax + 1); |
| 163 } else { |
| 164 UMA_HISTOGRAM_COUNTS_1M("Media.Remoting.AudioSamplesPerSecondUnexpected", |
| 165 last_sample_rate_); |
| 166 } |
| 167 } |
| 168 |
| 169 void SessionMetricsRecorder::RecordVideoConfiguration() { |
| 170 UMA_HISTOGRAM_ENUMERATION("Media.Remoting.VideoCodec", last_video_codec_, |
| 171 kVideoCodecMax + 1); |
| 172 UMA_HISTOGRAM_ENUMERATION("Media.Remoting.VideoCodecProfile", |
| 173 last_video_profile_, VIDEO_CODEC_PROFILE_MAX + 1); |
| 174 UMA_HISTOGRAM_CUSTOM_ENUMERATION( |
| 175 "Media.Remoting.VideoNaturalWidth", last_natural_size_.width(), |
| 176 base::CustomHistogram::ArrayToCustomRanges( |
| 177 kVideoWidthBuckets, arraysize(kVideoWidthBuckets))); |
| 178 // Intentionally use integer division to truncate the result. |
| 179 const int aspect_ratio_100 = |
| 180 last_natural_size_.height() |
| 181 ? (last_natural_size_.width() * 100) / last_natural_size_.height() |
| 182 : kInfiniteRatio; |
| 183 UMA_HISTOGRAM_CUSTOM_ENUMERATION( |
| 184 "Media.Remoting.VideoAspectRatio", aspect_ratio_100, |
| 185 base::CustomHistogram::ArrayToCustomRanges( |
| 186 kCommonAspectRatios100, arraysize(kCommonAspectRatios100))); |
| 187 } |
| 188 |
| 189 void SessionMetricsRecorder::RecordTrackConfiguration() { |
| 190 TrackConfiguration config = NEITHER_AUDIO_NOR_VIDEO; |
| 191 if (last_audio_codec_ != kUnknownAudioCodec) |
| 192 config = AUDIO_ONLY; |
| 193 if (last_video_codec_ != kUnknownVideoCodec) { |
| 194 if (config == AUDIO_ONLY) |
| 195 config = AUDIO_AND_VIDEO; |
| 196 else |
| 197 config = VIDEO_ONLY; |
| 198 } |
| 199 UMA_HISTOGRAM_ENUMERATION("Media.Remoting.TrackConfiguration", config, |
| 200 TRACK_CONFIGURATION_MAX + 1); |
| 201 } |
| 202 |
| 203 RendererMetricsRecorder::RendererMetricsRecorder() |
| 204 : start_time_(base::TimeTicks::Now()), did_record_first_playout_(false) {} |
| 205 |
| 206 RendererMetricsRecorder::~RendererMetricsRecorder() = default; |
| 207 |
| 208 void RendererMetricsRecorder::OnRendererInitialized() { |
| 209 const base::TimeDelta elapsed_since_start = |
| 210 base::TimeTicks::Now() - start_time_; |
| 211 UMA_HISTOGRAM_CUSTOM_TIMES("Media.Remoting.TimeUntilRemoteInitialized", |
| 212 elapsed_since_start, |
| 213 base::TimeDelta::FromMilliseconds(10), |
| 214 base::TimeDelta::FromSeconds(30), 50); |
| 215 } |
| 216 |
| 217 void RendererMetricsRecorder::OnEvidenceOfPlayoutAtReceiver() { |
| 218 if (did_record_first_playout_) |
| 219 return; |
| 220 const base::TimeDelta elapsed_since_start = |
| 221 base::TimeTicks::Now() - start_time_; |
| 222 UMA_HISTOGRAM_CUSTOM_TIMES("Media.Remoting.TimeUntilFirstPlayout", |
| 223 elapsed_since_start, |
| 224 base::TimeDelta::FromMilliseconds(10), |
| 225 base::TimeDelta::FromSeconds(30), 50); |
| 226 did_record_first_playout_ = true; |
| 227 } |
| 228 |
| 229 void RendererMetricsRecorder::OnAudioRateEstimate(int kilobits_per_second) { |
| 230 UMA_HISTOGRAM_CUSTOM_COUNTS("Media.Remoting.AudioBitrate", |
| 231 kilobits_per_second, 1, 1024, 50); |
| 232 } |
| 233 |
| 234 void RendererMetricsRecorder::OnVideoRateEstimate(int kilobits_per_second) { |
| 235 UMA_HISTOGRAM_CUSTOM_COUNTS("Media.Remoting.VideoBitrate", |
| 236 kilobits_per_second, 1, 16 * 1024, 50); |
| 237 } |
| 238 |
| 239 } // namespace remoting |
| 240 } // namespace media |
OLD | NEW |