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" |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
252 | 252 |
253 MediaInternals::MediaInternalsUMAHandler::MediaInternalsUMAHandler() { | 253 MediaInternals::MediaInternalsUMAHandler::MediaInternalsUMAHandler() { |
254 registrar_.Add(this, NOTIFICATION_RENDERER_PROCESS_TERMINATED, | 254 registrar_.Add(this, NOTIFICATION_RENDERER_PROCESS_TERMINATED, |
255 NotificationService::AllBrowserContextsAndSources()); | 255 NotificationService::AllBrowserContextsAndSources()); |
256 } | 256 } |
257 | 257 |
258 void MediaInternals::MediaInternalsUMAHandler::Observe( | 258 void MediaInternals::MediaInternalsUMAHandler::Observe( |
259 int type, | 259 int type, |
260 const NotificationSource& source, | 260 const NotificationSource& source, |
261 const NotificationDetails& details) { | 261 const NotificationDetails& details) { |
262 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 262 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
263 DCHECK_EQ(type, NOTIFICATION_RENDERER_PROCESS_TERMINATED); | 263 DCHECK_EQ(type, NOTIFICATION_RENDERER_PROCESS_TERMINATED); |
264 RenderProcessHost* process = Source<RenderProcessHost>(source).ptr(); | 264 RenderProcessHost* process = Source<RenderProcessHost>(source).ptr(); |
265 | 265 |
266 // Post the task to the IO thread to avoid race in updating renderer_info_ map | 266 // Post the task to the IO thread to avoid race in updating renderer_info_ map |
267 // by both SavePlayerState & LogAndClearPlayersInRenderer from different | 267 // by both SavePlayerState & LogAndClearPlayersInRenderer from different |
268 // threads. | 268 // threads. |
269 // Using base::Unretained() on MediaInternalsUMAHandler is safe since | 269 // Using base::Unretained() on MediaInternalsUMAHandler is safe since |
270 // it is owned by MediaInternals and share the same lifetime | 270 // it is owned by MediaInternals and share the same lifetime |
271 BrowserThread::PostTask( | 271 BrowserThread::PostTask( |
272 BrowserThread::IO, FROM_HERE, | 272 BrowserThread::IO, FROM_HERE, |
273 base::Bind(&MediaInternalsUMAHandler::LogAndClearPlayersInRenderer, | 273 base::Bind(&MediaInternalsUMAHandler::LogAndClearPlayersInRenderer, |
274 base::Unretained(this), process->GetID())); | 274 base::Unretained(this), process->GetID())); |
275 } | 275 } |
276 | 276 |
277 void MediaInternals::MediaInternalsUMAHandler::SavePlayerState( | 277 void MediaInternals::MediaInternalsUMAHandler::SavePlayerState( |
278 const media::MediaLogEvent& event, | 278 const media::MediaLogEvent& event, |
279 int render_process_id) { | 279 int render_process_id) { |
280 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 280 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
281 PlayerInfoMap& player_info = renderer_info_[render_process_id]; | 281 PlayerInfoMap& player_info = renderer_info_[render_process_id]; |
282 switch (event.type) { | 282 switch (event.type) { |
283 case media::MediaLogEvent::PIPELINE_ERROR: { | 283 case media::MediaLogEvent::PIPELINE_ERROR: { |
284 int status; | 284 int status; |
285 event.params.GetInteger("pipeline_error", &status); | 285 event.params.GetInteger("pipeline_error", &status); |
286 player_info[event.id].last_pipeline_status = | 286 player_info[event.id].last_pipeline_status = |
287 static_cast<media::PipelineStatus>(status); | 287 static_cast<media::PipelineStatus>(status); |
288 break; | 288 break; |
289 } | 289 } |
290 case media::MediaLogEvent::PROPERTY_CHANGE: | 290 case media::MediaLogEvent::PROPERTY_CHANGE: |
(...skipping 27 matching lines...) Expand all Loading... |
318 } | 318 } |
319 break; | 319 break; |
320 default: | 320 default: |
321 break; | 321 break; |
322 } | 322 } |
323 return; | 323 return; |
324 } | 324 } |
325 | 325 |
326 std::string MediaInternals::MediaInternalsUMAHandler::GetUMANameForAVStream( | 326 std::string MediaInternals::MediaInternalsUMAHandler::GetUMANameForAVStream( |
327 const PipelineInfo& player_info) { | 327 const PipelineInfo& player_info) { |
328 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 328 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
329 static const char kPipelineUmaPrefix[] = "Media.PipelineStatus.AudioVideo."; | 329 static const char kPipelineUmaPrefix[] = "Media.PipelineStatus.AudioVideo."; |
330 std::string uma_name = kPipelineUmaPrefix; | 330 std::string uma_name = kPipelineUmaPrefix; |
331 if (player_info.video_codec_name == "vp8") { | 331 if (player_info.video_codec_name == "vp8") { |
332 uma_name += "VP8."; | 332 uma_name += "VP8."; |
333 } else if (player_info.video_codec_name == "vp9") { | 333 } else if (player_info.video_codec_name == "vp9") { |
334 uma_name += "VP9."; | 334 uma_name += "VP9."; |
335 } else if (player_info.video_codec_name == "h264") { | 335 } else if (player_info.video_codec_name == "h264") { |
336 uma_name += "H264."; | 336 uma_name += "H264."; |
337 } else { | 337 } else { |
338 return uma_name + "Other"; | 338 return uma_name + "Other"; |
(...skipping 11 matching lines...) Expand all Loading... |
350 if (player_info.video_decoder == media::GpuVideoDecoder::kDecoderName) { | 350 if (player_info.video_decoder == media::GpuVideoDecoder::kDecoderName) { |
351 uma_name += "HW"; | 351 uma_name += "HW"; |
352 } else { | 352 } else { |
353 uma_name += "SW"; | 353 uma_name += "SW"; |
354 } | 354 } |
355 return uma_name; | 355 return uma_name; |
356 } | 356 } |
357 | 357 |
358 void MediaInternals::MediaInternalsUMAHandler::ReportUMAForPipelineStatus( | 358 void MediaInternals::MediaInternalsUMAHandler::ReportUMAForPipelineStatus( |
359 const PipelineInfo& player_info) { | 359 const PipelineInfo& player_info) { |
360 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 360 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
361 if (player_info.has_video && player_info.has_audio) { | 361 if (player_info.has_video && player_info.has_audio) { |
362 base::LinearHistogram::FactoryGet( | 362 base::LinearHistogram::FactoryGet( |
363 GetUMANameForAVStream(player_info), 1, media::PIPELINE_STATUS_MAX, | 363 GetUMANameForAVStream(player_info), 1, media::PIPELINE_STATUS_MAX, |
364 media::PIPELINE_STATUS_MAX + 1, | 364 media::PIPELINE_STATUS_MAX + 1, |
365 base::HistogramBase::kUmaTargetedHistogramFlag) | 365 base::HistogramBase::kUmaTargetedHistogramFlag) |
366 ->Add(player_info.last_pipeline_status); | 366 ->Add(player_info.last_pipeline_status); |
367 } else if (player_info.has_audio) { | 367 } else if (player_info.has_audio) { |
368 UMA_HISTOGRAM_ENUMERATION("Media.PipelineStatus.AudioOnly", | 368 UMA_HISTOGRAM_ENUMERATION("Media.PipelineStatus.AudioOnly", |
369 player_info.last_pipeline_status, | 369 player_info.last_pipeline_status, |
370 media::PIPELINE_STATUS_MAX + 1); | 370 media::PIPELINE_STATUS_MAX + 1); |
371 } else if (player_info.has_video) { | 371 } else if (player_info.has_video) { |
372 UMA_HISTOGRAM_ENUMERATION("Media.PipelineStatus.VideoOnly", | 372 UMA_HISTOGRAM_ENUMERATION("Media.PipelineStatus.VideoOnly", |
373 player_info.last_pipeline_status, | 373 player_info.last_pipeline_status, |
374 media::PIPELINE_STATUS_MAX + 1); | 374 media::PIPELINE_STATUS_MAX + 1); |
375 } else { | 375 } else { |
376 UMA_HISTOGRAM_ENUMERATION("Media.PipelineStatus.Unsupported", | 376 UMA_HISTOGRAM_ENUMERATION("Media.PipelineStatus.Unsupported", |
377 player_info.last_pipeline_status, | 377 player_info.last_pipeline_status, |
378 media::PIPELINE_STATUS_MAX + 1); | 378 media::PIPELINE_STATUS_MAX + 1); |
379 } | 379 } |
380 // Report whether video decoder fallback happened, but only if a video decoder | 380 // Report whether video decoder fallback happened, but only if a video decoder |
381 // was reported. | 381 // was reported. |
382 if (!player_info.video_decoder.empty()) { | 382 if (!player_info.video_decoder.empty()) { |
383 UMA_HISTOGRAM_BOOLEAN("Media.VideoDecoderFallback", | 383 UMA_HISTOGRAM_BOOLEAN("Media.VideoDecoderFallback", |
384 player_info.video_decoder_changed); | 384 player_info.video_decoder_changed); |
385 } | 385 } |
386 } | 386 } |
387 | 387 |
388 void MediaInternals::MediaInternalsUMAHandler::LogAndClearPlayersInRenderer( | 388 void MediaInternals::MediaInternalsUMAHandler::LogAndClearPlayersInRenderer( |
389 int render_process_id) { | 389 int render_process_id) { |
390 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 390 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
391 auto players_it = renderer_info_.find(render_process_id); | 391 auto players_it = renderer_info_.find(render_process_id); |
392 if (players_it == renderer_info_.end()) | 392 if (players_it == renderer_info_.end()) |
393 return; | 393 return; |
394 auto it = players_it->second.begin(); | 394 auto it = players_it->second.begin(); |
395 while (it != players_it->second.end()) { | 395 while (it != players_it->second.end()) { |
396 ReportUMAForPipelineStatus(it->second); | 396 ReportUMAForPipelineStatus(it->second); |
397 players_it->second.erase(it++); | 397 players_it->second.erase(it++); |
398 } | 398 } |
399 } | 399 } |
400 | 400 |
401 MediaInternals* MediaInternals::GetInstance() { | 401 MediaInternals* MediaInternals::GetInstance() { |
402 return g_media_internals.Pointer(); | 402 return g_media_internals.Pointer(); |
403 } | 403 } |
404 | 404 |
405 MediaInternals::MediaInternals() | 405 MediaInternals::MediaInternals() |
406 : owner_ids_(), uma_handler_(new MediaInternalsUMAHandler()) { | 406 : owner_ids_(), uma_handler_(new MediaInternalsUMAHandler()) { |
407 } | 407 } |
408 | 408 |
409 MediaInternals::~MediaInternals() {} | 409 MediaInternals::~MediaInternals() {} |
410 | 410 |
411 void MediaInternals::OnMediaEvents( | 411 void MediaInternals::OnMediaEvents( |
412 int render_process_id, const std::vector<media::MediaLogEvent>& events) { | 412 int render_process_id, const std::vector<media::MediaLogEvent>& events) { |
413 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 413 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
414 // Notify observers that |event| has occurred. | 414 // Notify observers that |event| has occurred. |
415 for (auto event = events.begin(); event != events.end(); ++event) { | 415 for (auto event = events.begin(); event != events.end(); ++event) { |
416 base::DictionaryValue dict; | 416 base::DictionaryValue dict; |
417 dict.SetInteger("renderer", render_process_id); | 417 dict.SetInteger("renderer", render_process_id); |
418 dict.SetInteger("player", event->id); | 418 dict.SetInteger("player", event->id); |
419 dict.SetString("type", media::MediaLog::EventTypeToString(event->type)); | 419 dict.SetString("type", media::MediaLog::EventTypeToString(event->type)); |
420 | 420 |
421 // TODO(dalecurtis): This is technically not correct. TimeTicks "can't" be | 421 // TODO(dalecurtis): This is technically not correct. TimeTicks "can't" be |
422 // converted to to a human readable time format. See base/time/time.h. | 422 // converted to to a human readable time format. See base/time/time.h. |
423 const double ticks = event->time.ToInternalValue(); | 423 const double ticks = event->time.ToInternalValue(); |
(...skipping 10 matching lines...) Expand all Loading... |
434 } else { | 434 } else { |
435 dict.Set("params", event->params.DeepCopy()); | 435 dict.Set("params", event->params.DeepCopy()); |
436 } | 436 } |
437 | 437 |
438 SendUpdate(SerializeUpdate("media.onMediaEvent", &dict)); | 438 SendUpdate(SerializeUpdate("media.onMediaEvent", &dict)); |
439 uma_handler_->SavePlayerState(*event, render_process_id); | 439 uma_handler_->SavePlayerState(*event, render_process_id); |
440 } | 440 } |
441 } | 441 } |
442 | 442 |
443 void MediaInternals::AddUpdateCallback(const UpdateCallback& callback) { | 443 void MediaInternals::AddUpdateCallback(const UpdateCallback& callback) { |
444 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 444 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
445 update_callbacks_.push_back(callback); | 445 update_callbacks_.push_back(callback); |
446 } | 446 } |
447 | 447 |
448 void MediaInternals::RemoveUpdateCallback(const UpdateCallback& callback) { | 448 void MediaInternals::RemoveUpdateCallback(const UpdateCallback& callback) { |
449 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 449 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
450 for (size_t i = 0; i < update_callbacks_.size(); ++i) { | 450 for (size_t i = 0; i < update_callbacks_.size(); ++i) { |
451 if (update_callbacks_[i].Equals(callback)) { | 451 if (update_callbacks_[i].Equals(callback)) { |
452 update_callbacks_.erase(update_callbacks_.begin() + i); | 452 update_callbacks_.erase(update_callbacks_.begin() + i); |
453 return; | 453 return; |
454 } | 454 } |
455 } | 455 } |
456 NOTREACHED(); | 456 NOTREACHED(); |
457 } | 457 } |
458 | 458 |
459 void MediaInternals::SendAudioStreamData() { | 459 void MediaInternals::SendAudioStreamData() { |
460 base::string16 audio_stream_update; | 460 base::string16 audio_stream_update; |
461 { | 461 { |
462 base::AutoLock auto_lock(lock_); | 462 base::AutoLock auto_lock(lock_); |
463 audio_stream_update = SerializeUpdate( | 463 audio_stream_update = SerializeUpdate( |
464 "media.onReceiveAudioStreamData", &audio_streams_cached_data_); | 464 "media.onReceiveAudioStreamData", &audio_streams_cached_data_); |
465 } | 465 } |
466 SendUpdate(audio_stream_update); | 466 SendUpdate(audio_stream_update); |
467 } | 467 } |
468 | 468 |
469 void MediaInternals::SendVideoCaptureDeviceCapabilities() { | 469 void MediaInternals::SendVideoCaptureDeviceCapabilities() { |
470 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 470 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
471 SendUpdate(SerializeUpdate("media.onReceiveVideoCaptureCapabilities", | 471 SendUpdate(SerializeUpdate("media.onReceiveVideoCaptureCapabilities", |
472 &video_capture_capabilities_cached_data_)); | 472 &video_capture_capabilities_cached_data_)); |
473 } | 473 } |
474 | 474 |
475 void MediaInternals::UpdateVideoCaptureDeviceCapabilities( | 475 void MediaInternals::UpdateVideoCaptureDeviceCapabilities( |
476 const media::VideoCaptureDeviceInfos& video_capture_device_infos) { | 476 const media::VideoCaptureDeviceInfos& video_capture_device_infos) { |
477 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 477 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
478 video_capture_capabilities_cached_data_.Clear(); | 478 video_capture_capabilities_cached_data_.Clear(); |
479 | 479 |
480 for (const auto& video_capture_device_info : video_capture_device_infos) { | 480 for (const auto& video_capture_device_info : video_capture_device_infos) { |
481 base::ListValue* format_list = new base::ListValue(); | 481 base::ListValue* format_list = new base::ListValue(); |
482 for (const auto& format : video_capture_device_info.supported_formats) | 482 for (const auto& format : video_capture_device_info.supported_formats) |
483 format_list->AppendString(format.ToString()); | 483 format_list->AppendString(format.ToString()); |
484 | 484 |
485 base::DictionaryValue* device_dict = new base::DictionaryValue(); | 485 base::DictionaryValue* device_dict = new base::DictionaryValue(); |
486 device_dict->SetString("id", video_capture_device_info.name.id()); | 486 device_dict->SetString("id", video_capture_device_info.name.id()); |
487 device_dict->SetString( | 487 device_dict->SetString( |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
542 const std::string& function, | 542 const std::string& function, |
543 const base::DictionaryValue* value) { | 543 const base::DictionaryValue* value) { |
544 SendUpdate(SerializeUpdate(function, value)); | 544 SendUpdate(SerializeUpdate(function, value)); |
545 | 545 |
546 base::AutoLock auto_lock(lock_); | 546 base::AutoLock auto_lock(lock_); |
547 scoped_ptr<base::Value> out_value; | 547 scoped_ptr<base::Value> out_value; |
548 CHECK(audio_streams_cached_data_.Remove(cache_key, &out_value)); | 548 CHECK(audio_streams_cached_data_.Remove(cache_key, &out_value)); |
549 } | 549 } |
550 | 550 |
551 } // namespace content | 551 } // namespace content |
OLD | NEW |