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