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

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

Issue 2443573003: Factor out AudioOutputDelegate from AudioRendererHost. (Closed)
Patch Set: . Created 4 years, 1 month 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
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/browser/renderer_host/media/audio_output_delegate.h"
6
7 #include <utility>
8
9 #include "base/bind.h"
10 #include "content/browser/media/audio_stream_monitor.h"
11 #include "content/browser/media/media_internals.h"
12 #include "content/public/browser/browser_thread.h"
13
14 namespace content {
15
16 AudioOutputDelegate::AudioOutputDelegate(
17 EventHandler* handler,
18 media::AudioManager* audio_manager,
19 std::unique_ptr<media::AudioLog> audio_log,
20 int stream_id,
21 int render_frame_id,
22 int render_process_id,
23 const media::AudioParameters& params,
24 const std::string& output_device_id)
25 : handler_(handler),
26 audio_log_(std::move(audio_log)),
27 reader_(AudioSyncReader::Create(params)),
28 controller_(media::AudioOutputController::Create(audio_manager,
29 this,
30 params,
31 output_device_id,
32 reader_.get())),
33 stream_id_(stream_id),
34 render_frame_id_(render_frame_id),
35 render_process_id_(render_process_id),
36 weak_factory_(this) {
37 DCHECK(handler_);
38 DCHECK(audio_log_);
39 DCHECK(controller_);
40 audio_log_->OnCreated(stream_id, params, output_device_id);
41 }
42
43 AudioOutputDelegate::~AudioOutputDelegate() {
44 DCHECK_CURRENTLY_ON(BrowserThread::IO);
45 DCHECK(!playing_);
46 DCHECK(!handler_);
47 }
48
49 void AudioOutputDelegate::Deleter::operator()(AudioOutputDelegate* delegate) {
50 DCHECK_CURRENTLY_ON(BrowserThread::IO);
51 delegate->UpdatePlayingState(false);
52 delegate->handler_ = nullptr;
53 delegate->audio_log_->OnClosed(delegate->stream_id_);
54
55 scoped_refptr<media::AudioOutputController> controller =
56 delegate->controller_;
57
58 // |controller| will call the closure (on IO thread) when it's done closing,
59 // and it is only after that call that we can delete |delegate|. By giving the
60 // closure ownership of |delegate|, we keep delegate alive until |controller|
61 // is closed.
62 //
63 // The mirroring manager is a singleton, so Unretained is fine.
64 delegate->controller_->Close(base::Bind(
65 [](AudioOutputDelegate*, AudioMirroringManager* mirroring_manager,
66 scoped_refptr<media::AudioOutputController> controller) {
67 // De-register the controller from the AudioMirroringManager now that
68 // the controller has closed the AudioOutputStream and shut itself down.
69 // This ensures that calling RemoveDiverter() here won't trigger the
70 // controller to re-start the default AudioOutputStream and cause a
71 // brief audio blip to come out the user's speakers.
72 // http://crbug.com/474432
73 if (mirroring_manager)
o1ka 2016/11/22 21:48:16 We need more comments :) It's ok that RemoveDivert
Max Morin 2016/11/25 15:32:35 Done.
74 mirroring_manager->RemoveDiverter(controller.get());
75 },
76 base::Owned(delegate), base::Unretained(mirroring_manager_), controller));
77 }
78
79 // static
80 AudioOutputDelegate::UniquePtr AudioOutputDelegate::Create(
81 EventHandler* handler,
82 media::AudioManager* audio_manager,
83 std::unique_ptr<media::AudioLog> audio_log,
84 AudioMirroringManager* mirroring_manager,
85 MediaObserver* media_observer,
86 int stream_id,
87 int render_frame_id,
88 int render_process_id,
89 const media::AudioParameters& params,
90 const std::string& output_device_id) {
91 if (media_observer)
92 media_observer->OnCreatingAudioStream(render_process_id, render_frame_id);
93 UniquePtr delegate = UniquePtr(
94 new AudioOutputDelegate(handler, audio_manager, std::move(audio_log),
95 stream_id, render_frame_id, render_process_id,
96 params, output_device_id),
97 Deleter(mirroring_manager));
98 if (mirroring_manager)
99 mirroring_manager->AddDiverter(render_process_id, render_frame_id,
100 delegate->controller_.get());
101 return delegate;
102 }
103
104 void AudioOutputDelegate::OnPlayStream() {
105 DCHECK_CURRENTLY_ON(BrowserThread::IO);
106 controller_->Play();
107 audio_log_->OnStarted(stream_id_);
108 }
109
110 void AudioOutputDelegate::OnPauseStream() {
111 DCHECK_CURRENTLY_ON(BrowserThread::IO);
112 controller_->Pause();
113 audio_log_->OnStopped(stream_id_);
114 }
115
116 void AudioOutputDelegate::OnSetVolume(double volume) {
117 DCHECK_CURRENTLY_ON(BrowserThread::IO);
118 DCHECK(volume >= 0 || volume <= 1);
o1ka 2016/11/22 21:48:16 && ?
Max Morin 2016/11/25 15:32:35 Yes
119 controller_->SetVolume(volume);
120 audio_log_->OnSetVolume(stream_id_, volume);
121 }
122
123 void AudioOutputDelegate::OnControllerCreated() {
124 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
125 BrowserThread::PostTask(
126 BrowserThread::IO, FROM_HERE,
127 base::Bind(&AudioOutputDelegate::OnControllerCreated,
128 weak_factory_.GetWeakPtr()));
129 return;
130 }
131 if (!handler_)
132 return;
133
134 handler_->OnStreamCreated(stream_id_, reader_->shared_memory(),
135 reader_->foreign_socket());
136 }
137
138 void AudioOutputDelegate::OnControllerPlaying() {
139 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
140 BrowserThread::PostTask(
141 BrowserThread::IO, FROM_HERE,
142 base::Bind(&AudioOutputDelegate::OnControllerPlaying,
143 weak_factory_.GetWeakPtr()));
144 return;
145 }
146 if (!handler_)
147 return;
148
149 UpdatePlayingState(true);
150 }
151
152 void AudioOutputDelegate::OnControllerPaused() {
153 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
154 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
155 base::Bind(&AudioOutputDelegate::OnControllerPaused,
156 weak_factory_.GetWeakPtr()));
157 return;
158 }
159 if (!handler_)
160 return;
161
162 UpdatePlayingState(false);
163 }
164
165 void AudioOutputDelegate::OnControllerError() {
166 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
167 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
168 base::Bind(&AudioOutputDelegate::OnControllerError,
169 weak_factory_.GetWeakPtr()));
170 return;
171 }
172 audio_log_->OnError(stream_id_);
173
174 if (!handler_)
175 return;
176
177 handler_->OnStreamError(stream_id_);
178 }
179
180 void AudioOutputDelegate::UpdatePlayingState(bool playing) {
181 DCHECK_CURRENTLY_ON(BrowserThread::IO);
182 DCHECK(handler_);
183 if (playing != playing_) {
184 playing_ = playing;
185 handler_->OnStreamStateChanged(playing_);
186 if (playing) {
187 // Note that this takes a reference to |controller_|, and
188 // (Start|Stop)MonitoringStream calls are async, so we don't have a
189 // guarantee for when the controller is destroyed.
190 AudioStreamMonitor::StartMonitoringStream(
191 render_process_id_, render_frame_id_, stream_id_,
192 base::Bind(&media::AudioOutputController::ReadCurrentPowerAndClip,
193 controller_));
194 } else {
195 AudioStreamMonitor::StopMonitoringStream(render_process_id_,
196 render_frame_id_, stream_id_);
197 }
198 }
199 }
200
201 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698