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

Side by Side Diff: content/renderer/media/audio_input_device.cc

Issue 10071038: RefCounted types should not have public destructors, content/browser part 2 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Copyright bump Created 8 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 | Annotate | Revision Log
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/renderer/media/audio_input_device.h" 5 #include "content/renderer/media/audio_input_device.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/message_loop.h" 8 #include "base/message_loop.h"
9 #include "base/threading/thread_restrictions.h" 9 #include "base/threading/thread_restrictions.h"
10 #include "base/time.h" 10 #include "base/time.h"
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 callback_(callback), 45 callback_(callback),
46 event_handler_(event_handler), 46 event_handler_(event_handler),
47 volume_(1.0), 47 volume_(1.0),
48 stream_id_(0), 48 stream_id_(0),
49 session_id_(0), 49 session_id_(0),
50 pending_device_ready_(false), 50 pending_device_ready_(false),
51 agc_is_enabled_(false) { 51 agc_is_enabled_(false) {
52 filter_ = RenderThreadImpl::current()->audio_input_message_filter(); 52 filter_ = RenderThreadImpl::current()->audio_input_message_filter();
53 } 53 }
54 54
55 AudioInputDevice::~AudioInputDevice() { 55 void AudioInputDevice::SetDevice(int session_id) {
56 // TODO(henrika): The current design requires that the user calls 56 DVLOG(1) << "SetDevice (session_id=" << session_id << ")";
57 // Stop before deleting this class. 57 message_loop()->PostTask(FROM_HERE,
58 CHECK_EQ(0, stream_id_); 58 base::Bind(&AudioInputDevice::SetSessionIdOnIOThread, this, session_id));
59 } 59 }
60 60
61 void AudioInputDevice::Start() { 61 void AudioInputDevice::Start() {
62 DVLOG(1) << "Start()"; 62 DVLOG(1) << "Start()";
63 message_loop()->PostTask(FROM_HERE, 63 message_loop()->PostTask(FROM_HERE,
64 base::Bind(&AudioInputDevice::InitializeOnIOThread, this)); 64 base::Bind(&AudioInputDevice::InitializeOnIOThread, this));
65 } 65 }
66 66
67 void AudioInputDevice::SetDevice(int session_id) {
68 DVLOG(1) << "SetDevice (session_id=" << session_id << ")";
69 message_loop()->PostTask(FROM_HERE,
70 base::Bind(&AudioInputDevice::SetSessionIdOnIOThread, this, session_id));
71 }
72
73 void AudioInputDevice::Stop() { 67 void AudioInputDevice::Stop() {
74 DVLOG(1) << "Stop()"; 68 DVLOG(1) << "Stop()";
75 69
76 { 70 {
77 base::AutoLock auto_lock(audio_thread_lock_); 71 base::AutoLock auto_lock(audio_thread_lock_);
78 audio_thread_.Stop(MessageLoop::current()); 72 audio_thread_.Stop(MessageLoop::current());
79 } 73 }
80 74
81 message_loop()->PostTask(FROM_HERE, 75 message_loop()->PostTask(FROM_HERE,
82 base::Bind(&AudioInputDevice::ShutDownOnIOThread, this)); 76 base::Bind(&AudioInputDevice::ShutDownOnIOThread, this));
(...skipping 14 matching lines...) Expand all
97 return false; 91 return false;
98 } 92 }
99 93
100 void AudioInputDevice::SetAutomaticGainControl(bool enabled) { 94 void AudioInputDevice::SetAutomaticGainControl(bool enabled) {
101 DVLOG(1) << "SetAutomaticGainControl(enabled=" << enabled << ")"; 95 DVLOG(1) << "SetAutomaticGainControl(enabled=" << enabled << ")";
102 message_loop()->PostTask(FROM_HERE, 96 message_loop()->PostTask(FROM_HERE,
103 base::Bind(&AudioInputDevice::SetAutomaticGainControlOnIOThread, 97 base::Bind(&AudioInputDevice::SetAutomaticGainControlOnIOThread,
104 this, enabled)); 98 this, enabled));
105 } 99 }
106 100
107 void AudioInputDevice::InitializeOnIOThread() {
108 DCHECK(message_loop()->BelongsToCurrentThread());
109 // Make sure we don't call Start() more than once.
110 DCHECK_EQ(0, stream_id_);
111 if (stream_id_)
112 return;
113
114 stream_id_ = filter_->AddDelegate(this);
115 // If |session_id_| is not specified, it will directly create the stream;
116 // otherwise it will send a AudioInputHostMsg_StartDevice msg to the browser
117 // and create the stream when getting a OnDeviceReady() callback.
118 if (!session_id_) {
119 Send(new AudioInputHostMsg_CreateStream(
120 stream_id_, audio_parameters_,
121 media::AudioManagerBase::kDefaultDeviceId,
122 agc_is_enabled_));
123 } else {
124 Send(new AudioInputHostMsg_StartDevice(stream_id_, session_id_));
125 pending_device_ready_ = true;
126 }
127 }
128
129 void AudioInputDevice::SetSessionIdOnIOThread(int session_id) {
130 DCHECK(message_loop()->BelongsToCurrentThread());
131 session_id_ = session_id;
132 }
133
134 void AudioInputDevice::StartOnIOThread() {
135 DCHECK(message_loop()->BelongsToCurrentThread());
136 if (stream_id_)
137 Send(new AudioInputHostMsg_RecordStream(stream_id_));
138 }
139
140 void AudioInputDevice::ShutDownOnIOThread() {
141 DCHECK(message_loop()->BelongsToCurrentThread());
142 // NOTE: |completion| may be NULL.
143 // Make sure we don't call shutdown more than once.
144 if (stream_id_) {
145 filter_->RemoveDelegate(stream_id_);
146 Send(new AudioInputHostMsg_CloseStream(stream_id_));
147
148 stream_id_ = 0;
149 session_id_ = 0;
150 pending_device_ready_ = false;
151 agc_is_enabled_ = false;
152 }
153
154 // We can run into an issue where ShutDownOnIOThread is called right after
155 // OnStreamCreated is called in cases where Start/Stop are called before we
156 // get the OnStreamCreated callback. To handle that corner case, we call
157 // Stop(). In most cases, the thread will already be stopped.
158 // Another situation is when the IO thread goes away before Stop() is called
159 // in which case, we cannot use the message loop to close the thread handle
160 // and can't not rely on the main thread existing either.
161 base::ThreadRestrictions::ScopedAllowIO allow_io;
162 audio_thread_.Stop(NULL);
163 audio_callback_.reset();
164 }
165
166 void AudioInputDevice::SetVolumeOnIOThread(double volume) {
167 DCHECK(message_loop()->BelongsToCurrentThread());
168 if (stream_id_)
169 Send(new AudioInputHostMsg_SetVolume(stream_id_, volume));
170 }
171
172 void AudioInputDevice::SetAutomaticGainControlOnIOThread(bool enabled) {
173 DCHECK(message_loop()->BelongsToCurrentThread());
174 DCHECK_EQ(0, stream_id_) <<
175 "The AGC state can not be modified while capturing is active.";
176 if (stream_id_)
177 return;
178
179 // We simply store the new AGC setting here. This value will be used when
180 // a new stream is initialized and by GetAutomaticGainControl().
181 agc_is_enabled_ = enabled;
182 }
183
184 void AudioInputDevice::OnStreamCreated( 101 void AudioInputDevice::OnStreamCreated(
185 base::SharedMemoryHandle handle, 102 base::SharedMemoryHandle handle,
186 base::SyncSocket::Handle socket_handle, 103 base::SyncSocket::Handle socket_handle,
187 uint32 length) { 104 uint32 length) {
188 DCHECK(message_loop()->BelongsToCurrentThread()); 105 DCHECK(message_loop()->BelongsToCurrentThread());
189 #if defined(OS_WIN) 106 #if defined(OS_WIN)
190 DCHECK(handle); 107 DCHECK(handle);
191 DCHECK(socket_handle); 108 DCHECK(socket_handle);
192 #else 109 #else
193 DCHECK_GE(handle.fd, 0); 110 DCHECK_GE(handle.fd, 0);
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 Send(new AudioInputHostMsg_CreateStream(stream_id_, audio_parameters_, 197 Send(new AudioInputHostMsg_CreateStream(stream_id_, audio_parameters_,
281 device_id, agc_is_enabled_)); 198 device_id, agc_is_enabled_));
282 } 199 }
283 200
284 pending_device_ready_ = false; 201 pending_device_ready_ = false;
285 // Notify the client that the device has been started. 202 // Notify the client that the device has been started.
286 if (event_handler_) 203 if (event_handler_)
287 event_handler_->OnDeviceStarted(device_id); 204 event_handler_->OnDeviceStarted(device_id);
288 } 205 }
289 206
207 AudioInputDevice::~AudioInputDevice() {
208 // TODO(henrika): The current design requires that the user calls
209 // Stop before deleting this class.
210 CHECK_EQ(0, stream_id_);
211 }
212
213 void AudioInputDevice::InitializeOnIOThread() {
214 DCHECK(message_loop()->BelongsToCurrentThread());
215 // Make sure we don't call Start() more than once.
216 DCHECK_EQ(0, stream_id_);
217 if (stream_id_)
218 return;
219
220 stream_id_ = filter_->AddDelegate(this);
221 // If |session_id_| is not specified, it will directly create the stream;
222 // otherwise it will send a AudioInputHostMsg_StartDevice msg to the browser
223 // and create the stream when getting a OnDeviceReady() callback.
224 if (!session_id_) {
225 Send(new AudioInputHostMsg_CreateStream(
226 stream_id_, audio_parameters_,
227 media::AudioManagerBase::kDefaultDeviceId,
228 agc_is_enabled_));
229 } else {
230 Send(new AudioInputHostMsg_StartDevice(stream_id_, session_id_));
231 pending_device_ready_ = true;
232 }
233 }
234
235 void AudioInputDevice::SetSessionIdOnIOThread(int session_id) {
236 DCHECK(message_loop()->BelongsToCurrentThread());
237 session_id_ = session_id;
238 }
239
240 void AudioInputDevice::StartOnIOThread() {
241 DCHECK(message_loop()->BelongsToCurrentThread());
242 if (stream_id_)
243 Send(new AudioInputHostMsg_RecordStream(stream_id_));
244 }
245
246 void AudioInputDevice::ShutDownOnIOThread() {
247 DCHECK(message_loop()->BelongsToCurrentThread());
248 // NOTE: |completion| may be NULL.
249 // Make sure we don't call shutdown more than once.
250 if (stream_id_) {
251 filter_->RemoveDelegate(stream_id_);
252 Send(new AudioInputHostMsg_CloseStream(stream_id_));
253
254 stream_id_ = 0;
255 session_id_ = 0;
256 pending_device_ready_ = false;
257 agc_is_enabled_ = false;
258 }
259
260 // We can run into an issue where ShutDownOnIOThread is called right after
261 // OnStreamCreated is called in cases where Start/Stop are called before we
262 // get the OnStreamCreated callback. To handle that corner case, we call
263 // Stop(). In most cases, the thread will already be stopped.
264 // Another situation is when the IO thread goes away before Stop() is called
265 // in which case, we cannot use the message loop to close the thread handle
266 // and can't not rely on the main thread existing either.
267 base::ThreadRestrictions::ScopedAllowIO allow_io;
268 audio_thread_.Stop(NULL);
269 audio_callback_.reset();
270 }
271
272 void AudioInputDevice::SetVolumeOnIOThread(double volume) {
273 DCHECK(message_loop()->BelongsToCurrentThread());
274 if (stream_id_)
275 Send(new AudioInputHostMsg_SetVolume(stream_id_, volume));
276 }
277
278 void AudioInputDevice::SetAutomaticGainControlOnIOThread(bool enabled) {
279 DCHECK(message_loop()->BelongsToCurrentThread());
280 DCHECK_EQ(0, stream_id_) <<
281 "The AGC state can not be modified while capturing is active.";
282 if (stream_id_)
283 return;
284
285 // We simply store the new AGC setting here. This value will be used when
286 // a new stream is initialized and by GetAutomaticGainControl().
287 agc_is_enabled_ = enabled;
288 }
289
290 void AudioInputDevice::Send(IPC::Message* message) { 290 void AudioInputDevice::Send(IPC::Message* message) {
291 filter_->Send(message); 291 filter_->Send(message);
292 } 292 }
293 293
294 void AudioInputDevice::WillDestroyCurrentMessageLoop() { 294 void AudioInputDevice::WillDestroyCurrentMessageLoop() {
295 LOG(ERROR) << "IO loop going away before the input device has been stopped"; 295 LOG(ERROR) << "IO loop going away before the input device has been stopped";
296 ShutDownOnIOThread(); 296 ShutDownOnIOThread();
297 } 297 }
298 298
299 // AudioInputDevice::AudioThreadCallback 299 // AudioInputDevice::AudioThreadCallback
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
338 channel_index, 338 channel_index,
339 bytes_per_sample, 339 bytes_per_sample,
340 number_of_frames); 340 number_of_frames);
341 } 341 }
342 342
343 // Deliver captured data to the client in floating point format 343 // Deliver captured data to the client in floating point format
344 // and update the audio-delay measurement. 344 // and update the audio-delay measurement.
345 capture_callback_->Capture(audio_data_, number_of_frames, 345 capture_callback_->Capture(audio_data_, number_of_frames,
346 audio_delay_milliseconds, volume); 346 audio_delay_milliseconds, volume);
347 } 347 }
OLDNEW
« no previous file with comments | « content/renderer/media/audio_input_device.h ('k') | content/renderer/media/audio_input_message_filter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698