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

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: simplify the CL to use NullAudioSink 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..1022a2c6d31f07abe43e5ba2285c5d209281e829 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"
#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,35 @@ using blink::WebView;
namespace content {
+static const int kSilenceInSecondsToEnterIdleMode = 30.0;
+
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),
+ audio_timestamp_helper_(
+ new media::AudioTimestampHelper(params.sample_rate())),
+ task_runner_(base::ThreadTaskRunnerHandle::Get()),
+ null_audio_sink_(new media::NullAudioSink(task_runner_)),
+ is_using_null_audio_sink_(false),
+ weak_factory_(this) {
DCHECK(client_callback_);
+ audio_timestamp_helper_->SetBaseTimestamp(base::TimeDelta());
+ null_audio_sink_->Initialize(params_, this);
+ weak_this_ = weak_factory_.GetWeakPtr();
}
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 +76,11 @@ void RendererWebAudioDeviceImpl::start() {
void RendererWebAudioDeviceImpl::stop() {
DCHECK(thread_checker_.CalledOnValidThread());
- if (output_device_.get()) {
+ if (output_device_) {
output_device_->Stop();
output_device_ = NULL;
}
+ StopNullAudioSink();
DaleCurtis 2015/06/22 19:14:40 Stop can be called multiple times, so I'd just cal
qinmin 2015/06/22 22:23:16 Done.
}
double RendererWebAudioDeviceImpl::sampleRate() {
@@ -87,6 +104,33 @@ int RendererWebAudioDeviceImpl::Render(media::AudioBus* dest,
dest->frames());
}
+#if defined(OS_ANDROID)
+ if (!dest->AreFramesZero() && is_using_null_audio_sink_) {
DaleCurtis 2015/06/22 19:14:40 We lose this buffer in this case, do we want to sa
qinmin 2015/06/22 22:23:16 I had the same question here. Changed the code to
+ // This is called on the main render thread when audio is detected.
+ output_device_->Play();
+ is_using_null_audio_sink_ = false;
+ task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&RendererWebAudioDeviceImpl::StopNullAudioSink,
+ weak_this_));
+ } else if (!is_using_null_audio_sink_) {
+ // Called on the audio device thread.
+ audio_timestamp_helper_->AddFrames(dest->frames());
DaleCurtis 2015/06/22 19:14:40 Instead of using a timestamp helper: On, l.108: c
qinmin 2015/06/22 22:23:16 If I remember clearly, TimtTicks::Now() are very e
DaleCurtis 2015/06/22 22:49:42 Do you have a source for TimeTicks::Now being expe
qinmin 2015/06/23 00:01:53 see http://gamasutra.com/view/feature/171774/getti
DaleCurtis 2015/06/23 16:38:14 Despite those early statements, the benchmarks sho
+ if (audio_timestamp_helper_->GetTimestamp().InSecondsF()
+ > kSilenceInSecondsToEnterIdleMode) {
+ output_device_->Pause();
+ audio_timestamp_helper_->SetBaseTimestamp(base::TimeDelta());
+ is_using_null_audio_sink_ = true;
+ // If Stop() is called right after the task is posted,
+ // StartNullAudioSink() should do nothing.
+ task_runner_->PostDelayedTask(
+ FROM_HERE,
+ base::Bind(&RendererWebAudioDeviceImpl::StartNullAudioSink,
+ weak_this_),
+ audio_timestamp_helper_->GetFrameDuration(dest->frames()));
+ }
+ }
+#endif
return dest->frames();
}
@@ -94,4 +138,14 @@ void RendererWebAudioDeviceImpl::OnRenderError() {
// TODO(crogers): implement error handling.
}
+void RendererWebAudioDeviceImpl::StopNullAudioSink() {
+ if (null_audio_sink_)
DaleCurtis 2015/06/22 19:14:41 Shouldn't this never be null? Additionally since A
qinmin 2015/06/22 22:23:16 Done.
+ null_audio_sink_->Stop();
+}
+
+void RendererWebAudioDeviceImpl::StartNullAudioSink() {
+ if (null_audio_sink_)
+ null_audio_sink_->Play();
+}
+
} // namespace content

Powered by Google App Engine
This is Rietveld 408576698