| 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_manager.h" | 5 #include "content/browser/renderer_host/media/video_capture_manager.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <set> | 8 #include <set> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 44 #if defined(ENABLE_SCREEN_CAPTURE) && defined(OS_ANDROID) | 44 #if defined(ENABLE_SCREEN_CAPTURE) && defined(OS_ANDROID) |
| 45 #include "content/browser/media/capture/screen_capture_device_android.h" | 45 #include "content/browser/media/capture/screen_capture_device_android.h" |
| 46 #endif | 46 #endif |
| 47 | 47 |
| 48 #if defined(OS_MACOSX) | 48 #if defined(OS_MACOSX) |
| 49 #include "media/base/mac/avfoundation_glue.h" | 49 #include "media/base/mac/avfoundation_glue.h" |
| 50 #endif | 50 #endif |
| 51 | 51 |
| 52 namespace { | 52 namespace { |
| 53 | 53 |
| 54 class ConsumerFeedbackObserverOnTaskRunner |
| 55 : public media::ConsumerFeedbackObserver { |
| 56 public: |
| 57 ConsumerFeedbackObserverOnTaskRunner( |
| 58 media::ConsumerFeedbackObserver* observer, |
| 59 scoped_refptr<base::SingleThreadTaskRunner> task_runner) |
| 60 : observer_(observer), task_runner_(std::move(task_runner)) {} |
| 61 |
| 62 void OnConsumerReportingUtilization(int frame_feedback_id, |
| 63 double utilization) override { |
| 64 task_runner_->PostTask( |
| 65 FROM_HERE, |
| 66 base::Bind( |
| 67 &media::ConsumerFeedbackObserver::OnConsumerReportingUtilization, |
| 68 base::Unretained(observer_), frame_feedback_id, utilization)); |
| 69 } |
| 70 |
| 71 private: |
| 72 media::ConsumerFeedbackObserver* observer_; |
| 73 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
| 74 }; |
| 75 |
| 54 // Compares two VideoCaptureFormat by checking smallest frame_size area, then | 76 // Compares two VideoCaptureFormat by checking smallest frame_size area, then |
| 55 // by _largest_ frame_rate. Used to order a VideoCaptureFormats vector so that | 77 // by _largest_ frame_rate. Used to order a VideoCaptureFormats vector so that |
| 56 // the first entry for a given resolution has the largest frame rate, as needed | 78 // the first entry for a given resolution has the largest frame rate, as needed |
| 57 // by the ConsolidateCaptureFormats() method. | 79 // by the ConsolidateCaptureFormats() method. |
| 58 bool IsCaptureFormatSmaller(const media::VideoCaptureFormat& format1, | 80 bool IsCaptureFormatSmaller(const media::VideoCaptureFormat& format1, |
| 59 const media::VideoCaptureFormat& format2) { | 81 const media::VideoCaptureFormat& format2) { |
| 60 DCHECK(format1.frame_size.GetCheckedArea().IsValid()); | 82 DCHECK(format1.frame_size.GetCheckedArea().IsValid()); |
| 61 DCHECK(format2.frame_size.GetCheckedArea().IsValid()); | 83 DCHECK(format2.frame_size.GetCheckedArea().IsValid()); |
| 62 if (format1.frame_size.GetCheckedArea().ValueOrDefault(0) == | 84 if (format1.frame_size.GetCheckedArea().ValueOrDefault(0) == |
| 63 format2.frame_size.GetCheckedArea().ValueOrDefault(0)) { | 85 format2.frame_size.GetCheckedArea().ValueOrDefault(0)) { |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 123 | 145 |
| 124 // Counter used for identifying a DeviceRequest to start a capture device. | 146 // Counter used for identifying a DeviceRequest to start a capture device. |
| 125 static int g_device_start_id = 0; | 147 static int g_device_start_id = 0; |
| 126 | 148 |
| 127 const media::VideoCaptureSessionId kFakeSessionId = -1; | 149 const media::VideoCaptureSessionId kFakeSessionId = -1; |
| 128 | 150 |
| 129 } // namespace | 151 } // namespace |
| 130 | 152 |
| 131 namespace content { | 153 namespace content { |
| 132 | 154 |
| 133 // This class owns a pair VideoCaptureDevice - VideoCaptureController. | 155 // Instances of this struct go through 3 different phases during their lifetime. |
| 134 // VideoCaptureManager owns all such pairs and is responsible for deleting the | 156 // Phase 1: When first created (in GetOrCreateDeviceEntry()), this consists of |
| 135 // instances when they are not used any longer. | 157 // only a controller. Clients can already connect to the controller, but there |
| 158 // is no device present. |
| 159 // Phase 2: When a request to "start" the entry comes in (via |
| 160 // HandleQueuedStartRequest()), a VideoCaptureDevice::Client is created |
| 161 // via video_capture_controller()->NewDeviceClient() and is used to schedule the |
| 162 // creation and start of a VideoCaptureDevice on the Device Thread. |
| 163 // Phase 3: As soon as the creation of the VideoCaptureDevice is complete, it |
| 164 // is connected to the VideoCaptureController as the ConsumerFeedbackObserver. |
| 136 class VideoCaptureManager::DeviceEntry { | 165 class VideoCaptureManager::DeviceEntry { |
| 137 public: | 166 public: |
| 138 DeviceEntry(MediaStreamType stream_type, | 167 DeviceEntry(MediaStreamType stream_type, |
| 139 const std::string& id, | 168 const std::string& id, |
| 140 std::unique_ptr<VideoCaptureController> controller, | 169 std::unique_ptr<VideoCaptureController> controller, |
| 141 const media::VideoCaptureParams& params); | 170 const media::VideoCaptureParams& params); |
| 142 ~DeviceEntry(); | 171 ~DeviceEntry(); |
| 143 | 172 |
| 144 const int serial_id; | 173 const int serial_id; |
| 145 const MediaStreamType stream_type; | 174 const MediaStreamType stream_type; |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 411 DVLOG(3) << "DoStopDevice, aborting start request for device " | 440 DVLOG(3) << "DoStopDevice, aborting start request for device " |
| 412 << entry->id << " serial_id = " << entry->serial_id; | 441 << entry->id << " serial_id = " << entry->serial_id; |
| 413 return; | 442 return; |
| 414 } | 443 } |
| 415 } | 444 } |
| 416 | 445 |
| 417 DVLOG(3) << "DoStopDevice. Send stop request for device = " << entry->id | 446 DVLOG(3) << "DoStopDevice. Send stop request for device = " << entry->id |
| 418 << " serial_id = " << entry->serial_id << "."; | 447 << " serial_id = " << entry->serial_id << "."; |
| 419 entry->video_capture_controller()->OnLog( | 448 entry->video_capture_controller()->OnLog( |
| 420 base::StringPrintf("Stopping device: id: %s", entry->id.c_str())); | 449 base::StringPrintf("Stopping device: id: %s", entry->id.c_str())); |
| 450 entry->video_capture_controller()->SetConsumerFeedbackObserver(nullptr); |
| 421 | 451 |
| 452 // |entry->video_capture_device| can be null if creating the device has |
| 453 // failed. |
| 422 if (entry->video_capture_device()) { | 454 if (entry->video_capture_device()) { |
| 423 // |entry->video_capture_device| can be null if creating the device fails. | |
| 424 device_task_runner_->PostTask( | 455 device_task_runner_->PostTask( |
| 425 FROM_HERE, | 456 FROM_HERE, |
| 426 base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this, | 457 base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this, |
| 427 base::Passed(entry->ReleaseVideoCaptureDevice()))); | 458 base::Passed(entry->ReleaseVideoCaptureDevice()))); |
| 428 } | 459 } |
| 429 } | 460 } |
| 430 | 461 |
| 431 void VideoCaptureManager::HandleQueuedStartRequest() { | 462 void VideoCaptureManager::HandleQueuedStartRequest() { |
| 432 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 463 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 433 // Remove all start requests that have been aborted. | 464 // Remove all start requests that have been aborted. |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 517 base::Bind(&VideoCaptureManager::OnDeviceStarted, this, | 548 base::Bind(&VideoCaptureManager::OnDeviceStarted, this, |
| 518 request->serial_id())); | 549 request->serial_id())); |
| 519 } | 550 } |
| 520 | 551 |
| 521 void VideoCaptureManager::OnDeviceStarted( | 552 void VideoCaptureManager::OnDeviceStarted( |
| 522 int serial_id, | 553 int serial_id, |
| 523 std::unique_ptr<VideoCaptureDevice> device) { | 554 std::unique_ptr<VideoCaptureDevice> device) { |
| 524 DVLOG(3) << __func__; | 555 DVLOG(3) << __func__; |
| 525 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 556 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 526 DCHECK_EQ(serial_id, device_start_queue_.begin()->serial_id()); | 557 DCHECK_EQ(serial_id, device_start_queue_.begin()->serial_id()); |
| 558 // |device| can be null if creation failed in |
| 559 // DoStartDeviceCaptureOnDeviceThread. |
| 527 if (device_start_queue_.front().abort_start()) { | 560 if (device_start_queue_.front().abort_start()) { |
| 528 // |device| can be null if creation failed in | |
| 529 // DoStartDeviceCaptureOnDeviceThread. | |
| 530 // The device is no longer wanted. Stop the device again. | 561 // The device is no longer wanted. Stop the device again. |
| 531 DVLOG(3) << "OnDeviceStarted but start request have been aborted."; | 562 DVLOG(3) << "OnDeviceStarted but start request have been aborted."; |
| 532 media::VideoCaptureDevice* device_ptr = device.get(); | 563 media::VideoCaptureDevice* device_ptr = device.get(); |
| 533 base::Closure closure = | 564 base::Closure closure = |
| 534 base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this, | 565 base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this, |
| 535 base::Passed(&device)); | 566 base::Passed(&device)); |
| 536 if (device_ptr && !device_task_runner_->PostTask(FROM_HERE, closure)) { | 567 if (device_ptr && !device_task_runner_->PostTask(FROM_HERE, closure)) { |
| 537 // PostTask failed. The device must be stopped anyway. | 568 // PostTask failed. The device must be stopped anyway. |
| 538 device_ptr->StopAndDeAllocate(); | 569 device_ptr->StopAndDeAllocate(); |
| 539 } | 570 } |
| 540 } else { | 571 } else { |
| 541 DeviceEntry* const entry = GetDeviceEntryBySerialId(serial_id); | 572 DeviceEntry* const entry = GetDeviceEntryBySerialId(serial_id); |
| 542 DCHECK(entry); | 573 DCHECK(entry); |
| 543 DCHECK(!entry->video_capture_device()); | 574 DCHECK(!entry->video_capture_device()); |
| 575 // Passing raw pointer |device.get()| to the controller is safe, |
| 576 // because we transfer ownership of it to |entry|. We are calling |
| 577 // SetConsumerFeedbackObserver(nullptr) before releasing |
| 578 // |entry->video_capture_device_| on the |device_task_runner_|. |
| 579 entry->video_capture_controller()->SetConsumerFeedbackObserver( |
| 580 base::MakeUnique<ConsumerFeedbackObserverOnTaskRunner>( |
| 581 device.get(), device_task_runner_)); |
| 544 entry->SetVideoCaptureDevice(std::move(device)); | 582 entry->SetVideoCaptureDevice(std::move(device)); |
| 545 | 583 |
| 546 if (entry->stream_type == MEDIA_DESKTOP_VIDEO_CAPTURE) { | 584 if (entry->stream_type == MEDIA_DESKTOP_VIDEO_CAPTURE) { |
| 547 const media::VideoCaptureSessionId session_id = | 585 const media::VideoCaptureSessionId session_id = |
| 548 device_start_queue_.front().session_id(); | 586 device_start_queue_.front().session_id(); |
| 549 DCHECK(session_id != kFakeSessionId); | 587 DCHECK(session_id != kFakeSessionId); |
| 550 MaybePostDesktopCaptureWindowId(session_id); | 588 MaybePostDesktopCaptureWindowId(session_id); |
| 551 } | 589 } |
| 552 | 590 |
| 553 auto it = photo_request_queue_.begin(); | 591 auto it = photo_request_queue_.begin(); |
| (...skipping 732 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1286 if (!device_in_queue) { | 1324 if (!device_in_queue) { |
| 1287 // Session ID is only valid for Screen capture. So we can fake it to | 1325 // Session ID is only valid for Screen capture. So we can fake it to |
| 1288 // resume video capture devices here. | 1326 // resume video capture devices here. |
| 1289 QueueStartDevice(kFakeSessionId, entry.get(), entry->parameters); | 1327 QueueStartDevice(kFakeSessionId, entry.get(), entry->parameters); |
| 1290 } | 1328 } |
| 1291 } | 1329 } |
| 1292 } | 1330 } |
| 1293 #endif // defined(OS_ANDROID) | 1331 #endif // defined(OS_ANDROID) |
| 1294 | 1332 |
| 1295 } // namespace content | 1333 } // namespace content |
| OLD | NEW |