| OLD | NEW |
| 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/win/audio_low_latency_output_win.h" | 5 #include "media/audio/win/audio_low_latency_output_win.h" |
| 6 | 6 |
| 7 #include <Functiondiscoverykeys_devpkey.h> | 7 #include <Functiondiscoverykeys_devpkey.h> |
| 8 | 8 |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 322 return AUDCLNT_SHAREMODE_EXCLUSIVE; | 322 return AUDCLNT_SHAREMODE_EXCLUSIVE; |
| 323 return AUDCLNT_SHAREMODE_SHARED; | 323 return AUDCLNT_SHAREMODE_SHARED; |
| 324 } | 324 } |
| 325 | 325 |
| 326 WASAPIAudioOutputStream::WASAPIAudioOutputStream(AudioManagerWin* manager, | 326 WASAPIAudioOutputStream::WASAPIAudioOutputStream(AudioManagerWin* manager, |
| 327 const AudioParameters& params, | 327 const AudioParameters& params, |
| 328 ERole device_role) | 328 ERole device_role) |
| 329 : com_init_(ScopedCOMInitializer::kMTA), | 329 : com_init_(ScopedCOMInitializer::kMTA), |
| 330 creating_thread_id_(base::PlatformThread::CurrentId()), | 330 creating_thread_id_(base::PlatformThread::CurrentId()), |
| 331 manager_(manager), | 331 manager_(manager), |
| 332 render_thread_(NULL), | |
| 333 opened_(false), | 332 opened_(false), |
| 334 started_(false), | 333 started_(false), |
| 335 restart_rendering_mode_(false), | 334 restart_rendering_mode_(false), |
| 336 volume_(1.0), | 335 volume_(1.0), |
| 337 endpoint_buffer_size_frames_(0), | 336 endpoint_buffer_size_frames_(0), |
| 338 device_role_(device_role), | 337 device_role_(device_role), |
| 339 share_mode_(GetShareMode()), | 338 share_mode_(GetShareMode()), |
| 340 client_channel_count_(params.channels()), | 339 client_channel_count_(params.channels()), |
| 341 num_written_frames_(0), | 340 num_written_frames_(0), |
| 342 source_(NULL) { | 341 source_(NULL) { |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 521 AUDCLNT_BUFFERFLAGS_SILENT); | 520 AUDCLNT_BUFFERFLAGS_SILENT); |
| 522 num_written_frames_ = endpoint_buffer_size_frames_; | 521 num_written_frames_ = endpoint_buffer_size_frames_; |
| 523 | 522 |
| 524 // Sanity check: verify that the endpoint buffer is filled with silence. | 523 // Sanity check: verify that the endpoint buffer is filled with silence. |
| 525 UINT32 num_queued_frames = 0; | 524 UINT32 num_queued_frames = 0; |
| 526 audio_client_->GetCurrentPadding(&num_queued_frames); | 525 audio_client_->GetCurrentPadding(&num_queued_frames); |
| 527 DCHECK(num_queued_frames == num_written_frames_); | 526 DCHECK(num_queued_frames == num_written_frames_); |
| 528 | 527 |
| 529 // Create and start the thread that will drive the rendering by waiting for | 528 // Create and start the thread that will drive the rendering by waiting for |
| 530 // render events. | 529 // render events. |
| 531 render_thread_ = new base::DelegateSimpleThread(this, "wasapi_render_thread"); | 530 render_thread_.reset( |
| 531 new base::DelegateSimpleThread(this, "wasapi_render_thread")); |
| 532 render_thread_->Start(); | 532 render_thread_->Start(); |
| 533 if (!render_thread_->HasBeenStarted()) { | 533 if (!render_thread_->HasBeenStarted()) { |
| 534 DLOG(ERROR) << "Failed to start WASAPI render thread."; | 534 DLOG(ERROR) << "Failed to start WASAPI render thread."; |
| 535 return; | 535 return; |
| 536 } | 536 } |
| 537 | 537 |
| 538 // Start streaming data between the endpoint buffer and the audio engine. | 538 // Start streaming data between the endpoint buffer and the audio engine. |
| 539 hr = audio_client_->Start(); | 539 hr = audio_client_->Start(); |
| 540 if (FAILED(hr)) { | 540 if (FAILED(hr)) { |
| 541 SetEvent(stop_render_event_.Get()); | 541 SetEvent(stop_render_event_.Get()); |
| 542 render_thread_->Join(); | 542 render_thread_->Join(); |
| 543 render_thread_ = NULL; | 543 render_thread_.reset(); |
| 544 HandleError(hr); | 544 HandleError(hr); |
| 545 return; | 545 return; |
| 546 } | 546 } |
| 547 | 547 |
| 548 started_ = true; | 548 started_ = true; |
| 549 } | 549 } |
| 550 | 550 |
| 551 void WASAPIAudioOutputStream::Stop() { | 551 void WASAPIAudioOutputStream::Stop() { |
| 552 DCHECK_EQ(GetCurrentThreadId(), creating_thread_id_); | 552 DCHECK_EQ(GetCurrentThreadId(), creating_thread_id_); |
| 553 if (!started_) | 553 if (!started_) |
| 554 return; | 554 return; |
| 555 | 555 |
| 556 // Shut down the render thread. | 556 // Shut down the render thread. |
| 557 if (stop_render_event_.IsValid()) { | 557 if (stop_render_event_.IsValid()) { |
| 558 SetEvent(stop_render_event_.Get()); | 558 SetEvent(stop_render_event_.Get()); |
| 559 } | 559 } |
| 560 | 560 |
| 561 // Stop output audio streaming. | 561 // Stop output audio streaming. |
| 562 HRESULT hr = audio_client_->Stop(); | 562 HRESULT hr = audio_client_->Stop(); |
| 563 if (FAILED(hr)) { | 563 if (FAILED(hr)) { |
| 564 DLOG_IF(ERROR, hr != AUDCLNT_E_NOT_INITIALIZED) | 564 DLOG_IF(ERROR, hr != AUDCLNT_E_NOT_INITIALIZED) |
| 565 << "Failed to stop output streaming: " << std::hex << hr; | 565 << "Failed to stop output streaming: " << std::hex << hr; |
| 566 } | 566 } |
| 567 | 567 |
| 568 // Wait until the thread completes and perform cleanup. | 568 // Wait until the thread completes and perform cleanup. |
| 569 if (render_thread_) { | 569 if (render_thread_.get()) { |
| 570 SetEvent(stop_render_event_.Get()); | 570 SetEvent(stop_render_event_.Get()); |
| 571 render_thread_->Join(); | 571 render_thread_->Join(); |
| 572 render_thread_ = NULL; | 572 render_thread_.reset(); |
| 573 } | 573 } |
| 574 | 574 |
| 575 // Flush all pending data and reset the audio clock stream position to 0. | 575 // Flush all pending data and reset the audio clock stream position to 0. |
| 576 hr = audio_client_->Reset(); | 576 hr = audio_client_->Reset(); |
| 577 if (FAILED(hr)) { | 577 if (FAILED(hr)) { |
| 578 DLOG_IF(ERROR, hr != AUDCLNT_E_NOT_INITIALIZED) | 578 DLOG_IF(ERROR, hr != AUDCLNT_E_NOT_INITIALIZED) |
| 579 << "Failed to reset streaming: " << std::hex << hr; | 579 << "Failed to reset streaming: " << std::hex << hr; |
| 580 } | 580 } |
| 581 | 581 |
| 582 // Extra safety check to ensure that the buffers are cleared. | 582 // Extra safety check to ensure that the buffers are cleared. |
| (...skipping 735 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1318 // are now re-initiated and it is now possible to re-start audio rendering. | 1318 // are now re-initiated and it is now possible to re-start audio rendering. |
| 1319 | 1319 |
| 1320 // Start rendering again using the new default audio endpoint. | 1320 // Start rendering again using the new default audio endpoint. |
| 1321 hr = audio_client_->Start(); | 1321 hr = audio_client_->Start(); |
| 1322 | 1322 |
| 1323 restart_rendering_mode_ = false; | 1323 restart_rendering_mode_ = false; |
| 1324 return SUCCEEDED(hr); | 1324 return SUCCEEDED(hr); |
| 1325 } | 1325 } |
| 1326 | 1326 |
| 1327 } // namespace media | 1327 } // namespace media |
| OLD | NEW |