Commit 3afbec1f authored by Christian Fremerey's avatar Christian Fremerey Committed by Commit Bot

[Video Capture ChromeOS] Make hard-coded camera config obtaining logic configurable in tests

This CL is part of a series, see Design Doc at
https://docs.google.com/document/d/1ihGDZloUGdDpZ5XfmiI3AcqsSxOP9kOe5GxXOTqpHW4/edit?usp=sharing

Test: capture_unittests --gtest_filter=VideoCaptureDeviceFactoryLinuxTest
Bug: 768887
Change-Id: I91c8f3ccd30663532437a62410a2f8bc6536308e
Reviewed-on: https://chromium-review.googlesource.com/1123655
Commit-Queue: Christian Fremerey <chfremer@chromium.org>
Reviewed-by: default avatarEmircan Uysaler <emircan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#576269}
parent bf7e4982
......@@ -61,16 +61,6 @@ class CAPTURE_EXPORT CameraConfigChromeOS {
CAPTURE_EXPORT VideoFacingMode
GetCameraFacing(const std::string& device_id,
const std::string& model_id) const;
// Get the orientation of the camera. The value is the angle that the camera
// image needs to be rotated clockwise so it shows correctly on the display in
// its natural orientation. It should be 0, 90, 180, or 270.
//
// For example, suppose a device has a naturally tall screen. The back-facing
// camera sensor is mounted in landscape. You are looking at the screen. If
// the top side of the camera sensor is aligned with the right edge of the
// screen in natural orientation, the value should be 90. If the top side of a
// front-facing camera sensor is aligned with the right of the screen, the
// value should be 270.
int GetOrientation(const std::string& device_id,
const std::string& model_id) const;
......
......@@ -17,37 +17,25 @@
namespace media {
static CameraConfigChromeOS* GetCameraConfig() {
static CameraConfigChromeOS* config = new CameraConfigChromeOS();
return config;
}
VideoCaptureDeviceChromeOS::VideoCaptureDeviceChromeOS(
const ChromeOSDeviceCameraConfig& camera_config,
scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
scoped_refptr<V4L2CaptureDevice> v4l2,
const VideoCaptureDeviceDescriptor& device_descriptor)
: VideoCaptureDeviceLinux(std::move(v4l2), device_descriptor),
camera_config_(camera_config),
screen_observer_delegate_(
new ScreenObserverDelegate(this, ui_task_runner)),
lens_facing_(
GetCameraConfig()->GetCameraFacing(device_descriptor.device_id,
device_descriptor.model_id)),
camera_orientation_(
GetCameraConfig()->GetOrientation(device_descriptor.device_id,
device_descriptor.model_id)),
// External cameras have lens_facing as MEDIA_VIDEO_FACING_NONE.
// We don't want to rotate the frame even if the device rotates.
rotates_with_device_(lens_facing_ !=
VideoFacingMode::MEDIA_VIDEO_FACING_NONE) {}
new ScreenObserverDelegate(this, ui_task_runner)) {}
VideoCaptureDeviceChromeOS::~VideoCaptureDeviceChromeOS() {
screen_observer_delegate_->RemoveObserver();
}
void VideoCaptureDeviceChromeOS::SetRotation(int rotation) {
if (!rotates_with_device_) {
if (!camera_config_.rotates_with_device) {
rotation = 0;
} else if (lens_facing_ == VideoFacingMode::MEDIA_VIDEO_FACING_ENVIRONMENT) {
} else if (camera_config_.lens_facing ==
VideoFacingMode::MEDIA_VIDEO_FACING_ENVIRONMENT) {
// Original frame when |rotation| = 0
// -----------------------
// | * |
......@@ -83,7 +71,7 @@ void VideoCaptureDeviceChromeOS::SetRotation(int rotation) {
}
// Take into account camera orientation w.r.t. the display. External cameras
// would have camera_orientation_ as 0.
rotation = (rotation + camera_orientation_) % 360;
rotation = (rotation + camera_config_.camera_orientation) % 360;
VideoCaptureDeviceLinux::SetRotation(rotation);
}
......
......@@ -8,7 +8,6 @@
#include "base/macros.h"
#include "base/single_thread_task_runner.h"
#include "media/capture/video/chromeos/display_rotation_observer.h"
#include "media/capture/video/linux/camera_config_chromeos.h"
#include "media/capture/video/linux/video_capture_device_linux.h"
namespace display {
......@@ -17,13 +16,30 @@ class Display;
namespace media {
struct ChromeOSDeviceCameraConfig {
ChromeOSDeviceCameraConfig(VideoFacingMode lens_facing,
int camera_orientation)
: lens_facing(lens_facing),
camera_orientation(camera_orientation),
// External cameras have lens_facing as MEDIA_VIDEO_FACING_NONE.
// We don't want to rotate the frame even if the device rotates.
rotates_with_device(lens_facing !=
VideoFacingMode::MEDIA_VIDEO_FACING_NONE) {}
const VideoFacingMode lens_facing;
const int camera_orientation;
// Whether the incoming frames should rotate when the device rotates.
const bool rotates_with_device;
};
// This class is functionally the same as VideoCaptureDeviceLinux, with the
// exception that it is aware of the orientation of the internal Display. When
// the internal Display is rotated, the frames captured are rotated to match.
class VideoCaptureDeviceChromeOS : public VideoCaptureDeviceLinux,
public DisplayRotationObserver {
public:
explicit VideoCaptureDeviceChromeOS(
VideoCaptureDeviceChromeOS(
const ChromeOSDeviceCameraConfig& camera_config,
scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
scoped_refptr<V4L2CaptureDevice> v4l2,
const VideoCaptureDeviceDescriptor& device_descriptor);
......@@ -35,11 +51,8 @@ class VideoCaptureDeviceChromeOS : public VideoCaptureDeviceLinux,
private:
// DisplayRotationObserver implementation.
void SetDisplayRotation(const display::Display& display) override;
const ChromeOSDeviceCameraConfig camera_config_;
scoped_refptr<ScreenObserverDelegate> screen_observer_delegate_;
const VideoFacingMode lens_facing_;
const int camera_orientation_;
// Whether the incoming frames should rotate when the device rotates.
const bool rotates_with_device_;
DISALLOW_IMPLICIT_CONSTRUCTORS(VideoCaptureDeviceChromeOS);
};
......
......@@ -44,6 +44,13 @@ const char kPidPathTemplate[] = "/sys/class/video4linux/%s/device/../idProduct";
const char kInterfacePathTemplate[] =
"/sys/class/video4linux/%s/device/interface";
#if defined(OS_CHROMEOS)
static CameraConfigChromeOS* GetCameraConfig() {
static CameraConfigChromeOS* config = new CameraConfigChromeOS();
return config;
}
#endif
bool ReadIdFile(const std::string& path, std::string* id) {
char id_buf[kVidPidSize];
FILE* file = fopen(path.c_str(), "rb");
......@@ -106,6 +113,26 @@ class DevVideoFilePathsDeviceProvider
}
return display_name;
}
VideoFacingMode GetCameraFacing(const std::string& device_id,
const std::string& model_id) override {
#if defined(OS_CHROMEOS)
return GetCameraConfig()->GetCameraFacing(device_id, model_id);
#else
NOTREACHED();
return MEDIA_VIDEO_FACING_NONE;
#endif
}
int GetOrientation(const std::string& device_id,
const std::string& model_id) override {
#if defined(OS_CHROMEOS)
return GetCameraConfig()->GetOrientation(device_id, model_id);
#else
NOTREACHED();
return 0;
#endif
}
};
} // namespace
......@@ -131,8 +158,13 @@ VideoCaptureDeviceFactoryLinux::CreateDevice(
const VideoCaptureDeviceDescriptor& device_descriptor) {
DCHECK(thread_checker_.CalledOnValidThread());
#if defined(OS_CHROMEOS)
ChromeOSDeviceCameraConfig camera_config(
device_provider_->GetCameraFacing(device_descriptor.device_id,
device_descriptor.model_id),
device_provider_->GetOrientation(device_descriptor.device_id,
device_descriptor.model_id));
VideoCaptureDeviceChromeOS* self = new VideoCaptureDeviceChromeOS(
ui_task_runner_, v4l2_.get(), device_descriptor);
camera_config, ui_task_runner_, v4l2_.get(), device_descriptor);
#else
VideoCaptureDeviceLinux* self =
new VideoCaptureDeviceLinux(v4l2_.get(), device_descriptor);
......@@ -182,12 +214,11 @@ void VideoCaptureDeviceFactoryLinux::GetDeviceDescriptors(
if (display_name.empty())
display_name = reinterpret_cast<char*>(cap.card);
#if defined(OS_CHROMEOS)
static CameraConfigChromeOS* config = new CameraConfigChromeOS();
device_descriptors->emplace_back(
display_name, unique_id, model_id,
VideoCaptureApi::LINUX_V4L2_SINGLE_PLANE,
VideoCaptureTransportType::OTHER_TRANSPORT,
config->GetCameraFacing(unique_id, model_id));
device_provider_->GetCameraFacing(unique_id, model_id));
#else
device_descriptors->emplace_back(
display_name, unique_id, model_id,
......
......@@ -27,6 +27,20 @@ class CAPTURE_EXPORT VideoCaptureDeviceFactoryLinux
virtual void GetDeviceIds(std::vector<std::string>* target_container) = 0;
virtual std::string GetDeviceModelId(const std::string& device_id) = 0;
virtual std::string GetDeviceDisplayName(const std::string& device_id) = 0;
virtual VideoFacingMode GetCameraFacing(const std::string& device_id,
const std::string& model_id) = 0;
// Get the orientation of the camera. The value is the angle that the camera
// image needs to be rotated clockwise so it shows correctly on the display
// in its natural orientation. It should be 0, 90, 180, or 270.
//
// For example, suppose a device has a naturally tall screen. The
// back-facing camera sensor is mounted in landscape. You are looking at the
// screen. If the top side of the camera sensor is aligned with the right
// edge of the screen in natural orientation, the value should be 90. If the
// top side of a front-facing camera sensor is aligned with the right of the
// screen, the value should be 270.
virtual int GetOrientation(const std::string& device_id,
const std::string& model_id) = 0;
};
explicit VideoCaptureDeviceFactoryLinux(
......
......@@ -50,6 +50,16 @@ class DescriptorDeviceProvider
return iter->display_name();
}
VideoFacingMode GetCameraFacing(const std::string& device_id,
const std::string& model_id) override {
return MEDIA_VIDEO_FACING_NONE;
}
int GetOrientation(const std::string& device_id,
const std::string& model_id) override {
return 0;
}
private:
std::vector<VideoCaptureDeviceDescriptor> descriptors_;
};
......@@ -76,11 +86,6 @@ class VideoCaptureDeviceFactoryLinuxTest : public ::testing::Test {
std::unique_ptr<VideoCaptureDeviceFactoryLinux> factory_;
};
// The ChromeOS code path still does some hard-coded reading of files that
// depend on a real device being present.
// TODO(chfremer): Enable this for ChromeOS after making the ChromeOS code path
// testable.
#if !defined(OS_CHROMEOS)
TEST_F(VideoCaptureDeviceFactoryLinuxTest, EnumerateSingleFakeV4L2Device) {
// Setup
const std::string stub_display_name = "Fake Device 0";
......@@ -98,6 +103,5 @@ TEST_F(VideoCaptureDeviceFactoryLinuxTest, EnumerateSingleFakeV4L2Device) {
ASSERT_EQ(stub_device_id, descriptors[0].device_id);
ASSERT_EQ(stub_display_name, descriptors[0].display_name());
}
#endif
}; // namespace media
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