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

Side by Side Diff: content/browser/renderer_host/media/audio_renderer_host.cc

Issue 1856673002: Mojofication of the Chrome Audio Rendering Prototype Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 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 "content/browser/renderer_host/media/audio_renderer_host.h" 5 #include "content/browser/renderer_host/media/audio_renderer_host.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/bind_helpers.h" 11 #include "base/bind_helpers.h"
12 #include "base/lazy_instance.h" 12 #include "base/lazy_instance.h"
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/memory/shared_memory.h"
15 #include "base/metrics/histogram.h" 14 #include "base/metrics/histogram.h"
16 #include "base/process/process.h" 15 #include "base/process/process.h"
17 #include "content/browser/bad_message.h" 16 #include "content/browser/bad_message.h"
18 #include "content/browser/browser_main_loop.h" 17 #include "content/browser/browser_main_loop.h"
19 #include "content/browser/child_process_security_policy_impl.h" 18 #include "content/browser/child_process_security_policy_impl.h"
20 #include "content/browser/media/audio_stream_monitor.h" 19 #include "content/browser/media/audio_stream_monitor.h"
21 #include "content/browser/media/capture/audio_mirroring_manager.h" 20 #include "content/browser/media/capture/audio_mirroring_manager.h"
22 #include "content/browser/media/media_internals.h" 21 #include "content/browser/media/media_internals.h"
23 #include "content/browser/renderer_host/media/audio_input_device_manager.h" 22 #include "content/browser/renderer_host/media/audio_input_device_manager.h"
24 #include "content/browser/renderer_host/media/audio_sync_reader.h" 23 #include "content/browser/renderer_host/media/audio_sync_reader.h"
25 #include "content/browser/renderer_host/media/media_stream_manager.h" 24 #include "content/browser/renderer_host/media/media_stream_manager.h"
26 #include "content/browser/renderer_host/media/media_stream_ui_proxy.h" 25 #include "content/browser/renderer_host/media/media_stream_ui_proxy.h"
27 #include "content/browser/renderer_host/render_widget_host_impl.h" 26 #include "content/browser/renderer_host/render_widget_host_impl.h"
28 #include "content/common/media/audio_messages.h" 27 #include "content/common/media/audio_messages.h"
29 #include "content/public/browser/content_browser_client.h" 28 #include "content/public/browser/content_browser_client.h"
30 #include "content/public/browser/media_device_id.h" 29 #include "content/public/browser/media_device_id.h"
31 #include "content/public/browser/media_observer.h" 30 #include "content/public/browser/media_observer.h"
32 #include "content/public/browser/render_frame_host.h" 31 #include "content/public/browser/render_frame_host.h"
33 #include "content/public/common/content_switches.h" 32 #include "content/public/common/content_switches.h"
33 #include "content/renderer/media/audio_output_client.h"
34 #include "media/audio/audio_device_name.h" 34 #include "media/audio/audio_device_name.h"
35 #include "media/audio/audio_manager_base.h" 35 #include "media/audio/audio_manager_base.h"
36 #include "media/audio/audio_streams_tracker.h" 36 #include "media/audio/audio_streams_tracker.h"
37 #include "media/base/audio_bus.h" 37 #include "media/base/audio_bus.h"
38 #include "media/base/limits.h" 38 #include "media/base/limits.h"
39 #include "mojo/edk/embedder/embedder.h"
40 #include "mojo/public/cpp/system/handle.h"
41 #include "base/time/time.h"
42
43 #include "content/browser/media/audio_output_impl.h"
39 44
40 using media::AudioBus; 45 using media::AudioBus;
41 using media::AudioManager; 46 using media::AudioManager;
42 47
43 namespace content { 48 namespace content {
44 49
45 namespace { 50 namespace {
46 51
47 // Tracks the maximum number of simultaneous output streams browser-wide. 52 // Tracks the maximum number of simultaneous output streams browser-wide.
48 // Accessed on IO thread. 53 // Accessed on IO thread.
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 params->set_channels_for_discrete(media::limits::kMaxChannels); 120 params->set_channels_for_discrete(media::limits::kMaxChannels);
116 121
117 // If hardware parameters are still invalid, use dummy parameters with 122 // If hardware parameters are still invalid, use dummy parameters with
118 // fake audio path and let the client handle the error. 123 // fake audio path and let the client handle the error.
119 if (!params->IsValid()) 124 if (!params->IsValid())
120 *params = media::AudioParameters::UnavailableDeviceParams(); 125 *params = media::AudioParameters::UnavailableDeviceParams();
121 } 126 }
122 127
123 } // namespace 128 } // namespace
124 129
125 class AudioRendererHost::AudioEntry 130 AudioEntry::AudioEntry(
126 : public media::AudioOutputController::EventHandler {
127 public:
128 AudioEntry(AudioRendererHost* host,
129 int stream_id,
130 int render_frame_id,
131 const media::AudioParameters& params,
132 const std::string& output_device_id,
133 scoped_ptr<base::SharedMemory> shared_memory,
134 scoped_ptr<media::AudioOutputController::SyncReader> reader);
135 ~AudioEntry() override;
136
137 int stream_id() const {
138 return stream_id_;
139 }
140
141 int render_frame_id() const { return render_frame_id_; }
142
143 media::AudioOutputController* controller() const { return controller_.get(); }
144
145 base::SharedMemory* shared_memory() {
146 return shared_memory_.get();
147 }
148
149 media::AudioOutputController::SyncReader* reader() const {
150 return reader_.get();
151 }
152
153 bool playing() const { return playing_; }
154 void set_playing(bool playing) { playing_ = playing; }
155
156 private:
157 // media::AudioOutputController::EventHandler implementation.
158 void OnCreated() override;
159 void OnPlaying() override;
160 void OnPaused() override;
161 void OnError() override;
162
163 AudioRendererHost* const host_;
164 const int stream_id_;
165
166 // The routing ID of the source RenderFrame.
167 const int render_frame_id_;
168
169 // Shared memory for transmission of the audio data. Used by |reader_|.
170 const scoped_ptr<base::SharedMemory> shared_memory_;
171
172 // The synchronous reader to be used by |controller_|.
173 const scoped_ptr<media::AudioOutputController::SyncReader> reader_;
174
175 // The AudioOutputController that manages the audio stream.
176 const scoped_refptr<media::AudioOutputController> controller_;
177
178 bool playing_;
179 };
180
181 AudioRendererHost::AudioEntry::AudioEntry(
182 AudioRendererHost* host, 131 AudioRendererHost* host,
183 int stream_id, 132 int stream_id,
184 int render_frame_id, 133 int render_frame_id,
185 const media::AudioParameters& params, 134 const media::AudioParameters& params,
186 const std::string& output_device_id, 135 const std::string& output_device_id,
187 scoped_ptr<base::SharedMemory> shared_memory, 136 scoped_ptr<base::SharedMemory> shared_memory,
188 scoped_ptr<media::AudioOutputController::SyncReader> reader) 137 scoped_ptr<media::AudioOutputController::SyncReader> reader)
189 : host_(host), 138 : host_(host),
190 stream_id_(stream_id), 139 stream_id_(stream_id),
191 render_frame_id_(render_frame_id), 140 render_frame_id_(render_frame_id),
192 shared_memory_(std::move(shared_memory)), 141 shared_memory_(std::move(shared_memory)),
193 reader_(std::move(reader)), 142 reader_(std::move(reader)),
194 controller_(media::AudioOutputController::Create(host->audio_manager_, 143 controller_(media::AudioOutputController::Create(host->audio_manager_,
195 this, 144 this,
196 params, 145 params,
197 output_device_id, 146 output_device_id,
198 reader_.get())), 147 reader_.get())),
199 playing_(false) { 148 playing_(false) {
200 DCHECK(controller_.get()); 149 DCHECK(controller_.get());
201 } 150 }
202 151
203 AudioRendererHost::AudioEntry::~AudioEntry() {} 152 AudioEntry::AudioEntry(
153 AudioRendererHost* host,
154 int stream_id,
155 int render_frame_id,
156 const media::AudioParameters& params,
157 const std::string& output_device_id,
158 scoped_ptr<base::SharedMemory> shared_memory,
159 scoped_ptr<media::AudioOutputController::SyncReader> reader,
160 mojom::AudioOutputStreamPtr stream,
161 const mojom::AudioOutput::CreateStreamCallback& callback)
162 : host_(host),
163 stream_id_(stream_id),
164 render_frame_id_(render_frame_id),
165 shared_memory_(std::move(shared_memory)),
166 reader_(std::move(reader)),
167 controller_(media::AudioOutputController::Create(host->audio_manager_,
168 this,
169 params,
170 output_device_id,
171 reader_.get(),
172 std::move(stream),
173 callback)),
174 playing_(false) {
175 DCHECK(controller_.get());
176 }
177
178 AudioEntry::~AudioEntry() {}
204 179
205 /////////////////////////////////////////////////////////////////////////////// 180 ///////////////////////////////////////////////////////////////////////////////
206 // AudioRendererHost implementations. 181 // AudioRendererHost implementations.
207 182
208 AudioRendererHost::AudioRendererHost( 183 AudioRendererHost::AudioRendererHost(
209 int render_process_id, 184 int render_process_id,
210 media::AudioManager* audio_manager, 185 media::AudioManager* audio_manager,
211 AudioMirroringManager* mirroring_manager, 186 AudioMirroringManager* mirroring_manager,
212 MediaInternals* media_internals, 187 MediaInternals* media_internals,
213 MediaStreamManager* media_stream_manager, 188 MediaStreamManager* media_stream_manager,
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 } 235 }
261 236
262 // Remove any authorizations for streams that were not yet created 237 // Remove any authorizations for streams that were not yet created
263 authorizations_.clear(); 238 authorizations_.clear();
264 } 239 }
265 240
266 void AudioRendererHost::OnDestruct() const { 241 void AudioRendererHost::OnDestruct() const {
267 BrowserThread::DeleteOnIOThread::Destruct(this); 242 BrowserThread::DeleteOnIOThread::Destruct(this);
268 } 243 }
269 244
270 void AudioRendererHost::AudioEntry::OnCreated() { 245 void AudioEntry::OnCreated() {
271 BrowserThread::PostTask( 246 BrowserThread::PostTask(
272 BrowserThread::IO, 247 BrowserThread::IO,
273 FROM_HERE, 248 FROM_HERE,
274 base::Bind(&AudioRendererHost::DoCompleteCreation, host_, stream_id_)); 249 base::Bind(&AudioRendererHost::DoCompleteCreation, host_, stream_id_));
275 } 250 }
276 251
277 void AudioRendererHost::AudioEntry::OnPlaying() { 252 void AudioEntry::OnCreated(
253 mojom::AudioOutputStreamPtr stream,
254 const mojom::AudioOutput::CreateStreamCallback& callback) {
255 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
256 base::Bind(&AudioRendererHost::DoCompleteCreationMojo,
257 host_, stream_id_, callback));
258 }
259
260 void AudioEntry::OnPlaying() {
278 BrowserThread::PostTask( 261 BrowserThread::PostTask(
279 BrowserThread::IO, 262 BrowserThread::IO,
280 FROM_HERE, 263 FROM_HERE,
281 base::Bind(&AudioRendererHost::DoNotifyStreamStateChanged, 264 base::Bind(&AudioRendererHost::DoNotifyStreamStateChanged,
282 host_, 265 host_,
283 stream_id_, 266 stream_id_,
284 true)); 267 true));
285 } 268 }
286 269
287 void AudioRendererHost::AudioEntry::OnPaused() { 270 void AudioEntry::OnPaused() {
288 BrowserThread::PostTask( 271 BrowserThread::PostTask(
289 BrowserThread::IO, 272 BrowserThread::IO,
290 FROM_HERE, 273 FROM_HERE,
291 base::Bind(&AudioRendererHost::DoNotifyStreamStateChanged, 274 base::Bind(&AudioRendererHost::DoNotifyStreamStateChanged,
292 host_, 275 host_,
293 stream_id_, 276 stream_id_,
294 false)); 277 false));
295 } 278 }
296 279
297 void AudioRendererHost::AudioEntry::OnError() { 280 void AudioEntry::OnError() {
298 BrowserThread::PostTask( 281 BrowserThread::PostTask(
299 BrowserThread::IO, 282 BrowserThread::IO,
300 FROM_HERE, 283 FROM_HERE,
301 base::Bind(&AudioRendererHost::ReportErrorAndClose, host_, stream_id_)); 284 base::Bind(&AudioRendererHost::ReportErrorAndClose, host_, stream_id_));
302 } 285 }
303 286
304 void AudioRendererHost::DoCompleteCreation(int stream_id) { 287 void AudioRendererHost::DoCompleteCreation(int stream_id) {
305 DCHECK_CURRENTLY_ON(BrowserThread::IO); 288 DCHECK_CURRENTLY_ON(BrowserThread::IO);
306 289
307 if (!PeerHandle()) { 290 if (!PeerHandle()) {
308 DLOG(WARNING) << "Renderer process handle is invalid."; 291 DLOG(WARNING) << "Renderer process handle is invalid.";
309 ReportErrorAndClose(stream_id); 292 // ReportErrorAndClose(stream_id);
310 return; 293 return;
311 } 294 }
312 295
313 AudioEntry* const entry = LookupById(stream_id); 296 AudioEntry* const entry = LookupById(stream_id);
314 if (!entry) { 297 if (!entry) {
315 ReportErrorAndClose(stream_id); 298 // ReportErrorAndClose(stream_id);
316 return; 299 return;
317 } 300 }
318 301
319 // Once the audio stream is created then complete the creation process by 302 // Once the audio stream is created then complete the creation process by
320 // mapping shared memory and sharing with the renderer process. 303 // mapping shared memory and sharing with the renderer process.
321 base::SharedMemoryHandle foreign_memory_handle; 304 base::SharedMemoryHandle foreign_memory_handle;
322 if (!entry->shared_memory()->ShareToProcess(PeerHandle(), 305 if (!entry->shared_memory()->ShareToProcess(PeerHandle(),
323 &foreign_memory_handle)) { 306 &foreign_memory_handle)) {
324 // If we failed to map and share the shared memory then close the audio 307 // If we failed to map and share the shared memory then close the audio
325 // stream and send an error message. 308 // stream and send an error message.
326 ReportErrorAndClose(entry->stream_id()); 309 // ReportErrorAndClose(entry->stream_id());
327 return; 310 return;
328 } 311 }
329 312
330 AudioSyncReader* reader = static_cast<AudioSyncReader*>(entry->reader()); 313 AudioSyncReader* reader = static_cast<AudioSyncReader*>(entry->reader());
331 314
332 base::SyncSocket::TransitDescriptor socket_descriptor; 315 base::SyncSocket::TransitDescriptor socket_descriptor;
333 316
334 // If we failed to prepare the sync socket for the renderer then we fail 317 // If we failed to prepare the sync socket for the renderer then we fail
335 // the construction of audio stream. 318 // the construction of audio stream.
336 if (!reader->PrepareForeignSocket(PeerHandle(), &socket_descriptor)) { 319 if (!reader->PrepareForeignSocket(PeerHandle(), &socket_descriptor)) {
337 ReportErrorAndClose(entry->stream_id()); 320 // ReportErrorAndClose(entry->stream_id());
338 return; 321 return;
339 } 322 }
340 323
341 Send(new AudioMsg_NotifyStreamCreated( 324 Send(new AudioMsg_NotifyStreamCreated(
342 entry->stream_id(), foreign_memory_handle, socket_descriptor, 325 entry->stream_id(), foreign_memory_handle, socket_descriptor,
343 entry->shared_memory()->requested_size())); 326 entry->shared_memory()->requested_size()));
344 } 327 }
345 328
329 void AudioRendererHost::DoCompleteCreationMojo(
330 int stream_id,
331 const mojom::AudioOutput::CreateStreamCallback& callback) {
332 DCHECK_CURRENTLY_ON(BrowserThread::IO);
333
334 if (!PeerHandle()) {
335 DLOG(WARNING) << "Renderer process handle is invalid.";
336 ReportErrorAndCloseMojo(stream_id, callback);
337 return;
338 }
339
340 AudioEntry* const entry = LookupById(stream_id);
341 if (!entry) {
342 ReportErrorAndCloseMojo(stream_id, callback);
343 return;
344 }
345
346 scoped_ptr<mojom::AudioOutputStreamPtr> stream_ptr(
347 AudioOutputImpl::CreateStream(entry, stream_id));
348
349 base::SharedMemoryHandle shared_memory_handle =
350 base::SharedMemory::DuplicateHandle(entry->shared_memory()->handle());
351
352 MojoHandle mojo_foreign_memory_handle;
353
354 MojoResult shared_buffer_result = mojo::edk::CreateSharedBufferWrapper(
355 shared_memory_handle, entry->shared_memory()->requested_size(), false,
356 &mojo_foreign_memory_handle);
357
358 if (shared_buffer_result != MOJO_RESULT_OK) {
359 LOG(WARNING) << "Failed to wrap transit descriptor. Closing: "
360 << shared_buffer_result;
361 ReportErrorAndCloseMojo(entry->stream_id(), callback);
362 return;
363 }
364
365 AudioSyncReader* reader = static_cast<AudioSyncReader*>(entry->reader());
366
367 base::SyncSocket::TransitDescriptor socket_descriptor;
368
369 // If we failed to prepare the sync socket for the renderer then we fail
370 // the construction of audio stream.
371 if (!reader->PrepareForeignSocket(PeerHandle(), &socket_descriptor)) {
372 ReportErrorAndCloseMojo(entry->stream_id(), callback);
373 return;
374 }
375 mojo::ScopedSharedBufferHandle shared_buffer_handle =
376 mojo::ScopedSharedBufferHandle(
377 mojo::SharedBufferHandle(mojo_foreign_memory_handle));
378
379 MojoHandle socket_descriptor_handle;
380 MojoResult platform_handle_result;
381
382 #if defined(OS_WIN)
383 platform_handle_result = mojo::edk::CreatePlatformHandleWrapper(
384 mojo::edk::ScopedPlatformHandle(
385 mojo::edk::PlatformHandle(socket_descriptor)),
386 &socket_descriptor_handle);
387 #else
388 platform_handle_result = mojo::edk::CreatePlatformHandleWrapper(
389 mojo::edk::ScopedPlatformHandle(
390 mojo::edk::PlatformHandle(socket_descriptor.fd)),
391 &socket_descriptor_handle);
392 LOG(WARNING) << "socket_descriptor.fd" << socket_descriptor.fd;
393 LOG(WARNING) << "socket_descriptor_handle" << socket_descriptor_handle;
394 #endif
395
396 if (platform_handle_result != MOJO_RESULT_OK) {
397 LOG(WARNING) << "Failed to wrap platform handle. Closing: "
398 << platform_handle_result;
399 ReportErrorAndCloseMojo(stream_id, callback);
400 return;
401 }
402
403 stream_ptr->get()->set(20);
404 mojo::ScopedHandle socket_handle =
405 mojo::ScopedHandle(mojo::Handle(socket_descriptor_handle));
406
407 LOG(ERROR) << "stream_id" << stream_id;
408 // LOG(ERROR) << "foreign_memory_handle.fd" << foreign_memory_handle.fd;
409 // LOG(ERROR) << "foreign_memory_handle.auto_close" <<
410 // foreign_memory_handle.auto_close;
411 LOG(ERROR) << "socket_descriptor.fd" << socket_descriptor.fd;
412 LOG(ERROR) << "socket_descriptor.auto_close" << socket_descriptor.auto_close;
413 LOG(ERROR) << "entry->shared_memory()->requested_size()"
414 << entry->shared_memory()->requested_size();
415 LOG(ERROR) << "AudioRendererHost::DoCompleteCreationMojo"
416 << base::TimeTicks::Now();
417
418 callback.Run(std::move(*stream_ptr), stream_id,
419 std::move(shared_buffer_handle), std::move(socket_handle));
420 }
421
346 void AudioRendererHost::DoNotifyStreamStateChanged(int stream_id, 422 void AudioRendererHost::DoNotifyStreamStateChanged(int stream_id,
347 bool is_playing) { 423 bool is_playing) {
348 DCHECK_CURRENTLY_ON(BrowserThread::IO); 424 DCHECK_CURRENTLY_ON(BrowserThread::IO);
349 425
350 AudioEntry* const entry = LookupById(stream_id); 426 AudioEntry* const entry = LookupById(stream_id);
351 if (!entry) 427 if (!entry)
352 return; 428 return;
353 429
354 Send(new AudioMsg_NotifyStreamStateChanged( 430 Send(new AudioMsg_NotifyStreamStateChanged(
355 stream_id, 431 stream_id,
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 if (auth_data == authorizations_.end()) { 618 if (auth_data == authorizations_.end()) {
543 DoCreateStream(stream_id, render_frame_id, params, std::string()); 619 DoCreateStream(stream_id, render_frame_id, params, std::string());
544 return; 620 return;
545 } 621 }
546 622
547 CHECK(auth_data->second.first); 623 CHECK(auth_data->second.first);
548 DoCreateStream(stream_id, render_frame_id, params, auth_data->second.second); 624 DoCreateStream(stream_id, render_frame_id, params, auth_data->second.second);
549 authorizations_.erase(auth_data); 625 authorizations_.erase(auth_data);
550 } 626 }
551 627
628 void AudioRendererHost::OnCreateStreamMojo(
629 int stream_id,
630 int render_frame_id,
631 const media::AudioParameters& params,
632 mojom::AudioOutputStreamPtr stream,
633 const mojom::AudioOutput::CreateStreamCallback& callback) {
634 DCHECK_CURRENTLY_ON(BrowserThread::IO);
635 DVLOG(1) << "AudioRendererHost@" << this << "::OnCreateStream"
636 << "(stream_id=" << stream_id << ")";
637 LOG(ERROR) << "stream_id" << stream_id;
638
639 const auto& auth_data = authorizations_.find(stream_id);
640
641 // If no previous authorization requested, assume default device
642 if (auth_data == authorizations_.end()) {
643 DoCreateStream(stream_id, render_frame_id, params, std::string(),
644 std::move(stream), callback);
645 return;
646 }
647
648 CHECK(auth_data->second.first);
649 DoCreateStream(stream_id, render_frame_id, params, auth_data->second.second,
650 std::move(stream), callback);
651 authorizations_.erase(auth_data);
652 }
653
552 void AudioRendererHost::DoCreateStream(int stream_id, 654 void AudioRendererHost::DoCreateStream(int stream_id,
553 int render_frame_id, 655 int render_frame_id,
554 const media::AudioParameters& params, 656 const media::AudioParameters& params,
555 const std::string& device_unique_id) { 657 const std::string& device_unique_id) {
556 DCHECK_CURRENTLY_ON(BrowserThread::IO); 658 DCHECK_CURRENTLY_ON(BrowserThread::IO);
557 659
558 // media::AudioParameters is validated in the deserializer. 660 // media::AudioParameters is validated in the deserializer.
559 if (LookupById(stream_id) != NULL) { 661 if (LookupById(stream_id) != NULL) {
560 SendErrorMessage(stream_id); 662 SendErrorMessage(stream_id);
561 return; 663 return;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
593 g_audio_streams_tracker.Get().IncreaseStreamCount(); 695 g_audio_streams_tracker.Get().IncreaseStreamCount();
594 696
595 audio_log_->OnCreated(stream_id, params, device_unique_id); 697 audio_log_->OnCreated(stream_id, params, device_unique_id);
596 MediaInternals::GetInstance()->SetWebContentsTitleForAudioLogEntry( 698 MediaInternals::GetInstance()->SetWebContentsTitleForAudioLogEntry(
597 stream_id, render_process_id_, render_frame_id, audio_log_.get()); 699 stream_id, render_process_id_, render_frame_id, audio_log_.get());
598 700
599 if (audio_entries_.size() > max_simultaneous_streams_) 701 if (audio_entries_.size() > max_simultaneous_streams_)
600 max_simultaneous_streams_ = audio_entries_.size(); 702 max_simultaneous_streams_ = audio_entries_.size();
601 } 703 }
602 704
705 void AudioRendererHost::DoCreateStream(
706 int stream_id,
707 int render_frame_id,
708 const media::AudioParameters& params,
709 const std::string& device_unique_id,
710 mojom::AudioOutputStreamPtr stream,
711 const mojom::AudioOutput::CreateStreamCallback& callback) {
712 DCHECK_CURRENTLY_ON(BrowserThread::IO);
713
714 // media::AudioParameters is validated in the deserializer.
715 if (LookupById(stream_id) != NULL) {
716 SendErrorMessage(stream_id);
717 return;
718 }
719
720 // Create the shared memory and share with the renderer process.
721 uint32_t shared_memory_size = sizeof(media::AudioOutputBufferParameters) +
722 AudioBus::CalculateMemorySize(params);
723 scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory());
724 if (!shared_memory->CreateAndMapAnonymous(shared_memory_size)) {
725 SendErrorMessage(stream_id);
726 return;
727 }
728
729 scoped_ptr<AudioSyncReader> reader(
730 new AudioSyncReader(shared_memory.get(), params));
731 if (!reader->Init()) {
732 SendErrorMessage(stream_id);
733 return;
734 }
735
736 MediaObserver* const media_observer =
737 GetContentClient()->browser()->GetMediaObserver();
738 if (media_observer)
739 media_observer->OnCreatingAudioStream(render_process_id_, render_frame_id);
740
741 scoped_ptr<AudioEntry> entry(
742 new AudioEntry(this, stream_id, render_frame_id, params, device_unique_id,
743 std::move(shared_memory), std::move(reader),
744 std::move(stream), callback));
745 if (mirroring_manager_) {
746 mirroring_manager_->AddDiverter(
747 render_process_id_, entry->render_frame_id(), entry->controller());
748 }
749 audio_entries_.insert(std::make_pair(stream_id, entry.release()));
750 g_audio_streams_tracker.Get().IncreaseStreamCount();
751
752 audio_log_->OnCreated(stream_id, params, device_unique_id);
753 MediaInternals::GetInstance()->SetWebContentsTitleForAudioLogEntry(
754 stream_id, render_process_id_, render_frame_id, audio_log_.get());
755
756 if (audio_entries_.size() > max_simultaneous_streams_)
757 max_simultaneous_streams_ = audio_entries_.size();
758 }
759
760 void AudioRendererHost::OnPlayEntry(AudioEntry* entry) {
761 DCHECK_CURRENTLY_ON(BrowserThread::IO);
762
763 if (!entry) {
764 SendErrorMessage(0);
765 return;
766 }
767
768 entry->controller()->Play();
769 audio_log_->OnStarted(0);
770 }
771
603 void AudioRendererHost::OnPlayStream(int stream_id) { 772 void AudioRendererHost::OnPlayStream(int stream_id) {
604 DCHECK_CURRENTLY_ON(BrowserThread::IO); 773 DCHECK_CURRENTLY_ON(BrowserThread::IO);
605 774
606 AudioEntry* entry = LookupById(stream_id); 775 AudioEntry* entry = LookupById(stream_id);
607 if (!entry) { 776 if (!entry) {
608 SendErrorMessage(stream_id); 777 SendErrorMessage(stream_id);
609 return; 778 return;
610 } 779 }
611 780
612 entry->controller()->Play(); 781 entry->controller()->Play();
(...skipping 28 matching lines...) Expand all
641 entry->controller()->SetVolume(volume); 810 entry->controller()->SetVolume(volume);
642 audio_log_->OnSetVolume(stream_id, volume); 811 audio_log_->OnSetVolume(stream_id, volume);
643 } 812 }
644 813
645 void AudioRendererHost::SendErrorMessage(int stream_id) { 814 void AudioRendererHost::SendErrorMessage(int stream_id) {
646 Send(new AudioMsg_NotifyStreamStateChanged( 815 Send(new AudioMsg_NotifyStreamStateChanged(
647 stream_id, media::AUDIO_OUTPUT_IPC_DELEGATE_STATE_ERROR)); 816 stream_id, media::AUDIO_OUTPUT_IPC_DELEGATE_STATE_ERROR));
648 } 817 }
649 818
650 void AudioRendererHost::OnCloseStream(int stream_id) { 819 void AudioRendererHost::OnCloseStream(int stream_id) {
820 DLOG(WARNING) << "OnCloseStream " << stream_id;
651 DCHECK_CURRENTLY_ON(BrowserThread::IO); 821 DCHECK_CURRENTLY_ON(BrowserThread::IO);
652 authorizations_.erase(stream_id); 822 authorizations_.erase(stream_id);
653 823
654 // Prevent oustanding callbacks from attempting to close/delete the same 824 // Prevent oustanding callbacks from attempting to close/delete the same
655 // AudioEntry twice. 825 // AudioEntry twice.
656 AudioEntryMap::iterator i = audio_entries_.find(stream_id); 826 AudioEntryMap::iterator i = audio_entries_.find(stream_id);
657 if (i == audio_entries_.end()) 827 if (i == audio_entries_.end())
658 return; 828 return;
659 scoped_ptr<AudioEntry> entry(i->second); 829 scoped_ptr<AudioEntry> entry(i->second);
660 audio_entries_.erase(i); 830 audio_entries_.erase(i);
(...skipping 29 matching lines...) Expand all
690 // is closed. 860 // is closed.
691 if (!LookupById(stream_id)) 861 if (!LookupById(stream_id))
692 return; 862 return;
693 863
694 SendErrorMessage(stream_id); 864 SendErrorMessage(stream_id);
695 865
696 audio_log_->OnError(stream_id); 866 audio_log_->OnError(stream_id);
697 OnCloseStream(stream_id); 867 OnCloseStream(stream_id);
698 } 868 }
699 869
700 AudioRendererHost::AudioEntry* AudioRendererHost::LookupById(int stream_id) { 870 void AudioRendererHost::ReportErrorAndCloseMojo(
871 int stream_id,
872 const mojom::AudioOutput::CreateStreamCallback& callback) {
873 DCHECK_CURRENTLY_ON(BrowserThread::IO);
874
875 // Make sure this isn't a stray callback executing after the stream has been
876 // closed, so error notifications aren't sent after clients believe the stream
877 // is closed.
878 if (!LookupById(stream_id))
879 return;
880 mojo::ScopedSharedBufferHandle shared_buffer_handle =
881 mojo::ScopedSharedBufferHandle(mojo::SharedBufferHandle());
882
883 mojo::ScopedHandle socket_handle = mojo::ScopedHandle(mojo::Handle());
884
885 callback.Run(mojom::AudioOutputStreamPtr(), stream_id,
886 std::move(shared_buffer_handle), std::move(socket_handle));
887
888 audio_log_->OnError(stream_id);
889 OnCloseStream(stream_id);
890 }
891
892 AudioEntry* AudioRendererHost::LookupById(int stream_id) {
701 DCHECK_CURRENTLY_ON(BrowserThread::IO); 893 DCHECK_CURRENTLY_ON(BrowserThread::IO);
702 894
703 AudioEntryMap::const_iterator i = audio_entries_.find(stream_id); 895 AudioEntryMap::const_iterator i = audio_entries_.find(stream_id);
704 return i != audio_entries_.end() ? i->second : NULL; 896 return i != audio_entries_.end() ? i->second : NULL;
705 } 897 }
706 898
707 void AudioRendererHost::UpdateNumPlayingStreams(AudioEntry* entry, 899 void AudioRendererHost::UpdateNumPlayingStreams(AudioEntry* entry,
708 bool is_playing) { 900 bool is_playing) {
709 DCHECK_CURRENTLY_ON(BrowserThread::IO); 901 DCHECK_CURRENTLY_ON(BrowserThread::IO);
710 if (entry->playing() == is_playing) 902 if (entry->playing() == is_playing)
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
818 callback.Run(false, device_info); 1010 callback.Run(false, device_info);
819 } 1011 }
820 1012
821 bool AudioRendererHost::IsAuthorizationStarted(int stream_id) { 1013 bool AudioRendererHost::IsAuthorizationStarted(int stream_id) {
822 DCHECK_CURRENTLY_ON(BrowserThread::IO); 1014 DCHECK_CURRENTLY_ON(BrowserThread::IO);
823 const auto& i = authorizations_.find(stream_id); 1015 const auto& i = authorizations_.find(stream_id);
824 return i != authorizations_.end(); 1016 return i != authorizations_.end();
825 } 1017 }
826 1018
827 } // namespace content 1019 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/renderer_host/media/audio_renderer_host.h ('k') | content/browser/renderer_host/render_process_host_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698