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

Unified Diff: media/base/audio_renderer_mixer.cc

Issue 1483433003: Second layer of mixing for audio elements. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: That fix Created 5 years 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
« no previous file with comments | « media/base/audio_renderer_mixer.h ('k') | media/base/audio_renderer_mixer_input.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/base/audio_renderer_mixer.cc
diff --git a/media/base/audio_renderer_mixer.cc b/media/base/audio_renderer_mixer.cc
index 984798d916d6ce59ace8ebd9244c23693eb9db4b..26171f944881b67ff5e1a5d4ad0f709272f4c056 100644
--- a/media/base/audio_renderer_mixer.cc
+++ b/media/base/audio_renderer_mixer.cc
@@ -13,10 +13,11 @@ namespace media {
enum { kPauseDelaySeconds = 10 };
AudioRendererMixer::AudioRendererMixer(
- const AudioParameters& input_params, const AudioParameters& output_params,
+ const AudioParameters& output_params,
const scoped_refptr<AudioRendererSink>& sink)
: audio_sink_(sink),
- audio_converter_(input_params, output_params, true),
+ output_params_(output_params),
+ master_converter_(output_params, output_params, true),
pause_delay_(base::TimeDelta::FromSeconds(kPauseDelaySeconds)),
last_play_time_(base::TimeTicks::Now()),
// Initialize |playing_| to true since Start() results in an auto-play.
@@ -30,11 +31,13 @@ AudioRendererMixer::~AudioRendererMixer() {
audio_sink_->Stop();
// Ensure that all mixer inputs have removed themselves prior to destruction.
- DCHECK(audio_converter_.empty());
+ DCHECK(master_converter_.empty());
+ DCHECK(converters_.empty());
DCHECK_EQ(error_callbacks_.size(), 0U);
}
-void AudioRendererMixer::AddMixerInput(AudioConverter::InputCallback* input) {
+void AudioRendererMixer::AddMixerInput(const AudioParameters& input_params,
+ AudioConverter::InputCallback* input) {
base::AutoLock auto_lock(lock_);
if (!playing_) {
playing_ = true;
@@ -42,13 +45,49 @@ void AudioRendererMixer::AddMixerInput(AudioConverter::InputCallback* input) {
audio_sink_->Play();
}
- audio_converter_.AddInput(input);
+ int input_sample_rate = input_params.sample_rate();
+ if (is_master_sample_rate(input_sample_rate)) {
+ master_converter_.AddInput(input);
+ } else {
+ AudioConvertersMap::iterator converter =
+ converters_.find(input_sample_rate);
+ if (converter == converters_.end()) {
+ std::pair<AudioConvertersMap::iterator, bool> result =
+ converters_.insert(std::make_pair(
+ input_sample_rate, make_scoped_ptr(
+ // We expect all InputCallbacks to be
+ // capable of handling arbitrary buffer
+ // size requests, disabling FIFO.
+ new LoopbackAudioConverter(
+ input_params, output_params_, true))));
+ converter = result.first;
+
+ // Add newly-created resampler as an input to the master mixer.
+ master_converter_.AddInput(converter->second.get());
+ }
+ converter->second->AddInput(input);
+ }
}
void AudioRendererMixer::RemoveMixerInput(
+ const AudioParameters& input_params,
AudioConverter::InputCallback* input) {
base::AutoLock auto_lock(lock_);
- audio_converter_.RemoveInput(input);
+
+ int input_sample_rate = input_params.sample_rate();
+ if (is_master_sample_rate(input_sample_rate)) {
+ master_converter_.RemoveInput(input);
+ } else {
+ AudioConvertersMap::iterator converter =
+ converters_.find(input_sample_rate);
+ DCHECK(converter != converters_.end());
+ converter->second->RemoveInput(input);
+ if (converter->second->empty()) {
+ // Remove converter when it's empty.
+ master_converter_.RemoveInput(converter->second.get());
+ converters_.erase(converter);
+ }
+ }
}
void AudioRendererMixer::AddErrorCallback(const base::Closure& error_cb) {
@@ -85,14 +124,14 @@ int AudioRendererMixer::Render(AudioBus* audio_bus,
// sink to avoid wasting resources when media elements are present but remain
// in the pause state.
const base::TimeTicks now = base::TimeTicks::Now();
- if (!audio_converter_.empty()) {
+ if (!master_converter_.empty()) {
last_play_time_ = now;
} else if (now - last_play_time_ >= pause_delay_ && playing_) {
audio_sink_->Pause();
playing_ = false;
}
- audio_converter_.ConvertWithDelay(
+ master_converter_.ConvertWithDelay(
base::TimeDelta::FromMilliseconds(audio_delay_milliseconds), audio_bus);
return audio_bus->frames();
}
« no previous file with comments | « media/base/audio_renderer_mixer.h ('k') | media/base/audio_renderer_mixer_input.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698