| 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 3e38a4d70fd09bedca4a613f34a938122a417b77..45351a50e6c3a42aa4541f18cdae0d862208b944 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,29 @@ 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
|
| + // 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;
|
| + }
|
| + }
|
| +
|
| + media::VideoCaptureDeviceInfo* device_info =
|
| + GetDeviceInfoById(controller->device_id());
|
| + DCHECK(device_info);
|
| + 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
|
| @@ -384,17 +324,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();
|
| @@ -585,7 +521,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;
|
| @@ -743,18 +679,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>>
|
| @@ -769,40 +705,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);
|
| @@ -871,7 +773,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)
|
| @@ -902,14 +804,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;
|
|
|