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 29 matching lines...) Expand all Loading... |
40 #include "content/browser/media/capture/desktop_capture_device_aura.h" | 40 #include "content/browser/media/capture/desktop_capture_device_aura.h" |
41 #endif | 41 #endif |
42 #endif | 42 #endif |
43 | 43 |
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 namespace { | 48 namespace { |
49 | 49 |
| 50 class VideoFrameConsumerFeedbackObserverOnTaskRunner |
| 51 : public media::VideoFrameConsumerFeedbackObserver { |
| 52 public: |
| 53 VideoFrameConsumerFeedbackObserverOnTaskRunner( |
| 54 media::VideoFrameConsumerFeedbackObserver* observer, |
| 55 scoped_refptr<base::SingleThreadTaskRunner> task_runner) |
| 56 : observer_(observer), task_runner_(std::move(task_runner)) {} |
| 57 |
| 58 void OnUtilizationReport(int frame_feedback_id, double utilization) override { |
| 59 task_runner_->PostTask( |
| 60 FROM_HERE, |
| 61 base::Bind( |
| 62 &media::VideoFrameConsumerFeedbackObserver::OnUtilizationReport, |
| 63 base::Unretained(observer_), frame_feedback_id, utilization)); |
| 64 } |
| 65 |
| 66 private: |
| 67 media::VideoFrameConsumerFeedbackObserver* const observer_; |
| 68 const scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
| 69 }; |
| 70 |
50 // Compares two VideoCaptureFormat by checking smallest frame_size area, then | 71 // Compares two VideoCaptureFormat by checking smallest frame_size area, then |
51 // by _largest_ frame_rate. Used to order a VideoCaptureFormats vector so that | 72 // by _largest_ frame_rate. Used to order a VideoCaptureFormats vector so that |
52 // the first entry for a given resolution has the largest frame rate, as needed | 73 // the first entry for a given resolution has the largest frame rate, as needed |
53 // by the ConsolidateCaptureFormats() method. | 74 // by the ConsolidateCaptureFormats() method. |
54 bool IsCaptureFormatSmaller(const media::VideoCaptureFormat& format1, | 75 bool IsCaptureFormatSmaller(const media::VideoCaptureFormat& format1, |
55 const media::VideoCaptureFormat& format2) { | 76 const media::VideoCaptureFormat& format2) { |
56 DCHECK(format1.frame_size.GetCheckedArea().IsValid()); | 77 DCHECK(format1.frame_size.GetCheckedArea().IsValid()); |
57 DCHECK(format2.frame_size.GetCheckedArea().IsValid()); | 78 DCHECK(format2.frame_size.GetCheckedArea().IsValid()); |
58 if (format1.frame_size.GetCheckedArea().ValueOrDefault(0) == | 79 if (format1.frame_size.GetCheckedArea().ValueOrDefault(0) == |
59 format2.frame_size.GetCheckedArea().ValueOrDefault(0)) { | 80 format2.frame_size.GetCheckedArea().ValueOrDefault(0)) { |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 | 140 |
120 // Counter used for identifying a DeviceRequest to start a capture device. | 141 // Counter used for identifying a DeviceRequest to start a capture device. |
121 static int g_device_start_id = 0; | 142 static int g_device_start_id = 0; |
122 | 143 |
123 const media::VideoCaptureSessionId kFakeSessionId = -1; | 144 const media::VideoCaptureSessionId kFakeSessionId = -1; |
124 | 145 |
125 } // namespace | 146 } // namespace |
126 | 147 |
127 namespace content { | 148 namespace content { |
128 | 149 |
129 // This class owns a pair VideoCaptureDevice - VideoCaptureController. | 150 // Instances of this struct go through 3 different phases during their lifetime. |
130 // VideoCaptureManager owns all such pairs and is responsible for deleting the | 151 // Phase 1: When first created (in GetOrCreateDeviceEntry()), this consists of |
131 // instances when they are not used any longer. | 152 // only a controller. Clients can already connect to the controller, but there |
| 153 // is no device present. |
| 154 // Phase 2: When a request to "start" the entry comes in (via |
| 155 // HandleQueuedStartRequest()), a VideoCaptureDevice::Client is created |
| 156 // via video_capture_controller()->NewDeviceClient() and is used to schedule the |
| 157 // creation and start of a VideoCaptureDevice on the Device Thread. |
| 158 // Phase 3: As soon as the creation of the VideoCaptureDevice is complete, this |
| 159 // newly created VideoCaptureDevice instance is connected to the |
| 160 // VideoCaptureController via SetConsumerFeedbackObserver(). |
132 class VideoCaptureManager::DeviceEntry { | 161 class VideoCaptureManager::DeviceEntry { |
133 public: | 162 public: |
134 DeviceEntry(MediaStreamType stream_type, | 163 DeviceEntry(MediaStreamType stream_type, |
135 const std::string& id, | 164 const std::string& id, |
136 std::unique_ptr<VideoCaptureController> controller, | 165 std::unique_ptr<VideoCaptureController> controller, |
137 const media::VideoCaptureParams& params); | 166 const media::VideoCaptureParams& params); |
138 ~DeviceEntry(); | 167 ~DeviceEntry(); |
139 | 168 |
140 const int serial_id; | 169 const int serial_id; |
141 const MediaStreamType stream_type; | 170 const MediaStreamType stream_type; |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
399 DVLOG(3) << "DoStopDevice, aborting start request for device " | 428 DVLOG(3) << "DoStopDevice, aborting start request for device " |
400 << entry->id << " serial_id = " << entry->serial_id; | 429 << entry->id << " serial_id = " << entry->serial_id; |
401 return; | 430 return; |
402 } | 431 } |
403 } | 432 } |
404 | 433 |
405 DVLOG(3) << "DoStopDevice. Send stop request for device = " << entry->id | 434 DVLOG(3) << "DoStopDevice. Send stop request for device = " << entry->id |
406 << " serial_id = " << entry->serial_id << "."; | 435 << " serial_id = " << entry->serial_id << "."; |
407 entry->video_capture_controller()->OnLog( | 436 entry->video_capture_controller()->OnLog( |
408 base::StringPrintf("Stopping device: id: %s", entry->id.c_str())); | 437 base::StringPrintf("Stopping device: id: %s", entry->id.c_str())); |
| 438 entry->video_capture_controller()->SetConsumerFeedbackObserver(nullptr); |
409 | 439 |
| 440 // |entry->video_capture_device| can be null if creating the device has |
| 441 // failed. |
410 if (entry->video_capture_device()) { | 442 if (entry->video_capture_device()) { |
411 // |entry->video_capture_device| can be null if creating the device fails. | |
412 device_task_runner_->PostTask( | 443 device_task_runner_->PostTask( |
413 FROM_HERE, | 444 FROM_HERE, |
414 base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this, | 445 base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this, |
415 base::Passed(entry->ReleaseVideoCaptureDevice()))); | 446 base::Passed(entry->ReleaseVideoCaptureDevice()))); |
416 } | 447 } |
417 } | 448 } |
418 | 449 |
419 void VideoCaptureManager::HandleQueuedStartRequest() { | 450 void VideoCaptureManager::HandleQueuedStartRequest() { |
420 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 451 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
421 // Remove all start requests that have been aborted. | 452 // Remove all start requests that have been aborted. |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
497 base::Bind(&VideoCaptureManager::OnDeviceStarted, this, | 528 base::Bind(&VideoCaptureManager::OnDeviceStarted, this, |
498 request->serial_id())); | 529 request->serial_id())); |
499 } | 530 } |
500 | 531 |
501 void VideoCaptureManager::OnDeviceStarted( | 532 void VideoCaptureManager::OnDeviceStarted( |
502 int serial_id, | 533 int serial_id, |
503 std::unique_ptr<VideoCaptureDevice> device) { | 534 std::unique_ptr<VideoCaptureDevice> device) { |
504 DVLOG(3) << __func__; | 535 DVLOG(3) << __func__; |
505 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 536 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
506 DCHECK_EQ(serial_id, device_start_queue_.begin()->serial_id()); | 537 DCHECK_EQ(serial_id, device_start_queue_.begin()->serial_id()); |
| 538 // |device| can be null if creation failed in |
| 539 // DoStartDeviceCaptureOnDeviceThread. |
507 if (device_start_queue_.front().abort_start()) { | 540 if (device_start_queue_.front().abort_start()) { |
508 // |device| can be null if creation failed in | |
509 // DoStartDeviceCaptureOnDeviceThread. | |
510 // The device is no longer wanted. Stop the device again. | 541 // The device is no longer wanted. Stop the device again. |
511 DVLOG(3) << "OnDeviceStarted but start request have been aborted."; | 542 DVLOG(3) << "OnDeviceStarted but start request have been aborted."; |
512 media::VideoCaptureDevice* device_ptr = device.get(); | 543 media::VideoCaptureDevice* device_ptr = device.get(); |
513 base::Closure closure = | 544 base::Closure closure = |
514 base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this, | 545 base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this, |
515 base::Passed(&device)); | 546 base::Passed(&device)); |
516 if (device_ptr && !device_task_runner_->PostTask(FROM_HERE, closure)) { | 547 if (device_ptr && !device_task_runner_->PostTask(FROM_HERE, closure)) { |
517 // PostTask failed. The device must be stopped anyway. | 548 // PostTask failed. The device must be stopped anyway. |
518 device_ptr->StopAndDeAllocate(); | 549 device_ptr->StopAndDeAllocate(); |
519 } | 550 } |
520 } else { | 551 } else { |
521 DeviceEntry* const entry = GetDeviceEntryBySerialId(serial_id); | 552 DeviceEntry* const entry = GetDeviceEntryBySerialId(serial_id); |
522 DCHECK(entry); | 553 DCHECK(entry); |
523 DCHECK(!entry->video_capture_device()); | 554 DCHECK(!entry->video_capture_device()); |
| 555 // Passing raw pointer |device.get()| to the controller is safe, |
| 556 // because we transfer ownership of it to |entry|. We are calling |
| 557 // SetConsumerFeedbackObserver(nullptr) before releasing |
| 558 // |entry->video_capture_device_| on the |device_task_runner_|. |
| 559 entry->video_capture_controller()->SetConsumerFeedbackObserver( |
| 560 base::MakeUnique<VideoFrameConsumerFeedbackObserverOnTaskRunner>( |
| 561 device.get(), device_task_runner_)); |
524 entry->SetVideoCaptureDevice(std::move(device)); | 562 entry->SetVideoCaptureDevice(std::move(device)); |
525 | 563 |
526 if (entry->stream_type == MEDIA_DESKTOP_VIDEO_CAPTURE) { | 564 if (entry->stream_type == MEDIA_DESKTOP_VIDEO_CAPTURE) { |
527 const media::VideoCaptureSessionId session_id = | 565 const media::VideoCaptureSessionId session_id = |
528 device_start_queue_.front().session_id(); | 566 device_start_queue_.front().session_id(); |
529 DCHECK(session_id != kFakeSessionId); | 567 DCHECK(session_id != kFakeSessionId); |
530 MaybePostDesktopCaptureWindowId(session_id); | 568 MaybePostDesktopCaptureWindowId(session_id); |
531 } | 569 } |
532 | 570 |
533 auto it = photo_request_queue_.begin(); | 571 auto it = photo_request_queue_.begin(); |
(...skipping 706 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1240 if (!device_in_queue) { | 1278 if (!device_in_queue) { |
1241 // Session ID is only valid for Screen capture. So we can fake it to | 1279 // Session ID is only valid for Screen capture. So we can fake it to |
1242 // resume video capture devices here. | 1280 // resume video capture devices here. |
1243 QueueStartDevice(kFakeSessionId, entry.get(), entry->parameters); | 1281 QueueStartDevice(kFakeSessionId, entry.get(), entry->parameters); |
1244 } | 1282 } |
1245 } | 1283 } |
1246 } | 1284 } |
1247 #endif // defined(OS_ANDROID) | 1285 #endif // defined(OS_ANDROID) |
1248 | 1286 |
1249 } // namespace content | 1287 } // namespace content |
OLD | NEW |