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

Unified Diff: content/renderer/media/renderer_webaudiodevice_impl.cc

Issue 1195633003: Add a silent audio sink to consume WebAudio data on silence detection. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: addressing comments Created 5 years, 6 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 side-by-side diff with in-line comments
Download patch
Index: content/renderer/media/renderer_webaudiodevice_impl.cc
diff --git a/content/renderer/media/renderer_webaudiodevice_impl.cc b/content/renderer/media/renderer_webaudiodevice_impl.cc
index 81817f79818c0bb0b68cdd31197f4d9a03f731ae..a714831201fe9d8fa0b2c783cb3d297dff94ef6f 100644
--- a/content/renderer/media/renderer_webaudiodevice_impl.cc
+++ b/content/renderer/media/renderer_webaudiodevice_impl.cc
@@ -6,9 +6,14 @@
#include "base/command_line.h"
#include "base/logging.h"
+#include "base/single_thread_task_runner.h"
+#include "base/thread_task_runner_handle.h"
+#include "base/time/time.h"
#include "content/renderer/media/audio_device_factory.h"
#include "content/renderer/render_frame_impl.h"
#include "media/audio/audio_output_device.h"
+#include "media/audio/null_audio_sink.h"
+#include "media/base/audio_timestamp_helper.h"
DaleCurtis 2015/06/22 22:49:42 Remove?
qinmin 2015/06/23 00:01:54 Done.
#include "media/base/media_switches.h"
#include "third_party/WebKit/public/web/WebLocalFrame.h"
#include "third_party/WebKit/public/web/WebView.h"
@@ -20,24 +25,32 @@ using blink::WebView;
namespace content {
+static const int kSilenceInSecondsToEnterIdleMode = 30.0;
DaleCurtis 2015/06/22 22:49:42 Remove .0
qinmin 2015/06/23 00:01:54 Done.
+
RendererWebAudioDeviceImpl::RendererWebAudioDeviceImpl(
const media::AudioParameters& params,
WebAudioDevice::RenderCallback* callback,
int session_id)
: params_(params),
client_callback_(callback),
- session_id_(session_id) {
+ session_id_(session_id),
+ task_runner_(base::ThreadTaskRunnerHandle::Get()),
+ null_audio_sink_(new media::NullAudioSink(task_runner_)),
+ is_using_null_audio_sink_(false),
+ weak_factory_(this) {
DaleCurtis 2015/06/22 22:49:42 Remove.
qinmin 2015/06/23 00:01:54 Done.
DCHECK(client_callback_);
+ null_audio_sink_->Initialize(params_, this);
+ weak_this_ = weak_factory_.GetWeakPtr();
DaleCurtis 2015/06/22 22:49:42 Remove.
qinmin 2015/06/23 00:01:54 Done.
}
RendererWebAudioDeviceImpl::~RendererWebAudioDeviceImpl() {
- DCHECK(!output_device_.get());
+ DCHECK(!output_device_);
}
void RendererWebAudioDeviceImpl::start() {
DCHECK(thread_checker_.CalledOnValidThread());
- if (output_device_.get())
+ if (output_device_)
return; // Already started.
// Assumption: This method is being invoked within a V8 call stack. CHECKs
@@ -60,10 +73,13 @@ void RendererWebAudioDeviceImpl::start() {
void RendererWebAudioDeviceImpl::stop() {
DCHECK(thread_checker_.CalledOnValidThread());
- if (output_device_.get()) {
+ if (output_device_) {
output_device_->Stop();
output_device_ = NULL;
}
+ is_using_null_audio_sink_ = false;
+ null_audio_sink_->Stop();
+ first_buffer_after_silence_.reset();
}
double RendererWebAudioDeviceImpl::sampleRate() {
@@ -73,6 +89,14 @@ double RendererWebAudioDeviceImpl::sampleRate() {
int RendererWebAudioDeviceImpl::Render(media::AudioBus* dest,
int audio_delay_milliseconds) {
if (client_callback_) {
+#if defined(OS_ANDROID)
+ if (first_buffer_after_silence_) {
+ DCHECK(!is_using_null_audio_sink_);
+ first_buffer_after_silence_->CopyTo(dest);
+ first_buffer_after_silence_.reset();
+ return dest->frames();
+ }
+#endif
// Wrap the output pointers using WebVector.
WebVector<float*> web_audio_dest_data(
static_cast<size_t>(dest->channels()));
@@ -87,6 +111,42 @@ int RendererWebAudioDeviceImpl::Render(media::AudioBus* dest,
dest->frames());
}
+#if defined(OS_ANDROID)
+ const bool is_zero = dest->AreFramesZero();
+ if (!is_zero) {
+ first_silence_time_ = base::TimeTicks();
+ if (is_using_null_audio_sink_) {
+ // This is called on the main render thread when audio is detected.
+ output_device_->Play();
+ is_using_null_audio_sink_ = false;
+ first_buffer_after_silence_ = media::AudioBus::Create(params_);
DaleCurtis 2015/06/22 22:49:42 If we ever lower the silence threshold it might be
qinmin 2015/06/23 00:01:54 Done.
+ dest->CopyTo(first_buffer_after_silence_.get());
+ task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&media::NullAudioSink::Stop, null_audio_sink_));
+ }
+ } else if (!is_using_null_audio_sink_) {
+ // Called on the audio device thread.
+ const base::TimeTicks now = base::TimeTicks::Now();
+ if (first_silence_time_.is_null())
+ first_silence_time_ = now;
+ if ((now - first_silence_time_).InSecondsF()
DaleCurtis 2015/06/22 22:49:42 Instead of doing this, compare against base::TimeD
qinmin 2015/06/23 00:01:54 Done.
+ > kSilenceInSecondsToEnterIdleMode) {
+ output_device_->Pause();
+ is_using_null_audio_sink_ = true;
+ // If Stop() is called right after the task is posted,
DaleCurtis 2015/06/22 22:49:42 This isn't true, only the Stop() above is safe, yo
qinmin 2015/06/23 00:01:54 That's why I kept the weak_ptr_ here. If StartNull
+ // StartNullAudioSink() should do nothing.
+ double delay =
DaleCurtis 2015/06/22 22:49:42 Just use params_.GetBufferDuration()
qinmin 2015/06/23 00:01:54 Thanks, didn't notice that method.
+ static_cast<double>(dest->frames() *
+ base::Time::kMicrosecondsPerSecond) / params_.sample_rate();
+ task_runner_->PostDelayedTask(
+ FROM_HERE,
+ base::Bind(&RendererWebAudioDeviceImpl::StartNullAudioSink,
DaleCurtis 2015/06/22 22:49:42 Bind directly to Play() here.
qinmin 2015/06/23 00:01:54 Done.
+ weak_this_),
+ base::TimeDelta::FromMicroseconds(delay));
+ }
+ }
+#endif
return dest->frames();
}
@@ -94,4 +154,9 @@ void RendererWebAudioDeviceImpl::OnRenderError() {
// TODO(crogers): implement error handling.
}
+void RendererWebAudioDeviceImpl::StartNullAudioSink() {
DaleCurtis 2015/06/22 22:49:42 Delete?
qinmin 2015/06/23 00:01:54 Done.
+ if (is_using_null_audio_sink_)
+ null_audio_sink_->Play();
+}
+
} // namespace content

Powered by Google App Engine
This is Rietveld 408576698