OLD | NEW |
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/browser/renderer_host/media/video_capture_controller.h" | 5 #include "content/browser/renderer_host/media/video_capture_controller.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
9 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
10 #include "content/browser/renderer_host/media/media_stream_manager.h" | 10 #include "content/browser/renderer_host/media/media_stream_manager.h" |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
66 | 66 |
67 VideoCaptureController::VideoCaptureController( | 67 VideoCaptureController::VideoCaptureController( |
68 media_stream::VideoCaptureManager* video_capture_manager) | 68 media_stream::VideoCaptureManager* video_capture_manager) |
69 : frame_info_available_(false), | 69 : frame_info_available_(false), |
70 video_capture_manager_(video_capture_manager), | 70 video_capture_manager_(video_capture_manager), |
71 device_in_use_(false), | 71 device_in_use_(false), |
72 state_(video_capture::kStopped) { | 72 state_(video_capture::kStopped) { |
73 memset(¤t_params_, 0, sizeof(current_params_)); | 73 memset(¤t_params_, 0, sizeof(current_params_)); |
74 } | 74 } |
75 | 75 |
76 VideoCaptureController::~VideoCaptureController() { | |
77 // Delete all DIBs. | |
78 STLDeleteContainerPairSecondPointers(owned_dibs_.begin(), | |
79 owned_dibs_.end()); | |
80 STLDeleteContainerPointers(controller_clients_.begin(), | |
81 controller_clients_.end()); | |
82 STLDeleteContainerPointers(pending_clients_.begin(), | |
83 pending_clients_.end()); | |
84 } | |
85 | |
86 void VideoCaptureController::StartCapture( | 76 void VideoCaptureController::StartCapture( |
87 const VideoCaptureControllerID& id, | 77 const VideoCaptureControllerID& id, |
88 VideoCaptureControllerEventHandler* event_handler, | 78 VideoCaptureControllerEventHandler* event_handler, |
89 base::ProcessHandle render_process, | 79 base::ProcessHandle render_process, |
90 const media::VideoCaptureParams& params) { | 80 const media::VideoCaptureParams& params) { |
91 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 81 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
92 // Signal error in case device is already in error state. | 82 // Signal error in case device is already in error state. |
93 if (state_ == video_capture::kError) { | 83 if (state_ == video_capture::kError) { |
94 event_handler->OnError(id); | 84 event_handler->OnError(id); |
95 return; | 85 return; |
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
354 | 344 |
355 void VideoCaptureController::OnFrameInfo( | 345 void VideoCaptureController::OnFrameInfo( |
356 const media::VideoCaptureDevice::Capability& info) { | 346 const media::VideoCaptureDevice::Capability& info) { |
357 frame_info_= info; | 347 frame_info_= info; |
358 BrowserThread::PostTask(BrowserThread::IO, | 348 BrowserThread::PostTask(BrowserThread::IO, |
359 FROM_HERE, | 349 FROM_HERE, |
360 base::Bind(&VideoCaptureController::DoFrameInfoOnIOThread, | 350 base::Bind(&VideoCaptureController::DoFrameInfoOnIOThread, |
361 this, info)); | 351 this, info)); |
362 } | 352 } |
363 | 353 |
| 354 VideoCaptureController::~VideoCaptureController() { |
| 355 // Delete all DIBs. |
| 356 STLDeleteContainerPairSecondPointers(owned_dibs_.begin(), |
| 357 owned_dibs_.end()); |
| 358 STLDeleteContainerPointers(controller_clients_.begin(), |
| 359 controller_clients_.end()); |
| 360 STLDeleteContainerPointers(pending_clients_.begin(), |
| 361 pending_clients_.end()); |
| 362 } |
| 363 |
| 364 // Called by VideoCaptureManager when a device have been stopped. |
| 365 void VideoCaptureController::OnDeviceStopped() { |
| 366 BrowserThread::PostTask(BrowserThread::IO, |
| 367 FROM_HERE, |
| 368 base::Bind(&VideoCaptureController::DoDeviceStoppedOnIOThread, this)); |
| 369 } |
| 370 |
364 void VideoCaptureController::DoIncomingCapturedFrameOnIOThread( | 371 void VideoCaptureController::DoIncomingCapturedFrameOnIOThread( |
365 int buffer_id, base::Time timestamp) { | 372 int buffer_id, base::Time timestamp) { |
366 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 373 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
367 | 374 |
368 int count = 0; | 375 int count = 0; |
369 if (state_ == video_capture::kStarted) { | 376 if (state_ == video_capture::kStarted) { |
370 for (ControllerClients::iterator client_it = controller_clients_.begin(); | 377 for (ControllerClients::iterator client_it = controller_clients_.begin(); |
371 client_it != controller_clients_.end(); client_it++) { | 378 client_it != controller_clients_.end(); client_it++) { |
372 if ((*client_it)->report_ready_to_delete) | 379 if ((*client_it)->report_ready_to_delete) |
373 continue; | 380 continue; |
374 | 381 |
375 (*client_it)->event_handler->OnBufferReady((*client_it)->controller_id, | 382 (*client_it)->event_handler->OnBufferReady((*client_it)->controller_id, |
376 buffer_id, timestamp); | 383 buffer_id, timestamp); |
377 (*client_it)->buffers.push_back(buffer_id); | 384 (*client_it)->buffers.push_back(buffer_id); |
378 count++; | 385 count++; |
379 } | 386 } |
380 } | 387 } |
381 | 388 |
382 base::AutoLock lock(lock_); | 389 base::AutoLock lock(lock_); |
383 DCHECK_EQ(owned_dibs_[buffer_id]->references, -1); | 390 DCHECK_EQ(owned_dibs_[buffer_id]->references, -1); |
384 owned_dibs_[buffer_id]->references = count; | 391 owned_dibs_[buffer_id]->references = count; |
385 } | 392 } |
386 | 393 |
387 void VideoCaptureController::DoErrorOnIOThread() { | |
388 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
389 state_ = video_capture::kError; | |
390 ControllerClients::iterator client_it; | |
391 for (client_it = controller_clients_.begin(); | |
392 client_it != controller_clients_.end(); client_it++) { | |
393 (*client_it)->event_handler->OnError((*client_it)->controller_id); | |
394 } | |
395 for (client_it = pending_clients_.begin(); | |
396 client_it != pending_clients_.end(); client_it++) { | |
397 (*client_it)->event_handler->OnError((*client_it)->controller_id); | |
398 } | |
399 } | |
400 | |
401 void VideoCaptureController::DoFrameInfoOnIOThread( | 394 void VideoCaptureController::DoFrameInfoOnIOThread( |
402 const media::VideoCaptureDevice::Capability info) { | 395 const media::VideoCaptureDevice::Capability info) { |
403 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 396 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
404 DCHECK(owned_dibs_.empty()) | 397 DCHECK(owned_dibs_.empty()) |
405 << "Device is restarted without releasing shared memory."; | 398 << "Device is restarted without releasing shared memory."; |
406 | 399 |
407 bool frames_created = true; | 400 bool frames_created = true; |
408 const size_t needed_size = (info.width * info.height * 3) / 2; | 401 const size_t needed_size = (info.width * info.height * 3) / 2; |
409 { | 402 { |
410 base::AutoLock lock(lock_); | 403 base::AutoLock lock(lock_); |
(...skipping 17 matching lines...) Expand all Loading... |
428 return; | 421 return; |
429 } | 422 } |
430 frame_info_available_ = true; | 423 frame_info_available_ = true; |
431 | 424 |
432 for (ControllerClients::iterator client_it = controller_clients_.begin(); | 425 for (ControllerClients::iterator client_it = controller_clients_.begin(); |
433 client_it != controller_clients_.end(); client_it++) { | 426 client_it != controller_clients_.end(); client_it++) { |
434 SendFrameInfoAndBuffers((*client_it), static_cast<int>(needed_size)); | 427 SendFrameInfoAndBuffers((*client_it), static_cast<int>(needed_size)); |
435 } | 428 } |
436 } | 429 } |
437 | 430 |
| 431 void VideoCaptureController::DoErrorOnIOThread() { |
| 432 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 433 state_ = video_capture::kError; |
| 434 ControllerClients::iterator client_it; |
| 435 for (client_it = controller_clients_.begin(); |
| 436 client_it != controller_clients_.end(); client_it++) { |
| 437 (*client_it)->event_handler->OnError((*client_it)->controller_id); |
| 438 } |
| 439 for (client_it = pending_clients_.begin(); |
| 440 client_it != pending_clients_.end(); client_it++) { |
| 441 (*client_it)->event_handler->OnError((*client_it)->controller_id); |
| 442 } |
| 443 } |
| 444 |
| 445 void VideoCaptureController::DoDeviceStoppedOnIOThread() { |
| 446 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 447 device_in_use_ = false; |
| 448 if (state_ == video_capture::kStopping) { |
| 449 PostStopping(); |
| 450 } |
| 451 } |
| 452 |
438 void VideoCaptureController::SendFrameInfoAndBuffers( | 453 void VideoCaptureController::SendFrameInfoAndBuffers( |
439 ControllerClient* client, int buffer_size) { | 454 ControllerClient* client, int buffer_size) { |
440 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 455 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
441 DCHECK(frame_info_available_); | 456 DCHECK(frame_info_available_); |
442 client->event_handler->OnFrameInfo(client->controller_id, | 457 client->event_handler->OnFrameInfo(client->controller_id, |
443 frame_info_.width, frame_info_.height, | 458 frame_info_.width, frame_info_.height, |
444 frame_info_.frame_rate); | 459 frame_info_.frame_rate); |
445 for (DIBMap::iterator dib_it = owned_dibs_.begin(); | 460 for (DIBMap::iterator dib_it = owned_dibs_.begin(); |
446 dib_it != owned_dibs_.end(); dib_it++) { | 461 dib_it != owned_dibs_.end(); dib_it++) { |
447 base::SharedMemory* shared_memory = dib_it->second->shared_memory.get(); | 462 base::SharedMemory* shared_memory = dib_it->second->shared_memory.get(); |
448 int index = dib_it->first; | 463 int index = dib_it->first; |
449 base::SharedMemoryHandle remote_handle; | 464 base::SharedMemoryHandle remote_handle; |
450 shared_memory->ShareToProcess(client->render_process_handle, | 465 shared_memory->ShareToProcess(client->render_process_handle, |
451 &remote_handle); | 466 &remote_handle); |
452 client->event_handler->OnBufferCreated(client->controller_id, | 467 client->event_handler->OnBufferCreated(client->controller_id, |
453 remote_handle, | 468 remote_handle, |
454 buffer_size, | 469 buffer_size, |
455 index); | 470 index); |
456 } | 471 } |
457 } | 472 } |
458 | 473 |
| 474 VideoCaptureController::ControllerClient* |
| 475 VideoCaptureController::FindClient( |
| 476 const VideoCaptureControllerID& id, |
| 477 VideoCaptureControllerEventHandler* handler, |
| 478 const ControllerClients& clients) { |
| 479 for (ControllerClients::const_iterator client_it = clients.begin(); |
| 480 client_it != clients.end(); client_it++) { |
| 481 if ((*client_it)->controller_id == id && |
| 482 (*client_it)->event_handler == handler) { |
| 483 return *client_it; |
| 484 } |
| 485 } |
| 486 return NULL; |
| 487 } |
| 488 |
459 // This function is called when all buffers have been returned to controller, | 489 // This function is called when all buffers have been returned to controller, |
460 // or when device is stopped. It decides whether the device needs to be | 490 // or when device is stopped. It decides whether the device needs to be |
461 // restarted. | 491 // restarted. |
462 void VideoCaptureController::PostStopping() { | 492 void VideoCaptureController::PostStopping() { |
463 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 493 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
464 DCHECK_EQ(state_, video_capture::kStopping); | 494 DCHECK_EQ(state_, video_capture::kStopping); |
465 | 495 |
466 // When clients still have some buffers, or device has not been stopped yet, | 496 // When clients still have some buffers, or device has not been stopped yet, |
467 // do nothing. | 497 // do nothing. |
468 if (ClientHasDIB() || device_in_use_) | 498 if (ClientHasDIB() || device_in_use_) |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
506 bool VideoCaptureController::ClientHasDIB() { | 536 bool VideoCaptureController::ClientHasDIB() { |
507 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 537 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
508 base::AutoLock lock(lock_); | 538 base::AutoLock lock(lock_); |
509 for (DIBMap::iterator dib_it = owned_dibs_.begin(); | 539 for (DIBMap::iterator dib_it = owned_dibs_.begin(); |
510 dib_it != owned_dibs_.end(); dib_it++) { | 540 dib_it != owned_dibs_.end(); dib_it++) { |
511 if (dib_it->second->references > 0) | 541 if (dib_it->second->references > 0) |
512 return true; | 542 return true; |
513 } | 543 } |
514 return false; | 544 return false; |
515 } | 545 } |
516 | |
517 VideoCaptureController::ControllerClient* | |
518 VideoCaptureController::FindClient( | |
519 const VideoCaptureControllerID& id, | |
520 VideoCaptureControllerEventHandler* handler, | |
521 const ControllerClients& clients) { | |
522 for (ControllerClients::const_iterator client_it = clients.begin(); | |
523 client_it != clients.end(); client_it++) { | |
524 if ((*client_it)->controller_id == id && | |
525 (*client_it)->event_handler == handler) { | |
526 return *client_it; | |
527 } | |
528 } | |
529 return NULL; | |
530 } | |
531 | |
532 /////////////////////////////////////////////////////////////////////////////// | |
533 // Called by VideoCaptureManager when a device have been stopped. | |
534 void VideoCaptureController::OnDeviceStopped() { | |
535 BrowserThread::PostTask(BrowserThread::IO, | |
536 FROM_HERE, | |
537 base::Bind(&VideoCaptureController::DoDeviceStoppedOnIOThread, this)); | |
538 } | |
539 | |
540 void VideoCaptureController::DoDeviceStoppedOnIOThread() { | |
541 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
542 device_in_use_ = false; | |
543 if (state_ == video_capture::kStopping) { | |
544 PostStopping(); | |
545 } | |
546 } | |
547 | |
OLD | NEW |