Commit 7974cc30 authored by Rahul Singh's avatar Rahul Singh Committed by Commit Bot

Video Capture: Fix VideoFacingMode and rear camera rotation for Windows

This CL addresses a couple issues with Windows Video Capture.
1. VideoFacingMode was incorrectly set for inbuilt cameras.
This was because we were using model_id to find devices in devices_info.
For inbuilt cameras this was an empty string. As a result, on devices
with multiple inbuilt cameras, all cameras had the same model_id and the
VideoFacingMode was set for the wrong camera.
Solution: Changed the code to use device_id instead of model_id.

2. Rear camera feed was incorrectly rotated.
This was because we had the same camera rotation values for Front and
Rear cameras. With this, when a device was rotated 90 or 270 degrees,
the rear camera was off by 180 degrees.
Solution: Set the camera rotation value in GetCameraRotation() for the
90 degree and 270 degree case after checking the VideoFacingMode.

Testing:
Verified that with these changes:
1. Windows devices with front and back cameras showed the correct
rotation behavior for both cameras.
2. Devices with external cameras connected over USB were unaffected.

Bug: 1090754

Change-Id: I44c13a9e77c050fe27875b8b22f5e2ee2f09f95b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2357556Reviewed-by: default avatarGuido Urdaneta <guidou@chromium.org>
Commit-Queue: Rahul Singh <rahsin@microsoft.com>
Cr-Commit-Position: refs/heads/master@{#800855}
parent 47ef259e
...@@ -592,7 +592,6 @@ void VideoCaptureDeviceFactoryWin::FoundAllDevicesUWP( ...@@ -592,7 +592,6 @@ void VideoCaptureDeviceFactoryWin::FoundAllDevicesUWP(
std::string device_id = ScopedHString(id).GetAsUTF8(); std::string device_id = ScopedHString(id).GetAsUTF8();
transform(device_id.begin(), device_id.end(), device_id.begin(), transform(device_id.begin(), device_id.end(), device_id.begin(),
::tolower); ::tolower);
const std::string model_id = GetDeviceModelId(device_id);
ComPtr<ABI::Windows::Devices::Enumeration::IEnclosureLocation> ComPtr<ABI::Windows::Devices::Enumeration::IEnclosureLocation>
enclosure_location; enclosure_location;
...@@ -621,7 +620,7 @@ void VideoCaptureDeviceFactoryWin::FoundAllDevicesUWP( ...@@ -621,7 +620,7 @@ void VideoCaptureDeviceFactoryWin::FoundAllDevicesUWP(
} }
for (auto& device : devices_info) { for (auto& device : devices_info) {
if (!device.descriptor.model_id.compare(model_id)) { if (!device.descriptor.device_id.compare(device_id)) {
device.descriptor.facing = facing; device.descriptor.facing = facing;
break; break;
} }
......
...@@ -20,8 +20,8 @@ const int kSecondsTo100MicroSeconds = 10000; ...@@ -20,8 +20,8 @@ const int kSecondsTo100MicroSeconds = 10000;
// Determines if camera is mounted on a device with naturally portrait display. // Determines if camera is mounted on a device with naturally portrait display.
bool IsPortraitDevice(DWORD display_height, bool IsPortraitDevice(DWORD display_height,
DWORD display_width, DWORD display_width,
int device_angle) { DWORD display_orientation) {
if (device_angle == 0 || device_angle == 180) if (display_orientation == DMDO_DEFAULT || display_orientation == DMDO_180)
return display_height >= display_width; return display_height >= display_width;
else else
return display_height < display_width; return display_height < display_width;
...@@ -102,35 +102,62 @@ int GetCameraRotation(VideoFacingMode facing) { ...@@ -102,35 +102,62 @@ int GetCameraRotation(VideoFacingMode facing) {
return rotation; return rotation;
} }
if (facing == VideoFacingMode::MEDIA_VIDEO_FACING_NONE) {
// We set camera facing using Win10 only DeviceInformation API. So pre-Win10
// cameras always have a facing of VideoFacingMode::MEDIA_VIDEO_FACING_NONE.
// Win10 cameras with VideoFacingMode::MEDIA_VIDEO_FACING_NONE should early
// exit as part of the IsInternalCamera(facing) check above.
DCHECK(base::win::GetVersion() < base::win::Version::WIN10);
}
DEVMODE mode; DEVMODE mode;
::ZeroMemory(&mode, sizeof(mode)); ::ZeroMemory(&mode, sizeof(mode));
mode.dmSize = sizeof(mode); mode.dmSize = sizeof(mode);
mode.dmDriverExtra = 0; mode.dmDriverExtra = 0;
if (::EnumDisplaySettings(internal_display_device.DeviceName, if (::EnumDisplaySettings(internal_display_device.DeviceName,
ENUM_CURRENT_SETTINGS, &mode)) { ENUM_CURRENT_SETTINGS, &mode)) {
int device_orientation = 0; int camera_offset = 0; // Measured in degrees, clockwise.
int portrait_correction = 0; bool portrait_device = IsPortraitDevice(mode.dmPelsHeight, mode.dmPelsWidth,
mode.dmDisplayOrientation);
switch (mode.dmDisplayOrientation) { switch (mode.dmDisplayOrientation) {
case DMDO_DEFAULT: case DMDO_DEFAULT:
device_orientation = 0; if (portrait_device &&
facing == VideoFacingMode::MEDIA_VIDEO_FACING_ENVIRONMENT) {
camera_offset = 270; // Adjust portrait device rear camera by 180.
} else if (portrait_device) {
camera_offset = 90; // Portrait device front camera is offset by 90.
} else {
camera_offset = 0;
}
break; break;
case DMDO_90: case DMDO_90:
device_orientation = 90; if (portrait_device)
camera_offset = 180;
else if (facing == VideoFacingMode::MEDIA_VIDEO_FACING_ENVIRONMENT)
camera_offset = 270; // Adjust landscape device rear camera by 180.
else
camera_offset = 90;
break; break;
case DMDO_180: case DMDO_180:
device_orientation = 180; if (portrait_device &&
facing == VideoFacingMode::MEDIA_VIDEO_FACING_ENVIRONMENT) {
camera_offset = 90; // Adjust portrait device rear camera by 180.
} else if (portrait_device) {
camera_offset = 270;
} else {
camera_offset = 180;
}
break; break;
case DMDO_270: case DMDO_270:
device_orientation = 270; if (portrait_device)
camera_offset = 0;
else if (facing == VideoFacingMode::MEDIA_VIDEO_FACING_ENVIRONMENT)
camera_offset = 90; // Adjust landscape device rear camera by 180.
else
camera_offset = 270;
break; break;
} }
// Correct the 90 degree offset between the camera mounted in landscape and rotation = (360 - camera_offset) % 360;
// the default orientation on a naturally portrait device.
if (IsPortraitDevice(mode.dmPelsHeight, mode.dmPelsWidth,
device_orientation)) {
portrait_correction = 90;
}
rotation = (360 - device_orientation - portrait_correction) % 360;
} }
return rotation; return rotation;
......
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