Index: chromecast/media/audio/chromecast_device_audio_output_stream.cc |
diff --git a/chromecast/media/audio/chromecast_device_audio_output_stream.cc b/chromecast/media/audio/chromecast_device_audio_output_stream.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..a69783d5da6065cbe3c63535bb9ed230221905c1 |
--- /dev/null |
+++ b/chromecast/media/audio/chromecast_device_audio_output_stream.cc |
@@ -0,0 +1,109 @@ |
+// Copyright 2015 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "chromecast/media/audio/chromecast_device_audio_output_stream.h" |
+ |
+#include "base/logging.h" |
+ |
+namespace chromecast { |
+namespace media { |
+ |
+ChromecastDeviceAudioOutputStream::ChromecastDeviceAudioOutputStream( |
+ CastAudioOutputStream* output_stream, |
+ const AudioParameters& params, |
+ CastAudioManager* manager) |
+ : output_stream_(output_stream), |
+ callback_(nullptr), |
+ params_(params), |
+ audio_manager_(manager) { |
+ // Verify validity of parameters. |
+ DCHECK(output_stream_); |
+ DCHECK(params_.bits_per_sample == 8 || params_.bits_per_sample == 16 || |
+ params_.bits_per_sample == 32); |
+} |
+ |
+ChromecastDeviceAudioOutputStream::~ChromecastDeviceAudioOutputStream() { |
+} |
+ |
+bool ChromecastDeviceAudioOutputStream::Open() { |
+ DCHECK(output_stream_); |
+ return output_stream_->Open(); |
+} |
+ |
+void ChromecastDeviceAudioOutputStream::Start( |
+ ::media::AudioOutputStream::AudioSourceCallback* callback) { |
+ DCHECK(output_stream_); |
+ DCHECK(callback); |
+ callback_ = callback; |
+ output_stream_->Start(this); |
+} |
+ |
+void ChromecastDeviceAudioOutputStream::Stop() { |
+ DCHECK(output_stream_); |
+ // Note that Stop() may generate AudioSourceCallback events. Ignore these by |
+ // setting the callback to NULL before calling stop. |
+ callback_ = nullptr; |
+ output_stream_->Stop(); |
+} |
+ |
+void ChromecastDeviceAudioOutputStream::SetVolume(double volume) { |
+ DCHECK(output_stream_); |
+ output_stream_->SetVolume(volume); |
+} |
+ |
+void ChromecastDeviceAudioOutputStream::GetVolume(double* volume) { |
+ DCHECK(output_stream_); |
+ DCHECK(volume); |
+ *volume = output_stream_->GetVolume(); |
+} |
+ |
+void ChromecastDeviceAudioOutputStream::Close() { |
+ DCHECK(output_stream_); |
+ DCHECK(audio_manager_); |
+ |
+ // Close the underlying stream. |
+ output_stream_->Close(); |
+ output_stream_ = nullptr; |
+ |
+ // Note: This method must be called to avoid a leak. |this| will be deleted |
+ // in this call, so this must be the last line, and this object must not be |
+ // used after this function returns. Please see |
+ // CastAudioManager::MakeCastOutputStream before changing this behavaior. |
+ // TODO(slan): m43 does not have the below API, so commit suicide instead. |
+ audio_manager_->ReleaseOutputStream(this); |
+} |
+ |
+int ChromecastDeviceAudioOutputStream::GetMoreData(void* dest, |
+ uint32_t len, |
+ int32_t frames, |
+ uint32_t total_bytes_delay) { |
+ CHECK(dest); |
+ CHECK_GE(frames, 0); |
+ uint32_t bytes_needed = |
+ frames * params_.channels * params_.bits_per_sample / 8; |
+ CHECK_GE(len, bytes_needed); |
+ |
+ // If the stream has been Stop()ped, return no frames filled. |
+ if (!callback_) |
+ return 0; |
+ |
+ // Pass an empty audio bus of the right size to the source to be filled. |
+ scoped_ptr< ::media::AudioBus> bus = |
+ ::media::AudioBus::Create(params_.channels, frames); |
+ int frames_filled = callback_->OnMoreData(bus.get(), total_bytes_delay); |
+ DCHECK_GE(frames_filled, 0); |
+ DCHECK_LE(frames_filled, frames); |
+ |
+ // Populate |dest| with interleaved data. |
+ bus->ToInterleaved(frames_filled, params_.bits_per_sample / 8, dest); |
+ return frames_filled; |
+} |
+ |
+void ChromecastDeviceAudioOutputStream::OnError(CastAudioOutputStream* stream) { |
+ if (callback_) |
+ callback_->OnError(this); |
+} |
+ |
+} // namespace media |
+} // namespace chromecast |