Index: content/renderer/media/external_media_stream_audio_source.cc |
diff --git a/content/renderer/media/external_media_stream_audio_source.cc b/content/renderer/media/external_media_stream_audio_source.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..60a68241b6fff060060078e60693b6ea43010041 |
--- /dev/null |
+++ b/content/renderer/media/external_media_stream_audio_source.cc |
@@ -0,0 +1,81 @@ |
+// Copyright 2016 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 "content/renderer/media/external_media_stream_audio_source.h" |
+ |
+namespace content { |
+ |
+ExternalMediaStreamAudioSource::ExternalMediaStreamAudioSource( |
+ scoped_refptr<media::AudioCapturerSource> source, |
+ int sample_rate, |
+ media::ChannelLayout channel_layout, |
+ int frames_per_buffer, |
+ bool is_remote) |
+ : MediaStreamAudioSource(!is_remote), source_(std::move(source)), |
+ was_started_(false) { |
+ DVLOG(1) |
+ << "ExternalMediaStreamAudioSource::ExternalMediaStreamAudioSource()"; |
+ DCHECK(source_.get()); |
+ MediaStreamAudioSource::SetFormat(media::AudioParameters( |
+ media::AudioParameters::AUDIO_PCM_LOW_LATENCY, channel_layout, |
+ sample_rate, |
+ 16, // Legacy parameter (data is always in 32-bit float format). |
+ frames_per_buffer)); |
+} |
+ |
+ExternalMediaStreamAudioSource::~ExternalMediaStreamAudioSource() { |
+ DVLOG(1) |
+ << "ExternalMediaStreamAudioSource::~ExternalMediaStreamAudioSource()"; |
+ EnsureSourceIsStopped(); |
+} |
+ |
+bool ExternalMediaStreamAudioSource::EnsureSourceIsStarted() { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ if (was_started_) |
+ return true; |
+ VLOG(1) << "Starting externally-provided " |
+ << (is_local_source() ? "local" : "remote") |
+ << " source with audio parameters={" |
+ << GetAudioParameters().AsHumanReadableString() << "}."; |
+ source_->Initialize(GetAudioParameters(), this, -1); |
+ source_->Start(); |
+ was_started_ = true; |
+ return true; |
+} |
+ |
+void ExternalMediaStreamAudioSource::EnsureSourceIsStopped() { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
+ if (!source_) |
+ return; |
+ if (was_started_) |
+ source_->Stop(); |
+ source_ = nullptr; |
+ VLOG(1) << "Stopped externally-provided " |
+ << (is_local_source() ? "local" : "remote") |
+ << " source with audio parameters={" |
+ << GetAudioParameters().AsHumanReadableString() << "}."; |
+} |
+ |
+void ExternalMediaStreamAudioSource::Capture(const media::AudioBus* audio_bus, |
+ int audio_delay_milliseconds, |
+ double volume, |
+ bool key_pressed) { |
+ DCHECK(audio_bus); |
+ // TODO(miu): Plumbing is needed to determine the actual capture timestamp |
+ // of the audio, instead of just snapshotting TimeTicks::Now(), for proper |
+ // audio/video sync. http://crbug.com/335335 |
+ MediaStreamAudioSource::DeliverDataToTracks( |
+ *audio_bus, |
+ base::TimeTicks::Now() - |
+ base::TimeDelta::FromMilliseconds(audio_delay_milliseconds)); |
+} |
+ |
+void ExternalMediaStreamAudioSource::OnCaptureError(const std::string& why) { |
+ // As of this writing, this method doesn't get called for anything useful, |
+ // and all other implementors just log the message, but don't disconnect sinks |
+ // or take any other action. So, just log the error. |
+ LOG(ERROR) << why; |
+} |
+ |
+} // namespace content |