Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/media/media_internals.h" | 5 #include "content/browser/media/media_internals.h" |
| 6 | 6 |
| 7 #include "base/metrics/histogram.h" | 7 #include "base/metrics/histogram.h" |
| 8 #include "base/strings/string16.h" | 8 #include "base/strings/string16.h" |
| 9 #include "base/strings/string_number_conversions.h" | 9 #include "base/strings/string_number_conversions.h" |
| 10 #include "base/strings/stringprintf.h" | 10 #include "base/strings/stringprintf.h" |
| 11 #include "content/public/browser/browser_thread.h" | 11 #include "content/public/browser/browser_thread.h" |
| 12 #include "content/public/browser/notification_observer.h" | 12 #include "content/public/browser/notification_observer.h" |
| 13 #include "content/public/browser/notification_registrar.h" | 13 #include "content/public/browser/notification_registrar.h" |
| 14 #include "content/public/browser/notification_service.h" | 14 #include "content/public/browser/notification_service.h" |
| 15 #include "content/public/browser/notification_types.h" | 15 #include "content/public/browser/notification_types.h" |
| 16 #include "content/public/browser/render_process_host.h" | 16 #include "content/public/browser/render_process_host.h" |
| 17 #include "content/public/browser/web_ui.h" | 17 #include "content/public/browser/web_ui.h" |
| 18 #include "media/audio/audio_parameters.h" | 18 #include "media/audio/audio_parameters.h" |
| 19 #include "media/base/media_log_event.h" | 19 #include "media/base/media_log_event.h" |
| 20 #include "media/filters/decrypting_video_decoder.h" | |
| 20 #include "media/filters/gpu_video_decoder.h" | 21 #include "media/filters/gpu_video_decoder.h" |
| 21 | 22 |
| 22 namespace { | 23 namespace { |
| 23 | 24 |
| 24 static base::LazyInstance<content::MediaInternals>::Leaky g_media_internals = | 25 static base::LazyInstance<content::MediaInternals>::Leaky g_media_internals = |
| 25 LAZY_INSTANCE_INITIALIZER; | 26 LAZY_INSTANCE_INITIALIZER; |
| 26 | 27 |
| 27 base::string16 SerializeUpdate(const std::string& function, | 28 base::string16 SerializeUpdate(const std::string& function, |
| 28 const base::Value* value) { | 29 const base::Value* value) { |
| 29 return content::WebUI::GetJavascriptCall( | 30 return content::WebUI::GetJavascriptCall( |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 191 | 192 |
| 192 // Helper function to save the event payload to RendererPlayerMap. | 193 // Helper function to save the event payload to RendererPlayerMap. |
| 193 void SavePlayerState(const media::MediaLogEvent& event, | 194 void SavePlayerState(const media::MediaLogEvent& event, |
| 194 int render_process_id); | 195 int render_process_id); |
| 195 | 196 |
| 196 private: | 197 private: |
| 197 struct PipelineInfo { | 198 struct PipelineInfo { |
| 198 media::PipelineStatus last_pipeline_status; | 199 media::PipelineStatus last_pipeline_status; |
| 199 bool has_audio; | 200 bool has_audio; |
| 200 bool has_video; | 201 bool has_video; |
| 202 bool video_dds; | |
| 203 bool audio_dds; | |
|
xhwang
2014/12/03 21:39:50
nit: typically audio goes before video
prabhur1
2014/12/03 23:24:31
Done.
| |
| 201 std::string audio_codec_name; | 204 std::string audio_codec_name; |
| 202 std::string video_codec_name; | 205 std::string video_codec_name; |
| 203 std::string video_decoder; | 206 std::string video_decoder; |
| 204 PipelineInfo() | 207 PipelineInfo() |
| 205 : last_pipeline_status(media::PIPELINE_OK), | 208 : last_pipeline_status(media::PIPELINE_OK), |
| 206 has_audio(false), | 209 has_audio(false), |
| 207 has_video(false) {} | 210 has_video(false), |
| 211 video_dds(false), | |
| 212 audio_dds(false) {} | |
| 208 }; | 213 }; |
| 209 | 214 |
| 210 // Helper function to report PipelineStatus associated with a player to UMA. | 215 // Helper function to report PipelineStatus associated with a player to UMA. |
| 211 void ReportUMAForPipelineStatus(const PipelineInfo& player_info); | 216 void ReportUMAForPipelineStatus(const PipelineInfo& player_info); |
| 212 | 217 |
| 218 // Helper to generate pipelinestatus_UMA_prefix for AudioVideo streams. | |
| 219 std::string GetUMANameForAVStream(const PipelineInfo& player_info); | |
| 220 | |
| 213 // Key is playerid | 221 // Key is playerid |
| 214 typedef std::map<int, PipelineInfo> PlayerInfoMap; | 222 typedef std::map<int, PipelineInfo> PlayerInfoMap; |
| 215 | 223 |
| 216 // Key is renderer id | 224 // Key is renderer id |
| 217 typedef std::map<int, PlayerInfoMap> RendererPlayerMap; | 225 typedef std::map<int, PlayerInfoMap> RendererPlayerMap; |
| 218 | 226 |
| 219 // Stores player information per renderer | 227 // Stores player information per renderer |
| 220 RendererPlayerMap renderer_info_; | 228 RendererPlayerMap renderer_info_; |
| 221 | 229 |
| 222 NotificationRegistrar registrar_; | 230 NotificationRegistrar registrar_; |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 279 &player_info[event.id].audio_codec_name); | 287 &player_info[event.id].audio_codec_name); |
| 280 } | 288 } |
| 281 if (event.params.HasKey("video_codec_name")) { | 289 if (event.params.HasKey("video_codec_name")) { |
| 282 event.params.GetString("video_codec_name", | 290 event.params.GetString("video_codec_name", |
| 283 &player_info[event.id].video_codec_name); | 291 &player_info[event.id].video_codec_name); |
| 284 } | 292 } |
| 285 if (event.params.HasKey("video_decoder")) { | 293 if (event.params.HasKey("video_decoder")) { |
| 286 event.params.GetString("video_decoder", | 294 event.params.GetString("video_decoder", |
| 287 &player_info[event.id].video_decoder); | 295 &player_info[event.id].video_decoder); |
| 288 } | 296 } |
| 297 if (event.params.HasKey("video_dds")) { | |
| 298 event.params.GetBoolean("video_dds", &player_info[event.id].video_dds); | |
| 299 } | |
| 300 if (event.params.HasKey("audio_dds")) { | |
| 301 event.params.GetBoolean("audio_dds", &player_info[event.id].audio_dds); | |
| 302 } | |
| 289 break; | 303 break; |
| 290 default: | 304 default: |
| 291 break; | 305 break; |
| 292 } | 306 } |
| 293 return; | 307 return; |
| 294 } | 308 } |
| 295 | 309 |
| 310 std::string MediaInternals::MediaInternalsUMAHandler::GetUMANameForAVStream( | |
| 311 const PipelineInfo& player_info) { | |
| 312 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 313 std::string pipeline_uma_prefix = "Media.PipelineStatus.AudioVideo."; | |
| 314 if (player_info.video_codec_name == "vp8") { | |
| 315 pipeline_uma_prefix += "VP8."; | |
| 316 } else if (player_info.video_codec_name == "vp9") { | |
| 317 pipeline_uma_prefix += "VP9."; | |
| 318 } else if (player_info.video_codec_name == "h264") { | |
| 319 pipeline_uma_prefix += "H264."; | |
| 320 } else { | |
| 321 return pipeline_uma_prefix + "Other"; | |
| 322 } | |
| 323 if (player_info.video_decoder == | |
| 324 media::DecryptingVideoDecoder::kDecoderName) { | |
| 325 pipeline_uma_prefix += "DVD"; | |
| 326 } else if (player_info.video_dds || player_info.audio_dds) { | |
|
xhwang
2014/12/03 21:39:49
Now AudioVideo.VP8.DDS could be because we use aud
prabhur1
2014/12/03 23:24:31
Done.
| |
| 327 pipeline_uma_prefix += "DDS"; | |
|
xhwang
2014/12/03 21:39:50
When we use DDS, we are not checking HW vs SW anym
prabhur1
2014/12/03 23:24:31
Done.
| |
| 328 } else if (player_info.video_decoder == | |
| 329 media::GpuVideoDecoder::kDecoderName) { | |
| 330 pipeline_uma_prefix += "HW"; | |
| 331 } else { | |
| 332 pipeline_uma_prefix += "SW"; | |
| 333 } | |
| 334 return pipeline_uma_prefix; | |
|
xhwang
2014/12/03 21:39:50
Returning a uma prefix seems weird. How about some
prabhur1
2014/12/03 23:24:31
Done.
| |
| 335 } | |
| 336 | |
| 296 void MediaInternals::MediaInternalsUMAHandler::ReportUMAForPipelineStatus( | 337 void MediaInternals::MediaInternalsUMAHandler::ReportUMAForPipelineStatus( |
| 297 const PipelineInfo& player_info) { | 338 const PipelineInfo& player_info) { |
| 298 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 339 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 299 if (player_info.has_video && player_info.has_audio) { | 340 if (player_info.has_video && player_info.has_audio) { |
| 300 if (player_info.video_codec_name == "vp8") { | 341 base::LinearHistogram::FactoryGet( |
|
DaleCurtis
2014/12/02 23:21:17
Is this the (new?) hotness for dynamic UMA names?
prabhur1
2014/12/03 02:04:32
Done.
prabhur1
2014/12/03 02:04:32
Yep. I think this API has been around for sometime
| |
| 301 UMA_HISTOGRAM_ENUMERATION("Media.PipelineStatus.AudioVideo.VP8.SW", | 342 GetUMANameForAVStream(player_info), media::PIPELINE_OK, |
|
xhwang
2014/12/03 21:39:50
media::PIPELINE_OK is 0, which is not recommended.
prabhur1
2014/12/03 23:24:31
Done.
| |
| 302 player_info.last_pipeline_status, | 343 media::PIPELINE_STATUS_MAX, media::PIPELINE_STATUS_MAX + 1, |
| 303 media::PIPELINE_STATUS_MAX + 1); | 344 base::HistogramBase::kUmaTargetedHistogramFlag) |
| 304 } else if (player_info.video_codec_name == "vp9") { | 345 ->Add(player_info.last_pipeline_status); |
| 305 UMA_HISTOGRAM_ENUMERATION("Media.PipelineStatus.AudioVideo.VP9.SW", | |
| 306 player_info.last_pipeline_status, | |
| 307 media::PIPELINE_STATUS_MAX + 1); | |
| 308 } else if (player_info.video_codec_name == "h264") { | |
| 309 if (player_info.video_decoder == media::GpuVideoDecoder::kDecoderName) { | |
| 310 UMA_HISTOGRAM_ENUMERATION("Media.PipelineStatus.AudioVideo.H264.HW", | |
| 311 player_info.last_pipeline_status, | |
| 312 media::PIPELINE_STATUS_MAX + 1); | |
| 313 } else { | |
| 314 UMA_HISTOGRAM_ENUMERATION("Media.PipelineStatus.AudioVideo.H264.SW", | |
| 315 player_info.last_pipeline_status, | |
| 316 media::PIPELINE_STATUS_MAX + 1); | |
| 317 } | |
| 318 } else { | |
| 319 UMA_HISTOGRAM_ENUMERATION("Media.PipelineStatus.AudioVideo.Other", | |
| 320 player_info.last_pipeline_status, | |
| 321 media::PIPELINE_STATUS_MAX + 1); | |
| 322 } | |
| 323 } else if (player_info.has_audio) { | 346 } else if (player_info.has_audio) { |
| 324 UMA_HISTOGRAM_ENUMERATION("Media.PipelineStatus.AudioOnly", | 347 UMA_HISTOGRAM_ENUMERATION("Media.PipelineStatus.AudioOnly", |
| 325 player_info.last_pipeline_status, | 348 player_info.last_pipeline_status, |
| 326 media::PIPELINE_STATUS_MAX + 1); | 349 media::PIPELINE_STATUS_MAX + 1); |
| 327 } else if (player_info.has_video) { | 350 } else if (player_info.has_video) { |
| 328 UMA_HISTOGRAM_ENUMERATION("Media.PipelineStatus.VideoOnly", | 351 UMA_HISTOGRAM_ENUMERATION("Media.PipelineStatus.VideoOnly", |
| 329 player_info.last_pipeline_status, | 352 player_info.last_pipeline_status, |
| 330 media::PIPELINE_STATUS_MAX + 1); | 353 media::PIPELINE_STATUS_MAX + 1); |
| 331 } else { | 354 } else { |
| 332 UMA_HISTOGRAM_ENUMERATION("Media.PipelineStatus.Unsupported", | 355 UMA_HISTOGRAM_ENUMERATION("Media.PipelineStatus.Unsupported", |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 492 const std::string& function, | 515 const std::string& function, |
| 493 const base::DictionaryValue* value) { | 516 const base::DictionaryValue* value) { |
| 494 SendUpdate(SerializeUpdate(function, value)); | 517 SendUpdate(SerializeUpdate(function, value)); |
| 495 | 518 |
| 496 base::AutoLock auto_lock(lock_); | 519 base::AutoLock auto_lock(lock_); |
| 497 scoped_ptr<base::Value> out_value; | 520 scoped_ptr<base::Value> out_value; |
| 498 CHECK(audio_streams_cached_data_.Remove(cache_key, &out_value)); | 521 CHECK(audio_streams_cached_data_.Remove(cache_key, &out_value)); |
| 499 } | 522 } |
| 500 | 523 |
| 501 } // namespace content | 524 } // namespace content |
| OLD | NEW |