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

Side by Side Diff: media/base/audio_renderer_mixer_input.cc

Issue 2359883002: Make ARMI::SwitchOutputDevice work after Stop is called. (Closed)
Patch Set: Update unit test Created 4 years, 3 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/base/audio_renderer_mixer_input.h" 5 #include "media/base/audio_renderer_mixer_input.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback_helpers.h" 10 #include "base/callback_helpers.h"
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 started_ = true; 59 started_ = true;
60 mixer_ = mixer_pool_->GetMixer(owner_id_, params_, latency_, device_id_, 60 mixer_ = mixer_pool_->GetMixer(owner_id_, params_, latency_, device_id_,
61 security_origin_, nullptr); 61 security_origin_, nullptr);
62 if (!mixer_) { 62 if (!mixer_) {
63 callback_->OnRenderError(); 63 callback_->OnRenderError();
64 return; 64 return;
65 } 65 }
66 66
67 // Note: OnRenderError() may be called immediately after this call returns. 67 // Note: OnRenderError() may be called immediately after this call returns.
68 mixer_->AddErrorCallback(error_cb_); 68 mixer_->AddErrorCallback(error_cb_);
69
70 if (!pending_switch_callback_.is_null()) {
71 SwitchOutputDevice(pending_switch_device_id_,
72 pending_switch_security_origin_,
73 base::ResetAndReturn(&pending_switch_callback_));
74 }
75 } 69 }
76 70
77 void AudioRendererMixerInput::Stop() { 71 void AudioRendererMixerInput::Stop() {
78 // Stop() may be called at any time, if Pause() hasn't been called we need to 72 // Stop() may be called at any time, if Pause() hasn't been called we need to
79 // remove our mixer input before shutdown. 73 // remove our mixer input before shutdown.
80 Pause(); 74 Pause();
81 75
82 if (mixer_) { 76 if (mixer_) {
83 // TODO(dalecurtis): This is required so that |callback_| isn't called after 77 // TODO(dalecurtis): This is required so that |callback_| isn't called after
84 // Stop() by an error event since it may outlive this ref-counted object. We 78 // Stop() by an error event since it may outlive this ref-counted object. We
85 // should instead have sane ownership semantics: http://crbug.com/151051 79 // should instead have sane ownership semantics: http://crbug.com/151051
86 mixer_->RemoveErrorCallback(error_cb_); 80 mixer_->RemoveErrorCallback(error_cb_);
87 mixer_pool_->ReturnMixer(mixer_); 81 mixer_pool_->ReturnMixer(mixer_);
88 mixer_ = nullptr; 82 mixer_ = nullptr;
89 } 83 }
90 84
91 started_ = false; 85 started_ = false;
92
93 if (!pending_switch_callback_.is_null()) {
94 base::ResetAndReturn(&pending_switch_callback_)
95 .Run(OUTPUT_DEVICE_STATUS_ERROR_INTERNAL);
96 }
97 } 86 }
98 87
99 void AudioRendererMixerInput::Play() { 88 void AudioRendererMixerInput::Play() {
100 if (playing_ || !mixer_) 89 if (playing_ || !mixer_)
101 return; 90 return;
102 91
103 mixer_->AddMixerInput(params_, this); 92 mixer_->AddMixerInput(params_, this);
104 playing_ = true; 93 playing_ = true;
105 } 94 }
106 95
(...skipping 19 matching lines...) Expand all
126 } 115 }
127 116
128 bool AudioRendererMixerInput::CurrentThreadIsRenderingThread() { 117 bool AudioRendererMixerInput::CurrentThreadIsRenderingThread() {
129 return mixer_->CurrentThreadIsRenderingThread(); 118 return mixer_->CurrentThreadIsRenderingThread();
130 } 119 }
131 120
132 void AudioRendererMixerInput::SwitchOutputDevice( 121 void AudioRendererMixerInput::SwitchOutputDevice(
133 const std::string& device_id, 122 const std::string& device_id,
134 const url::Origin& security_origin, 123 const url::Origin& security_origin,
135 const OutputDeviceStatusCB& callback) { 124 const OutputDeviceStatusCB& callback) {
136 if (!mixer_) {
137 if (pending_switch_callback_.is_null()) {
138 pending_switch_callback_ = callback;
139 pending_switch_device_id_ = device_id;
140 pending_switch_security_origin_ = security_origin;
141 } else {
142 callback.Run(OUTPUT_DEVICE_STATUS_ERROR_INTERNAL);
143 }
144
145 return;
146 }
147
148 DCHECK(pending_switch_callback_.is_null());
149 if (device_id == device_id_) { 125 if (device_id == device_id_) {
150 callback.Run(OUTPUT_DEVICE_STATUS_OK); 126 callback.Run(OUTPUT_DEVICE_STATUS_OK);
151 return; 127 return;
152 } 128 }
153 129
154 OutputDeviceStatus new_mixer_status = OUTPUT_DEVICE_STATUS_ERROR_INTERNAL; 130 OutputDeviceStatus new_mixer_status = OUTPUT_DEVICE_STATUS_ERROR_INTERNAL;
155 AudioRendererMixer* new_mixer = 131 AudioRendererMixer* new_mixer =
156 mixer_pool_->GetMixer(owner_id_, params_, latency_, device_id, 132 mixer_pool_->GetMixer(owner_id_, params_, latency_, device_id,
157 security_origin, &new_mixer_status); 133 security_origin, &new_mixer_status);
158 if (new_mixer_status != OUTPUT_DEVICE_STATUS_OK) { 134 if (new_mixer_status != OUTPUT_DEVICE_STATUS_OK) {
159 callback.Run(new_mixer_status); 135 callback.Run(new_mixer_status);
160 return; 136 return;
161 } 137 }
162 138
163 bool was_playing = playing_;
164 Stop();
165 device_id_ = device_id; 139 device_id_ = device_id;
166 security_origin_ = security_origin; 140 security_origin_ = security_origin;
167 mixer_ = new_mixer;
168 mixer_->AddErrorCallback(error_cb_);
169 started_ = true;
170 141
171 if (was_playing) 142 if (mixer_) {
172 Play(); 143 bool was_playing = playing_;
144 Stop();
145 mixer_ = new_mixer;
146 mixer_->AddErrorCallback(error_cb_);
147 started_ = true;
148 if (was_playing)
149 Play();
150 } else {
151 mixer_pool_->ReturnMixer(new_mixer);
152 }
173 153
174 callback.Run(OUTPUT_DEVICE_STATUS_OK); 154 callback.Run(OUTPUT_DEVICE_STATUS_OK);
175 } 155 }
176 156
177 double AudioRendererMixerInput::ProvideInput(AudioBus* audio_bus, 157 double AudioRendererMixerInput::ProvideInput(AudioBus* audio_bus,
178 uint32_t frames_delayed) { 158 uint32_t frames_delayed) {
179 TRACE_EVENT0("audio", "AudioRendererMixerInput::ProvideInput"); 159 TRACE_EVENT0("audio", "AudioRendererMixerInput::ProvideInput");
180 int frames_filled = callback_->Render(audio_bus, frames_delayed, 0); 160 int frames_filled = callback_->Render(audio_bus, frames_delayed, 0);
181 161
182 // AudioConverter expects unfilled frames to be zeroed. 162 // AudioConverter expects unfilled frames to be zeroed.
183 if (frames_filled < audio_bus->frames()) { 163 if (frames_filled < audio_bus->frames()) {
184 audio_bus->ZeroFramesPartial( 164 audio_bus->ZeroFramesPartial(
185 frames_filled, audio_bus->frames() - frames_filled); 165 frames_filled, audio_bus->frames() - frames_filled);
186 } 166 }
187 167
188 // We're reading |volume_| from the audio device thread and must avoid racing 168 // We're reading |volume_| from the audio device thread and must avoid racing
189 // with the main/media thread calls to SetVolume(). See thread safety comment 169 // with the main/media thread calls to SetVolume(). See thread safety comment
190 // in the header file. 170 // in the header file.
191 { 171 {
192 base::AutoLock auto_lock(volume_lock_); 172 base::AutoLock auto_lock(volume_lock_);
193 return frames_filled > 0 ? volume_ : 0; 173 return frames_filled > 0 ? volume_ : 0;
194 } 174 }
195 } 175 }
196 176
197 void AudioRendererMixerInput::OnRenderError() { 177 void AudioRendererMixerInput::OnRenderError() {
198 callback_->OnRenderError(); 178 callback_->OnRenderError();
199 } 179 }
200 180
201 } // namespace media 181 } // namespace media
OLDNEW
« no previous file with comments | « media/base/audio_renderer_mixer_input.h ('k') | media/base/audio_renderer_mixer_input_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698