OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "base/metrics/histogram.h" | 7 #include "base/metrics/histogram.h" |
8 #include "base/process.h" | 8 #include "base/process.h" |
9 #include "base/shared_memory.h" | 9 #include "base/shared_memory.h" |
10 #include "content/browser/renderer_host/media/audio_common.h" | 10 #include "content/browser/renderer_host/media/audio_common.h" |
11 #include "content/browser/renderer_host/media/audio_sync_reader.h" | 11 #include "content/browser/renderer_host/media/audio_sync_reader.h" |
12 #include "content/common/media/audio_messages.h" | 12 #include "content/common/media/audio_messages.h" |
13 #include "ipc/ipc_logging.h" | 13 #include "ipc/ipc_logging.h" |
14 | 14 |
15 | 15 |
16 AudioRendererHost::AudioEntry::AudioEntry() | 16 AudioRendererHost::AudioEntry::AudioEntry() |
17 : render_view_id(0), | 17 : stream_id(0), |
18 stream_id(0), | |
19 pending_buffer_request(false), | 18 pending_buffer_request(false), |
20 pending_close(false) { | 19 pending_close(false) { |
21 } | 20 } |
22 | 21 |
23 AudioRendererHost::AudioEntry::~AudioEntry() {} | 22 AudioRendererHost::AudioEntry::~AudioEntry() {} |
24 | 23 |
25 /////////////////////////////////////////////////////////////////////////////// | |
26 // AudioRendererHost implementations. | |
27 AudioRendererHost::AudioRendererHost() { | 24 AudioRendererHost::AudioRendererHost() { |
28 } | 25 } |
29 | 26 |
30 AudioRendererHost::~AudioRendererHost() { | 27 AudioRendererHost::~AudioRendererHost() { |
31 DCHECK(audio_entries_.empty()); | 28 DCHECK(audio_entries_.empty()); |
32 } | 29 } |
33 | 30 |
34 void AudioRendererHost::OnChannelClosing() { | 31 void AudioRendererHost::OnChannelClosing() { |
35 BrowserMessageFilter::OnChannelClosing(); | 32 BrowserMessageFilter::OnChannelClosing(); |
36 | 33 |
37 // Since the IPC channel is gone, close all requested audio streams. | 34 // Since the IPC channel is gone, close all requested audio streams. |
38 DeleteEntries(); | 35 DeleteEntries(); |
39 } | 36 } |
40 | 37 |
41 void AudioRendererHost::OnDestruct() const { | 38 void AudioRendererHost::OnDestruct() const { |
42 BrowserThread::DeleteOnIOThread::Destruct(this); | 39 BrowserThread::DeleteOnIOThread::Destruct(this); |
43 } | 40 } |
44 | 41 |
45 /////////////////////////////////////////////////////////////////////////////// | |
46 // media::AudioOutputController::EventHandler implementations. | |
47 void AudioRendererHost::OnCreated(media::AudioOutputController* controller) { | 42 void AudioRendererHost::OnCreated(media::AudioOutputController* controller) { |
48 BrowserThread::PostTask( | 43 BrowserThread::PostTask( |
49 BrowserThread::IO, | 44 BrowserThread::IO, |
50 FROM_HERE, | 45 FROM_HERE, |
51 NewRunnableMethod( | 46 NewRunnableMethod( |
52 this, | 47 this, |
53 &AudioRendererHost::DoCompleteCreation, | 48 &AudioRendererHost::DoCompleteCreation, |
54 make_scoped_refptr(controller))); | 49 make_scoped_refptr(controller))); |
55 } | 50 } |
56 | 51 |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
133 | 128 |
134 // If we failed to prepare the sync socket for the renderer then we fail | 129 // If we failed to prepare the sync socket for the renderer then we fail |
135 // the construction of audio stream. | 130 // the construction of audio stream. |
136 if (!reader->PrepareForeignSocketHandle(peer_handle(), | 131 if (!reader->PrepareForeignSocketHandle(peer_handle(), |
137 &foreign_socket_handle)) { | 132 &foreign_socket_handle)) { |
138 DeleteEntryOnError(entry); | 133 DeleteEntryOnError(entry); |
139 return; | 134 return; |
140 } | 135 } |
141 | 136 |
142 Send(new AudioMsg_NotifyLowLatencyStreamCreated( | 137 Send(new AudioMsg_NotifyLowLatencyStreamCreated( |
143 entry->render_view_id, entry->stream_id, foreign_memory_handle, | 138 entry->stream_id, foreign_memory_handle, |
144 foreign_socket_handle, entry->shared_memory.created_size())); | 139 foreign_socket_handle, entry->shared_memory.created_size())); |
145 return; | 140 return; |
146 } | 141 } |
147 | 142 |
148 // The normal audio stream has created, send a message to the renderer | 143 // The normal audio stream has created, send a message to the renderer |
149 // process. | 144 // process. |
150 Send(new AudioMsg_NotifyStreamCreated( | 145 Send(new AudioMsg_NotifyStreamCreated( |
151 entry->render_view_id, entry->stream_id, foreign_memory_handle, | 146 entry->stream_id, foreign_memory_handle, |
152 entry->shared_memory.created_size())); | 147 entry->shared_memory.created_size())); |
153 } | 148 } |
154 | 149 |
155 void AudioRendererHost::DoSendPlayingMessage( | 150 void AudioRendererHost::DoSendPlayingMessage( |
156 media::AudioOutputController* controller) { | 151 media::AudioOutputController* controller) { |
157 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 152 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
158 | 153 |
159 AudioEntry* entry = LookupByController(controller); | 154 AudioEntry* entry = LookupByController(controller); |
160 if (!entry) | 155 if (!entry) |
161 return; | 156 return; |
162 | 157 |
163 Send(new AudioMsg_NotifyStreamStateChanged( | 158 Send(new AudioMsg_NotifyStreamStateChanged( |
164 entry->render_view_id, entry->stream_id, kAudioStreamPlaying)); | 159 entry->stream_id, kAudioStreamPlaying)); |
165 } | 160 } |
166 | 161 |
167 void AudioRendererHost::DoSendPausedMessage( | 162 void AudioRendererHost::DoSendPausedMessage( |
168 media::AudioOutputController* controller) { | 163 media::AudioOutputController* controller) { |
169 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 164 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
170 | 165 |
171 AudioEntry* entry = LookupByController(controller); | 166 AudioEntry* entry = LookupByController(controller); |
172 if (!entry) | 167 if (!entry) |
173 return; | 168 return; |
174 | 169 |
175 Send(new AudioMsg_NotifyStreamStateChanged( | 170 Send(new AudioMsg_NotifyStreamStateChanged( |
176 entry->render_view_id, entry->stream_id, kAudioStreamPaused)); | 171 entry->stream_id, kAudioStreamPaused)); |
177 } | 172 } |
178 | 173 |
179 void AudioRendererHost::DoRequestMoreData( | 174 void AudioRendererHost::DoRequestMoreData( |
180 media::AudioOutputController* controller, | 175 media::AudioOutputController* controller, |
181 AudioBuffersState buffers_state) { | 176 AudioBuffersState buffers_state) { |
182 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 177 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
183 | 178 |
184 // If we already have a pending request then return. | 179 // If we already have a pending request then return. |
185 AudioEntry* entry = LookupByController(controller); | 180 AudioEntry* entry = LookupByController(controller); |
186 if (!entry || entry->pending_buffer_request) | 181 if (!entry || entry->pending_buffer_request) |
187 return; | 182 return; |
188 | 183 |
189 DCHECK(!entry->controller->LowLatencyMode()); | 184 DCHECK(!entry->controller->LowLatencyMode()); |
190 entry->pending_buffer_request = true; | 185 entry->pending_buffer_request = true; |
191 Send(new AudioMsg_RequestPacket( | 186 Send(new AudioMsg_RequestPacket(entry->stream_id, buffers_state)); |
192 entry->render_view_id, entry->stream_id, buffers_state)); | |
193 } | 187 } |
194 | 188 |
195 void AudioRendererHost::DoHandleError(media::AudioOutputController* controller, | 189 void AudioRendererHost::DoHandleError(media::AudioOutputController* controller, |
196 int error_code) { | 190 int error_code) { |
197 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 191 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
198 | 192 |
199 AudioEntry* entry = LookupByController(controller); | 193 AudioEntry* entry = LookupByController(controller); |
200 if (!entry) | 194 if (!entry) |
201 return; | 195 return; |
202 | 196 |
203 DeleteEntryOnError(entry); | 197 DeleteEntryOnError(entry); |
204 } | 198 } |
205 | 199 |
206 /////////////////////////////////////////////////////////////////////////////// | |
207 // IPC Messages handler | |
208 bool AudioRendererHost::OnMessageReceived(const IPC::Message& message, | 200 bool AudioRendererHost::OnMessageReceived(const IPC::Message& message, |
209 bool* message_was_ok) { | 201 bool* message_was_ok) { |
210 bool handled = true; | 202 bool handled = true; |
211 IPC_BEGIN_MESSAGE_MAP_EX(AudioRendererHost, message, *message_was_ok) | 203 IPC_BEGIN_MESSAGE_MAP_EX(AudioRendererHost, message, *message_was_ok) |
212 IPC_MESSAGE_HANDLER(AudioHostMsg_CreateStream, OnCreateStream) | 204 IPC_MESSAGE_HANDLER(AudioHostMsg_CreateStream, OnCreateStream) |
213 IPC_MESSAGE_HANDLER(AudioHostMsg_PlayStream, OnPlayStream) | 205 IPC_MESSAGE_HANDLER(AudioHostMsg_PlayStream, OnPlayStream) |
214 IPC_MESSAGE_HANDLER(AudioHostMsg_PauseStream, OnPauseStream) | 206 IPC_MESSAGE_HANDLER(AudioHostMsg_PauseStream, OnPauseStream) |
215 IPC_MESSAGE_HANDLER(AudioHostMsg_FlushStream, OnFlushStream) | 207 IPC_MESSAGE_HANDLER(AudioHostMsg_FlushStream, OnFlushStream) |
216 IPC_MESSAGE_HANDLER(AudioHostMsg_CloseStream, OnCloseStream) | 208 IPC_MESSAGE_HANDLER(AudioHostMsg_CloseStream, OnCloseStream) |
217 IPC_MESSAGE_HANDLER(AudioHostMsg_NotifyPacketReady, OnNotifyPacketReady) | 209 IPC_MESSAGE_HANDLER(AudioHostMsg_NotifyPacketReady, OnNotifyPacketReady) |
218 IPC_MESSAGE_HANDLER(AudioHostMsg_GetVolume, OnGetVolume) | 210 IPC_MESSAGE_HANDLER(AudioHostMsg_GetVolume, OnGetVolume) |
219 IPC_MESSAGE_HANDLER(AudioHostMsg_SetVolume, OnSetVolume) | 211 IPC_MESSAGE_HANDLER(AudioHostMsg_SetVolume, OnSetVolume) |
220 IPC_MESSAGE_UNHANDLED(handled = false) | 212 IPC_MESSAGE_UNHANDLED(handled = false) |
221 IPC_END_MESSAGE_MAP_EX() | 213 IPC_END_MESSAGE_MAP_EX() |
222 | 214 |
223 return handled; | 215 return handled; |
224 } | 216 } |
225 | 217 |
226 void AudioRendererHost::OnCreateStream( | 218 void AudioRendererHost::OnCreateStream( |
227 const IPC::Message& msg, int stream_id, | 219 int stream_id, const AudioParameters& params, bool low_latency) { |
228 const AudioParameters& params, bool low_latency) { | |
229 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 220 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
230 DCHECK(LookupById(msg.routing_id(), stream_id) == NULL); | 221 DCHECK(LookupById(stream_id) == NULL); |
231 | 222 |
232 AudioParameters audio_params(params); | 223 AudioParameters audio_params(params); |
233 | 224 |
234 // Select the hardware packet size if not specified. | 225 // Select the hardware packet size if not specified. |
235 if (!audio_params.samples_per_packet) { | 226 if (!audio_params.samples_per_packet) { |
236 audio_params.samples_per_packet = SelectSamplesPerPacket(audio_params); | 227 audio_params.samples_per_packet = SelectSamplesPerPacket(audio_params); |
237 } | 228 } |
238 uint32 packet_size = audio_params.GetPacketSize(); | 229 uint32 packet_size = audio_params.GetPacketSize(); |
239 | 230 |
240 scoped_ptr<AudioEntry> entry(new AudioEntry()); | 231 scoped_ptr<AudioEntry> entry(new AudioEntry()); |
241 // Create the shared memory and share with the renderer process. | 232 // Create the shared memory and share with the renderer process. |
242 if (!entry->shared_memory.CreateAndMapAnonymous(packet_size)) { | 233 if (!entry->shared_memory.CreateAndMapAnonymous(packet_size)) { |
243 // If creation of shared memory failed then send an error message. | 234 // If creation of shared memory failed then send an error message. |
244 SendErrorMessage(msg.routing_id(), stream_id); | 235 SendErrorMessage(stream_id); |
245 return; | 236 return; |
246 } | 237 } |
247 | 238 |
248 if (low_latency) { | 239 if (low_latency) { |
249 // If this is the low latency mode, we need to construct a SyncReader first. | 240 // If this is the low latency mode, we need to construct a SyncReader first. |
250 scoped_ptr<AudioSyncReader> reader( | 241 scoped_ptr<AudioSyncReader> reader( |
251 new AudioSyncReader(&entry->shared_memory)); | 242 new AudioSyncReader(&entry->shared_memory)); |
252 | 243 |
253 // Then try to initialize the sync reader. | 244 // Then try to initialize the sync reader. |
254 if (!reader->Init()) { | 245 if (!reader->Init()) { |
255 SendErrorMessage(msg.routing_id(), stream_id); | 246 SendErrorMessage(stream_id); |
256 return; | 247 return; |
257 } | 248 } |
258 | 249 |
259 // If we have successfully created the SyncReader then assign it to the | 250 // If we have successfully created the SyncReader then assign it to the |
260 // entry and construct an AudioOutputController. | 251 // entry and construct an AudioOutputController. |
261 entry->reader.reset(reader.release()); | 252 entry->reader.reset(reader.release()); |
262 entry->controller = | 253 entry->controller = |
263 media::AudioOutputController::CreateLowLatency(this, audio_params, | 254 media::AudioOutputController::CreateLowLatency(this, audio_params, |
264 entry->reader.get()); | 255 entry->reader.get()); |
265 } else { | 256 } else { |
266 // The choice of buffer capacity is based on experiment. | 257 // The choice of buffer capacity is based on experiment. |
267 entry->controller = | 258 entry->controller = |
268 media::AudioOutputController::Create(this, audio_params, | 259 media::AudioOutputController::Create(this, audio_params, |
269 3 * packet_size); | 260 3 * packet_size); |
270 } | 261 } |
271 | 262 |
272 if (!entry->controller) { | 263 if (!entry->controller) { |
273 SendErrorMessage(msg.routing_id(), stream_id); | 264 SendErrorMessage(stream_id); |
274 return; | 265 return; |
275 } | 266 } |
276 | 267 |
277 // If we have created the controller successfully create a entry and add it | 268 // If we have created the controller successfully create a entry and add it |
278 // to the map. | 269 // to the map. |
279 entry->render_view_id = msg.routing_id(); | |
280 entry->stream_id = stream_id; | 270 entry->stream_id = stream_id; |
281 | 271 audio_entries_.insert(std::make_pair(stream_id, entry.release())); |
282 audio_entries_.insert(std::make_pair( | |
283 AudioEntryId(msg.routing_id(), stream_id), | |
284 entry.release())); | |
285 } | 272 } |
286 | 273 |
287 void AudioRendererHost::OnPlayStream(const IPC::Message& msg, int stream_id) { | 274 void AudioRendererHost::OnPlayStream(int stream_id) { |
288 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 275 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
289 | 276 |
290 AudioEntry* entry = LookupById(msg.routing_id(), stream_id); | 277 AudioEntry* entry = LookupById(stream_id); |
291 if (!entry) { | 278 if (!entry) { |
292 SendErrorMessage(msg.routing_id(), stream_id); | 279 SendErrorMessage(stream_id); |
293 return; | 280 return; |
294 } | 281 } |
295 | 282 |
296 entry->controller->Play(); | 283 entry->controller->Play(); |
297 } | 284 } |
298 | 285 |
299 void AudioRendererHost::OnPauseStream(const IPC::Message& msg, int stream_id) { | 286 void AudioRendererHost::OnPauseStream(int stream_id) { |
300 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 287 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
301 | 288 |
302 AudioEntry* entry = LookupById(msg.routing_id(), stream_id); | 289 AudioEntry* entry = LookupById(stream_id); |
303 if (!entry) { | 290 if (!entry) { |
304 SendErrorMessage(msg.routing_id(), stream_id); | 291 SendErrorMessage(stream_id); |
305 return; | 292 return; |
306 } | 293 } |
307 | 294 |
308 entry->controller->Pause(); | 295 entry->controller->Pause(); |
309 } | 296 } |
310 | 297 |
311 void AudioRendererHost::OnFlushStream(const IPC::Message& msg, int stream_id) { | 298 void AudioRendererHost::OnFlushStream(int stream_id) { |
312 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 299 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
313 | 300 |
314 AudioEntry* entry = LookupById(msg.routing_id(), stream_id); | 301 AudioEntry* entry = LookupById(stream_id); |
315 if (!entry) { | 302 if (!entry) { |
316 SendErrorMessage(msg.routing_id(), stream_id); | 303 SendErrorMessage(stream_id); |
317 return; | 304 return; |
318 } | 305 } |
319 | 306 |
320 entry->controller->Flush(); | 307 entry->controller->Flush(); |
321 } | 308 } |
322 | 309 |
323 void AudioRendererHost::OnCloseStream(const IPC::Message& msg, int stream_id) { | 310 void AudioRendererHost::OnCloseStream(int stream_id) { |
324 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 311 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
325 | 312 |
326 AudioEntry* entry = LookupById(msg.routing_id(), stream_id); | 313 AudioEntry* entry = LookupById(stream_id); |
327 | 314 |
328 if (entry) | 315 if (entry) |
329 CloseAndDeleteStream(entry); | 316 CloseAndDeleteStream(entry); |
330 } | 317 } |
331 | 318 |
332 void AudioRendererHost::OnSetVolume(const IPC::Message& msg, int stream_id, | 319 void AudioRendererHost::OnSetVolume(int stream_id, |
333 double volume) { | 320 double volume) { |
334 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 321 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
335 | 322 |
336 AudioEntry* entry = LookupById(msg.routing_id(), stream_id); | 323 AudioEntry* entry = LookupById(stream_id); |
337 if (!entry) { | 324 if (!entry) { |
338 SendErrorMessage(msg.routing_id(), stream_id); | 325 SendErrorMessage(stream_id); |
339 return; | 326 return; |
340 } | 327 } |
341 | 328 |
342 // Make sure the volume is valid. | 329 // Make sure the volume is valid. |
343 if (volume < 0 || volume > 1.0) | 330 if (volume < 0 || volume > 1.0) |
344 return; | 331 return; |
345 entry->controller->SetVolume(volume); | 332 entry->controller->SetVolume(volume); |
346 } | 333 } |
347 | 334 |
348 void AudioRendererHost::OnGetVolume(const IPC::Message& msg, int stream_id) { | 335 void AudioRendererHost::OnGetVolume(int stream_id) { |
349 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 336 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
350 NOTREACHED() << "This message shouldn't be received"; | 337 NOTREACHED() << "This message shouldn't be received"; |
351 } | 338 } |
352 | 339 |
353 void AudioRendererHost::OnNotifyPacketReady( | 340 void AudioRendererHost::OnNotifyPacketReady(int stream_id, uint32 packet_size) { |
354 const IPC::Message& msg, int stream_id, uint32 packet_size) { | |
355 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 341 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
356 | 342 |
357 AudioEntry* entry = LookupById(msg.routing_id(), stream_id); | 343 AudioEntry* entry = LookupById(stream_id); |
358 if (!entry) { | 344 if (!entry) { |
359 SendErrorMessage(msg.routing_id(), stream_id); | 345 SendErrorMessage(stream_id); |
360 return; | 346 return; |
361 } | 347 } |
362 | 348 |
363 DCHECK(!entry->controller->LowLatencyMode()); | 349 DCHECK(!entry->controller->LowLatencyMode()); |
364 CHECK(packet_size <= entry->shared_memory.created_size()); | 350 CHECK(packet_size <= entry->shared_memory.created_size()); |
365 | 351 |
366 if (!entry->pending_buffer_request) { | 352 if (!entry->pending_buffer_request) { |
367 NOTREACHED() << "Buffer received but no such pending request"; | 353 NOTREACHED() << "Buffer received but no such pending request"; |
368 } | 354 } |
369 entry->pending_buffer_request = false; | 355 entry->pending_buffer_request = false; |
370 | 356 |
371 // Enqueue the data to media::AudioOutputController. | 357 // Enqueue the data to media::AudioOutputController. |
372 entry->controller->EnqueueData( | 358 entry->controller->EnqueueData( |
373 reinterpret_cast<uint8*>(entry->shared_memory.memory()), | 359 reinterpret_cast<uint8*>(entry->shared_memory.memory()), |
374 packet_size); | 360 packet_size); |
375 } | 361 } |
376 | 362 |
377 void AudioRendererHost::SendErrorMessage(int32 render_view_id, | 363 void AudioRendererHost::SendErrorMessage(int32 stream_id) { |
378 int32 stream_id) { | |
379 Send(new AudioMsg_NotifyStreamStateChanged( | 364 Send(new AudioMsg_NotifyStreamStateChanged( |
380 render_view_id, stream_id, kAudioStreamError)); | 365 stream_id, kAudioStreamError)); |
381 } | 366 } |
382 | 367 |
383 void AudioRendererHost::DeleteEntries() { | 368 void AudioRendererHost::DeleteEntries() { |
384 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 369 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
385 | 370 |
386 for (AudioEntryMap::iterator i = audio_entries_.begin(); | 371 for (AudioEntryMap::iterator i = audio_entries_.begin(); |
387 i != audio_entries_.end(); ++i) { | 372 i != audio_entries_.end(); ++i) { |
388 CloseAndDeleteStream(i->second); | 373 CloseAndDeleteStream(i->second); |
389 } | 374 } |
390 } | 375 } |
(...skipping 12 matching lines...) Expand all Loading... |
403 BrowserThread::IO, FROM_HERE, | 388 BrowserThread::IO, FROM_HERE, |
404 NewRunnableMethod(this, &AudioRendererHost::DeleteEntry, entry)); | 389 NewRunnableMethod(this, &AudioRendererHost::DeleteEntry, entry)); |
405 } | 390 } |
406 | 391 |
407 void AudioRendererHost::DeleteEntry(AudioEntry* entry) { | 392 void AudioRendererHost::DeleteEntry(AudioEntry* entry) { |
408 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 393 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
409 | 394 |
410 // Delete the entry when this method goes out of scope. | 395 // Delete the entry when this method goes out of scope. |
411 scoped_ptr<AudioEntry> entry_deleter(entry); | 396 scoped_ptr<AudioEntry> entry_deleter(entry); |
412 | 397 |
413 // Erase the entry from the map. | 398 // Erase the entry identified by |stream_id| from the map. |
414 audio_entries_.erase( | 399 audio_entries_.erase(entry->stream_id); |
415 AudioEntryId(entry->render_view_id, entry->stream_id)); | |
416 } | 400 } |
417 | 401 |
418 void AudioRendererHost::DeleteEntryOnError(AudioEntry* entry) { | 402 void AudioRendererHost::DeleteEntryOnError(AudioEntry* entry) { |
419 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 403 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
420 | 404 |
421 // Sends the error message first before we close the stream because | 405 // Sends the error message first before we close the stream because |
422 // |entry| is destroyed in DeleteEntry(). | 406 // |entry| is destroyed in DeleteEntry(). |
423 SendErrorMessage(entry->render_view_id, entry->stream_id); | 407 SendErrorMessage(entry->stream_id); |
424 CloseAndDeleteStream(entry); | 408 CloseAndDeleteStream(entry); |
425 } | 409 } |
426 | 410 |
427 AudioRendererHost::AudioEntry* AudioRendererHost::LookupById( | 411 AudioRendererHost::AudioEntry* AudioRendererHost::LookupById(int stream_id) { |
428 int route_id, int stream_id) { | |
429 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 412 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
430 | 413 |
431 AudioEntryMap::iterator i = audio_entries_.find( | 414 AudioEntryMap::iterator i = audio_entries_.find(stream_id); |
432 AudioEntryId(route_id, stream_id)); | |
433 if (i != audio_entries_.end() && !i->second->pending_close) | 415 if (i != audio_entries_.end() && !i->second->pending_close) |
434 return i->second; | 416 return i->second; |
435 return NULL; | 417 return NULL; |
436 } | 418 } |
437 | 419 |
438 AudioRendererHost::AudioEntry* AudioRendererHost::LookupByController( | 420 AudioRendererHost::AudioEntry* AudioRendererHost::LookupByController( |
439 media::AudioOutputController* controller) { | 421 media::AudioOutputController* controller) { |
440 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 422 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
441 | 423 |
442 // Iterate the map of entries. | 424 // Iterate the map of entries. |
443 // TODO(hclam): Implement a faster look up method. | |
444 for (AudioEntryMap::iterator i = audio_entries_.begin(); | 425 for (AudioEntryMap::iterator i = audio_entries_.begin(); |
445 i != audio_entries_.end(); ++i) { | 426 i != audio_entries_.end(); ++i) { |
446 if (!i->second->pending_close && controller == i->second->controller.get()) | 427 if (!i->second->pending_close && controller == i->second->controller.get()) |
447 return i->second; | 428 return i->second; |
448 } | 429 } |
449 return NULL; | 430 return NULL; |
450 } | 431 } |
OLD | NEW |