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