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

Side by Side Diff: content/renderer/media/webrtc_audio_renderer.cc

Issue 2264073002: Add UMA histograms for time spent getting WebRTC audio render data. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Exclude low resolution clocks. Created 4 years, 3 months 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
« no previous file with comments | « content/renderer/media/webrtc_audio_renderer.h ('k') | tools/metrics/histograms/histograms.xml » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/renderer/media/webrtc_audio_renderer.h" 5 #include "content/renderer/media/webrtc_audio_renderer.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
(...skipping 16 matching lines...) Expand all
27 27
28 #if defined(OS_WIN) 28 #if defined(OS_WIN)
29 #include "base/win/windows_version.h" 29 #include "base/win/windows_version.h"
30 #include "media/audio/win/core_audio_util_win.h" 30 #include "media/audio/win/core_audio_util_win.h"
31 #endif 31 #endif
32 32
33 namespace content { 33 namespace content {
34 34
35 namespace { 35 namespace {
36 36
37 // We add a UMA histogram measuring the execution time of the Render() method
38 // every |kNumCallbacksBetweenRenderTimeHistograms| callback. Assuming 10ms
39 // between each callback leads to one UMA update each 100ms.
40 const int kNumCallbacksBetweenRenderTimeHistograms = 10;
41
42 // Audio parameters that don't change. 37 // Audio parameters that don't change.
43 const media::AudioParameters::Format kFormat = 38 const media::AudioParameters::Format kFormat =
44 media::AudioParameters::AUDIO_PCM_LOW_LATENCY; 39 media::AudioParameters::AUDIO_PCM_LOW_LATENCY;
45 const media::ChannelLayout kChannelLayout = media::CHANNEL_LAYOUT_STEREO; 40 const media::ChannelLayout kChannelLayout = media::CHANNEL_LAYOUT_STEREO;
46 const int kChannels = 2; 41 const int kChannels = 2;
47 const int kBitsPerSample = 16; 42 const int kBitsPerSample = 16;
48 43
44 // Used for UMA histograms.
45 const int kRenderTimeHistogramMinMicroseconds = 100;
46 const int kRenderTimeHistogramMaxMicroseconds = 30 * 1000; // 30 milliseconds
Ilya Sherman 2016/08/24 21:53:41 I somewhat suspect that this is too low an upper b
Henrik Grunell 2016/08/25 08:34:07 That makes sense, changed to max 1 s.
47
49 // This is a simple wrapper class that's handed out to users of a shared 48 // This is a simple wrapper class that's handed out to users of a shared
50 // WebRtcAudioRenderer instance. This class maintains the per-user 'playing' 49 // WebRtcAudioRenderer instance. This class maintains the per-user 'playing'
51 // and 'started' states to avoid problems related to incorrect usage which 50 // and 'started' states to avoid problems related to incorrect usage which
52 // might violate the implementation assumptions inside WebRtcAudioRenderer 51 // might violate the implementation assumptions inside WebRtcAudioRenderer
53 // (see the play reference count). 52 // (see the play reference count).
54 class SharedAudioRenderer : public MediaStreamAudioRenderer { 53 class SharedAudioRenderer : public MediaStreamAudioRenderer {
55 public: 54 public:
56 // Callback definition for a callback that is called when when Play(), Pause() 55 // Callback definition for a callback that is called when when Play(), Pause()
57 // or SetVolume are called (whenever the internal |playing_state_| changes). 56 // or SetVolume are called (whenever the internal |playing_state_| changes).
58 typedef base::Callback<void(const blink::WebMediaStream&, 57 typedef base::Callback<void(const blink::WebMediaStream&,
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
164 source_render_frame_id_(source_render_frame_id), 163 source_render_frame_id_(source_render_frame_id),
165 session_id_(session_id), 164 session_id_(session_id),
166 signaling_thread_(signaling_thread), 165 signaling_thread_(signaling_thread),
167 media_stream_(media_stream), 166 media_stream_(media_stream),
168 source_(NULL), 167 source_(NULL),
169 play_ref_count_(0), 168 play_ref_count_(0),
170 start_ref_count_(0), 169 start_ref_count_(0),
171 audio_delay_milliseconds_(0), 170 audio_delay_milliseconds_(0),
172 sink_params_(kFormat, kChannelLayout, 0, kBitsPerSample, 0), 171 sink_params_(kFormat, kChannelLayout, 0, kBitsPerSample, 0),
173 output_device_id_(device_id), 172 output_device_id_(device_id),
174 security_origin_(security_origin), 173 security_origin_(security_origin) {
175 render_callback_count_(0) {
176 WebRtcLogMessage(base::StringPrintf( 174 WebRtcLogMessage(base::StringPrintf(
177 "WAR::WAR. source_render_frame_id=%d, session_id=%d, effects=%i", 175 "WAR::WAR. source_render_frame_id=%d, session_id=%d, effects=%i",
178 source_render_frame_id, session_id, sink_params_.effects())); 176 source_render_frame_id, session_id, sink_params_.effects()));
179 } 177 }
180 178
181 WebRtcAudioRenderer::~WebRtcAudioRenderer() { 179 WebRtcAudioRenderer::~WebRtcAudioRenderer() {
182 DCHECK(thread_checker_.CalledOnValidThread()); 180 DCHECK(thread_checker_.CalledOnValidThread());
183 DCHECK_EQ(state_, UNINITIALIZED); 181 DCHECK_EQ(state_, UNINITIALIZED);
184 } 182 }
185 183
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 } 242 }
245 243
246 void WebRtcAudioRenderer::Play() { 244 void WebRtcAudioRenderer::Play() {
247 DVLOG(1) << "WebRtcAudioRenderer::Play()"; 245 DVLOG(1) << "WebRtcAudioRenderer::Play()";
248 DCHECK(thread_checker_.CalledOnValidThread()); 246 DCHECK(thread_checker_.CalledOnValidThread());
249 247
250 if (playing_state_.playing()) 248 if (playing_state_.playing())
251 return; 249 return;
252 250
253 playing_state_.set_playing(true); 251 playing_state_.set_playing(true);
254 render_callback_count_ = 0;
255 252
256 OnPlayStateChanged(media_stream_, &playing_state_); 253 OnPlayStateChanged(media_stream_, &playing_state_);
257 } 254 }
258 255
259 void WebRtcAudioRenderer::EnterPlayState() { 256 void WebRtcAudioRenderer::EnterPlayState() {
260 DVLOG(1) << "WebRtcAudioRenderer::EnterPlayState()"; 257 DVLOG(1) << "WebRtcAudioRenderer::EnterPlayState()";
261 DCHECK(thread_checker_.CalledOnValidThread()); 258 DCHECK(thread_checker_.CalledOnValidThread());
262 DCHECK_GT(start_ref_count_, 0) << "Did you forget to call Start()?"; 259 DCHECK_GT(start_ref_count_, 0) << "Did you forget to call Start()?";
263 base::AutoLock auto_lock(lock_); 260 base::AutoLock auto_lock(lock_);
264 if (state_ == UNINITIALIZED) 261 if (state_ == UNINITIALIZED)
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 295
299 DCHECK_EQ(state_, PLAYING); 296 DCHECK_EQ(state_, PLAYING);
300 DCHECK_GT(play_ref_count_, 0); 297 DCHECK_GT(play_ref_count_, 0);
301 if (!--play_ref_count_) 298 if (!--play_ref_count_)
302 state_ = PAUSED; 299 state_ = PAUSED;
303 } 300 }
304 301
305 void WebRtcAudioRenderer::Stop() { 302 void WebRtcAudioRenderer::Stop() {
306 DVLOG(1) << "WebRtcAudioRenderer::Stop()"; 303 DVLOG(1) << "WebRtcAudioRenderer::Stop()";
307 DCHECK(thread_checker_.CalledOnValidThread()); 304 DCHECK(thread_checker_.CalledOnValidThread());
305 // If |max_render_time_| is zero, no render call has been made.
306 if (!max_render_time_.is_zero()) {
307 UMA_HISTOGRAM_CUSTOM_COUNTS(
308 "Media.Audio.Render.GetSourceDataTimeMax.WebRTC",
309 max_render_time_.InMicroseconds(), kRenderTimeHistogramMinMicroseconds,
310 kRenderTimeHistogramMaxMicroseconds, 50);
311 max_render_time_ = base::TimeDelta();
312 }
313
308 { 314 {
309 base::AutoLock auto_lock(lock_); 315 base::AutoLock auto_lock(lock_);
310 if (state_ == UNINITIALIZED) 316 if (state_ == UNINITIALIZED)
311 return; 317 return;
312 318
313 if (--start_ref_count_) 319 if (--start_ref_count_)
314 return; 320 return;
315 321
316 DVLOG(1) << "Calling RemoveAudioRenderer and Stop()."; 322 DVLOG(1) << "Calling RemoveAudioRenderer and Stop().";
317 323
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 // otherwise the data will be buffered up inside |source_|. 475 // otherwise the data will be buffered up inside |source_|.
470 source_->RenderData(audio_bus, sink_params_.sample_rate(), 476 source_->RenderData(audio_bus, sink_params_.sample_rate(),
471 output_delay_milliseconds, 477 output_delay_milliseconds,
472 &current_time_); 478 &current_time_);
473 479
474 // Avoid filling up the audio bus if we are not playing; instead 480 // Avoid filling up the audio bus if we are not playing; instead
475 // return here and ensure that the returned value in Render() is 0. 481 // return here and ensure that the returned value in Render() is 0.
476 if (state_ != PLAYING) 482 if (state_ != PLAYING)
477 audio_bus->Zero(); 483 audio_bus->Zero();
478 484
479 if (++render_callback_count_ == kNumCallbacksBetweenRenderTimeHistograms) { 485 // Measure the elapsed time for this function and log it to UMA. Store the max
486 // value. Don't do this for low resolution clocks to not skew data.
487 if (base::TimeTicks::IsHighResolution()) {
Henrik Grunell 2016/08/24 12:38:37 This is only applicable to Windows (as of now), wi
o1ka 2016/08/24 12:43:14 I think it's fine to log it for high res only.
Henrik Grunell 2016/08/25 08:34:07 Let's go for that.
480 base::TimeDelta elapsed = base::TimeTicks::Now() - start_time; 488 base::TimeDelta elapsed = base::TimeTicks::Now() - start_time;
481 render_callback_count_ = 0; 489 UMA_HISTOGRAM_CUSTOM_COUNTS("Media.Audio.Render.GetSourceDataTime.WebRTC",
482 UMA_HISTOGRAM_TIMES("WebRTC.AudioRenderTimes", elapsed); 490 elapsed.InMicroseconds(),
491 kRenderTimeHistogramMinMicroseconds,
492 kRenderTimeHistogramMaxMicroseconds, 50);
493
494 if (elapsed > max_render_time_)
495 max_render_time_ = elapsed;
483 } 496 }
484 } 497 }
485 498
486 void WebRtcAudioRenderer::UpdateSourceVolume( 499 void WebRtcAudioRenderer::UpdateSourceVolume(
487 webrtc::AudioSourceInterface* source) { 500 webrtc::AudioSourceInterface* source) {
488 DCHECK(thread_checker_.CalledOnValidThread()); 501 DCHECK(thread_checker_.CalledOnValidThread());
489 502
490 // Note: If there are no playing audio renderers, then the volume will be 503 // Note: If there are no playing audio renderers, then the volume will be
491 // set to 0.0. 504 // set to 0.0.
492 float volume = 0.0f; 505 float volume = 0.0f;
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
648 base::Bind(&WebRtcAudioRenderer::SourceCallback, 661 base::Bind(&WebRtcAudioRenderer::SourceCallback,
649 base::Unretained(this)))); 662 base::Unretained(this))));
650 } 663 }
651 sink_params_ = new_sink_params; 664 sink_params_ = new_sink_params;
652 } 665 }
653 666
654 sink_->Initialize(new_sink_params, this); 667 sink_->Initialize(new_sink_params, this);
655 } 668 }
656 669
657 } // namespace content 670 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/media/webrtc_audio_renderer.h ('k') | tools/metrics/histograms/histograms.xml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698