Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(974)

Side by Side Diff: content/browser/media/media_internals.cc

Issue 697463005: Add PipelineStatus UMA logging to media_internals (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/strings/string16.h" 8 #include "base/strings/string16.h"
8 #include "base/strings/string_number_conversions.h" 9 #include "base/strings/string_number_conversions.h"
9 #include "base/strings/stringprintf.h" 10 #include "base/strings/stringprintf.h"
10 #include "content/public/browser/browser_thread.h" 11 #include "content/public/browser/browser_thread.h"
12 #include "content/public/browser/notification_service.h"
13 #include "content/public/browser/notification_types.h"
14 #include "content/public/browser/render_process_host.h"
11 #include "content/public/browser/web_ui.h" 15 #include "content/public/browser/web_ui.h"
12 #include "media/audio/audio_parameters.h" 16 #include "media/audio/audio_parameters.h"
13 #include "media/base/media_log.h"
14 #include "media/base/media_log_event.h" 17 #include "media/base/media_log_event.h"
15 18
16 namespace { 19 namespace {
17 20
18 static base::LazyInstance<content::MediaInternals>::Leaky g_media_internals = 21 static base::LazyInstance<content::MediaInternals>::Leaky g_media_internals =
19 LAZY_INSTANCE_INITIALIZER; 22 LAZY_INSTANCE_INITIALIZER;
20 23
21 base::string16 SerializeUpdate(const std::string& function, 24 base::string16 SerializeUpdate(const std::string& function,
22 const base::Value* value) { 25 const base::Value* value) {
23 return content::WebUI::GetJavascriptCall( 26 return content::WebUI::GetJavascriptCall(
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
167 base::DictionaryValue* dict) { 170 base::DictionaryValue* dict) {
168 dict->SetInteger("owner_id", owner_id_); 171 dict->SetInteger("owner_id", owner_id_);
169 dict->SetInteger("component_id", component_id); 172 dict->SetInteger("component_id", component_id);
170 dict->SetInteger("component_type", component_); 173 dict->SetInteger("component_type", component_);
171 } 174 }
172 175
173 MediaInternals* MediaInternals::GetInstance() { 176 MediaInternals* MediaInternals::GetInstance() {
174 return g_media_internals.Pointer(); 177 return g_media_internals.Pointer();
175 } 178 }
176 179
177 MediaInternals::MediaInternals() : owner_ids_() {} 180 MediaInternals::MediaInternals() : owner_ids_() {
181 registrar_.Add(this,
182 NOTIFICATION_RENDERER_PROCESS_TERMINATED,
183 NotificationService::AllBrowserContextsAndSources());
184 }
185
178 MediaInternals::~MediaInternals() {} 186 MediaInternals::~MediaInternals() {}
179 187
188 void MediaInternals::Observe(int type,
189 const NotificationSource& source,
190 const NotificationDetails& details) {
191 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
192 DCHECK_EQ(type, NOTIFICATION_RENDERER_PROCESS_TERMINATED);
193 RenderProcessHost* process = Source<RenderProcessHost>(source).ptr();
194 LogAndClearPlayersInRenderer(process->GetID());
195 }
196
197 void MediaInternals::LogAndClearPlayersInRenderer(int render_process_id) {
198 auto players_it = renderer_info.find(render_process_id);
199 if (players_it == renderer_info.end())
200 return;
201
202 auto it = players_it->second.begin();
203 while (it != players_it->second.end()) {
204 LogUMAForPipelineStatus(*(it->second));
205 //delete memory allocated for PipelineStatus
206 delete it->second;
207 players_it->second.erase(it++);
208 }
209 }
210
180 void MediaInternals::OnMediaEvents( 211 void MediaInternals::OnMediaEvents(
181 int render_process_id, const std::vector<media::MediaLogEvent>& events) { 212 int render_process_id, const std::vector<media::MediaLogEvent>& events) {
182 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 213 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
183 // Notify observers that |event| has occurred. 214 // Notify observers that |event| has occurred.
184 for (std::vector<media::MediaLogEvent>::const_iterator event = events.begin(); 215 for (std::vector<media::MediaLogEvent>::const_iterator event = events.begin();
185 event != events.end(); ++event) { 216 event != events.end(); ++event) {
186 base::DictionaryValue dict; 217 base::DictionaryValue dict;
187 dict.SetInteger("renderer", render_process_id); 218 dict.SetInteger("renderer", render_process_id);
188 dict.SetInteger("player", event->id); 219 dict.SetInteger("player", event->id);
189 dict.SetString("type", media::MediaLog::EventTypeToString(event->type)); 220 dict.SetString("type", media::MediaLog::EventTypeToString(event->type));
190 221
191 // TODO(dalecurtis): This is technically not correct. TimeTicks "can't" be 222 // TODO(dalecurtis): This is technically not correct. TimeTicks "can't" be
192 // converted to to a human readable time format. See base/time/time.h. 223 // converted to to a human readable time format. See base/time/time.h.
193 const double ticks = event->time.ToInternalValue(); 224 const double ticks = event->time.ToInternalValue();
194 const double ticks_millis = ticks / base::Time::kMicrosecondsPerMillisecond; 225 const double ticks_millis = ticks / base::Time::kMicrosecondsPerMillisecond;
195 dict.SetDouble("ticksMillis", ticks_millis); 226 dict.SetDouble("ticksMillis", ticks_millis);
196 dict.Set("params", event->params.DeepCopy()); 227 dict.Set("params", event->params.DeepCopy());
197 SendUpdate(SerializeUpdate("media.onMediaEvent", &dict)); 228 SendUpdate(SerializeUpdate("media.onMediaEvent", &dict));
229 SavePlayerState(*event, render_process_id);
198 } 230 }
199 } 231 }
200 232
233 void MediaInternals::SavePlayerState(const media::MediaLogEvent& event,
234 int render_process_id) {
235 PlayerInfoMap& player_info = renderer_info[render_process_id];
236 switch (event.type) {
237 case media::MediaLogEvent::WEBMEDIAPLAYER_CREATED: {
238 auto it = player_info.find(event.id);
239 if (it == player_info.end()) {
240 player_info[event.id] = new PipelineInfo();
241 }
242 break;
243 }
244 case media::MediaLogEvent::PIPELINE_ERROR: {
245 std::string status = "";
DaleCurtis 2014/11/06 23:49:08 No need for =""
prabhur1 2014/11/07 23:43:23 Done.
246 event.params.GetString("pipeline_error", &status);
247 media::MediaLog::StringToPipelineStatus(
248 status, player_info[event.id]->last_pipeline_status);
249 break;
250 }
251 case media::MediaLogEvent::PROPERTY_CHANGE:
252 if (event.params.HasKey("found_audio_stream")) {
253 event.params.GetBoolean("found_audio_stream",
254 &player_info[event.id]->has_audio);
255 }
256 if (event.params.HasKey("found_video_stream")) {
257 event.params.GetBoolean("found_video_stream",
258 &player_info[event.id]->has_video);
259 }
260 if (event.params.HasKey("audio_codec_name")) {
261 event.params.GetString("audio_codec_name",
262 &player_info[event.id]->audio_codec_name);
263 }
264 if (event.params.HasKey("video_codec_name")) {
265 event.params.GetString("video_codec_name",
266 &player_info[event.id]->video_codec_name);
267 }
268 if (event.params.HasKey("video_decoder")) {
269 event.params.GetString("video_decoder",
270 &player_info[event.id]->video_decoder);
prabhur1 2014/11/06 21:17:51 Just noticed the formatting. Will fix it in the ne
prabhur1 2014/11/07 23:43:23 Done.
271 }
272 break;
273 default:
274 break;
275 }
276 return;
277 }
278
279 void MediaInternals::LogUMAForPipelineStatus(const PipelineInfo& player_info) {
280 if (player_info.has_video && player_info.has_audio) {
281 if (player_info.video_codec_name == "vp8") {
282 UMA_HISTOGRAM_ENUMERATION("Media.PipelineStatus.AudioVideo.VP8",
283 player_info.last_pipeline_status,
284 media::PIPELINE_STATUS_MAX + 1);
285 } else if (player_info.video_codec_name == "vp9") {
prabhur1 2014/11/06 21:17:51 This code is not getting hit while playing a vp9 v
DaleCurtis 2014/11/06 23:49:08 Yeah sounds like it, can you fix or file a bug?
prabhur1 2014/11/07 23:43:23 Assigned to me : https://code.google.com/p/chromiu
286 UMA_HISTOGRAM_ENUMERATION("Media.PipelineStatus.AudioVideo.VP9",
287 player_info.last_pipeline_status,
288 media::PIPELINE_STATUS_MAX + 1);
289 } else if (player_info.video_codec_name == "h264") {
290
291 if (player_info.video_decoder == "gpu") {
292 UMA_HISTOGRAM_ENUMERATION("Media.PipelineStatus.AudioVideo.HW.H264",
293 player_info.last_pipeline_status,
294 media::PIPELINE_STATUS_MAX + 1);
295 }
296 else {
297 UMA_HISTOGRAM_ENUMERATION("Media.PipelineStatus.AudioVideo.SW.H264",
298 player_info.last_pipeline_status,
299 media::PIPELINE_STATUS_MAX + 1);
300 }
301 } else {
302 UMA_HISTOGRAM_ENUMERATION("Media.PipelineStatus.AudioVideo",
303 player_info.last_pipeline_status,
304 media::PIPELINE_STATUS_MAX + 1);
305 }
306 } else if (player_info.has_audio) {
307 UMA_HISTOGRAM_ENUMERATION("Media.PipelineStatus.Audio",
308 player_info.last_pipeline_status,
309 media::PIPELINE_STATUS_MAX + 1);
310 } else if (player_info.has_video) {
311 UMA_HISTOGRAM_ENUMERATION("Media.PipelineStatus.Video",
312 player_info.last_pipeline_status,
313 media::PIPELINE_STATUS_MAX + 1);
314 } else {
315 UMA_HISTOGRAM_ENUMERATION("Media.PipelineStatus.Unsupported",
prabhur1 2014/11/06 21:17:51 Youtube videos end up showing as Unsupported becau
DaleCurtis 2014/11/06 23:49:08 Hmm, yeah it looks like MSE is sending the raw vid
prabhur1 2014/11/07 23:43:23 Assigned to me: https://code.google.com/p/chromium
prabhur1 2014/11/07 23:43:23 Done.
316 player_info.last_pipeline_status,
317 media::PIPELINE_STATUS_MAX + 1);
318 }
319 }
320
201 void MediaInternals::AddUpdateCallback(const UpdateCallback& callback) { 321 void MediaInternals::AddUpdateCallback(const UpdateCallback& callback) {
202 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 322 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
203 update_callbacks_.push_back(callback); 323 update_callbacks_.push_back(callback);
204 } 324 }
205 325
206 void MediaInternals::RemoveUpdateCallback(const UpdateCallback& callback) { 326 void MediaInternals::RemoveUpdateCallback(const UpdateCallback& callback) {
207 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 327 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
208 for (size_t i = 0; i < update_callbacks_.size(); ++i) { 328 for (size_t i = 0; i < update_callbacks_.size(); ++i) {
209 if (update_callbacks_[i].Equals(callback)) { 329 if (update_callbacks_[i].Equals(callback)) {
210 update_callbacks_.erase(update_callbacks_.begin() + i); 330 update_callbacks_.erase(update_callbacks_.begin() + i);
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 const std::string& function, 420 const std::string& function,
301 const base::DictionaryValue* value) { 421 const base::DictionaryValue* value) {
302 SendUpdate(SerializeUpdate(function, value)); 422 SendUpdate(SerializeUpdate(function, value));
303 423
304 base::AutoLock auto_lock(lock_); 424 base::AutoLock auto_lock(lock_);
305 scoped_ptr<base::Value> out_value; 425 scoped_ptr<base::Value> out_value;
306 CHECK(audio_streams_cached_data_.Remove(cache_key, &out_value)); 426 CHECK(audio_streams_cached_data_.Remove(cache_key, &out_value));
307 } 427 }
308 428
309 } // namespace content 429 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698