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 2118857ecee7866c2e984854298eaee4c37e217e..7f5215b1e5379321ff669fe934ae8244fa017e8c 100644 |
| --- a/content/browser/renderer_host/media/video_capture_manager.cc |
| +++ b/content/browser/renderer_host/media/video_capture_manager.cc |
| @@ -25,10 +25,10 @@ |
| #include "content/browser/media/capture/desktop_capture_device_uma_types.h" |
| #include "content/browser/media/capture/web_contents_video_capture_device.h" |
| #include "content/browser/media/media_internals.h" |
| +#include "content/browser/renderer_host/media/in_process_buildable_video_capture_device.h" |
| #include "content/browser/renderer_host/media/video_capture_controller.h" |
| #include "content/browser/renderer_host/media/video_capture_controller_event_handler.h" |
| -#include "content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.h" |
| -#include "content/browser/renderer_host/media/video_frame_receiver_on_io_thread.h" |
| +#include "content/browser/renderer_host/media/video_capture_device_entry.h" |
| #include "content/public/browser/browser_thread.h" |
| #include "content/public/browser/desktop_media_id.h" |
| #include "content/public/common/media_stream_request.h" |
| @@ -59,27 +59,6 @@ |
| namespace { |
| -class VideoFrameConsumerFeedbackObserverOnTaskRunner |
| - : public media::VideoFrameConsumerFeedbackObserver { |
| - public: |
| - VideoFrameConsumerFeedbackObserverOnTaskRunner( |
| - media::VideoFrameConsumerFeedbackObserver* observer, |
| - scoped_refptr<base::SingleThreadTaskRunner> task_runner) |
| - : observer_(observer), task_runner_(std::move(task_runner)) {} |
| - |
| - void OnUtilizationReport(int frame_feedback_id, double utilization) override { |
| - task_runner_->PostTask( |
| - FROM_HERE, |
| - base::Bind( |
| - &media::VideoFrameConsumerFeedbackObserver::OnUtilizationReport, |
| - base::Unretained(observer_), frame_feedback_id, utilization)); |
| - } |
| - |
| - private: |
| - media::VideoFrameConsumerFeedbackObserver* const observer_; |
| - const scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
| -}; |
| - |
| // Compares two VideoCaptureFormat by checking smallest frame_size area, then |
| // by _largest_ frame_rate. Used to order a VideoCaptureFormats vector so that |
| // the first entry for a given resolution has the largest frame rate, as needed |
| @@ -125,16 +104,6 @@ void ConsolidateCaptureFormats(media::VideoCaptureFormats* formats) { |
| } |
| } |
| -// The maximum number of video frame buffers in-flight at any one time. This |
| -// value should be based on the logical capacity of the capture pipeline, and |
| -// not on hardware performance. For example, tab capture requires more buffers |
| -// than webcam capture because the pipeline is longer (it includes read-backs |
| -// pending in the GPU pipeline). |
| -const int kMaxNumberOfBuffers = 3; |
| -// TODO(miu): The value for tab capture should be determined programmatically. |
| -// http://crbug.com/460318 |
| -const int kMaxNumberOfBuffersForTabCapture = 10; |
| - |
| // Used for logging capture events. |
| // Elements in this enum should not be deleted or rearranged; the only |
| // permitted operation is to add new elements before NUM_VIDEO_CAPTURE_EVENT. |
| @@ -148,56 +117,16 @@ enum VideoCaptureEvent { |
| }; |
| void LogVideoCaptureEvent(VideoCaptureEvent event) { |
| - UMA_HISTOGRAM_ENUMERATION("Media.VideoCaptureManager.Event", |
| - event, |
| + UMA_HISTOGRAM_ENUMERATION("Media.VideoCaptureManager.Event", event, |
| NUM_VIDEO_CAPTURE_EVENT); |
| } |
| -// Counter used for identifying a DeviceRequest to start a capture device. |
| -static int g_device_start_id = 0; |
| - |
| const media::VideoCaptureSessionId kFakeSessionId = -1; |
| -std::unique_ptr<media::VideoCaptureJpegDecoder> CreateGpuJpegDecoder( |
| - const media::VideoCaptureJpegDecoder::DecodeDoneCB& decode_done_cb) { |
| - return base::MakeUnique<content::VideoCaptureGpuJpegDecoder>(decode_done_cb); |
| -} |
| - |
| } // namespace |
| namespace content { |
| -// Instances of this struct go through several different phases during their |
| -// lifetime. |
| -// Phase 1: When first created (in GetOrCreateDeviceEntry()), this consists of |
| -// only the |video_capture_controller|. Clients can already connect to the |
| -// controller, but there is no |video_capture_device| present. |
| -// Phase 2: When a request to "start" the entry comes in (via |
| -// HandleQueuedStartRequest()), creation of |video_capture_device| is scheduled |
| -// to run asynchronously on the Device Thread. |
| -// Phase 3: As soon as the creation of the VideoCaptureDevice is complete, this |
| -// newly created VideoCaptureDevice instance is connected to the |
| -// VideoCaptureController via SetConsumerFeedbackObserver(). |
| -// Phase 4: This phase can only be reached on Android. When the application goes |
| -// to the background, the |video_capture_device| is asynchronously stopped and |
| -// released on the Device Thread. When the application is resumed, we |
| -// transition to Phase 2. |
| -struct VideoCaptureManager::DeviceEntry { |
| - public: |
| - DeviceEntry(MediaStreamType stream_type, |
| - const std::string& id, |
| - const media::VideoCaptureParams& params); |
| - ~DeviceEntry(); |
| - std::unique_ptr<media::VideoCaptureDevice::Client> CreateDeviceClient(); |
| - |
| - const int serial_id; |
| - const MediaStreamType stream_type; |
| - const std::string id; |
| - const media::VideoCaptureParams parameters; |
| - VideoCaptureController video_capture_controller; |
| - std::unique_ptr<media::VideoCaptureDevice> video_capture_device; |
| -}; |
| - |
| // Bundles a media::VideoCaptureDeviceDescriptor with corresponding supported |
| // video formats. |
| struct VideoCaptureManager::DeviceInfo { |
| @@ -235,44 +164,6 @@ class VideoCaptureManager::CaptureDeviceStartRequest { |
| bool abort_start_; |
| }; |
| -VideoCaptureManager::DeviceEntry::DeviceEntry( |
| - MediaStreamType stream_type, |
| - const std::string& id, |
| - const media::VideoCaptureParams& params) |
| - : serial_id(g_device_start_id++), |
| - stream_type(stream_type), |
| - id(id), |
| - parameters(params) {} |
| - |
| -VideoCaptureManager::DeviceEntry::~DeviceEntry() { |
| - DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| - // DCHECK that this DeviceEntry does not still own a |
| - // media::VideoCaptureDevice. media::VideoCaptureDevice must be deleted on |
| - // the device thread. |
| - DCHECK(video_capture_device == nullptr); |
| -} |
| - |
| -std::unique_ptr<media::VideoCaptureDevice::Client> |
| -VideoCaptureManager::DeviceEntry::CreateDeviceClient() { |
| - DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| - |
| - const int max_buffers = stream_type == MEDIA_TAB_VIDEO_CAPTURE |
| - ? kMaxNumberOfBuffersForTabCapture |
| - : kMaxNumberOfBuffers; |
| - scoped_refptr<media::VideoCaptureBufferPool> buffer_pool = |
| - new media::VideoCaptureBufferPoolImpl( |
| - base::MakeUnique<media::VideoCaptureBufferTrackerFactoryImpl>(), |
| - max_buffers); |
| - |
| - return base::MakeUnique<media::VideoCaptureDeviceClient>( |
| - base::MakeUnique<VideoFrameReceiverOnIOThread>( |
| - video_capture_controller.GetWeakPtrForIOThread()), |
| - std::move(buffer_pool), |
| - base::Bind(&CreateGpuJpegDecoder, |
| - base::Bind(&media::VideoFrameReceiver::OnFrameReadyInBuffer, |
| - video_capture_controller.GetWeakPtrForIOThread()))); |
| -} |
| - |
| VideoCaptureManager::DeviceInfo::DeviceInfo() = default; |
| VideoCaptureManager::DeviceInfo::DeviceInfo( |
| @@ -294,8 +185,7 @@ VideoCaptureManager::CaptureDeviceStartRequest::CaptureDeviceStartRequest( |
| : serial_id_(serial_id), |
| session_id_(session_id), |
| params_(params), |
| - abort_start_(false) { |
| -} |
| + abort_start_(false) {} |
| VideoCaptureManager::VideoCaptureManager( |
| std::unique_ptr<media::VideoCaptureDeviceFactory> factory, |
| @@ -365,6 +255,16 @@ void VideoCaptureManager::EnumerateDevices( |
| devices_enumerated_callback)); |
| } |
| +bool VideoCaptureManager::LookupDeviceDescriptor( |
|
miu
2017/03/11 01:13:22
Suggestion for simplification:
media::VideoCaptur
chfremer
2017/03/13 22:02:03
Done.
|
| + const std::string& id, |
| + media::VideoCaptureDeviceDescriptor* descriptor) { |
| + const DeviceInfo* found = GetDeviceInfoById(id); |
| + if (!found) |
| + return false; |
| + *descriptor = found->descriptor; |
| + return true; |
| +} |
| + |
| int VideoCaptureManager::Open(const MediaStreamDevice& device) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| @@ -397,12 +297,12 @@ void VideoCaptureManager::Close(int capture_session_id) { |
| return; |
| } |
| - DeviceEntry* const existing_device = |
| + VideoCaptureDeviceEntry* const existing_device = |
| GetDeviceEntryByTypeAndId(session_it->second.type, session_it->second.id); |
| if (existing_device) { |
| // Remove any client that is still using the session. This is safe to call |
| // even if there are no clients using the session. |
| - existing_device->video_capture_controller.StopSession(capture_session_id); |
| + existing_device->StopSession(capture_session_id); |
| // StopSession() may have removed the last client, so we might need to |
| // close the device. |
| @@ -418,55 +318,54 @@ void VideoCaptureManager::Close(int capture_session_id) { |
| void VideoCaptureManager::QueueStartDevice( |
| media::VideoCaptureSessionId session_id, |
| - DeviceEntry* entry, |
| + VideoCaptureDeviceEntry* entry, |
| const media::VideoCaptureParams& params) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| device_start_queue_.push_back( |
| - CaptureDeviceStartRequest(entry->serial_id, session_id, params)); |
| + CaptureDeviceStartRequest(entry->serial_id(), session_id, params)); |
| if (device_start_queue_.size() == 1) |
| HandleQueuedStartRequest(); |
| } |
| -void VideoCaptureManager::DoStopDevice(DeviceEntry* entry) { |
| +void VideoCaptureManager::DoStopDevice(VideoCaptureDeviceEntry* entry) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| // TODO(mcasas): use a helper function https://crbug.com/624854. |
| DCHECK( |
| - std::find_if(devices_.begin(), devices_.end(), |
| - [entry](const std::unique_ptr<DeviceEntry>& device_entry) { |
| - return device_entry.get() == entry; |
| - }) != devices_.end()); |
| + std::find_if( |
| + devices_.begin(), devices_.end(), |
| + [entry](const scoped_refptr<VideoCaptureDeviceEntry>& device_entry) { |
| + return device_entry.get() == entry; |
| + }) != devices_.end()); |
| // Find the matching start request. |
| for (DeviceStartQueue::reverse_iterator request = |
| device_start_queue_.rbegin(); |
| request != device_start_queue_.rend(); ++request) { |
| - if (request->serial_id() == entry->serial_id) { |
| + if (request->serial_id() == entry->serial_id()) { |
| request->set_abort_start(); |
| DVLOG(3) << "DoStopDevice, aborting start request for device " |
| - << entry->id << " serial_id = " << entry->serial_id; |
| + << entry->id() << " serial_id = " << entry->serial_id(); |
| return; |
| } |
| } |
| - const DeviceInfo* device_info = GetDeviceInfoById(entry->id); |
| + const DeviceInfo* device_info = GetDeviceInfoById(entry->id()); |
| if (device_info != nullptr) { |
| for (auto& observer : capture_observers_) |
| observer.OnVideoCaptureStopped(device_info->descriptor.facing); |
| } |
| - DVLOG(3) << "DoStopDevice. Send stop request for device = " << entry->id |
| - << " serial_id = " << entry->serial_id << "."; |
| - entry->video_capture_controller.OnLog( |
| - base::StringPrintf("Stopping device: id: %s", entry->id.c_str())); |
| - entry->video_capture_controller.SetConsumerFeedbackObserver(nullptr); |
| - |
| - // |entry->video_capture_device| can be null if creating the device has |
| - // failed. |
| - if (entry->video_capture_device) { |
| - device_task_runner_->PostTask( |
| - FROM_HERE, |
| - base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this, |
| - base::Passed(&entry->video_capture_device))); |
| + DVLOG(3) << "DoStopDevice. Send stop request for device = " << entry->id() |
| + << " serial_id = " << entry->serial_id() << "."; |
| + entry->OnLog( |
| + base::StringPrintf("Stopping device: id: %s", entry->id().c_str())); |
| + |
| + if (entry->HasDevice()) { |
| + // Since we may be removing |entry| from |devices_| while |
| + // ReleaseDeviceAsnyc() is executing, we pass it shared ownership to |
| + // |entry|. |
| + entry->ReleaseDeviceAsync(MakeScopedRefptrOwnership( |
| + GetDeviceEntrySharedRefBySerialId(entry->serial_id()))); |
| } |
| } |
| @@ -474,7 +373,7 @@ void VideoCaptureManager::HandleQueuedStartRequest() { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| // Remove all start requests that have been aborted. |
| while (device_start_queue_.begin() != device_start_queue_.end() && |
| - device_start_queue_.begin()->abort_start()) { |
| + device_start_queue_.begin()->abort_start()) { |
| device_start_queue_.pop_front(); |
| } |
| DeviceStartQueue::iterator request = device_start_queue_.begin(); |
| @@ -482,115 +381,49 @@ void VideoCaptureManager::HandleQueuedStartRequest() { |
| return; |
| const int serial_id = request->serial_id(); |
| - DeviceEntry* const entry = GetDeviceEntryBySerialId(serial_id); |
| + VideoCaptureDeviceEntry* const entry = GetDeviceEntryBySerialId(serial_id); |
| DCHECK(entry); |
| DVLOG(3) << "HandleQueuedStartRequest, Post start to device thread, device = " |
| - << entry->id << " start id = " << entry->serial_id; |
| - |
| - std::unique_ptr<media::VideoCaptureDevice::Client> device_client = |
| - entry->CreateDeviceClient(); |
| - |
| - base::Callback<std::unique_ptr<VideoCaptureDevice>(void)> |
| - start_capture_function; |
| - |
| - switch (entry->stream_type) { |
| - case MEDIA_DEVICE_VIDEO_CAPTURE: { |
| - // We look up the device id from the renderer in our local enumeration |
| - // since the renderer does not have all the information that might be |
| - // held in the browser-side VideoCaptureDevice::Name structure. |
| - const DeviceInfo* found = GetDeviceInfoById(entry->id); |
| - if (found) { |
| - entry->video_capture_controller.OnLog( |
| - base::StringPrintf("Starting device: id: %s, name: %s, api: %s", |
| - found->descriptor.device_id.c_str(), |
| - found->descriptor.GetNameAndModel().c_str(), |
| - found->descriptor.GetCaptureApiTypeString())); |
| - |
| - for (auto& observer : capture_observers_) |
| - observer.OnVideoCaptureStarted(found->descriptor.facing); |
| - |
| - 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 |
| - // dancing to get errors processed on the IO thread. But since |
| - // we're on that thread, we call VideoCaptureController |
| - // methods directly. |
| - const std::string log_message = base::StringPrintf( |
| - "Error on %s:%d: device %s unknown. Maybe recently disconnected?", |
| - __FILE__, __LINE__, entry->id.c_str()); |
| - DLOG(ERROR) << log_message; |
| - entry->video_capture_controller.OnLog(log_message); |
| - entry->video_capture_controller.OnError(); |
| - // Drop the failed start request. |
| - device_start_queue_.pop_front(); |
| - |
| - return; |
| - } |
| - break; |
| - } |
| - case MEDIA_TAB_VIDEO_CAPTURE: |
| - 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(std::move(device_client))); |
| - break; |
| - |
| - default: { |
| - NOTIMPLEMENTED(); |
| - return; |
| - } |
| - } |
| - base::PostTaskAndReplyWithResult( |
| - device_task_runner_.get(), FROM_HERE, start_capture_function, |
| - base::Bind(&VideoCaptureManager::OnDeviceStarted, this, |
| - request->serial_id())); |
| -} |
| - |
| -void VideoCaptureManager::OnDeviceStarted( |
| - int serial_id, |
| - std::unique_ptr<VideoCaptureDevice> device) { |
| + << entry->id() << " start id = " << entry->serial_id(); |
| + |
| + // The method CreateAndStartDeviceAsync() is going to run asynchronously. |
| + // Since we may be removing the entry while it is executing, we need to pass |
| + // it shared ownership to itself so that it stays alive while executing. |
| + // And since the execution may make callbacks into |this|, we also need |
| + // to pass it shared ownership to |this|. |
| + auto context_reference = base::MakeUnique<OwnershipCollection>(); |
| + context_reference->AttachOwnership( |
| + MakeScopedRefptrOwnership(scoped_refptr<VideoCaptureManager>(this))); |
| + context_reference->AttachOwnership( |
| + MakeScopedRefptrOwnership(GetDeviceEntrySharedRefBySerialId(serial_id))); |
|
miu
2017/03/11 01:13:22
Interesting. It feels like you're creating your ow
chfremer
2017/03/13 22:02:03
Interesting comparison of this mechanism to a base
|
| + // TODO(chfremer): Check if request->params() can actually be different from |
| + // entry->parameters, and simplify if this is not the case. |
| + entry->CreateAndStartDeviceAsync(request->params(), |
| + static_cast<BuildableDeviceCallbacks*>(this), |
| + std::move(context_reference)); |
| +} |
| + |
| +void VideoCaptureManager::OnDeviceAboutToStart( |
| + media::VideoFacingMode facing_mode) { |
| + for (auto& observer : capture_observers_) |
| + observer.OnVideoCaptureStarted(facing_mode); |
| +} |
| + |
| +void VideoCaptureManager::OnDeviceStarted(VideoCaptureDeviceEntry* entry) { |
| 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. |
| + DCHECK(entry); |
| + DCHECK_EQ(entry->serial_id(), device_start_queue_.begin()->serial_id()); |
| if (device_start_queue_.front().abort_start()) { |
| - // 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(); |
| - base::Closure closure = |
| - base::Bind(&VideoCaptureManager::DoStopDeviceOnDeviceThread, this, |
| - base::Passed(&device)); |
| - if (device_ptr && !device_task_runner_->PostTask(FROM_HERE, closure)) { |
| - // PostTask failed. The device must be stopped anyway. |
| - device_ptr->StopAndDeAllocate(); |
| - } |
| + // A request to release the device may have arrived during the asynchronous |
| + // device startup. |
| + DVLOG(3) << "Device release request has been issued while device was " |
| + << "starting up asynchronously."; |
| + entry->ReleaseDeviceAsync(MakeScopedRefptrOwnership( |
|
miu
2017/03/11 01:13:22
ditto here: Feels like a done callback would work
chfremer
2017/03/13 22:02:03
See other reply.
|
| + GetDeviceEntrySharedRefBySerialId(entry->serial_id()))); |
| } else { |
| - DeviceEntry* const entry = GetDeviceEntryBySerialId(serial_id); |
| - DCHECK(entry); |
| - DCHECK(!entry->video_capture_device); |
| - if (device) { |
| - // Passing raw pointer |device.get()| to the controller is safe, |
| - // because we transfer ownership of it to |entry|. We are calling |
| - // SetConsumerFeedbackObserver(nullptr) before releasing |
| - // |entry->video_capture_device_| on the |device_task_runner_|. |
| - entry->video_capture_controller.SetConsumerFeedbackObserver( |
| - base::MakeUnique<VideoFrameConsumerFeedbackObserverOnTaskRunner>( |
| - device.get(), device_task_runner_)); |
| - } |
| - entry->video_capture_device = std::move(device); |
| - |
| - if (entry->stream_type == MEDIA_DESKTOP_VIDEO_CAPTURE) { |
| + if (entry->stream_type() == MEDIA_DESKTOP_VIDEO_CAPTURE) { |
| const media::VideoCaptureSessionId session_id = |
| device_start_queue_.front().session_id(); |
| DCHECK(session_id != kFakeSessionId); |
| @@ -600,9 +433,10 @@ void VideoCaptureManager::OnDeviceStarted( |
| auto it = photo_request_queue_.begin(); |
| while (it != photo_request_queue_.end()) { |
| auto request = it++; |
| - DeviceEntry* maybe_entry = GetDeviceEntryBySessionId(request->first); |
| - if (maybe_entry && maybe_entry->video_capture_device) { |
| - request->second.Run(maybe_entry->video_capture_device.get()); |
| + VideoCaptureDeviceEntry* maybe_entry = |
| + GetDeviceEntryBySessionId(request->first); |
| + if (maybe_entry && maybe_entry->HasDevice()) { |
| + request->second.Run(); |
| photo_request_queue_.erase(request); |
| } |
| } |
| @@ -612,97 +446,16 @@ void VideoCaptureManager::OnDeviceStarted( |
| HandleQueuedStartRequest(); |
| } |
| -std::unique_ptr<media::VideoCaptureDevice> |
| -VideoCaptureManager::DoStartDeviceCaptureOnDeviceThread( |
| - const VideoCaptureDeviceDescriptor& descriptor, |
| - const media::VideoCaptureParams& params, |
| - std::unique_ptr<VideoCaptureDevice::Client> device_client) { |
| - SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StartDeviceTime"); |
| - DCHECK(IsOnDeviceThread()); |
| - |
| - std::unique_ptr<VideoCaptureDevice> video_capture_device; |
| - video_capture_device = |
| - video_capture_device_factory_->CreateDevice(descriptor); |
| - |
| - if (!video_capture_device) { |
| - device_client->OnError(FROM_HERE, "Could not create capture device"); |
| - return nullptr; |
| - } |
| - |
| - video_capture_device->AllocateAndStart(params, std::move(device_client)); |
| - return video_capture_device; |
| -} |
| - |
| -std::unique_ptr<media::VideoCaptureDevice> |
| -VideoCaptureManager::DoStartTabCaptureOnDeviceThread( |
| - const std::string& id, |
| - const media::VideoCaptureParams& params, |
| - std::unique_ptr<VideoCaptureDevice::Client> device_client) { |
| - SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StartDeviceTime"); |
| - DCHECK(IsOnDeviceThread()); |
| - |
| - std::unique_ptr<VideoCaptureDevice> video_capture_device; |
| -#if defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_WIN) |
| - video_capture_device = WebContentsVideoCaptureDevice::Create(id); |
| -#endif |
| - |
| - if (!video_capture_device) { |
| - device_client->OnError(FROM_HERE, "Could not create capture device"); |
| - return nullptr; |
| - } |
| - |
| - video_capture_device->AllocateAndStart(params, std::move(device_client)); |
| - return video_capture_device; |
| -} |
| +void VideoCaptureManager::OnDeviceStartFailed(VideoCaptureDeviceEntry* entry) { |
| + const std::string log_message = base::StringPrintf( |
| + "Starting device %s has failed. Maybe recently disconnected?", |
| + entry->id().c_str()); |
| + DLOG(ERROR) << log_message; |
| + entry->OnLog(log_message); |
| + entry->OnError(); |
| -std::unique_ptr<media::VideoCaptureDevice> |
| -VideoCaptureManager::DoStartDesktopCaptureOnDeviceThread( |
| - const std::string& id, |
| - const media::VideoCaptureParams& params, |
| - std::unique_ptr<VideoCaptureDevice::Client> device_client) { |
| - SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StartDeviceTime"); |
| - DCHECK(IsOnDeviceThread()); |
| - |
| - std::unique_ptr<VideoCaptureDevice> video_capture_device; |
| -#if defined(ENABLE_SCREEN_CAPTURE) |
| - DesktopMediaID desktop_id = DesktopMediaID::Parse(id); |
| - if (desktop_id.is_null()) { |
| - device_client->OnError(FROM_HERE, "Desktop media ID is null"); |
| - return nullptr; |
| - } |
| - |
| - if (desktop_id.type == DesktopMediaID::TYPE_WEB_CONTENTS) { |
| -#if defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_WIN) |
| - video_capture_device = WebContentsVideoCaptureDevice::Create(id); |
| - IncrementDesktopCaptureCounter(TAB_VIDEO_CAPTURER_CREATED); |
| - if (desktop_id.audio_share) { |
| - IncrementDesktopCaptureCounter(TAB_VIDEO_CAPTURER_CREATED_WITH_AUDIO); |
| - } else { |
| - IncrementDesktopCaptureCounter(TAB_VIDEO_CAPTURER_CREATED_WITHOUT_AUDIO); |
| - } |
| -#endif |
| - } else { |
| -#if defined(OS_ANDROID) |
| - video_capture_device = base::MakeUnique<ScreenCaptureDeviceAndroid>(); |
| -#else |
| -#if defined(USE_AURA) |
| - video_capture_device = DesktopCaptureDeviceAura::Create(desktop_id); |
| -#endif // defined(USE_AURA) |
| -#if BUILDFLAG(ENABLE_WEBRTC) |
| - if (!video_capture_device) |
| - video_capture_device = DesktopCaptureDevice::Create(desktop_id); |
| -#endif // BUILDFLAG(ENABLE_WEBRTC) |
| -#endif // defined (OS_ANDROID) |
| - } |
| -#endif // defined(ENABLE_SCREEN_CAPTURE) |
| - |
| - if (!video_capture_device) { |
| - device_client->OnError(FROM_HERE, "Could not create capture device"); |
| - return nullptr; |
| - } |
| - |
| - video_capture_device->AllocateAndStart(params, std::move(device_client)); |
| - return video_capture_device; |
| + device_start_queue_.pop_front(); |
| + HandleQueuedStartRequest(); |
| } |
| void VideoCaptureManager::StartCaptureForClient( |
| @@ -715,7 +468,7 @@ void VideoCaptureManager::StartCaptureForClient( |
| DVLOG(1) << __func__ << ", session_id = " << session_id << ", request: " |
| << media::VideoCaptureFormat::ToString(params.requested_format); |
| - DeviceEntry* entry = GetOrCreateDeviceEntry(session_id, params); |
| + VideoCaptureDeviceEntry* entry = GetOrCreateDeviceEntry(session_id, params); |
| if (!entry) { |
| done_cb.Run(base::WeakPtr<VideoCaptureController>()); |
| return; |
| @@ -724,16 +477,14 @@ void VideoCaptureManager::StartCaptureForClient( |
| LogVideoCaptureEvent(VIDEO_CAPTURE_START_CAPTURE); |
| // First client starts the device. |
| - if (!entry->video_capture_controller.HasActiveClient() && |
| - !entry->video_capture_controller.HasPausedClient()) { |
| - DVLOG(1) << "VideoCaptureManager starting device (type = " |
| - << entry->stream_type << ", id = " << entry->id << ")"; |
| + if (!entry->HasActiveClient() && !entry->HasPausedClient()) { |
| + DVLOG(1) << "VideoCaptureManager starting device (id = " << entry->id() |
| + << ")"; |
| QueueStartDevice(session_id, entry, params); |
| } |
| // Run the callback first, as AddClient() may trigger OnFrameInfo(). |
| - done_cb.Run(entry->video_capture_controller.GetWeakPtrForIOThread()); |
| - entry->video_capture_controller.AddClient(client_id, client_handler, |
| - session_id, params); |
| + done_cb.Run(entry->GetControllerWeakPtrForIOThread()); |
| + entry->AddClient(client_id, client_handler, session_id, params); |
| } |
| void VideoCaptureManager::StopCaptureForClient( |
| @@ -745,7 +496,7 @@ void VideoCaptureManager::StopCaptureForClient( |
| DCHECK(controller); |
| DCHECK(client_handler); |
| - DeviceEntry* entry = GetDeviceEntryByController(controller); |
| + VideoCaptureDeviceEntry* entry = GetDeviceEntryByController(controller); |
| if (!entry) { |
| NOTREACHED(); |
| return; |
| @@ -753,7 +504,7 @@ void VideoCaptureManager::StopCaptureForClient( |
| if (!aborted_due_to_error) { |
| if (controller->has_received_frames()) { |
| LogVideoCaptureEvent(VIDEO_CAPTURE_STOP_CAPTURE_OK); |
| - } else if (entry->stream_type == MEDIA_DEVICE_VIDEO_CAPTURE) { |
| + } else if (entry->stream_type() == MEDIA_DEVICE_VIDEO_CAPTURE) { |
| LogVideoCaptureEvent( |
| VIDEO_CAPTURE_STOP_CAPTURE_OK_NO_FRAMES_PRODUCED_BY_DEVICE); |
| } else { |
| @@ -763,7 +514,8 @@ void VideoCaptureManager::StopCaptureForClient( |
| } else { |
| LogVideoCaptureEvent(VIDEO_CAPTURE_STOP_CAPTURE_DUE_TO_ERROR); |
| for (auto it : sessions_) { |
| - if (it.second.type == entry->stream_type && it.second.id == entry->id) { |
| + if (it.second.type == entry->stream_type() && |
| + it.second.id == entry->id()) { |
| for (auto& listener : listeners_) |
| listener.Aborted(it.second.type, it.first); |
| // Aborted() call might synchronously destroy |entry|, recheck. |
| @@ -791,7 +543,7 @@ void VideoCaptureManager::PauseCaptureForClient( |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| DCHECK(controller); |
| DCHECK(client_handler); |
| - DeviceEntry* entry = GetDeviceEntryByController(controller); |
| + VideoCaptureDeviceEntry* entry = GetDeviceEntryByController(controller); |
| if (!entry) |
| NOTREACHED() << "Got Null entry while pausing capture"; |
| @@ -799,16 +551,9 @@ void VideoCaptureManager::PauseCaptureForClient( |
| controller->PauseClient(client_id, client_handler); |
| if (!had_active_client || controller->HasActiveClient()) |
| return; |
| - if (media::VideoCaptureDevice* device = entry->video_capture_device.get()) { |
| - device_task_runner_->PostTask( |
| - FROM_HERE, |
| - base::Bind(&VideoCaptureDevice::MaybeSuspend, |
| - // Unretained is safe to use here because |device| would be |
| - // null if it was scheduled for shutdown and destruction, and |
| - // because this task is guaranteed to run before the task |
| - // that destroys the |device|. |
| - base::Unretained(device))); |
| - } |
| + if (entry->HasDevice() == false) |
|
miu
2017/03/11 01:13:22
nit:
if (!entry->HasDevice())
(and in multiple
chfremer
2017/03/13 22:02:03
Done.
|
| + return; |
| + entry->MaybeSuspend(); |
| } |
| void VideoCaptureManager::ResumeCaptureForClient( |
| @@ -821,7 +566,7 @@ void VideoCaptureManager::ResumeCaptureForClient( |
| DCHECK(controller); |
| DCHECK(client_handler); |
| - DeviceEntry* entry = GetDeviceEntryByController(controller); |
| + VideoCaptureDeviceEntry* entry = GetDeviceEntryByController(controller); |
| if (!entry) |
| NOTREACHED() << "Got Null entry while resuming capture"; |
| @@ -829,33 +574,19 @@ void VideoCaptureManager::ResumeCaptureForClient( |
| controller->ResumeClient(client_id, client_handler); |
| if (had_active_client || !controller->HasActiveClient()) |
| return; |
| - if (media::VideoCaptureDevice* device = entry->video_capture_device.get()) { |
| - device_task_runner_->PostTask( |
| - FROM_HERE, |
| - base::Bind(&VideoCaptureDevice::Resume, |
| - // Unretained is safe to use here because |device| would be |
| - // null if it was scheduled for shutdown and destruction, and |
| - // because this task is guaranteed to run before the task |
| - // that destroys the |device|. |
| - base::Unretained(device))); |
| - } |
| + if (entry->HasDevice() == false) |
| + return; |
| + entry->Resume(); |
| } |
| void VideoCaptureManager::RequestRefreshFrameForClient( |
| VideoCaptureController* controller) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| - if (DeviceEntry* entry = GetDeviceEntryByController(controller)) { |
| - if (media::VideoCaptureDevice* device = entry->video_capture_device.get()) { |
| - device_task_runner_->PostTask( |
| - FROM_HERE, |
| - base::Bind(&VideoCaptureDevice::RequestRefreshFrame, |
| - // Unretained is safe to use here because |device| would be |
| - // null if it was scheduled for shutdown and destruction, |
| - // and because this task is guaranteed to run before the |
| - // task that destroys the |device|. |
| - base::Unretained(device))); |
| - } |
| + if (VideoCaptureDeviceEntry* entry = GetDeviceEntryByController(controller)) { |
| + if (entry->HasDevice() == false) |
| + return; |
| + entry->RequestRefreshFrame(); |
| } |
| } |
| @@ -907,12 +638,11 @@ bool VideoCaptureManager::GetDeviceFormatsInUse( |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| DCHECK(formats_in_use->empty()); |
| // Return the currently in-use format(s) of the device, if it's started. |
| - DeviceEntry* device_in_use = |
| + VideoCaptureDeviceEntry* device_in_use = |
| GetDeviceEntryByTypeAndId(stream_type, device_id); |
| if (device_in_use) { |
| // Currently only one format-in-use is supported at the VCC level. |
| - formats_in_use->push_back( |
| - device_in_use->video_capture_controller.GetVideoCaptureFormat()); |
| + formats_in_use->push_back(device_in_use->GetVideoCaptureFormat()); |
| } |
| return true; |
| } |
| @@ -933,20 +663,20 @@ void VideoCaptureManager::MaybePostDesktopCaptureWindowId( |
| if (session_it == sessions_.end()) |
| return; |
| - DeviceEntry* const existing_device = |
| + VideoCaptureDeviceEntry* const existing_device = |
| GetDeviceEntryByTypeAndId(session_it->second.type, session_it->second.id); |
| if (!existing_device) { |
| DVLOG(2) << "Failed to find an existing screen capture device."; |
| return; |
| } |
| - if (!existing_device->video_capture_device) { |
| + if (!existing_device->HasDevice()) { |
| DVLOG(2) << "Screen capture device not yet started."; |
| return; |
| } |
| - DCHECK_EQ(MEDIA_DESKTOP_VIDEO_CAPTURE, existing_device->stream_type); |
| - DesktopMediaID id = DesktopMediaID::Parse(existing_device->id); |
| + DCHECK_EQ(MEDIA_DESKTOP_VIDEO_CAPTURE, existing_device->stream_type()); |
| + DesktopMediaID id = DesktopMediaID::Parse(existing_device->id()); |
| if (id.is_null()) |
| return; |
| @@ -956,83 +686,66 @@ void VideoCaptureManager::MaybePostDesktopCaptureWindowId( |
| return; |
| } |
| - // Post |existing_device->video_capture_device| to the VideoCaptureDevice to |
| - // the device_task_runner_. This is safe since the device is destroyed on the |
| - // device_task_runner_. |
| - device_task_runner_->PostTask( |
| - FROM_HERE, |
| - base::Bind(&VideoCaptureManager::SetDesktopCaptureWindowIdOnDeviceThread, |
| - this, existing_device->video_capture_device.get(), |
| - window_id_it->second)); |
| - |
| + existing_device->SetDesktopCaptureWindowIdAsync( |
| + window_id_it->second, |
| + MakeScopedRefptrOwnership(scoped_refptr<VideoCaptureManager>(this))); |
| notification_window_ids_.erase(window_id_it); |
| } |
| void VideoCaptureManager::GetPhotoCapabilities( |
| int session_id, |
| - VideoCaptureDevice::GetPhotoCapabilitiesCallback callback) { |
| + media::VideoCaptureDevice::GetPhotoCapabilitiesCallback callback) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| - const DeviceEntry* entry = GetDeviceEntryBySessionId(session_id); |
| + const VideoCaptureDeviceEntry* entry = GetDeviceEntryBySessionId(session_id); |
| if (!entry) |
| return; |
| - VideoCaptureDevice* device = entry->video_capture_device.get(); |
| - if (device) { |
| - VideoCaptureManager::DoGetPhotoCapabilities(std::move(callback), device); |
| + if (entry->HasDevice()) { |
| + entry->GetPhotoCapabilities(std::move(callback)); |
| return; |
| } |
| // |entry| is known but |device| is nullptr, queue up a request for later. |
| photo_request_queue_.emplace_back( |
| - session_id, base::Bind(&VideoCaptureManager::DoGetPhotoCapabilities, this, |
| - base::Passed(&callback))); |
| + session_id, base::Bind(&VideoCaptureDeviceEntry::GetPhotoCapabilities, |
| + base::Unretained(entry), base::Passed(&callback))); |
| } |
| void VideoCaptureManager::SetPhotoOptions( |
| int session_id, |
| media::mojom::PhotoSettingsPtr settings, |
| - VideoCaptureDevice::SetPhotoOptionsCallback callback) { |
| + media::VideoCaptureDevice::SetPhotoOptionsCallback callback) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| - const DeviceEntry* entry = GetDeviceEntryBySessionId(session_id); |
| + VideoCaptureDeviceEntry* entry = GetDeviceEntryBySessionId(session_id); |
| if (!entry) |
| return; |
| - VideoCaptureDevice* device = entry->video_capture_device.get(); |
| - if (device) { |
| - VideoCaptureManager::DoSetPhotoOptions(std::move(callback), |
| - std::move(settings), device); |
| + if (entry->HasDevice()) { |
| + entry->SetPhotoOptions(std::move(settings), std::move(callback)); |
| return; |
| } |
| // |entry| is known but |device| is nullptr, queue up a request for later. |
| photo_request_queue_.emplace_back( |
| - session_id, base::Bind(&VideoCaptureManager::DoSetPhotoOptions, this, |
| - base::Passed(&callback), base::Passed(&settings))); |
| + session_id, base::Bind(&VideoCaptureDeviceEntry::SetPhotoOptions, |
| + base::Unretained(entry), base::Passed(&settings), |
| + base::Passed(&callback))); |
| } |
| void VideoCaptureManager::TakePhoto( |
| int session_id, |
| - VideoCaptureDevice::TakePhotoCallback callback) { |
| + media::VideoCaptureDevice::TakePhotoCallback callback) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| - const DeviceEntry* entry = GetDeviceEntryBySessionId(session_id); |
| + VideoCaptureDeviceEntry* entry = GetDeviceEntryBySessionId(session_id); |
| if (!entry) |
| return; |
| - VideoCaptureDevice* device = entry->video_capture_device.get(); |
| - if (device) { |
| - VideoCaptureManager::DoTakePhoto(std::move(callback), device); |
| + if (entry->HasDevice()) { |
| + entry->TakePhoto(std::move(callback)); |
| return; |
| } |
| // |entry| is known but |device| is nullptr, queue up a request for later. |
| photo_request_queue_.emplace_back( |
| - session_id, base::Bind(&VideoCaptureManager::DoTakePhoto, this, |
| - base::Passed(&callback))); |
| -} |
| - |
| -void VideoCaptureManager::DoStopDeviceOnDeviceThread( |
| - std::unique_ptr<VideoCaptureDevice> device) { |
| - SCOPED_UMA_HISTOGRAM_TIMER("Media.VideoCaptureManager.StopDeviceTime"); |
| - DCHECK(IsOnDeviceThread()); |
| - device->StopAndDeAllocate(); |
| - DVLOG(3) << "DoStopDeviceOnDeviceThread"; |
| + session_id, base::Bind(&VideoCaptureDeviceEntry::TakePhoto, |
| + base::Unretained(entry), base::Passed(&callback))); |
| } |
| void VideoCaptureManager::OnOpened( |
| @@ -1070,9 +783,6 @@ void VideoCaptureManager::OnDevicesInfoEnumerated( |
| for (const auto& it : devices_info_cache_) { |
| devices.emplace_back(it.descriptor); |
| descriptors_and_formats.emplace_back(it.descriptor, it.supported_formats); |
| - } |
| - |
| - if (!descriptors_and_formats.empty()) { |
| MediaInternals::GetInstance()->UpdateVideoCaptureDeviceCapabilities( |
| descriptors_and_formats); |
| } |
| @@ -1118,31 +828,32 @@ void VideoCaptureManager::ConsolidateDevicesInfoOnDeviceThread( |
| on_devices_enumerated_callback.Run(new_devices_info_cache); |
| } |
| -void VideoCaptureManager::DestroyDeviceEntryIfNoClients(DeviceEntry* entry) { |
| +void VideoCaptureManager::DestroyDeviceEntryIfNoClients( |
| + VideoCaptureDeviceEntry* entry) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| // Removal of the last client stops the device. |
| - if (!entry->video_capture_controller.HasActiveClient() && |
| - !entry->video_capture_controller.HasPausedClient()) { |
| + if (!entry->HasActiveClient() && !entry->HasPausedClient()) { |
| DVLOG(1) << "VideoCaptureManager stopping device (type = " |
| - << entry->stream_type << ", id = " << entry->id << ")"; |
| + << entry->stream_type() << ", id = " << entry->id() << ")"; |
| - // The DeviceEntry is removed from |devices_| immediately. The controller is |
| - // deleted immediately, and the device is freed asynchronously. After this |
| - // point, subsequent requests to open this same device ID will create a new |
| - // DeviceEntry, VideoCaptureController, and VideoCaptureDevice. |
| + // The VideoCaptureDeviceEntry is removed from |devices_| immediately. The |
| + // controller is deleted immediately, and the device is freed |
| + // asynchronously. After this point, subsequent requests to open this same |
| + // device ID will create a new VideoCaptureDeviceEntry, |
| + // VideoCaptureController, and VideoCaptureDevice. |
| DoStopDevice(entry); |
| // TODO(mcasas): use a helper function https://crbug.com/624854. |
| - DeviceEntries::iterator device_it = |
| - std::find_if(devices_.begin(), devices_.end(), |
| - [entry](const std::unique_ptr<DeviceEntry>& device_entry) { |
| - return device_entry.get() == entry; |
| - }); |
| + DeviceEntries::iterator device_it = std::find_if( |
| + devices_.begin(), devices_.end(), |
| + [entry](const scoped_refptr<VideoCaptureDeviceEntry>& device_entry) { |
| + return device_entry.get() == entry; |
| + }); |
| devices_.erase(device_it); |
| } |
| } |
| -VideoCaptureManager::DeviceEntry* |
| -VideoCaptureManager::GetDeviceEntryBySessionId(int session_id) { |
| +VideoCaptureDeviceEntry* VideoCaptureManager::GetDeviceEntryBySessionId( |
| + int session_id) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| SessionMap::const_iterator session_it = sessions_.find(session_id); |
| if (session_it == sessions_.end()) |
| @@ -1152,43 +863,52 @@ VideoCaptureManager::GetDeviceEntryBySessionId(int session_id) { |
| session_it->second.id); |
| } |
| -VideoCaptureManager::DeviceEntry* |
| -VideoCaptureManager::GetDeviceEntryByTypeAndId( |
| +VideoCaptureDeviceEntry* VideoCaptureManager::GetDeviceEntryByTypeAndId( |
| MediaStreamType type, |
| const std::string& device_id) const { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| - for (const std::unique_ptr<DeviceEntry>& device : devices_) { |
| - if (type == device->stream_type && device_id == device->id) |
| + for (const auto& device : devices_) { |
| + if (type == device->stream_type() && device_id == device->id()) |
| return device.get(); |
| } |
| return nullptr; |
| } |
| -VideoCaptureManager::DeviceEntry* |
| -VideoCaptureManager::GetDeviceEntryByController( |
| +VideoCaptureDeviceEntry* VideoCaptureManager::GetDeviceEntryByController( |
| const VideoCaptureController* controller) const { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| // Look up |controller| in |devices_|. |
| - for (const std::unique_ptr<DeviceEntry>& device : devices_) { |
| - if (&device->video_capture_controller == controller) |
| + for (const auto& device : devices_) { |
| + if (device->CorrespondsToController(controller)) |
| return device.get(); |
| } |
| return nullptr; |
| } |
| -VideoCaptureManager::DeviceEntry* VideoCaptureManager::GetDeviceEntryBySerialId( |
| +VideoCaptureDeviceEntry* VideoCaptureManager::GetDeviceEntryBySerialId( |
| int serial_id) const { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| - for (const std::unique_ptr<DeviceEntry>& device : devices_) { |
| - if (device->serial_id == serial_id) |
| + for (const auto& device : devices_) { |
| + if (device->serial_id() == serial_id) |
| return device.get(); |
| } |
| return nullptr; |
| } |
| +scoped_refptr<VideoCaptureDeviceEntry> |
| +VideoCaptureManager::GetDeviceEntrySharedRefBySerialId(int serial_id) const { |
| + DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| + |
| + for (const auto& device : devices_) { |
| + if (device->serial_id() == serial_id) |
| + return device; |
| + } |
| + return nullptr; |
| +} |
| + |
| VideoCaptureManager::DeviceInfo* VideoCaptureManager::GetDeviceInfoById( |
| const std::string& id) { |
| for (auto& it : devices_info_cache_) { |
| @@ -1198,7 +918,7 @@ VideoCaptureManager::DeviceInfo* VideoCaptureManager::GetDeviceInfoById( |
| return nullptr; |
| } |
| -VideoCaptureManager::DeviceEntry* VideoCaptureManager::GetOrCreateDeviceEntry( |
| +VideoCaptureDeviceEntry* VideoCaptureManager::GetOrCreateDeviceEntry( |
| media::VideoCaptureSessionId capture_session_id, |
| const media::VideoCaptureParams& params) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| @@ -1210,63 +930,19 @@ VideoCaptureManager::DeviceEntry* VideoCaptureManager::GetOrCreateDeviceEntry( |
| // Check if another session has already opened this device. If so, just |
| // use that opened device. |
| - DeviceEntry* const existing_device = |
| + VideoCaptureDeviceEntry* const existing_device = |
| GetDeviceEntryByTypeAndId(device_info.type, device_info.id); |
| if (existing_device) { |
| - DCHECK_EQ(device_info.type, existing_device->stream_type); |
| + DCHECK_EQ(device_info.type, existing_device->stream_type()); |
| return existing_device; |
| } |
| - devices_.emplace_back( |
| - new DeviceEntry(device_info.type, device_info.id, params)); |
| - return devices_.back().get(); |
| -} |
| - |
| -void VideoCaptureManager::SetDesktopCaptureWindowIdOnDeviceThread( |
| - media::VideoCaptureDevice* device, |
| - gfx::NativeViewId window_id) { |
| - DCHECK(IsOnDeviceThread()); |
| -#if defined(ENABLE_SCREEN_CAPTURE) && BUILDFLAG(ENABLE_WEBRTC) && !defined(OS_ANDROID) |
| - DesktopCaptureDevice* desktop_device = |
| - static_cast<DesktopCaptureDevice*>(device); |
| - desktop_device->SetNotificationWindowId(window_id); |
| - VLOG(2) << "Screen capture notification window passed on device thread."; |
| -#endif |
| -} |
| - |
| -void VideoCaptureManager::DoGetPhotoCapabilities( |
| - VideoCaptureDevice::GetPhotoCapabilitiesCallback callback, |
| - VideoCaptureDevice* device) { |
| - // Unretained() is safe to use here because |device| would be null if it |
| - // was scheduled for shutdown and destruction, and because this task is |
| - // guaranteed to run before the task that destroys the |device|. |
| - device_task_runner_->PostTask( |
| - FROM_HERE, base::Bind(&VideoCaptureDevice::GetPhotoCapabilities, |
| - base::Unretained(device), base::Passed(&callback))); |
| -} |
| - |
| -void VideoCaptureManager::DoSetPhotoOptions( |
| - VideoCaptureDevice::SetPhotoOptionsCallback callback, |
| - media::mojom::PhotoSettingsPtr settings, |
| - VideoCaptureDevice* device) { |
| - // Unretained() is safe to use here because |device| would be null if it |
| - // was scheduled for shutdown and destruction, and because this task is |
| - // guaranteed to run before the task that destroys the |device|. |
| - device_task_runner_->PostTask( |
| - FROM_HERE, |
| - base::Bind(&VideoCaptureDevice::SetPhotoOptions, base::Unretained(device), |
| - base::Passed(&settings), base::Passed(&callback))); |
| -} |
| - |
| -void VideoCaptureManager::DoTakePhoto( |
| - VideoCaptureDevice::TakePhotoCallback callback, |
| - VideoCaptureDevice* device) { |
| - // Unretained() is safe to use here because |device| would be null if it |
| - // was scheduled for shutdown and destruction, and because this task is |
| - // guaranteed to run before the task that destroys the |device|. |
| - device_task_runner_->PostTask( |
| - FROM_HERE, base::Bind(&VideoCaptureDevice::TakePhoto, |
| - base::Unretained(device), base::Passed(&callback))); |
| + VideoCaptureDeviceEntry* new_device_entry = new VideoCaptureDeviceEntry( |
| + device_info.id, device_info.type, params, |
| + base::MakeUnique<InProcessBuildableVideoCaptureDevice>( |
| + device_task_runner_, video_capture_device_factory_.get())); |
| + devices_.emplace_back(new_device_entry); |
| + return new_device_entry; |
| } |
| base::Optional<CameraCalibration> VideoCaptureManager::GetCameraCalibration( |
| @@ -1299,7 +975,7 @@ void VideoCaptureManager::ReleaseDevices() { |
| for (auto& entry : devices_) { |
| // Do not stop Content Video Capture devices, e.g. Tab or Screen capture. |
| - if (entry->stream_type != MEDIA_DEVICE_VIDEO_CAPTURE) |
| + if (entry->stream_type() != MEDIA_DEVICE_VIDEO_CAPTURE) |
| continue; |
| DoStopDevice(entry.get()); |
| @@ -1312,14 +988,14 @@ void VideoCaptureManager::ResumeDevices() { |
| for (auto& entry : devices_) { |
| // Do not resume Content Video Capture devices, e.g. Tab or Screen capture. |
| // Do not try to restart already running devices. |
| - if (entry->stream_type != MEDIA_DEVICE_VIDEO_CAPTURE || |
| - entry->video_capture_device) |
| + if (entry->stream_type() != MEDIA_DEVICE_VIDEO_CAPTURE || |
| + entry->HasDevice()) |
| continue; |
| // Check if the device is already in the start queue. |
| bool device_in_queue = false; |
| for (auto& request : device_start_queue_) { |
| - if (request.serial_id() == entry->serial_id) { |
| + if (request.serial_id() == entry->serial_id()) { |
| device_in_queue = true; |
| break; |
| } |
| @@ -1328,7 +1004,7 @@ void VideoCaptureManager::ResumeDevices() { |
| if (!device_in_queue) { |
| // Session ID is only valid for Screen capture. So we can fake it to |
| // resume video capture devices here. |
| - QueueStartDevice(kFakeSessionId, entry.get(), entry->parameters); |
| + QueueStartDevice(kFakeSessionId, entry.get(), entry->parameters()); |
| } |
| } |
| } |