Index: content/browser/media/media_internals.cc |
diff --git a/content/browser/media/media_internals.cc b/content/browser/media/media_internals.cc |
index 3ef867386b38ba2c1d3df7d8e3b1e29f5092261b..ae0a737fb4d119263b81ed2c395b68cfc755ac4b 100644 |
--- a/content/browser/media/media_internals.cc |
+++ b/content/browser/media/media_internals.cc |
@@ -25,6 +25,7 @@ |
#include "content/public/browser/web_ui.h" |
#include "media/base/audio_parameters.h" |
#include "media/base/media_log_event.h" |
+#include "media/blink/watch_time_reporter.h" |
#include "media/filters/gpu_video_decoder.h" |
#if !defined(OS_ANDROID) |
@@ -289,6 +290,15 @@ class MediaInternals::MediaInternalsUMAHandler { |
const media::MediaLogEvent& event); |
private: |
+ struct WatchTimeInfo { |
+ base::TimeDelta all_watch_time = media::kNoTimestamp; |
+ base::TimeDelta mse_watch_time = media::kNoTimestamp; |
+ base::TimeDelta eme_watch_time = media::kNoTimestamp; |
+ base::TimeDelta src_watch_time = media::kNoTimestamp; |
+ base::TimeDelta ac_watch_time = media::kNoTimestamp; |
+ base::TimeDelta battery_watch_time = media::kNoTimestamp; |
+ }; |
+ |
struct PipelineInfo { |
bool has_pipeline = false; |
media::PipelineStatus last_pipeline_status = media::PIPELINE_OK; |
@@ -299,6 +309,7 @@ class MediaInternals::MediaInternalsUMAHandler { |
std::string audio_codec_name; |
std::string video_codec_name; |
std::string video_decoder; |
+ WatchTimeInfo watch_time_info; |
}; |
// Helper function to report PipelineStatus associated with a player to UMA. |
@@ -307,6 +318,23 @@ class MediaInternals::MediaInternalsUMAHandler { |
// Helper to generate PipelineStatus UMA name for AudioVideo streams. |
std::string GetUMANameForAVStream(const PipelineInfo& player_info); |
+ // Saves the watch time info from |event| under |key| at |watch_time| if |key| |
+ // is present in |event.params|. |
+ void MaybeSaveWatchTime(const media::MediaLogEvent& event, |
+ const char* key, |
+ base::TimeDelta* watch_time) { |
+ if (!event.params.HasKey(key)) |
+ return; |
+ |
+ double in_seconds; |
+ const bool result = |
+ event.params.GetDoubleWithoutPathExpansion(key, &in_seconds); |
+ DCHECK(result); |
+ *watch_time = base::TimeDelta::FromSecondsD(in_seconds); |
+ |
+ DVLOG(2) << "Saved watch time for " << key << " of " << *watch_time; |
+ } |
+ |
// Key is player id. |
typedef std::map<int, PipelineInfo> PlayerInfoMap; |
@@ -369,6 +397,29 @@ void MediaInternals::MediaInternalsUMAHandler::SavePlayerState( |
event.params.GetBoolean("video_dds", &player_info[event.id].video_dds); |
} |
break; |
+ case media::MediaLogEvent::Type::WATCH_TIME_UPDATE: { |
+ DVLOG(2) << "Processing watch time update."; |
+ WatchTimeInfo& wti = player_info[event.id].watch_time_info; |
+ MaybeSaveWatchTime(event, |
+ media::WatchTimeReporter::kHistogramAudioVideoAll, |
+ &wti.all_watch_time); |
+ MaybeSaveWatchTime(event, |
+ media::WatchTimeReporter::kHistogramAudioVideoMse, |
+ &wti.mse_watch_time); |
+ MaybeSaveWatchTime(event, |
+ media::WatchTimeReporter::kHistogramAudioVideoEme, |
+ &wti.eme_watch_time); |
+ MaybeSaveWatchTime(event, |
+ media::WatchTimeReporter::kHistogramAudioVideoSrc, |
+ &wti.src_watch_time); |
+ MaybeSaveWatchTime(event, |
+ media::WatchTimeReporter::kHistogramAudioVideoBattery, |
+ &wti.battery_watch_time); |
+ MaybeSaveWatchTime(event, |
+ media::WatchTimeReporter::kHistogramAudioVideoAc, |
+ &wti.ac_watch_time); |
+ break; |
+ } |
default: |
break; |
} |
@@ -446,6 +497,22 @@ void MediaInternals::MediaInternalsUMAHandler::ReportUMAForPipelineStatus( |
UMA_HISTOGRAM_BOOLEAN("Media.VideoDecoderFallback", |
player_info.video_decoder_changed); |
} |
+ |
+// Use a macro instead of a function so we can use the histogram macro (which |
+// checks that the uma name is a static value). |
+#define MAYBE_RECORD_WATCH_TIME(uma_name, watch_time) \ |
+ if (player_info.watch_time_info.watch_time != media::kNoTimestamp) { \ |
+ UMA_HISTOGRAM_LONG_TIMES(media::WatchTimeReporter::uma_name, \ |
+ player_info.watch_time_info.watch_time); \ |
+ } |
+ |
+ MAYBE_RECORD_WATCH_TIME(kHistogramAudioVideoAll, all_watch_time); |
+ MAYBE_RECORD_WATCH_TIME(kHistogramAudioVideoMse, mse_watch_time); |
+ MAYBE_RECORD_WATCH_TIME(kHistogramAudioVideoEme, eme_watch_time); |
+ MAYBE_RECORD_WATCH_TIME(kHistogramAudioVideoSrc, src_watch_time); |
+ MAYBE_RECORD_WATCH_TIME(kHistogramAudioVideoBattery, battery_watch_time); |
+ MAYBE_RECORD_WATCH_TIME(kHistogramAudioVideoAc, ac_watch_time); |
+#undef MAYBE_RECORD_WATCH_TIME |
} |
void MediaInternals::MediaInternalsUMAHandler::OnProcessTerminated( |
@@ -529,13 +596,15 @@ void MediaInternals::OnMediaEvents( |
DCHECK_CURRENTLY_ON(BrowserThread::UI); |
// Notify observers that |event| has occurred. |
for (const auto& event : events) { |
- if (CanUpdate()) { |
- base::string16 update; |
- if (ConvertEventToUpdate(render_process_id, event, &update)) |
- SendUpdate(update); |
+ // Some events should not be recorded in the UI. |
+ if (event.type != media::MediaLogEvent::Type::WATCH_TIME_UPDATE) { |
+ if (CanUpdate()) { |
+ base::string16 update; |
+ if (ConvertEventToUpdate(render_process_id, event, &update)) |
+ SendUpdate(update); |
+ } |
+ SaveEvent(render_process_id, event); |
} |
- |
- SaveEvent(render_process_id, event); |
uma_handler_->SavePlayerState(render_process_id, event); |
} |
} |