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 c5b56cea4fe37a2491dd0ce19afd1d2702a22862..57fd9d94f5ce6443dc0a1c30fd1d79f00bdae91b 100644 |
| --- a/content/browser/renderer_host/media/video_capture_manager.cc |
| +++ b/content/browser/renderer_host/media/video_capture_manager.cc |
| @@ -58,51 +58,6 @@ |
| namespace { |
| -// 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 |
| -// by the ConsolidateCaptureFormats() method. |
| -bool IsCaptureFormatSmaller(const media::VideoCaptureFormat& format1, |
| - const media::VideoCaptureFormat& format2) { |
| - DCHECK(format1.frame_size.GetCheckedArea().IsValid()); |
| - DCHECK(format2.frame_size.GetCheckedArea().IsValid()); |
| - if (format1.frame_size.GetCheckedArea().ValueOrDefault(0) == |
| - format2.frame_size.GetCheckedArea().ValueOrDefault(0)) { |
| - return format1.frame_rate > format2.frame_rate; |
| - } |
| - return format1.frame_size.GetCheckedArea().ValueOrDefault(0) < |
| - format2.frame_size.GetCheckedArea().ValueOrDefault(0); |
| -} |
| - |
| -bool IsCaptureFormatSizeEqual(const media::VideoCaptureFormat& format1, |
| - const media::VideoCaptureFormat& format2) { |
| - DCHECK(format1.frame_size.GetCheckedArea().IsValid()); |
| - DCHECK(format2.frame_size.GetCheckedArea().IsValid()); |
| - return format1.frame_size.GetCheckedArea().ValueOrDefault(0) == |
| - format2.frame_size.GetCheckedArea().ValueOrDefault(0); |
| -} |
| - |
| -// This function receives a list of capture formats, removes duplicated |
| -// resolutions while keeping the highest frame rate for each, and forcing I420 |
| -// pixel format. |
| -void ConsolidateCaptureFormats(media::VideoCaptureFormats* formats) { |
| - if (formats->empty()) |
| - return; |
| - std::sort(formats->begin(), formats->end(), IsCaptureFormatSmaller); |
| - // Due to the ordering imposed, the largest frame_rate is kept while removing |
| - // duplicated resolutions. |
| - media::VideoCaptureFormats::iterator last = |
| - std::unique(formats->begin(), formats->end(), IsCaptureFormatSizeEqual); |
| - formats->erase(last, formats->end()); |
| - // Mark all formats as I420, since this is what the renderer side will get |
| - // anyhow: the actual pixel format is decided at the device level. |
| - // Don't do this for Y16 format as it is handled separatelly. |
| - for (auto& format : *formats) { |
| - if (format.pixel_format != media::PIXEL_FORMAT_Y16) |
| - format.pixel_format = media::PIXEL_FORMAT_I420; |
| - } |
| -} |
| - |
| // 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. |
| @@ -126,19 +81,6 @@ const media::VideoCaptureSessionId kFakeSessionId = -1; |
| namespace content { |
| -// Bundles a media::VideoCaptureDeviceDescriptor with corresponding supported |
| -// video formats. |
| -struct VideoCaptureManager::DeviceInfo { |
| - DeviceInfo(); |
| - DeviceInfo(media::VideoCaptureDeviceDescriptor descriptor); |
| - DeviceInfo(const DeviceInfo& other); |
| - ~DeviceInfo(); |
| - DeviceInfo& operator=(const DeviceInfo& other); |
| - |
| - media::VideoCaptureDeviceDescriptor descriptor; |
| - media::VideoCaptureFormats supported_formats; |
| -}; |
| - |
| // Class used for queuing request for starting a device. |
| class VideoCaptureManager::CaptureDeviceStartRequest { |
| public: |
| @@ -155,20 +97,6 @@ class VideoCaptureManager::CaptureDeviceStartRequest { |
| const media::VideoCaptureParams params_; |
| }; |
| -VideoCaptureManager::DeviceInfo::DeviceInfo() = default; |
| - |
| -VideoCaptureManager::DeviceInfo::DeviceInfo( |
| - media::VideoCaptureDeviceDescriptor descriptor) |
| - : descriptor(descriptor) {} |
| - |
| -VideoCaptureManager::DeviceInfo::DeviceInfo( |
| - const VideoCaptureManager::DeviceInfo& other) = default; |
| - |
| -VideoCaptureManager::DeviceInfo::~DeviceInfo() = default; |
| - |
| -VideoCaptureManager::DeviceInfo& VideoCaptureManager::DeviceInfo::operator=( |
| - const VideoCaptureManager::DeviceInfo& other) = default; |
| - |
| VideoCaptureManager::CaptureDeviceStartRequest::CaptureDeviceStartRequest( |
| VideoCaptureController* controller, |
| media::VideoCaptureSessionId session_id, |
| @@ -176,11 +104,11 @@ VideoCaptureManager::CaptureDeviceStartRequest::CaptureDeviceStartRequest( |
| : controller_(controller), session_id_(session_id), params_(params) {} |
| VideoCaptureManager::VideoCaptureManager( |
| - std::unique_ptr<media::VideoCaptureDeviceFactory> factory, |
| + std::unique_ptr<media::VideoCaptureSystem> video_capture_system, |
| scoped_refptr<base::SingleThreadTaskRunner> device_task_runner) |
| : device_task_runner_(std::move(device_task_runner)), |
| new_capture_session_id_(1), |
| - video_capture_device_factory_(std::move(factory)) {} |
| + video_capture_system_(std::move(video_capture_system)) {} |
| VideoCaptureManager::~VideoCaptureManager() { |
| DCHECK(controllers_.empty()); |
| @@ -224,29 +152,17 @@ void VideoCaptureManager::EnumerateDevices( |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| DVLOG(1) << "VideoCaptureManager::EnumerateDevices"; |
| - // Bind a callback to ConsolidateDevicesInfoOnDeviceThread() with an argument |
| - // for another callback to OnDevicesInfoEnumerated() to be run in the current |
| - // loop, i.e. IO loop. Pass a timer for UMA histogram collection. |
| - base::Callback<void(std::unique_ptr<VideoCaptureDeviceDescriptors>)> |
| - devices_enumerated_callback = base::Bind( |
| - &VideoCaptureManager::ConsolidateDevicesInfoOnDeviceThread, this, |
| - media::BindToCurrentLoop(base::Bind( |
| - &VideoCaptureManager::OnDevicesInfoEnumerated, this, |
| - base::Owned(new base::ElapsedTimer()), client_callback)), |
| - devices_info_cache_); |
| - // OK to use base::Unretained() since we own the VCDFactory and |this| is |
| - // bound in |devices_enumerated_callback|. |
| + // OK to use base::Unretained(video_capture_system_) since we own the |
| + // |video_capture_system_| and |this| is bound in |
| + // |devices_enumerated_callback|. |
| device_task_runner_->PostTask( |
| FROM_HERE, |
| - base::Bind(&media::VideoCaptureDeviceFactory::EnumerateDeviceDescriptors, |
| - base::Unretained(video_capture_device_factory_.get()), |
| - devices_enumerated_callback)); |
| -} |
| - |
| -const media::VideoCaptureDeviceDescriptor* |
| -VideoCaptureManager::LookupDeviceDescriptor(const std::string& id) { |
| - const DeviceInfo* info = GetDeviceInfoById(id); |
| - return info ? (&info->descriptor) : nullptr; |
| + base::Bind(&media::VideoCaptureSystem::GetDeviceInfosAsync, |
| + base::Unretained(video_capture_system_.get()), |
| + // Pass a timer for UMA histogram collection. |
| + media::BindToCurrentLoop(base::Bind( |
| + &VideoCaptureManager::OnDeviceInfosReceived, this, |
| + base::Owned(new base::ElapsedTimer()), client_callback)))); |
| } |
| int VideoCaptureManager::Open(const MediaStreamDevice& device) { |
| @@ -337,7 +253,8 @@ void VideoCaptureManager::DoStopDevice(VideoCaptureController* controller) { |
| } |
| } |
| - const DeviceInfo* device_info = GetDeviceInfoById(controller->device_id()); |
| + const media::VideoCaptureDeviceInfo* device_info = |
| + GetDeviceInfoById(controller->device_id()); |
| if (device_info != nullptr) { |
| for (auto& observer : capture_observers_) |
| observer.OnVideoCaptureStopped(device_info->descriptor.facing); |
| @@ -368,6 +285,25 @@ void VideoCaptureManager::ProcessDeviceStartRequestQueue() { |
| DVLOG(3) << "HandleQueuedStartRequest, Post start to device thread, device = " |
| << controller->device_id() |
| << " start id = " << controller->serial_id(); |
| + // The unit test VideoCaptureManagerTest.OpenNotExisting requires us to fail |
| + // synchronously if the stream_type is MEDIA_DEVICE_VIDEO_CAPTURE and no |
| + // DeviceInfo matching the requested id is present (which is the case when |
| + // requesting a device with a bogus id). Note, that since other types of |
| + // failure during startup of the device are allowed to be reported |
| + // asynchronously, this requirement is questionable. |
| + // TODO(chfremer): Check if any production code actually depends on this |
|
mcasas
2017/04/04 18:38:41
Add a crbug.com for this plz.
chfremer
2017/04/04 19:05:33
Done.
|
| + // requirement. If not, relax the requirement in the test and remove the below |
| + // if block. |
| + if (controller->stream_type() == MEDIA_DEVICE_VIDEO_CAPTURE) { |
| + const media::VideoCaptureDeviceInfo* device_info = |
| + GetDeviceInfoById(controller->device_id()); |
| + if (!device_info) { |
| + OnDeviceStartFailed(controller); |
| + return; |
| + } |
| + for (auto& observer : capture_observers_) |
| + observer.OnVideoCaptureStarted(device_info->descriptor.facing); |
| + } |
| // The method CreateAndStartDeviceAsync() is going to run asynchronously. |
| // Since we may be removing the controller while it is executing, we need to |
| @@ -385,17 +321,13 @@ void VideoCaptureManager::ProcessDeviceStartRequestQueue() { |
| GetControllerSharedRef(controller))); |
| } |
| -void VideoCaptureManager::WillStartDevice(media::VideoFacingMode facing_mode) { |
| - for (auto& observer : capture_observers_) |
| - observer.OnVideoCaptureStarted(facing_mode); |
| -} |
| - |
| -void VideoCaptureManager::DidStartDevice(VideoCaptureController* controller) { |
| +void VideoCaptureManager::OnDeviceStarted(VideoCaptureController* controller) { |
| DVLOG(3) << __func__; |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| DCHECK(!device_start_request_queue_.empty()); |
| DCHECK_EQ(controller, device_start_request_queue_.begin()->controller()); |
| DCHECK(controller); |
| + |
| if (controller->stream_type() == MEDIA_DESKTOP_VIDEO_CAPTURE) { |
| const media::VideoCaptureSessionId session_id = |
| device_start_request_queue_.front().session_id(); |
| @@ -586,7 +518,7 @@ bool VideoCaptureManager::GetDeviceSupportedFormats( |
| DCHECK(supported_formats->empty()); |
| // Return all available formats of the device, regardless its started state. |
| - DeviceInfo* existing_device = GetDeviceInfoById(device_id); |
| + media::VideoCaptureDeviceInfo* existing_device = GetDeviceInfoById(device_id); |
| if (existing_device) |
| *supported_formats = existing_device->supported_formats; |
| return true; |
| @@ -744,18 +676,18 @@ void VideoCaptureManager::OnClosed( |
| listener.Closed(stream_type, capture_session_id); |
| } |
| -void VideoCaptureManager::OnDevicesInfoEnumerated( |
| +void VideoCaptureManager::OnDeviceInfosReceived( |
| base::ElapsedTimer* timer, |
| const EnumerationCallback& client_callback, |
| - const VideoCaptureManager::DeviceInfos& new_devices_info_cache) { |
| + const std::vector<media::VideoCaptureDeviceInfo>& device_infos) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| UMA_HISTOGRAM_TIMES( |
| "Media.VideoCaptureManager.GetAvailableDevicesInfoOnDeviceThreadTime", |
| timer->Elapsed()); |
| - devices_info_cache_ = new_devices_info_cache; |
| + devices_info_cache_ = device_infos; |
| // Walk the |devices_info_cache_| and produce a |
| - // media::VideoCaptureDeviceDescriptors for return purposes. |
| + // media::VideoCaptureDeviceDescriptors for |client_callback|. |
| media::VideoCaptureDeviceDescriptors devices; |
| std::vector<std::tuple<media::VideoCaptureDeviceDescriptor, |
| media::VideoCaptureFormats>> |
| @@ -770,40 +702,6 @@ void VideoCaptureManager::OnDevicesInfoEnumerated( |
| client_callback.Run(devices); |
| } |
| -void VideoCaptureManager::ConsolidateDevicesInfoOnDeviceThread( |
| - base::Callback<void(const VideoCaptureManager::DeviceInfos&)> |
| - on_devices_enumerated_callback, |
| - const VideoCaptureManager::DeviceInfos& old_device_info_cache, |
| - std::unique_ptr<VideoCaptureDeviceDescriptors> descriptors_snapshot) { |
| - DCHECK(device_task_runner_->BelongsToCurrentThread()); |
| - // Construct |new_devices_info_cache| with the cached devices that are still |
| - // present in the system, and remove their names from |names_snapshot|, so we |
| - // keep there the truly new devices. |
| - VideoCaptureManager::DeviceInfos new_devices_info_cache; |
| - for (const auto& device_info : old_device_info_cache) { |
| - for (VideoCaptureDeviceDescriptors::iterator it = |
| - descriptors_snapshot->begin(); |
| - it != descriptors_snapshot->end(); ++it) { |
| - if (device_info.descriptor.device_id == it->device_id) { |
| - new_devices_info_cache.push_back(device_info); |
| - descriptors_snapshot->erase(it); |
| - break; |
| - } |
| - } |
| - } |
| - |
| - // Get the device info for the new devices in |names_snapshot|. |
| - for (const auto& it : *descriptors_snapshot) { |
| - DeviceInfo device_info(it); |
| - video_capture_device_factory_->GetSupportedFormats( |
| - it, &device_info.supported_formats); |
| - ConsolidateCaptureFormats(&device_info.supported_formats); |
| - new_devices_info_cache.push_back(device_info); |
| - } |
| - |
| - on_devices_enumerated_callback.Run(new_devices_info_cache); |
| -} |
| - |
| void VideoCaptureManager::DestroyControllerIfNoClients( |
| VideoCaptureController* controller) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| @@ -872,7 +770,7 @@ VideoCaptureManager::GetControllerSharedRef( |
| return nullptr; |
| } |
| -VideoCaptureManager::DeviceInfo* VideoCaptureManager::GetDeviceInfoById( |
| +media::VideoCaptureDeviceInfo* VideoCaptureManager::GetDeviceInfoById( |
| const std::string& id) { |
| for (auto& it : devices_info_cache_) { |
| if (it.descriptor.device_id == id) |
| @@ -903,14 +801,14 @@ VideoCaptureController* VideoCaptureManager::GetOrCreateController( |
| VideoCaptureController* new_controller = new VideoCaptureController( |
| device_info.id, device_info.type, params, |
| base::MakeUnique<InProcessBuildableVideoCaptureDevice>( |
| - device_task_runner_, video_capture_device_factory_.get())); |
| + device_task_runner_, video_capture_system_.get())); |
| controllers_.emplace_back(new_controller); |
| return new_controller; |
| } |
| base::Optional<CameraCalibration> VideoCaptureManager::GetCameraCalibration( |
| const std::string& device_id) { |
| - VideoCaptureManager::DeviceInfo* info = GetDeviceInfoById(device_id); |
| + media::VideoCaptureDeviceInfo* info = GetDeviceInfoById(device_id); |
| if (!info) |
| return base::Optional<CameraCalibration>(); |
| return info->descriptor.camera_calibration; |