Chromium Code Reviews| Index: content/browser/renderer_host/media/video_capture_manager.cc |
| diff --git a/content/browser/renderer_host/media/video_capture_manager.cc b/content/browser/renderer_host/media/video_capture_manager.cc |
| index 8ce5a592c86f08c53164c1cfe74b518f0231e207..f7ff0aaeb2095183a402bc87fcbfa6378f1a7a95 100644 |
| --- a/content/browser/renderer_host/media/video_capture_manager.cc |
| +++ b/content/browser/renderer_host/media/video_capture_manager.cc |
| @@ -32,6 +32,7 @@ |
| #include "media/base/bind_to_current_loop.h" |
| #include "media/base/media_switches.h" |
| #include "media/capture/video/video_capture_device.h" |
| +#include "media/capture/video/video_capture_device_client.h" |
| #include "media/capture/video/video_capture_device_factory.h" |
| #if defined(ENABLE_SCREEN_CAPTURE) && !defined(OS_ANDROID) |
| @@ -130,9 +131,16 @@ const media::VideoCaptureSessionId kFakeSessionId = -1; |
| namespace content { |
| -// This class owns a pair VideoCaptureDevice - VideoCaptureController. |
| -// VideoCaptureManager owns all such pairs and is responsible for deleting the |
| -// instances when they are not used any longer. |
| +// Instances of this struct go through 3 different phases during their lifetime. |
| +// Phase 1: When first created (in GetOrCreateDeviceEntry()), this consists of a |
|
miu
2016/12/01 05:25:18
s/consists of a only a controller/consists of only
chfremer
2016/12/02 01:28:28
Done.
|
| +// only a controller. Clients can already connect to the controller, but there |
| +// is no device present. |
| +// Phase 2: When a request to "start" the entry comes in (via |
| +// HandleQueuedStartRequest()), a VideoCaptureDevice::Client is created |
| +// via video_capture_controller()->NewDeviceClient() and is used to schedule the |
| +// creation and start of a VideoCaptureDevice on the Device Thread. |
| +// Phase 3: As soon as the creation of the VideoCaptureDevice is complete, it |
| +// is connected to the VideoCaptureDevice::Client as the ConsumerLoadObserver. |
| class VideoCaptureManager::DeviceEntry { |
| public: |
| DeviceEntry(MediaStreamType stream_type, |
| @@ -418,6 +426,7 @@ void VideoCaptureManager::DoStopDevice(DeviceEntry* entry) { |
| << " serial_id = " << entry->serial_id << "."; |
| entry->video_capture_controller()->OnLog( |
| base::StringPrintf("Stopping device: id: %s", entry->id.c_str())); |
| + entry->video_capture_controller()->SetFrameReceiverObserver(nullptr); |
| if (entry->video_capture_device()) { |
| // |entry->video_capture_device| can be null if creating the device fails. |
| @@ -454,6 +463,10 @@ void VideoCaptureManager::HandleQueuedStartRequest() { |
| DVLOG(3) << "HandleQueuedStartRequest, Post start to device thread, device = " |
| << entry->id << " start id = " << entry->serial_id; |
| + std::unique_ptr<media::VideoCaptureDeviceClient> device_client = |
| + entry->video_capture_controller()->NewDeviceClient(); |
| + media::VideoCaptureDeviceClient* device_client_ptr = device_client.get(); |
| + |
| base::Callback<std::unique_ptr<VideoCaptureDevice>(void)> |
| start_capture_function; |
| @@ -470,10 +483,10 @@ void VideoCaptureManager::HandleQueuedStartRequest() { |
| found->descriptor.GetNameAndModel().c_str(), |
| found->descriptor.GetCaptureApiTypeString())); |
| - start_capture_function = base::Bind( |
| - &VideoCaptureManager::DoStartDeviceCaptureOnDeviceThread, this, |
| - found->descriptor, request->params(), |
| - base::Passed(entry->video_capture_controller()->NewDeviceClient())); |
| + start_capture_function = |
| + base::Bind(&VideoCaptureManager::DoStartDeviceCaptureOnDeviceThread, |
| + this, found->descriptor, request->params(), |
| + base::Passed(std::move(device_client))); |
| } else { |
| // Errors from DoStartDeviceCaptureOnDeviceThread go via |
| // VideoCaptureDeviceClient::OnError, which needs some thread |
| @@ -494,17 +507,17 @@ void VideoCaptureManager::HandleQueuedStartRequest() { |
| break; |
| } |
| case MEDIA_TAB_VIDEO_CAPTURE: |
| - start_capture_function = base::Bind( |
| - &VideoCaptureManager::DoStartTabCaptureOnDeviceThread, this, |
| - entry->id, request->params(), |
| - base::Passed(entry->video_capture_controller()->NewDeviceClient())); |
| + start_capture_function = |
| + base::Bind(&VideoCaptureManager::DoStartTabCaptureOnDeviceThread, |
| + this, entry->id, request->params(), |
| + base::Passed(std::move(device_client))); |
| break; |
| case MEDIA_DESKTOP_VIDEO_CAPTURE: |
| - start_capture_function = base::Bind( |
| - &VideoCaptureManager::DoStartDesktopCaptureOnDeviceThread, this, |
| - entry->id, request->params(), |
| - base::Passed(entry->video_capture_controller()->NewDeviceClient())); |
| + start_capture_function = |
| + base::Bind(&VideoCaptureManager::DoStartDesktopCaptureOnDeviceThread, |
| + this, entry->id, request->params(), |
| + base::Passed(std::move(device_client))); |
| break; |
| default: { |
| @@ -515,18 +528,19 @@ void VideoCaptureManager::HandleQueuedStartRequest() { |
| base::PostTaskAndReplyWithResult( |
| device_task_runner_.get(), FROM_HERE, start_capture_function, |
| base::Bind(&VideoCaptureManager::OnDeviceStarted, this, |
| - request->serial_id())); |
| + request->serial_id(), device_client_ptr)); |
|
miu
2016/12/01 05:25:17
Is this safe (passing the raw pointer)? Could, in
chfremer
2016/12/02 01:28:28
Yes, but that fact that you had to raise the quest
|
| } |
| void VideoCaptureManager::OnDeviceStarted( |
| int serial_id, |
| + media::VideoCaptureDeviceClient* device_client_ptr, |
| std::unique_ptr<VideoCaptureDevice> device) { |
| DVLOG(3) << __func__; |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| DCHECK_EQ(serial_id, device_start_queue_.begin()->serial_id()); |
| + // |device| can be null if creation failed in |
| + // DoStartDeviceCaptureOnDeviceThread. |
| if (device_start_queue_.front().abort_start()) { |
| - // |device| can be null if creation failed in |
| - // DoStartDeviceCaptureOnDeviceThread. |
| // The device is no longer wanted. Stop the device again. |
| DVLOG(3) << "OnDeviceStarted but start request have been aborted."; |
| media::VideoCaptureDevice* device_ptr = device.get(); |
| @@ -541,6 +555,10 @@ void VideoCaptureManager::OnDeviceStarted( |
| DeviceEntry* const entry = GetDeviceEntryBySerialId(serial_id); |
| DCHECK(entry); |
| DCHECK(!entry->video_capture_device()); |
| + if (device) { |
| + entry->video_capture_controller()->SetFrameReceiverObserver( |
| + device_client_ptr); |
| + } |
| entry->SetVideoCaptureDevice(std::move(device)); |
| if (entry->stream_type == MEDIA_DESKTOP_VIDEO_CAPTURE) { |
| @@ -569,7 +587,7 @@ std::unique_ptr<media::VideoCaptureDevice> |
| VideoCaptureManager::DoStartDeviceCaptureOnDeviceThread( |
| const VideoCaptureDeviceDescriptor& descriptor, |
| const media::VideoCaptureParams& params, |
| - std::unique_ptr<VideoCaptureDevice::Client> device_client) { |
| + std::unique_ptr<media::VideoCaptureDeviceClient> device_client) { |
| SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StartDeviceTime"); |
| DCHECK(IsOnDeviceThread()); |
| @@ -582,6 +600,7 @@ VideoCaptureManager::DoStartDeviceCaptureOnDeviceThread( |
| return nullptr; |
| } |
| + device_client->SetConsumerLoadObserver(video_capture_device.get()); |
| video_capture_device->AllocateAndStart(params, std::move(device_client)); |
| return video_capture_device; |
| } |
| @@ -590,7 +609,7 @@ std::unique_ptr<media::VideoCaptureDevice> |
| VideoCaptureManager::DoStartTabCaptureOnDeviceThread( |
| const std::string& id, |
| const media::VideoCaptureParams& params, |
| - std::unique_ptr<VideoCaptureDevice::Client> device_client) { |
| + std::unique_ptr<media::VideoCaptureDeviceClient> device_client) { |
| SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StartDeviceTime"); |
| DCHECK(IsOnDeviceThread()); |
| @@ -602,6 +621,7 @@ VideoCaptureManager::DoStartTabCaptureOnDeviceThread( |
| return nullptr; |
| } |
| + device_client->SetConsumerLoadObserver(video_capture_device.get()); |
|
miu
2016/12/01 05:25:17
OOC, should we call SetConsumerLoadObserver(nullpt
chfremer
2016/12/02 01:28:28
Again, this is no longer needed with the other sim
|
| video_capture_device->AllocateAndStart(params, std::move(device_client)); |
| return video_capture_device; |
| } |
| @@ -610,7 +630,7 @@ std::unique_ptr<media::VideoCaptureDevice> |
| VideoCaptureManager::DoStartDesktopCaptureOnDeviceThread( |
| const std::string& id, |
| const media::VideoCaptureParams& params, |
| - std::unique_ptr<VideoCaptureDevice::Client> device_client) { |
| + std::unique_ptr<media::VideoCaptureDeviceClient> device_client) { |
| SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StartDeviceTime"); |
| DCHECK(IsOnDeviceThread()); |
| @@ -648,6 +668,7 @@ VideoCaptureManager::DoStartDesktopCaptureOnDeviceThread( |
| return nullptr; |
| } |
| + device_client->SetConsumerLoadObserver(video_capture_device.get()); |
| video_capture_device->AllocateAndStart(params, std::move(device_client)); |
| return video_capture_device; |
| } |