Commit e9ddb687 authored by Rahul Singh's avatar Rahul Singh Committed by Commit Bot

Video Capture: List user-facing video cameras first in device

enumerations on Windows

Problem:
On certain Windows devices like Surface Pro 4, the default camera for
GetUserMedia() is not the Front facing color camera. Further, an
external camera attached to a Windows devices with multiple internal
cameras isn't guaranteed to be the default camera.

Cause:
The MFEnumDeviceSources() API makes no guarantees about the ordering of
returned Media Foundation devices. The |devices_info| vector in
video_capture_device_factory_win.cc adopts this device order and the
same is propagated through GetUserMedia().

Fix:
Added a new FindAndSetDefaultVideoCamera() helper that iterates over
|devices_info|. When an external video camera is available, it is moved
to the front of |devices_info|. Otherwise, we move the internal user
facing camera to the first index.

Testing:
Validated that:
1. The default camera on Surface Pro 4 for GetUserMedia()
on: https://webrtc.github.io/samples/src/content/getusermedia/gum/
is now the front-facing color camera.

2. On a Surface device with an external camera attached, the default
camera for GetUserMedia() is now the external camera.

Bug: 1121374
Change-Id: Ia7b0f773b6e5012024519b1ec1a261e082af2e31
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2376458Reviewed-by: default avatarGuido Urdaneta <guidou@chromium.org>
Commit-Queue: Rahul Singh <rahsin@microsoft.com>
Cr-Commit-Position: refs/heads/master@{#802535}
parent 3f2cef39
...@@ -13,6 +13,8 @@ ...@@ -13,6 +13,8 @@
#include <wrl.h> #include <wrl.h>
#include <wrl/client.h> #include <wrl/client.h>
#include <utility>
#include "base/bind.h" #include "base/bind.h"
#include "base/command_line.h" #include "base/command_line.h"
#include "base/feature_list.h" #include "base/feature_list.h"
...@@ -62,6 +64,10 @@ const wchar_t* kVideoAndSensorCamerasAqsString = ...@@ -62,6 +64,10 @@ const wchar_t* kVideoAndSensorCamerasAqsString =
L"\"{24e552d7-6523-47f7-a647-d3465bf1f5ca}\" AND " L"\"{24e552d7-6523-47f7-a647-d3465bf1f5ca}\" AND "
L"System.Devices.InterfaceEnabled:=System.StructuredQueryType.Boolean#True"; L"System.Devices.InterfaceEnabled:=System.StructuredQueryType.Boolean#True";
// Class GUID for KSCATEGORY_VIDEO_CAMERA. Only devices from that category will
// contain this GUID in their |device_id|.
const char kVideoCameraGuid[] = "e5323777-f976-4f5b-9b55-b94699c46e44";
// Avoid enumerating and/or using certain devices due to they provoking crashes // Avoid enumerating and/or using certain devices due to they provoking crashes
// or any other reason (http://crbug.com/378494). This enum is defined for the // or any other reason (http://crbug.com/378494). This enum is defined for the
// purposes of UMA collection. Existing entries cannot be removed. // purposes of UMA collection. Existing entries cannot be removed.
...@@ -271,6 +277,25 @@ bool IsEnclosureLocationSupported() { ...@@ -271,6 +277,25 @@ bool IsEnclosureLocationSupported() {
return true; return true;
} }
void FindAndSetDefaultVideoCamera(
std::vector<VideoCaptureDeviceInfo>* devices_info) {
// When available, the default video camera should be external with
// MEDIA_VIDEO_FACING_NONE. Otherwise, it should be internal with
// MEDIA_VIDEO_FACING_USER. It occupies the first index in |devices_info|.
for (auto it = devices_info->begin(); it != devices_info->end(); ++it) {
// Default video camera belongs to KSCATEGORY_VIDEO_CAMERA.
if (it->descriptor.device_id.find(kVideoCameraGuid) != std::string::npos) {
if (it->descriptor.facing == VideoFacingMode::MEDIA_VIDEO_FACING_NONE) {
std::iter_swap(devices_info->begin(), it);
break; // Stop iterating once an external video camera is found.
} else if (it->descriptor.facing ==
VideoFacingMode::MEDIA_VIDEO_FACING_USER) {
std::iter_swap(devices_info->begin(), it);
}
}
}
}
} // namespace } // namespace
// Returns true if the current platform supports the Media Foundation API // Returns true if the current platform supports the Media Foundation API
...@@ -645,6 +670,8 @@ void VideoCaptureDeviceFactoryWin::FoundAllDevicesUWP( ...@@ -645,6 +670,8 @@ void VideoCaptureDeviceFactoryWin::FoundAllDevicesUWP(
} }
} }
FindAndSetDefaultVideoCamera(&devices_info);
origin_task_runner_->PostTask( origin_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&VideoCaptureDeviceFactoryWin::DeviceInfoReady, FROM_HERE, base::BindOnce(&VideoCaptureDeviceFactoryWin::DeviceInfoReady,
base::Unretained(this), std::move(devices_info), base::Unretained(this), std::move(devices_info),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment