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

Side by Side Diff: media/audio/audio_output_controller.cc

Issue 22339024: Crash fix: Remove MessageLoop from AudioPowerMonitor and instead use MessageLoopProxy in AudioOutpu… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: boolean style Created 7 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « media/audio/audio_output_controller.h ('k') | media/audio/audio_power_monitor.h » ('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 "media/audio/audio_output_controller.h" 5 #include "media/audio/audio_output_controller.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/debug/trace_event.h" 8 #include "base/debug/trace_event.h"
9 #include "base/message_loop/message_loop.h" 9 #include "base/message_loop/message_loop.h"
10 #include "base/metrics/histogram.h" 10 #include "base/metrics/histogram.h"
11 #include "base/threading/platform_thread.h" 11 #include "base/threading/platform_thread.h"
12 #include "base/time/time.h" 12 #include "base/time/time.h"
13 #include "build/build_config.h" 13 #include "build/build_config.h"
14 #include "media/audio/audio_power_monitor.h"
15 #include "media/audio/audio_util.h" 14 #include "media/audio/audio_util.h"
16 #include "media/audio/shared_memory_util.h" 15 #include "media/audio/shared_memory_util.h"
17 #include "media/base/scoped_histogram_timer.h" 16 #include "media/base/scoped_histogram_timer.h"
18 17
19 using base::Time; 18 using base::Time;
20 using base::TimeDelta; 19 using base::TimeDelta;
21 20
22 namespace media { 21 namespace media {
23 22
24 // Time constant for AudioPowerMonitor. See AudioPowerMonitor ctor comments for 23 // Time constant for AudioPowerMonitor. See AudioPowerMonitor ctor comments for
(...skipping 17 matching lines...) Expand all
42 params_(params), 41 params_(params),
43 handler_(handler), 42 handler_(handler),
44 input_device_id_(input_device_id), 43 input_device_id_(input_device_id),
45 stream_(NULL), 44 stream_(NULL),
46 diverting_to_stream_(NULL), 45 diverting_to_stream_(NULL),
47 volume_(1.0), 46 volume_(1.0),
48 state_(kEmpty), 47 state_(kEmpty),
49 num_allowed_io_(0), 48 num_allowed_io_(0),
50 sync_reader_(sync_reader), 49 sync_reader_(sync_reader),
51 message_loop_(audio_manager->GetMessageLoop()), 50 message_loop_(audio_manager->GetMessageLoop()),
52 number_polling_attempts_left_(0) { 51 number_polling_attempts_left_(0),
52 power_monitor_(
53 params.sample_rate(),
54 TimeDelta::FromMilliseconds(kPowerMeasurementTimeConstantMillis)) {
53 DCHECK(audio_manager); 55 DCHECK(audio_manager);
54 DCHECK(handler_); 56 DCHECK(handler_);
55 DCHECK(sync_reader_); 57 DCHECK(sync_reader_);
56 DCHECK(message_loop_.get()); 58 DCHECK(message_loop_.get());
57 } 59 }
58 60
59 AudioOutputController::~AudioOutputController() { 61 AudioOutputController::~AudioOutputController() {
60 DCHECK_EQ(kClosed, state_); 62 DCHECK_EQ(kClosed, state_);
61 } 63 }
62 64
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 151
150 // We can start from created or paused state. 152 // We can start from created or paused state.
151 if (state_ != kCreated && state_ != kPaused) 153 if (state_ != kCreated && state_ != kPaused)
152 return; 154 return;
153 155
154 // Ask for first packet. 156 // Ask for first packet.
155 sync_reader_->UpdatePendingBytes(0); 157 sync_reader_->UpdatePendingBytes(0);
156 158
157 state_ = kPlaying; 159 state_ = kPlaying;
158 160
159 // Start monitoring power levels and send an initial notification that we're 161 power_monitor_.Reset();
160 // starting in silence. 162 power_poll_callback_.Reset(
161 handler_->OnPowerMeasured(AudioPowerMonitor::zero_power(), false); 163 base::Bind(&AudioOutputController::ReportPowerMeasurementPeriodically,
162 power_monitor_callback_.Reset( 164 this));
163 base::Bind(&EventHandler::OnPowerMeasured, base::Unretained(handler_))); 165 // Run the callback to send an initial notification that we're starting in
164 power_monitor_.reset(new AudioPowerMonitor( 166 // silence, and to schedule periodic callbacks.
165 params_.sample_rate(), 167 power_poll_callback_.callback().Run();
166 TimeDelta::FromMilliseconds(kPowerMeasurementTimeConstantMillis),
167 TimeDelta::FromSeconds(1) / kPowerMeasurementsPerSecond,
168 base::MessageLoop::current(),
169 power_monitor_callback_.callback()));
170 168
171 // We start the AudioOutputStream lazily. 169 // We start the AudioOutputStream lazily.
172 AllowEntryToOnMoreIOData(); 170 AllowEntryToOnMoreIOData();
173 stream_->Start(this); 171 stream_->Start(this);
174 172
175 handler_->OnPlaying(); 173 handler_->OnPlaying();
176 } 174 }
177 175
176 void AudioOutputController::ReportPowerMeasurementPeriodically() {
177 DCHECK(message_loop_->BelongsToCurrentThread());
178 const std::pair<float, bool>& reading =
179 power_monitor_.ReadCurrentPowerAndClip();
180 handler_->OnPowerMeasured(reading.first, reading.second);
181 message_loop_->PostDelayedTask(
182 FROM_HERE, power_poll_callback_.callback(),
183 TimeDelta::FromSeconds(1) / kPowerMeasurementsPerSecond);
184 }
185
178 void AudioOutputController::StopStream() { 186 void AudioOutputController::StopStream() {
179 DCHECK(message_loop_->BelongsToCurrentThread()); 187 DCHECK(message_loop_->BelongsToCurrentThread());
180 188
181 if (state_ == kPlaying) { 189 if (state_ == kPlaying) {
182 stream_->Stop(); 190 stream_->Stop();
183 DisallowEntryToOnMoreIOData(); 191 DisallowEntryToOnMoreIOData();
184 192
185 // Stop monitoring power levels. By canceling power_monitor_callback_, any 193 power_poll_callback_.Cancel();
186 // tasks posted to |message_loop_| by AudioPowerMonitor during the
187 // stream_->Stop() call above will not run.
188 power_monitor_.reset();
189 power_monitor_callback_.Cancel();
190 194
191 state_ = kPaused; 195 state_ = kPaused;
192 } 196 }
193 } 197 }
194 198
195 void AudioOutputController::DoPause() { 199 void AudioOutputController::DoPause() {
196 DCHECK(message_loop_->BelongsToCurrentThread()); 200 DCHECK(message_loop_->BelongsToCurrentThread());
197 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioOutputController.PauseTime"); 201 SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioOutputController.PauseTime");
198 202
199 StopStream(); 203 StopStream();
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 const bool kShouldBlock = true; 276 const bool kShouldBlock = true;
273 #else 277 #else
274 const bool kShouldBlock = diverting_to_stream_ != NULL; 278 const bool kShouldBlock = diverting_to_stream_ != NULL;
275 #endif 279 #endif
276 280
277 const int frames = sync_reader_->Read(kShouldBlock, source, dest); 281 const int frames = sync_reader_->Read(kShouldBlock, source, dest);
278 DCHECK_LE(0, frames); 282 DCHECK_LE(0, frames);
279 sync_reader_->UpdatePendingBytes( 283 sync_reader_->UpdatePendingBytes(
280 buffers_state.total_bytes() + frames * params_.GetBytesPerFrame()); 284 buffers_state.total_bytes() + frames * params_.GetBytesPerFrame());
281 285
282 power_monitor_->Scan(*dest, frames); 286 power_monitor_.Scan(*dest, frames);
283 287
284 AllowEntryToOnMoreIOData(); 288 AllowEntryToOnMoreIOData();
285 return frames; 289 return frames;
286 } 290 }
287 291
288 void AudioOutputController::OnError(AudioOutputStream* stream) { 292 void AudioOutputController::OnError(AudioOutputStream* stream) {
289 // Handle error on the audio controller thread. 293 // Handle error on the audio controller thread.
290 message_loop_->PostTask(FROM_HERE, base::Bind( 294 message_loop_->PostTask(FROM_HERE, base::Bind(
291 &AudioOutputController::DoReportError, this)); 295 &AudioOutputController::DoReportError, this));
292 } 296 }
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
386 DCHECK(base::AtomicRefCountIsZero(&num_allowed_io_)); 390 DCHECK(base::AtomicRefCountIsZero(&num_allowed_io_));
387 base::AtomicRefCountInc(&num_allowed_io_); 391 base::AtomicRefCountInc(&num_allowed_io_);
388 } 392 }
389 393
390 void AudioOutputController::DisallowEntryToOnMoreIOData() { 394 void AudioOutputController::DisallowEntryToOnMoreIOData() {
391 const bool is_zero = !base::AtomicRefCountDec(&num_allowed_io_); 395 const bool is_zero = !base::AtomicRefCountDec(&num_allowed_io_);
392 DCHECK(is_zero); 396 DCHECK(is_zero);
393 } 397 }
394 398
395 } // namespace media 399 } // namespace media
OLDNEW
« no previous file with comments | « media/audio/audio_output_controller.h ('k') | media/audio/audio_power_monitor.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698