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 | |
mcasas
2016/12/03 01:35:48
I would s/ConsumerFeedbackObserverOnTaskRunner/Con
chfremer
2016/12/05 18:16:59
I am not sure I follow why it would be a good idea
| |
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_; | |
mcasas
2016/12/03 01:35:48
media::ConsumerFeedbackObserver* const
chfremer
2016/12/05 18:16:59
Done.
| |
73 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; | |
mcasas
2016/12/03 01:35:48
const
chfremer
2016/12/05 18:17:00
Done.
| |
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. | |
mcasas
2016/12/03 01:35:48
This reads like: VCD is connected to the VCC as a
chfremer
2016/12/05 18:17:00
That is correct. This is the message the comment i
| |
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 |