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

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

Issue 2330393002: Change sync primitives ownership for audio rendering. (Closed)
Patch Set: Comments 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
« no previous file with comments | « no previous file | content/browser/renderer_host/media/audio_renderer_host_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/memory/ptr_util.h"
13 #include "base/memory/shared_memory.h" 14 #include "base/memory/shared_memory.h"
14 #include "base/metrics/histogram_macros.h" 15 #include "base/metrics/histogram_macros.h"
15 #include "base/process/process.h" 16 #include "base/process/process.h"
16 #include "content/browser/bad_message.h" 17 #include "content/browser/bad_message.h"
17 #include "content/browser/browser_main_loop.h" 18 #include "content/browser/browser_main_loop.h"
18 #include "content/browser/media/audio_stream_monitor.h" 19 #include "content/browser/media/audio_stream_monitor.h"
19 #include "content/browser/media/capture/audio_mirroring_manager.h" 20 #include "content/browser/media/capture/audio_mirroring_manager.h"
20 #include "content/browser/media/media_internals.h" 21 #include "content/browser/media/media_internals.h"
21 #include "content/browser/renderer_host/media/audio_input_device_manager.h" 22 #include "content/browser/renderer_host/media/audio_input_device_manager.h"
22 #include "content/browser/renderer_host/media/audio_sync_reader.h" 23 #include "content/browser/renderer_host/media/audio_sync_reader.h"
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 !!RenderFrameHost::FromID(render_process_id, render_frame_id); 128 !!RenderFrameHost::FromID(render_process_id, render_frame_id);
128 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, 129 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
129 base::Bind(callback, frame_exists)); 130 base::Bind(callback, frame_exists));
130 } 131 }
131 132
132 } // namespace 133 } // namespace
133 134
134 class AudioRendererHost::AudioEntry 135 class AudioRendererHost::AudioEntry
135 : public media::AudioOutputController::EventHandler { 136 : public media::AudioOutputController::EventHandler {
136 public: 137 public:
137 AudioEntry(AudioRendererHost* host,
138 int stream_id,
139 int render_frame_id,
140 const media::AudioParameters& params,
141 const std::string& output_device_id,
142 std::unique_ptr<base::SharedMemory> shared_memory,
143 std::unique_ptr<media::AudioOutputController::SyncReader> reader);
144 ~AudioEntry() override; 138 ~AudioEntry() override;
145 139
140 // Returns nullptr on failure.
141 static std::unique_ptr<AudioRendererHost::AudioEntry> Create(
142 AudioRendererHost* host,
143 int stream_id,
144 int render_frame_id,
145 const media::AudioParameters& params,
146 const std::string& output_device_id);
147
146 int stream_id() const { 148 int stream_id() const {
147 return stream_id_; 149 return stream_id_;
148 } 150 }
149 151
150 int render_frame_id() const { return render_frame_id_; } 152 int render_frame_id() const { return render_frame_id_; }
151 153
152 media::AudioOutputController* controller() const { return controller_.get(); } 154 media::AudioOutputController* controller() const { return controller_.get(); }
153 155
154 base::SharedMemory* shared_memory() { 156 AudioSyncReader* reader() const { return reader_.get(); }
155 return shared_memory_.get();
156 }
157 157
158 media::AudioOutputController::SyncReader* reader() const { 158 // Used by ARH to track the number of active streams for UMA stats.
159 return reader_.get();
160 }
161
162 bool playing() const { return playing_; } 159 bool playing() const { return playing_; }
163 void set_playing(bool playing) { playing_ = playing; } 160 void set_playing(bool playing) { playing_ = playing; }
164 161
165 private: 162 private:
163 AudioEntry(AudioRendererHost* host,
164 int stream_id,
165 int render_frame_id,
166 const media::AudioParameters& params,
167 const std::string& output_device_id,
168 std::unique_ptr<AudioSyncReader> reader);
169
166 // media::AudioOutputController::EventHandler implementation. 170 // media::AudioOutputController::EventHandler implementation.
167 void OnCreated() override; 171 void OnCreated() override;
168 void OnPlaying() override; 172 void OnPlaying() override;
169 void OnPaused() override; 173 void OnPaused() override;
170 void OnError() override; 174 void OnError() override;
171 175
172 AudioRendererHost* const host_; 176 AudioRendererHost* const host_;
173 const int stream_id_; 177 const int stream_id_;
174 178
175 // The routing ID of the source RenderFrame. 179 // The routing ID of the source RenderFrame.
176 const int render_frame_id_; 180 const int render_frame_id_;
177 181
178 // Shared memory for transmission of the audio data. Used by |reader_|.
179 const std::unique_ptr<base::SharedMemory> shared_memory_;
180
181 // The synchronous reader to be used by |controller_|. 182 // The synchronous reader to be used by |controller_|.
182 const std::unique_ptr<media::AudioOutputController::SyncReader> reader_; 183 const std::unique_ptr<AudioSyncReader> reader_;
183 184
184 // The AudioOutputController that manages the audio stream. 185 // The AudioOutputController that manages the audio stream.
185 const scoped_refptr<media::AudioOutputController> controller_; 186 const scoped_refptr<media::AudioOutputController> controller_;
186 187
187 bool playing_; 188 bool playing_;
189
190 DISALLOW_COPY_AND_ASSIGN(AudioEntry);
188 }; 191 };
189 192
190 AudioRendererHost::AudioEntry::AudioEntry( 193 AudioRendererHost::AudioEntry::AudioEntry(
191 AudioRendererHost* host, 194 AudioRendererHost* host,
192 int stream_id, 195 int stream_id,
193 int render_frame_id, 196 int render_frame_id,
194 const media::AudioParameters& params, 197 const media::AudioParameters& params,
195 const std::string& output_device_id, 198 const std::string& output_device_id,
196 std::unique_ptr<base::SharedMemory> shared_memory, 199 std::unique_ptr<AudioSyncReader> reader)
197 std::unique_ptr<media::AudioOutputController::SyncReader> reader)
198 : host_(host), 200 : host_(host),
199 stream_id_(stream_id), 201 stream_id_(stream_id),
200 render_frame_id_(render_frame_id), 202 render_frame_id_(render_frame_id),
201 shared_memory_(std::move(shared_memory)),
202 reader_(std::move(reader)), 203 reader_(std::move(reader)),
203 controller_(media::AudioOutputController::Create(host->audio_manager_, 204 controller_(media::AudioOutputController::Create(host->audio_manager_,
204 this, 205 this,
205 params, 206 params,
206 output_device_id, 207 output_device_id,
207 reader_.get())), 208 reader_.get())),
208 playing_(false) { 209 playing_(false) {
209 DCHECK(controller_.get()); 210 DCHECK(controller_);
210 } 211 }
211 212
212 AudioRendererHost::AudioEntry::~AudioEntry() {} 213 AudioRendererHost::AudioEntry::~AudioEntry() {}
213 214
215 // static
216 std::unique_ptr<AudioRendererHost::AudioEntry>
217 AudioRendererHost::AudioEntry::Create(AudioRendererHost* host,
218 int stream_id,
219 int render_frame_id,
220 const media::AudioParameters& params,
221 const std::string& output_device_id) {
222 std::unique_ptr<AudioSyncReader> reader(AudioSyncReader::Create(params));
223 if (!reader) {
224 return nullptr;
225 }
226 return base::WrapUnique(new AudioEntry(host, stream_id, render_frame_id,
227 params, output_device_id,
228 std::move(reader)));
229 }
230
214 /////////////////////////////////////////////////////////////////////////////// 231 ///////////////////////////////////////////////////////////////////////////////
215 // AudioRendererHost implementations. 232 // AudioRendererHost implementations.
216 233
217 AudioRendererHost::AudioRendererHost(int render_process_id, 234 AudioRendererHost::AudioRendererHost(int render_process_id,
218 media::AudioManager* audio_manager, 235 media::AudioManager* audio_manager,
219 AudioMirroringManager* mirroring_manager, 236 AudioMirroringManager* mirroring_manager,
220 MediaInternals* media_internals, 237 MediaInternals* media_internals,
221 MediaStreamManager* media_stream_manager, 238 MediaStreamManager* media_stream_manager,
222 const std::string& salt) 239 const std::string& salt)
223 : BrowserMessageFilter(AudioMsgStart), 240 : BrowserMessageFilter(AudioMsgStart),
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
319 ReportErrorAndClose(stream_id); 336 ReportErrorAndClose(stream_id);
320 return; 337 return;
321 } 338 }
322 339
323 AudioEntry* const entry = LookupById(stream_id); 340 AudioEntry* const entry = LookupById(stream_id);
324 if (!entry) { 341 if (!entry) {
325 ReportErrorAndClose(stream_id); 342 ReportErrorAndClose(stream_id);
326 return; 343 return;
327 } 344 }
328 345
329 // Once the audio stream is created then complete the creation process by 346 // Now construction is done and we are ready to send the shared memory and the
330 // mapping shared memory and sharing with the renderer process. 347 // sync socket to the renderer.
348 base::SharedMemory* shared_memory = entry->reader()->shared_memory();
349 base::CancelableSyncSocket* foreign_socket =
350 entry->reader()->foreign_socket();
351
331 base::SharedMemoryHandle foreign_memory_handle; 352 base::SharedMemoryHandle foreign_memory_handle;
332 if (!entry->shared_memory()->ShareToProcess(PeerHandle(), 353 base::SyncSocket::TransitDescriptor socket_descriptor;
333 &foreign_memory_handle)) { 354 size_t shared_memory_size = shared_memory->requested_size();
334 // If we failed to map and share the shared memory then close the audio
335 // stream and send an error message.
336 ReportErrorAndClose(entry->stream_id());
337 return;
338 }
339 355
340 AudioSyncReader* reader = static_cast<AudioSyncReader*>(entry->reader()); 356 if (!(shared_memory->ShareToProcess(PeerHandle(), &foreign_memory_handle) &&
341 357 foreign_socket->PrepareTransitDescriptor(PeerHandle(),
342 base::SyncSocket::TransitDescriptor socket_descriptor; 358 &socket_descriptor))) {
343 359 // Something went wrong in preparing the IPC handles.
344 // If we failed to prepare the sync socket for the renderer then we fail
345 // the construction of audio stream.
346 if (!reader->PrepareForeignSocket(PeerHandle(), &socket_descriptor)) {
347 ReportErrorAndClose(entry->stream_id()); 360 ReportErrorAndClose(entry->stream_id());
348 return; 361 return;
349 } 362 }
350 363
351 Send(new AudioMsg_NotifyStreamCreated( 364 Send(new AudioMsg_NotifyStreamCreated(
352 entry->stream_id(), foreign_memory_handle, socket_descriptor, 365 stream_id, foreign_memory_handle, socket_descriptor,
353 entry->shared_memory()->requested_size())); 366 base::checked_cast<uint32_t>(shared_memory_size)));
354 } 367 }
355 368
356 void AudioRendererHost::DidValidateRenderFrame(int stream_id, bool is_valid) { 369 void AudioRendererHost::DidValidateRenderFrame(int stream_id, bool is_valid) {
357 DCHECK_CURRENTLY_ON(BrowserThread::IO); 370 DCHECK_CURRENTLY_ON(BrowserThread::IO);
358 371
359 if (!is_valid) { 372 if (!is_valid) {
360 DLOG(WARNING) << "Render frame for stream (id=" << stream_id 373 DLOG(WARNING) << "Render frame for stream (id=" << stream_id
361 << ") no longer exists."; 374 << ") no longer exists.";
362 ReportErrorAndClose(stream_id); 375 ReportErrorAndClose(stream_id);
363 } 376 }
364 } 377 }
365 378
366 void AudioRendererHost::DoNotifyStreamStateChanged(int stream_id, 379 void AudioRendererHost::DoNotifyStreamStateChanged(int stream_id,
367 bool is_playing) { 380 bool is_playing) {
368 DCHECK_CURRENTLY_ON(BrowserThread::IO); 381 DCHECK_CURRENTLY_ON(BrowserThread::IO);
369 382
370 AudioEntry* const entry = LookupById(stream_id); 383 AudioEntry* const entry = LookupById(stream_id);
371 if (!entry) 384 if (!entry)
372 return; 385 return;
373 386
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
601 // a valid render frame. This validation is important for all the reasons 614 // a valid render frame. This validation is important for all the reasons
602 // stated in the comments above. This does not block stream creation, but will 615 // stated in the comments above. This does not block stream creation, but will
603 // force-close the stream later if validation fails. 616 // force-close the stream later if validation fails.
604 BrowserThread::PostTask( 617 BrowserThread::PostTask(
605 BrowserThread::UI, FROM_HERE, 618 BrowserThread::UI, FROM_HERE,
606 base::Bind(validate_render_frame_id_function_, render_process_id_, 619 base::Bind(validate_render_frame_id_function_, render_process_id_,
607 render_frame_id, 620 render_frame_id,
608 base::Bind(&AudioRendererHost::DidValidateRenderFrame, this, 621 base::Bind(&AudioRendererHost::DidValidateRenderFrame, this,
609 stream_id))); 622 stream_id)));
610 623
611 // Create the shared memory and share with the renderer process. 624 std::unique_ptr<AudioEntry> entry = AudioEntry::Create(
612 uint32_t shared_memory_size = sizeof(media::AudioOutputBufferParameters) + 625 this, stream_id, render_frame_id, params, device_unique_id);
613 AudioBus::CalculateMemorySize(params); 626 if (!entry) {
614 std::unique_ptr<base::SharedMemory> shared_memory(new base::SharedMemory());
615 if (!shared_memory->CreateAndMapAnonymous(shared_memory_size)) {
616 SendErrorMessage(stream_id); 627 SendErrorMessage(stream_id);
617 return; 628 return;
618 } 629 }
619
620 std::unique_ptr<AudioSyncReader> reader(
621 new AudioSyncReader(shared_memory.get(), params));
622 if (!reader->Init()) {
623 SendErrorMessage(stream_id);
624 return;
625 }
626 630
627 MediaObserver* const media_observer = 631 MediaObserver* const media_observer =
628 GetContentClient()->browser()->GetMediaObserver(); 632 GetContentClient()->browser()->GetMediaObserver();
629 if (media_observer) 633 if (media_observer)
630 media_observer->OnCreatingAudioStream(render_process_id_, render_frame_id); 634 media_observer->OnCreatingAudioStream(render_process_id_, render_frame_id);
631 635
632 std::unique_ptr<AudioEntry> entry(
633 new AudioEntry(this, stream_id, render_frame_id, params, device_unique_id,
634 std::move(shared_memory), std::move(reader)));
635 if (mirroring_manager_) { 636 if (mirroring_manager_) {
636 mirroring_manager_->AddDiverter( 637 mirroring_manager_->AddDiverter(
637 render_process_id_, entry->render_frame_id(), entry->controller()); 638 render_process_id_, entry->render_frame_id(), entry->controller());
638 } 639 }
639 audio_entries_.insert(std::make_pair(stream_id, entry.release())); 640 audio_entries_.insert(std::make_pair(stream_id, entry.release()));
640 g_audio_streams_tracker.Get().IncreaseStreamCount(); 641 g_audio_streams_tracker.Get().IncreaseStreamCount();
641 642
642 audio_log_->OnCreated(stream_id, params, device_unique_id); 643 audio_log_->OnCreated(stream_id, params, device_unique_id);
643 MediaInternals::GetInstance()->SetWebContentsTitleForAudioLogEntry( 644 MediaInternals::GetInstance()->SetWebContentsTitleForAudioLogEntry(
644 stream_id, render_process_id_, render_frame_id, audio_log_.get()); 645 stream_id, render_process_id_, render_frame_id, audio_log_.get());
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
855 callback.Run(false, device_info); 856 callback.Run(false, device_info);
856 } 857 }
857 858
858 bool AudioRendererHost::IsAuthorizationStarted(int stream_id) { 859 bool AudioRendererHost::IsAuthorizationStarted(int stream_id) {
859 DCHECK_CURRENTLY_ON(BrowserThread::IO); 860 DCHECK_CURRENTLY_ON(BrowserThread::IO);
860 const auto& i = authorizations_.find(stream_id); 861 const auto& i = authorizations_.find(stream_id);
861 return i != authorizations_.end(); 862 return i != authorizations_.end();
862 } 863 }
863 864
864 } // namespace content 865 } // namespace content
OLDNEW
« no previous file with comments | « no previous file | content/browser/renderer_host/media/audio_renderer_host_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698