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

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

Issue 2621993002: Makes AudioOutputProxy -> AudioOutputDispatcher reference weak. (Closed)
Patch Set: adds StopPhysicalStream Created 3 years, 11 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 | « media/audio/audio_output_resampler.h ('k') | no next file » | 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_resampler.h" 5 #include "media/audio/audio_output_resampler.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <string> 10 #include <string>
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
222 const base::TimeDelta& close_delay) 222 const base::TimeDelta& close_delay)
223 : AudioOutputDispatcher(audio_manager, input_params, output_device_id), 223 : AudioOutputDispatcher(audio_manager, input_params, output_device_id),
224 close_delay_(close_delay), 224 close_delay_(close_delay),
225 output_params_(output_params), 225 output_params_(output_params),
226 original_output_params_(output_params), 226 original_output_params_(output_params),
227 streams_opened_(false), 227 streams_opened_(false),
228 reinitialize_timer_(FROM_HERE, 228 reinitialize_timer_(FROM_HERE,
229 close_delay_, 229 close_delay_,
230 base::Bind(&AudioOutputResampler::Reinitialize, 230 base::Bind(&AudioOutputResampler::Reinitialize,
231 base::Unretained(this)), 231 base::Unretained(this)),
232 false) { 232 false),
233 weak_factory_(this) {
233 DCHECK(input_params.IsValid()); 234 DCHECK(input_params.IsValid());
234 DCHECK(output_params.IsValid()); 235 DCHECK(output_params.IsValid());
235 DCHECK_EQ(output_params_.format(), AudioParameters::AUDIO_PCM_LOW_LATENCY); 236 DCHECK_EQ(output_params_.format(), AudioParameters::AUDIO_PCM_LOW_LATENCY);
236 237
237 // Record UMA statistics for the hardware configuration. 238 // Record UMA statistics for the hardware configuration.
238 RecordStats(output_params); 239 RecordStats(output_params);
239 240
240 Initialize(); 241 Initialize();
241 } 242 }
242 243
243 AudioOutputResampler::~AudioOutputResampler() { 244 AudioOutputResampler::~AudioOutputResampler() {
244 DCHECK(callbacks_.empty()); 245 for (auto& iter : callbacks_) {
246 StopStream(iter.first);
247 }
245 } 248 }
246 249
247 void AudioOutputResampler::Reinitialize() { 250 void AudioOutputResampler::Reinitialize() {
248 DCHECK(task_runner_->BelongsToCurrentThread()); 251 DCHECK(task_runner_->BelongsToCurrentThread());
249 DCHECK(streams_opened_); 252 DCHECK(streams_opened_);
250 253
251 // We can only reinitialize the dispatcher if it has no active proxies. Check 254 // We can only reinitialize the dispatcher if it has no active proxies. Check
252 // if one has been created since the reinitialization timer was started. 255 // if one has been created since the reinitialization timer was started.
253 if (dispatcher_->HasOutputProxies()) 256 if (dispatcher_->HasOutputProxies())
254 return; 257 return;
255 258
256 // Log a trace event so we can get feedback in the field when this happens. 259 // Log a trace event so we can get feedback in the field when this happens.
257 TRACE_EVENT0("audio", "AudioOutputResampler::Reinitialize"); 260 TRACE_EVENT0("audio", "AudioOutputResampler::Reinitialize");
258 261
259 output_params_ = original_output_params_; 262 output_params_ = original_output_params_;
260 streams_opened_ = false; 263 streams_opened_ = false;
261 Initialize(); 264 Initialize();
262 } 265 }
263 266
264 void AudioOutputResampler::Initialize() { 267 void AudioOutputResampler::Initialize() {
265 DCHECK(!streams_opened_); 268 DCHECK(!streams_opened_);
266 DCHECK(callbacks_.empty()); 269 DCHECK(callbacks_.empty());
267 dispatcher_ = base::MakeUnique<AudioOutputDispatcherImpl>( 270 dispatcher_ = base::MakeUnique<AudioOutputDispatcherImpl>(
268 audio_manager_, output_params_, device_id_, close_delay_); 271 audio_manager_, output_params_, device_id_, close_delay_);
269 } 272 }
270 273
274 AudioOutputProxy* AudioOutputResampler::CreateStreamProxy() {
275 DCHECK(task_runner_->BelongsToCurrentThread());
276 return new AudioOutputProxy(weak_factory_.GetWeakPtr());
277 }
278
271 bool AudioOutputResampler::OpenStream() { 279 bool AudioOutputResampler::OpenStream() {
272 DCHECK(task_runner_->BelongsToCurrentThread()); 280 DCHECK(task_runner_->BelongsToCurrentThread());
273 281
274 if (dispatcher_->OpenStream()) { 282 if (dispatcher_->OpenStream()) {
275 // Only record the UMA statistic if we didn't fallback during construction 283 // Only record the UMA statistic if we didn't fallback during construction
276 // and only for the first stream we open. 284 // and only for the first stream we open.
277 if (!streams_opened_ && 285 if (!streams_opened_ &&
278 output_params_.format() == AudioParameters::AUDIO_PCM_LOW_LATENCY) { 286 output_params_.format() == AudioParameters::AUDIO_PCM_LOW_LATENCY) {
279 UMA_HISTOGRAM_BOOLEAN("Media.FallbackToHighLatencyAudioPath", false); 287 UMA_HISTOGRAM_BOOLEAN("Media.FallbackToHighLatencyAudioPath", false);
280 } 288 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
326 334
327 bool AudioOutputResampler::StartStream( 335 bool AudioOutputResampler::StartStream(
328 AudioOutputStream::AudioSourceCallback* callback, 336 AudioOutputStream::AudioSourceCallback* callback,
329 AudioOutputProxy* stream_proxy) { 337 AudioOutputProxy* stream_proxy) {
330 DCHECK(task_runner_->BelongsToCurrentThread()); 338 DCHECK(task_runner_->BelongsToCurrentThread());
331 339
332 OnMoreDataConverter* resampler_callback = nullptr; 340 OnMoreDataConverter* resampler_callback = nullptr;
333 CallbackMap::iterator it = callbacks_.find(stream_proxy); 341 CallbackMap::iterator it = callbacks_.find(stream_proxy);
334 if (it == callbacks_.end()) { 342 if (it == callbacks_.end()) {
335 resampler_callback = new OnMoreDataConverter(params_, output_params_); 343 resampler_callback = new OnMoreDataConverter(params_, output_params_);
336 callbacks_[stream_proxy] = resampler_callback; 344 callbacks_[stream_proxy] =
345 base::WrapUnique<OnMoreDataConverter>(resampler_callback);
337 } else { 346 } else {
338 resampler_callback = it->second; 347 resampler_callback = it->second.get();
339 } 348 }
340 349
341 resampler_callback->Start(callback); 350 resampler_callback->Start(callback);
342 bool result = dispatcher_->StartStream(resampler_callback, stream_proxy); 351 bool result = dispatcher_->StartStream(resampler_callback, stream_proxy);
343 if (!result) 352 if (!result)
344 resampler_callback->Stop(); 353 resampler_callback->Stop();
345 return result; 354 return result;
346 } 355 }
347 356
348 void AudioOutputResampler::StreamVolumeSet(AudioOutputProxy* stream_proxy, 357 void AudioOutputResampler::StreamVolumeSet(AudioOutputProxy* stream_proxy,
(...skipping 20 matching lines...) Expand all
369 dispatcher_->CloseAllIdleStreams(); 378 dispatcher_->CloseAllIdleStreams();
370 } 379 }
371 } 380 }
372 381
373 void AudioOutputResampler::CloseStream(AudioOutputProxy* stream_proxy) { 382 void AudioOutputResampler::CloseStream(AudioOutputProxy* stream_proxy) {
374 DCHECK(task_runner_->BelongsToCurrentThread()); 383 DCHECK(task_runner_->BelongsToCurrentThread());
375 dispatcher_->CloseStream(stream_proxy); 384 dispatcher_->CloseStream(stream_proxy);
376 385
377 // We assume that StopStream() is always called prior to CloseStream(), so 386 // We assume that StopStream() is always called prior to CloseStream(), so
378 // that it is safe to delete the OnMoreDataConverter here. 387 // that it is safe to delete the OnMoreDataConverter here.
379 CallbackMap::iterator it = callbacks_.find(stream_proxy); 388 callbacks_.erase(stream_proxy);
380 if (it != callbacks_.end()) {
381 delete it->second;
382 callbacks_.erase(it);
383 }
384 389
385 // Start the reinitialization timer if there are no active proxies and we're 390 // Start the reinitialization timer if there are no active proxies and we're
386 // not using the originally requested output parameters. This allows us to 391 // not using the originally requested output parameters. This allows us to
387 // recover from transient output creation errors. 392 // recover from transient output creation errors.
388 if (!dispatcher_->HasOutputProxies() && callbacks_.empty() && 393 if (!dispatcher_->HasOutputProxies() && callbacks_.empty() &&
389 !output_params_.Equals(original_output_params_)) { 394 !output_params_.Equals(original_output_params_)) {
390 reinitialize_timer_.Reset(); 395 reinitialize_timer_.Reset();
391 } 396 }
392 } 397 }
393 398
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 dest->ZeroFramesPartial(frames, dest->frames() - frames); 462 dest->ZeroFramesPartial(frames, dest->frames() - frames);
458 return frames > 0 ? 1 : 0; 463 return frames > 0 ? 1 : 0;
459 } 464 }
460 465
461 void OnMoreDataConverter::OnError(AudioOutputStream* stream) { 466 void OnMoreDataConverter::OnError(AudioOutputStream* stream) {
462 error_occurred_ = true; 467 error_occurred_ = true;
463 source_callback_->OnError(stream); 468 source_callback_->OnError(stream);
464 } 469 }
465 470
466 } // namespace media 471 } // namespace media
OLDNEW
« no previous file with comments | « media/audio/audio_output_resampler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698