| 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 |