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

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

Issue 1930393002: Switch stream creation and closing in Chrome audio rendering from IPC to Mojo (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: render_frame_id Created 4 years, 7 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 #if defined(OS_WIN)
10 #include <windows.h>
11 #endif
9 12
10 #include "base/bind.h" 13 #include "base/bind.h"
11 #include "base/bind_helpers.h" 14 #include "base/bind_helpers.h"
12 #include "base/lazy_instance.h" 15 #include "base/lazy_instance.h"
13 #include "base/logging.h" 16 #include "base/logging.h"
14 #include "base/memory/shared_memory.h" 17 #include "base/memory/shared_memory.h"
15 #include "base/metrics/histogram.h" 18 #include "base/metrics/histogram.h"
16 #include "base/process/process.h" 19 #include "base/process/process.h"
17 #include "content/browser/bad_message.h" 20 #include "content/browser/bad_message.h"
18 #include "content/browser/browser_main_loop.h" 21 #include "content/browser/browser_main_loop.h"
22 #include "content/browser/media/audio_output_impl.h"
19 #include "content/browser/media/audio_stream_monitor.h" 23 #include "content/browser/media/audio_stream_monitor.h"
20 #include "content/browser/media/capture/audio_mirroring_manager.h" 24 #include "content/browser/media/capture/audio_mirroring_manager.h"
21 #include "content/browser/media/media_internals.h" 25 #include "content/browser/media/media_internals.h"
22 #include "content/browser/renderer_host/media/audio_input_device_manager.h" 26 #include "content/browser/renderer_host/media/audio_input_device_manager.h"
23 #include "content/browser/renderer_host/media/audio_sync_reader.h" 27 #include "content/browser/renderer_host/media/audio_sync_reader.h"
24 #include "content/browser/renderer_host/media/media_stream_manager.h" 28 #include "content/browser/renderer_host/media/media_stream_manager.h"
25 #include "content/browser/renderer_host/media/media_stream_ui_proxy.h" 29 #include "content/browser/renderer_host/media/media_stream_ui_proxy.h"
26 #include "content/browser/renderer_host/render_widget_host_impl.h" 30 #include "content/browser/renderer_host/render_widget_host_impl.h"
27 #include "content/common/media/audio_messages.h" 31 #include "content/common/media/audio_messages.h"
28 #include "content/public/browser/content_browser_client.h" 32 #include "content/public/browser/content_browser_client.h"
29 #include "content/public/browser/media_device_id.h" 33 #include "content/public/browser/media_device_id.h"
30 #include "content/public/browser/media_observer.h" 34 #include "content/public/browser/media_observer.h"
31 #include "content/public/browser/render_frame_host.h" 35 #include "content/public/browser/render_frame_host.h"
32 #include "content/public/common/content_switches.h" 36 #include "content/public/common/content_switches.h"
33 #include "media/audio/audio_device_description.h" 37 #include "media/audio/audio_device_description.h"
34 #include "media/audio/audio_streams_tracker.h" 38 #include "media/audio/audio_streams_tracker.h"
35 #include "media/base/audio_bus.h" 39 #include "media/base/audio_bus.h"
36 #include "media/base/limits.h" 40 #include "media/base/limits.h"
41 #include "mojo/edk/embedder/embedder.h"
42 #include "mojo/public/cpp/system/handle.h"
37 43
38 using media::AudioBus; 44 using media::AudioBus;
39 using media::AudioManager; 45 using media::AudioManager;
40 46
41 namespace content { 47 namespace content {
42 48
43 namespace { 49 namespace {
44 50
45 // Tracks the maximum number of simultaneous output streams browser-wide. 51 // Tracks the maximum number of simultaneous output streams browser-wide.
46 // Accessed on IO thread. 52 // Accessed on IO thread.
47 base::LazyInstance<media::AudioStreamsTracker> g_audio_streams_tracker = 53 base::LazyInstance<media::AudioStreamsTracker> g_audio_streams_tracker =
48 LAZY_INSTANCE_INITIALIZER; 54 LAZY_INSTANCE_INITIALIZER;
49 55
50 std::pair<int, std::pair<bool, std::string>> MakeAuthorizationData( 56 std::pair<int, std::pair<bool, std::string>> MakeAuthorizationData(
51 int stream_id, 57 int stream_id,
52 bool authorized, 58 bool authorized,
53 const std::string& device_unique_id) { 59 const std::string& device_unique_id) {
54 return std::make_pair(stream_id, 60 return std::make_pair(stream_id,
55 std::make_pair(authorized, device_unique_id)); 61 std::make_pair(authorized, device_unique_id));
56 } 62 }
57 63
64 base::SyncSocket::TransitDescriptor DuplicateSocket(
65 base::SyncSocket::TransitDescriptor socket_descriptor) {
66 base::SyncSocket::TransitDescriptor socket_descriptor_dup;
67
68 #if defined(OS_WIN)
69 socket_descriptor_dup = 0;
70 if (!::DuplicateHandle(GetCurrentProcess(), // hSourceProcessHandle
71 socket_descriptor,
72 GetCurrentProcess(), // hTargetProcessHandle
73 &socket_descriptor_dup,
74 0, // dwDesiredAccess ignored due to SAME_ACCESS
75 FALSE, // !bInheritHandle
76 DUPLICATE_SAME_ACCESS)) {
77 LOG(ERROR) << "Unable to duplicate socket handle.";
78 }
79
80 #else
81 socket_descriptor_dup.fd = dup(socket_descriptor.fd);
82 #endif
83 return socket_descriptor_dup;
84 }
85
58 bool IsValidDeviceId(const std::string& device_id) { 86 bool IsValidDeviceId(const std::string& device_id) {
59 static const std::string::size_type kValidLength = 64; 87 static const std::string::size_type kValidLength = 64;
60 88
61 if (device_id.empty() || 89 if (device_id.empty() ||
62 device_id == media::AudioDeviceDescription::kDefaultDeviceId || 90 device_id == media::AudioDeviceDescription::kDefaultDeviceId ||
63 device_id == media::AudioDeviceDescription::kCommunicationsDeviceId) { 91 device_id == media::AudioDeviceDescription::kCommunicationsDeviceId) {
64 return true; 92 return true;
65 } 93 }
66 94
67 if (device_id.length() != kValidLength) 95 if (device_id.length() != kValidLength)
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 // fake audio path and let the client handle the error. 135 // fake audio path and let the client handle the error.
108 if (!params->IsValid()) 136 if (!params->IsValid())
109 *params = media::AudioParameters::UnavailableDeviceParams(); 137 *params = media::AudioParameters::UnavailableDeviceParams();
110 } 138 }
111 139
112 } // namespace 140 } // namespace
113 141
114 class AudioRendererHost::AudioEntry 142 class AudioRendererHost::AudioEntry
115 : public media::AudioOutputController::EventHandler { 143 : public media::AudioOutputController::EventHandler {
116 public: 144 public:
117 AudioEntry(AudioRendererHost* host, 145 AudioEntry(
118 int stream_id, 146 AudioRendererHost* host,
119 int render_frame_id, 147 int stream_id,
120 const media::AudioParameters& params, 148 int render_frame_id,
121 const std::string& output_device_id, 149 const media::AudioParameters& params,
122 std::unique_ptr<base::SharedMemory> shared_memory, 150 const std::string& output_device_id,
123 std::unique_ptr<media::AudioOutputController::SyncReader> reader); 151 std::unique_ptr<base::SharedMemory> shared_memory,
152 std::unique_ptr<media::AudioOutputController::SyncReader> reader,
153 const media::mojom::AudioOutput::CreateStreamCallback&
154 create_stream_callback);
124 ~AudioEntry() override; 155 ~AudioEntry() override;
125 156
126 int stream_id() const { 157 int stream_id() const {
127 return stream_id_; 158 return stream_id_;
128 } 159 }
129 160
130 int render_frame_id() const { return render_frame_id_; } 161 int render_frame_id() const { return render_frame_id_; }
131 162
132 media::AudioOutputController* controller() const { return controller_.get(); } 163 media::AudioOutputController* controller() const { return controller_.get(); }
133 164
(...skipping 24 matching lines...) Expand all
158 // Shared memory for transmission of the audio data. Used by |reader_|. 189 // Shared memory for transmission of the audio data. Used by |reader_|.
159 const std::unique_ptr<base::SharedMemory> shared_memory_; 190 const std::unique_ptr<base::SharedMemory> shared_memory_;
160 191
161 // The synchronous reader to be used by |controller_|. 192 // The synchronous reader to be used by |controller_|.
162 const std::unique_ptr<media::AudioOutputController::SyncReader> reader_; 193 const std::unique_ptr<media::AudioOutputController::SyncReader> reader_;
163 194
164 // The AudioOutputController that manages the audio stream. 195 // The AudioOutputController that manages the audio stream.
165 const scoped_refptr<media::AudioOutputController> controller_; 196 const scoped_refptr<media::AudioOutputController> controller_;
166 197
167 bool playing_; 198 bool playing_;
199
200 // Callback for media::mojom::AudioOutput::CreateStream.
201 media::mojom::AudioOutput::CreateStreamCallback create_stream_callback_;
168 }; 202 };
169 203
170 AudioRendererHost::AudioEntry::AudioEntry( 204 AudioRendererHost::AudioEntry::AudioEntry(
171 AudioRendererHost* host, 205 AudioRendererHost* host,
172 int stream_id, 206 int stream_id,
173 int render_frame_id, 207 int render_frame_id,
174 const media::AudioParameters& params, 208 const media::AudioParameters& params,
175 const std::string& output_device_id, 209 const std::string& output_device_id,
176 std::unique_ptr<base::SharedMemory> shared_memory, 210 std::unique_ptr<base::SharedMemory> shared_memory,
177 std::unique_ptr<media::AudioOutputController::SyncReader> reader) 211 std::unique_ptr<media::AudioOutputController::SyncReader> reader,
212 const media::mojom::AudioOutput::CreateStreamCallback&
213 create_stream_callback)
178 : host_(host), 214 : host_(host),
179 stream_id_(stream_id), 215 stream_id_(stream_id),
180 render_frame_id_(render_frame_id), 216 render_frame_id_(render_frame_id),
181 shared_memory_(std::move(shared_memory)), 217 shared_memory_(std::move(shared_memory)),
182 reader_(std::move(reader)), 218 reader_(std::move(reader)),
183 controller_(media::AudioOutputController::Create(host->audio_manager_, 219 controller_(media::AudioOutputController::Create(host->audio_manager_,
184 this, 220 this,
185 params, 221 params,
186 output_device_id, 222 output_device_id,
187 reader_.get())), 223 reader_.get())),
188 playing_(false) { 224 playing_(false),
225 create_stream_callback_(create_stream_callback) {
189 DCHECK(controller_.get()); 226 DCHECK(controller_.get());
190 } 227 }
191 228
192 AudioRendererHost::AudioEntry::~AudioEntry() {} 229 AudioRendererHost::AudioEntry::~AudioEntry() {}
193 230
194 /////////////////////////////////////////////////////////////////////////////// 231 ///////////////////////////////////////////////////////////////////////////////
195 // AudioRendererHost implementations. 232 // AudioRendererHost implementations.
196 233
197 AudioRendererHost::AudioRendererHost( 234 AudioRendererHost::AudioRendererHost(
198 int render_process_id, 235 int render_process_id,
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 // Remove any authorizations for streams that were not yet created 288 // Remove any authorizations for streams that were not yet created
252 authorizations_.clear(); 289 authorizations_.clear();
253 } 290 }
254 291
255 void AudioRendererHost::OnDestruct() const { 292 void AudioRendererHost::OnDestruct() const {
256 BrowserThread::DeleteOnIOThread::Destruct(this); 293 BrowserThread::DeleteOnIOThread::Destruct(this);
257 } 294 }
258 295
259 void AudioRendererHost::AudioEntry::OnCreated() { 296 void AudioRendererHost::AudioEntry::OnCreated() {
260 BrowserThread::PostTask( 297 BrowserThread::PostTask(
261 BrowserThread::IO, 298 BrowserThread::IO, FROM_HERE,
262 FROM_HERE, 299 base::Bind(&AudioRendererHost::DoCompleteCreation, host_, stream_id_,
263 base::Bind(&AudioRendererHost::DoCompleteCreation, host_, stream_id_)); 300 create_stream_callback_));
264 } 301 }
265 302
266 void AudioRendererHost::AudioEntry::OnPlaying() { 303 void AudioRendererHost::AudioEntry::OnPlaying() {
267 BrowserThread::PostTask( 304 BrowserThread::PostTask(
268 BrowserThread::IO, 305 BrowserThread::IO,
269 FROM_HERE, 306 FROM_HERE,
270 base::Bind(&AudioRendererHost::DoNotifyStreamStateChanged, 307 base::Bind(&AudioRendererHost::DoNotifyStreamStateChanged,
271 host_, 308 host_,
272 stream_id_, 309 stream_id_,
273 true)); 310 true));
274 } 311 }
275 312
276 void AudioRendererHost::AudioEntry::OnPaused() { 313 void AudioRendererHost::AudioEntry::OnPaused() {
277 BrowserThread::PostTask( 314 BrowserThread::PostTask(
278 BrowserThread::IO, 315 BrowserThread::IO,
279 FROM_HERE, 316 FROM_HERE,
280 base::Bind(&AudioRendererHost::DoNotifyStreamStateChanged, 317 base::Bind(&AudioRendererHost::DoNotifyStreamStateChanged,
281 host_, 318 host_,
282 stream_id_, 319 stream_id_,
283 false)); 320 false));
284 } 321 }
285 322
286 void AudioRendererHost::AudioEntry::OnError() { 323 void AudioRendererHost::AudioEntry::OnError() {
287 BrowserThread::PostTask( 324 BrowserThread::PostTask(
288 BrowserThread::IO, 325 BrowserThread::IO,
289 FROM_HERE, 326 FROM_HERE,
290 base::Bind(&AudioRendererHost::ReportErrorAndClose, host_, stream_id_)); 327 base::Bind(&AudioRendererHost::ReportErrorAndClose, host_, stream_id_));
291 } 328 }
292 329
293 void AudioRendererHost::DoCompleteCreation(int stream_id) { 330 void AudioRendererHost::DoCompleteCreation(
331 int stream_id,
332 const media::mojom::AudioOutput::CreateStreamCallback& callback) {
294 DCHECK_CURRENTLY_ON(BrowserThread::IO); 333 DCHECK_CURRENTLY_ON(BrowserThread::IO);
295 334
296 if (!PeerHandle()) { 335 if (!PeerHandle()) {
297 DLOG(WARNING) << "Renderer process handle is invalid."; 336 DLOG(WARNING) << "Renderer process handle is invalid.";
298 ReportErrorAndClose(stream_id); 337 ReportErrorAndCloseStream(stream_id, callback);
299 return; 338 return;
300 } 339 }
301 340
302 AudioEntry* const entry = LookupById(stream_id); 341 AudioEntry* const entry = LookupById(stream_id);
303 if (!entry) { 342 if (!entry) {
304 ReportErrorAndClose(stream_id); 343 ReportErrorAndCloseStream(stream_id, callback);
305 return; 344 return;
306 } 345 }
307 346
308 // Once the audio stream is created then complete the creation process by 347 media::mojom::AudioOutputStreamPtr stream_ptr =
309 // mapping shared memory and sharing with the renderer process. 348 (audio_output_impl_->StreamFactory(stream_id, this));
310 base::SharedMemoryHandle foreign_memory_handle; 349
311 if (!entry->shared_memory()->ShareToProcess(PeerHandle(), 350 base::SharedMemoryHandle shared_memory_handle =
312 &foreign_memory_handle)) { 351 base::SharedMemory::DuplicateHandle(entry->shared_memory()->handle());
313 // If we failed to map and share the shared memory then close the audio 352
314 // stream and send an error message. 353 MojoHandle mojo_foreign_memory_handle;
315 ReportErrorAndClose(entry->stream_id()); 354
355 MojoResult shared_buffer_result = mojo::edk::CreateSharedBufferWrapper(
356 shared_memory_handle, entry->shared_memory()->requested_size(), false,
357 &mojo_foreign_memory_handle);
358
359 if (shared_buffer_result != MOJO_RESULT_OK) {
360 DLOG(WARNING) << "Failed to wrap transit descriptor. Closing: "
361 << shared_buffer_result;
362 ReportErrorAndCloseStream(entry->stream_id(), callback);
316 return; 363 return;
317 } 364 }
318 365
319 AudioSyncReader* reader = static_cast<AudioSyncReader*>(entry->reader()); 366 AudioSyncReader* reader = static_cast<AudioSyncReader*>(entry->reader());
320 367
321 base::SyncSocket::TransitDescriptor socket_descriptor; 368 base::SyncSocket::TransitDescriptor socket_descriptor;
322 369
323 // If we failed to prepare the sync socket for the renderer then we fail 370 // If we failed to prepare the sync socket for the renderer then we fail
324 // the construction of audio stream. 371 // the construction of audio stream.
325 if (!reader->PrepareForeignSocket(PeerHandle(), &socket_descriptor)) { 372 if (!reader->PrepareForeignSocket(PeerHandle(), &socket_descriptor)) {
326 ReportErrorAndClose(entry->stream_id()); 373 ReportErrorAndCloseStream(entry->stream_id(), callback);
374 return;
375 }
376 mojo::ScopedSharedBufferHandle shared_buffer_handle =
377 mojo::ScopedSharedBufferHandle(
378 mojo::SharedBufferHandle(mojo_foreign_memory_handle));
379
380 MojoHandle socket_descriptor_handle;
381 MojoResult platform_handle_result;
382
383 // The socket handle is going to be closed when |mojo_application_host_| is
384 // reset. AudioOutputIPCDelegate is going to need to close the socket handle
385 // too when the steam it controls is closed. This is going to cause an issue
386 // because both of them are going to close the same socket handle.
387 // This is why a duplicate of the socket handler is going to be created,
388 // stored in |socket_descriptor_dup| and sent through Mojo to the renderer so
389 // it can be used by AudioOutputIPCDelegate.
390
391 base::SyncSocket::TransitDescriptor socket_descriptor_dup =
392 DuplicateSocket(socket_descriptor);
393 #if defined(OS_WIN)
394 platform_handle_result = mojo::edk::CreatePlatformHandleWrapper(
395 mojo::edk::ScopedPlatformHandle(
396 mojo::edk::PlatformHandle(socket_descriptor_dup),
397 &socket_descriptor_handle);
398 #else
399 platform_handle_result = mojo::edk::CreatePlatformHandleWrapper(
400 mojo::edk::ScopedPlatformHandle(
401 mojo::edk::PlatformHandle(socket_descriptor_dup.fd)),
402 &socket_descriptor_handle);
403 #endif
404
405 if (platform_handle_result != MOJO_RESULT_OK) {
406 DLOG(WARNING) << "Failed to wrap platform handle. Closing: "
407 << platform_handle_result;
408 ReportErrorAndCloseStream(stream_id, callback);
327 return; 409 return;
328 } 410 }
329 411
330 Send(new AudioMsg_NotifyStreamCreated( 412 mojo::ScopedHandle socket_handle =
331 entry->stream_id(), foreign_memory_handle, socket_descriptor, 413 mojo::ScopedHandle(mojo::Handle(socket_descriptor_handle));
332 entry->shared_memory()->requested_size())); 414 callback.Run(stream_id, std::move(stream_ptr),
415 std::move(shared_buffer_handle), std::move(socket_handle));
333 } 416 }
334 417
335 void AudioRendererHost::DoNotifyStreamStateChanged(int stream_id, 418 void AudioRendererHost::DoNotifyStreamStateChanged(int stream_id,
336 bool is_playing) { 419 bool is_playing) {
337 DCHECK_CURRENTLY_ON(BrowserThread::IO); 420 DCHECK_CURRENTLY_ON(BrowserThread::IO);
338 421
339 AudioEntry* const entry = LookupById(stream_id); 422 AudioEntry* const entry = LookupById(stream_id);
340 if (!entry) 423 if (!entry)
341 return; 424 return;
342 425
(...skipping 30 matching lines...) Expand all
373 return controllers; 456 return controllers;
374 } 457 }
375 458
376 /////////////////////////////////////////////////////////////////////////////// 459 ///////////////////////////////////////////////////////////////////////////////
377 // IPC Messages handler 460 // IPC Messages handler
378 bool AudioRendererHost::OnMessageReceived(const IPC::Message& message) { 461 bool AudioRendererHost::OnMessageReceived(const IPC::Message& message) {
379 bool handled = true; 462 bool handled = true;
380 IPC_BEGIN_MESSAGE_MAP(AudioRendererHost, message) 463 IPC_BEGIN_MESSAGE_MAP(AudioRendererHost, message)
381 IPC_MESSAGE_HANDLER(AudioHostMsg_RequestDeviceAuthorization, 464 IPC_MESSAGE_HANDLER(AudioHostMsg_RequestDeviceAuthorization,
382 OnRequestDeviceAuthorization) 465 OnRequestDeviceAuthorization)
383 IPC_MESSAGE_HANDLER(AudioHostMsg_CreateStream, OnCreateStream)
384 IPC_MESSAGE_HANDLER(AudioHostMsg_PlayStream, OnPlayStream) 466 IPC_MESSAGE_HANDLER(AudioHostMsg_PlayStream, OnPlayStream)
385 IPC_MESSAGE_HANDLER(AudioHostMsg_PauseStream, OnPauseStream) 467 IPC_MESSAGE_HANDLER(AudioHostMsg_PauseStream, OnPauseStream)
386 IPC_MESSAGE_HANDLER(AudioHostMsg_CloseStream, OnCloseStream) 468 IPC_MESSAGE_HANDLER(AudioHostMsg_CloseStream, OnCloseStream)
387 IPC_MESSAGE_HANDLER(AudioHostMsg_SetVolume, OnSetVolume) 469 IPC_MESSAGE_HANDLER(AudioHostMsg_SetVolume, OnSetVolume)
388 IPC_MESSAGE_UNHANDLED(handled = false) 470 IPC_MESSAGE_UNHANDLED(handled = false)
389 IPC_END_MESSAGE_MAP() 471 IPC_END_MESSAGE_MAP()
390 472
391 return handled; 473 return handled;
392 } 474 }
393 475
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
510 592
511 auth_data->second.first = true; 593 auth_data->second.first = true;
512 auth_data->second.second = device_info.unique_id; 594 auth_data->second.second = device_info.unique_id;
513 595
514 media::AudioParameters output_params = device_info.output_params; 596 media::AudioParameters output_params = device_info.output_params;
515 MaybeFixAudioParameters(&output_params); 597 MaybeFixAudioParameters(&output_params);
516 Send(new AudioMsg_NotifyDeviceAuthorized( 598 Send(new AudioMsg_NotifyDeviceAuthorized(
517 stream_id, media::OUTPUT_DEVICE_STATUS_OK, output_params, std::string())); 599 stream_id, media::OUTPUT_DEVICE_STATUS_OK, output_params, std::string()));
518 } 600 }
519 601
520 void AudioRendererHost::OnCreateStream(int stream_id, 602 void AudioRendererHost::CreateStream(
521 int render_frame_id, 603 int stream_id,
522 const media::AudioParameters& params) { 604 int render_frame_id,
605 const media::AudioParameters& params,
606 const media::mojom::AudioOutput::CreateStreamCallback&
607 create_stream_callback) {
523 DCHECK_CURRENTLY_ON(BrowserThread::IO); 608 DCHECK_CURRENTLY_ON(BrowserThread::IO);
524 DVLOG(1) << "AudioRendererHost@" << this << "::OnCreateStream" 609 DVLOG(1) << "AudioRendererHost@" << this << "::CreateStream"
525 << "(stream_id=" << stream_id << ")"; 610 << "(stream_id=" << stream_id << ")";
526 611
527 const auto& auth_data = authorizations_.find(stream_id); 612 const auto& auth_data = authorizations_.find(stream_id);
528 613
529 // If no previous authorization requested, assume default device 614 // If no previous authorization requested, assume default device
530 if (auth_data == authorizations_.end()) { 615 if (auth_data == authorizations_.end()) {
531 DoCreateStream(stream_id, render_frame_id, params, std::string()); 616 DoCreateStream(stream_id, render_frame_id, params, std::string(),
617 create_stream_callback);
532 return; 618 return;
533 } 619 }
534 620
535 CHECK(auth_data->second.first); 621 CHECK(auth_data->second.first);
536 DoCreateStream(stream_id, render_frame_id, params, auth_data->second.second); 622 DoCreateStream(stream_id, render_frame_id, params, auth_data->second.second,
623 create_stream_callback);
537 authorizations_.erase(auth_data); 624 authorizations_.erase(auth_data);
538 } 625 }
539 626
540 void AudioRendererHost::DoCreateStream(int stream_id, 627 void AudioRendererHost::DoCreateStream(
541 int render_frame_id, 628 int stream_id,
542 const media::AudioParameters& params, 629 int render_frame_id,
543 const std::string& device_unique_id) { 630 const media::AudioParameters& params,
631 const std::string& device_unique_id,
632 const media::mojom::AudioOutput::CreateStreamCallback&
633 create_stream_callback) {
544 DCHECK_CURRENTLY_ON(BrowserThread::IO); 634 DCHECK_CURRENTLY_ON(BrowserThread::IO);
545 635
546 // media::AudioParameters is validated in the deserializer. 636 // media::AudioParameters is validated in the deserializer.
547 if (LookupById(stream_id) != NULL) { 637 if (LookupById(stream_id) != NULL) {
548 SendErrorMessage(stream_id); 638 SendErrorMessage(stream_id);
549 return; 639 return;
550 } 640 }
551 641
552 // Create the shared memory and share with the renderer process. 642 // Create the shared memory and share with the renderer process.
553 uint32_t shared_memory_size = sizeof(media::AudioOutputBufferParameters) + 643 uint32_t shared_memory_size = sizeof(media::AudioOutputBufferParameters) +
(...skipping 11 matching lines...) Expand all
565 return; 655 return;
566 } 656 }
567 657
568 MediaObserver* const media_observer = 658 MediaObserver* const media_observer =
569 GetContentClient()->browser()->GetMediaObserver(); 659 GetContentClient()->browser()->GetMediaObserver();
570 if (media_observer) 660 if (media_observer)
571 media_observer->OnCreatingAudioStream(render_process_id_, render_frame_id); 661 media_observer->OnCreatingAudioStream(render_process_id_, render_frame_id);
572 662
573 std::unique_ptr<AudioEntry> entry( 663 std::unique_ptr<AudioEntry> entry(
574 new AudioEntry(this, stream_id, render_frame_id, params, device_unique_id, 664 new AudioEntry(this, stream_id, render_frame_id, params, device_unique_id,
575 std::move(shared_memory), std::move(reader))); 665 std::move(shared_memory), std::move(reader),
666 create_stream_callback));
576 if (mirroring_manager_) { 667 if (mirroring_manager_) {
577 mirroring_manager_->AddDiverter( 668 mirroring_manager_->AddDiverter(
578 render_process_id_, entry->render_frame_id(), entry->controller()); 669 render_process_id_, entry->render_frame_id(), entry->controller());
579 } 670 }
580 audio_entries_.insert(std::make_pair(stream_id, entry.release())); 671 audio_entries_.insert(std::make_pair(stream_id, entry.release()));
581 g_audio_streams_tracker.Get().IncreaseStreamCount(); 672 g_audio_streams_tracker.Get().IncreaseStreamCount();
582 673
583 audio_log_->OnCreated(stream_id, params, device_unique_id); 674 audio_log_->OnCreated(stream_id, params, device_unique_id);
584 MediaInternals::GetInstance()->SetWebContentsTitleForAudioLogEntry( 675 MediaInternals::GetInstance()->SetWebContentsTitleForAudioLogEntry(
585 stream_id, render_process_id_, render_frame_id, audio_log_.get()); 676 stream_id, render_process_id_, render_frame_id, audio_log_.get());
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
678 // is closed. 769 // is closed.
679 if (!LookupById(stream_id)) 770 if (!LookupById(stream_id))
680 return; 771 return;
681 772
682 SendErrorMessage(stream_id); 773 SendErrorMessage(stream_id);
683 774
684 audio_log_->OnError(stream_id); 775 audio_log_->OnError(stream_id);
685 OnCloseStream(stream_id); 776 OnCloseStream(stream_id);
686 } 777 }
687 778
779 void AudioRendererHost::ReportErrorAndCloseStream(
780 int stream_id,
781 const media::mojom::AudioOutput::CreateStreamCallback& callback) {
782 DCHECK_CURRENTLY_ON(BrowserThread::IO);
783
784 // Make sure this isn't a stray callback executing after the stream has been
785 // closed, so error notifications aren't sent after clients believe the stream
786 // is closed.
787 if (!LookupById(stream_id))
788 return;
789 mojo::ScopedSharedBufferHandle shared_buffer_handle =
790 mojo::ScopedSharedBufferHandle(mojo::SharedBufferHandle());
791
792 mojo::ScopedHandle socket_handle = mojo::ScopedHandle(mojo::Handle());
793
794 callback.Run(stream_id, media::mojom::AudioOutputStreamPtr(),
795 std::move(shared_buffer_handle), std::move(socket_handle));
796
797 audio_log_->OnError(stream_id);
798 OnCloseStream(stream_id);
799 }
800
688 AudioRendererHost::AudioEntry* AudioRendererHost::LookupById(int stream_id) { 801 AudioRendererHost::AudioEntry* AudioRendererHost::LookupById(int stream_id) {
689 DCHECK_CURRENTLY_ON(BrowserThread::IO); 802 DCHECK_CURRENTLY_ON(BrowserThread::IO);
690 803
691 AudioEntryMap::const_iterator i = audio_entries_.find(stream_id); 804 AudioEntryMap::const_iterator i = audio_entries_.find(stream_id);
692 return i != audio_entries_.end() ? i->second : NULL; 805 return i != audio_entries_.end() ? i->second : NULL;
693 } 806 }
694 807
695 void AudioRendererHost::UpdateNumPlayingStreams(AudioEntry* entry, 808 void AudioRendererHost::UpdateNumPlayingStreams(AudioEntry* entry,
696 bool is_playing) { 809 bool is_playing) {
697 DCHECK_CURRENTLY_ON(BrowserThread::IO); 810 DCHECK_CURRENTLY_ON(BrowserThread::IO);
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
808 callback.Run(false, device_info); 921 callback.Run(false, device_info);
809 } 922 }
810 923
811 bool AudioRendererHost::IsAuthorizationStarted(int stream_id) { 924 bool AudioRendererHost::IsAuthorizationStarted(int stream_id) {
812 DCHECK_CURRENTLY_ON(BrowserThread::IO); 925 DCHECK_CURRENTLY_ON(BrowserThread::IO);
813 const auto& i = authorizations_.find(stream_id); 926 const auto& i = authorizations_.find(stream_id);
814 return i != authorizations_.end(); 927 return i != authorizations_.end();
815 } 928 }
816 929
817 } // namespace content 930 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698