summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
authordalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-31 04:37:17 +0000
committerdalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-31 04:37:17 +0000
commita1b9dfeb459092e3400fc7e23dc9c9696872be38 (patch)
tree9b57c3fa52b891ca4bafc314772caee43749be4c /content
parent675c847ddce27acfae3812dca0e5342f345e2b2a (diff)
downloadchromium_src-a1b9dfeb459092e3400fc7e23dc9c9696872be38.zip
chromium_src-a1b9dfeb459092e3400fc7e23dc9c9696872be38.tar.gz
chromium_src-a1b9dfeb459092e3400fc7e23dc9c9696872be38.tar.bz2
Don't background processes with active audio output.
If a process is actively rendering audio, it should not be put into the background state. "Active" is determined by having any stream in the playing state as considered by AudioRendererHost. When a tab has active audio, it's already being woken up ~ every 10-20ms, so I expect the power impact of this change to be negligible. This should reduce glitching under load. BUG=362294 TEST=Ensure Windows playback under load no longer glitches. Review URL: https://codereview.chromium.org/298253004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@274020 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r--content/browser/renderer_host/media/audio_renderer_host.cc25
-rw-r--r--content/browser/renderer_host/media/audio_renderer_host.h8
-rw-r--r--content/browser/renderer_host/render_process_host_impl.cc4
3 files changed, 35 insertions, 2 deletions
diff --git a/content/browser/renderer_host/media/audio_renderer_host.cc b/content/browser/renderer_host/media/audio_renderer_host.cc
index fd6b474..9334d94 100644
--- a/content/browser/renderer_host/media/audio_renderer_host.cc
+++ b/content/browser/renderer_host/media/audio_renderer_host.cc
@@ -61,6 +61,9 @@ class AudioRendererHost::AudioEntry
return reader_.get();
}
+ bool playing() const { return playing_; }
+ void set_playing(bool playing) { playing_ = playing; }
+
private:
// media::AudioOutputController::EventHandler implementation.
virtual void OnCreated() OVERRIDE;
@@ -85,6 +88,8 @@ class AudioRendererHost::AudioEntry
// The AudioOutputController that manages the audio stream.
const scoped_refptr<media::AudioOutputController> controller_;
+
+ bool playing_;
};
AudioRendererHost::AudioEntry::AudioEntry(
@@ -106,7 +111,8 @@ AudioRendererHost::AudioEntry::AudioEntry(
this,
params,
output_device_id,
- reader_.get())) {
+ reader_.get())),
+ playing_(false) {
DCHECK(controller_.get());
}
@@ -127,7 +133,8 @@ AudioRendererHost::AudioRendererHost(
mirroring_manager_(mirroring_manager),
audio_log_(media_internals->CreateAudioLog(
media::AudioLogFactory::AUDIO_OUTPUT_CONTROLLER)),
- media_stream_manager_(media_stream_manager) {
+ media_stream_manager_(media_stream_manager),
+ num_playing_streams_(0) {
DCHECK(audio_manager_);
DCHECK(media_stream_manager_);
}
@@ -275,10 +282,18 @@ void AudioRendererHost::DoNotifyStreamStateChanged(int stream_id,
entry->stream_id(),
base::Bind(&media::AudioOutputController::ReadCurrentPowerAndClip,
entry->controller()));
+ if (!entry->playing()) {
+ entry->set_playing(true);
+ base::AtomicRefCountInc(&num_playing_streams_);
+ }
} else {
media_observer->OnAudioStreamStopped(render_process_id_,
entry->render_frame_id(),
entry->stream_id());
+ if (entry->playing()) {
+ entry->set_playing(false);
+ base::AtomicRefCountDec(&num_playing_streams_);
+ }
}
}
}
@@ -458,6 +473,8 @@ void AudioRendererHost::DeleteEntry(scoped_ptr<AudioEntry> entry) {
media_observer->OnAudioStreamStopped(render_process_id_,
entry->render_frame_id(),
entry->stream_id());
+ if (entry->playing())
+ base::AtomicRefCountDec(&num_playing_streams_);
}
}
@@ -483,4 +500,8 @@ AudioRendererHost::AudioEntry* AudioRendererHost::LookupById(int stream_id) {
return i != audio_entries_.end() ? i->second : NULL;
}
+bool AudioRendererHost::HasActiveAudio() {
+ return !base::AtomicRefCountIsZero(&num_playing_streams_);
+}
+
} // namespace content
diff --git a/content/browser/renderer_host/media/audio_renderer_host.h b/content/browser/renderer_host/media/audio_renderer_host.h
index 60556ee..38317ef 100644
--- a/content/browser/renderer_host/media/audio_renderer_host.h
+++ b/content/browser/renderer_host/media/audio_renderer_host.h
@@ -39,6 +39,7 @@
#include <map>
+#include "base/atomic_ref_count.h"
#include "base/gtest_prod_util.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
@@ -84,6 +85,10 @@ class CONTENT_EXPORT AudioRendererHost : public BrowserMessageFilter {
virtual void OnDestruct() const OVERRIDE;
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
+ // Returns true if any streams managed by this host are actively playing. Can
+ // be called from any thread.
+ bool HasActiveAudio();
+
private:
friend class AudioRendererHostTest;
friend class BrowserThread;
@@ -165,6 +170,9 @@ class CONTENT_EXPORT AudioRendererHost : public BrowserMessageFilter {
// A map of stream IDs to audio sources.
AudioEntryMap audio_entries_;
+ // The number of streams in the playing state.
+ base::AtomicRefCount num_playing_streams_;
+
DISALLOW_COPY_AND_ASSIGN(AudioRendererHost);
};
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
index ef0fea2..7a6506e 100644
--- a/content/browser/renderer_host/render_process_host_impl.cc
+++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -1960,6 +1960,10 @@ void RenderProcessHostImpl::SetBackgrounded(bool backgrounded) {
if (!child_process_launcher_.get() || child_process_launcher_->IsStarting())
return;
+ // Don't background processes which have active audio streams.
+ if (backgrounded_ && audio_renderer_host_->HasActiveAudio())
+ return;
+
#if defined(OS_WIN)
// The cbstext.dll loads as a global GetMessage hook in the browser process
// and intercepts/unintercepts the kernel32 API SetPriorityClass in a