Commit 0b048ac6 authored by Heng-Ruey Hsu's avatar Heng-Ruey Hsu Committed by Chromium LUCI CQ

Reland "Add IPC for enabling multiple streams from CCA"

This is a reland of db6fcd22.

Original change's description:
> Creates a virtual device when CCA opens a camera.
>
> Bug: b:151047537
> Test: Manually test
> Change-Id: I3a2196e32e18ecfb127553f47178f8ebe43656c0
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2351933
> Reviewed-by: Ken Buchanan <kenrb@chromium.org>
> Reviewed-by: Wei Lee <wtlee@chromium.org>
> Commit-Queue: Heng-ruey Hsu <henryhsu@chromium.org>
> Auto-Submit: Heng-ruey Hsu <henryhsu@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#837425}

TBR=wtlee@chromium.org,rsesek@chromium.org

Bug: b:151047537
Test: Manually test.
Change-Id: I3d06b0aecd972024b89582ce4847075da3b55b20
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2612314Reviewed-by: default avatarHeng-ruey Hsu <henryhsu@chromium.org>
Commit-Queue: Heng-ruey Hsu <henryhsu@chromium.org>
Auto-Submit: Heng-ruey Hsu <henryhsu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#842469}
parent ad281183
......@@ -39,6 +39,11 @@ void CameraAppDeviceBridgeImpl::SetCameraInfoGetter(
camera_info_getter_ = std::move(camera_info_getter);
}
void CameraAppDeviceBridgeImpl::SetVirtualDeviceController(
VirtualDeviceController virtual_device_controller) {
virtual_device_controller_ = std::move(virtual_device_controller);
}
void CameraAppDeviceBridgeImpl::UnsetCameraInfoGetter() {
camera_info_getter_ = {};
}
......@@ -81,4 +86,12 @@ void CameraAppDeviceBridgeImpl::IsSupported(IsSupportedCallback callback) {
std::move(callback).Run(is_supported_);
}
void CameraAppDeviceBridgeImpl::SetMultipleStreamsEnabled(
const std::string& device_id,
bool enabled,
SetMultipleStreamsEnabledCallback callback) {
virtual_device_controller_.Run(device_id, enabled);
std::move(callback).Run(true);
}
} // namespace media
......@@ -21,6 +21,8 @@ class CAPTURE_EXPORT CameraAppDeviceBridgeImpl
public:
using CameraInfoGetter =
base::RepeatingCallback<cros::mojom::CameraInfoPtr(const std::string&)>;
using VirtualDeviceController =
base::RepeatingCallback<void(const std::string&, bool)>;
CameraAppDeviceBridgeImpl();
......@@ -37,6 +39,9 @@ class CAPTURE_EXPORT CameraAppDeviceBridgeImpl
void UnsetCameraInfoGetter();
void SetVirtualDeviceController(
VirtualDeviceController virtual_device_controller);
CameraAppDeviceImpl* GetCameraAppDevice(const std::string& device_id);
// cros::mojom::CameraAppDeviceBridge implementations.
......@@ -45,6 +50,11 @@ class CAPTURE_EXPORT CameraAppDeviceBridgeImpl
void IsSupported(IsSupportedCallback callback) override;
void SetMultipleStreamsEnabled(
const std::string& device_id,
bool enabled,
SetMultipleStreamsEnabledCallback callback) override;
private:
CameraAppDeviceImpl* CreateCameraAppDevice(const std::string& device_id);
......@@ -52,6 +62,8 @@ class CAPTURE_EXPORT CameraAppDeviceBridgeImpl
CameraInfoGetter camera_info_getter_;
VirtualDeviceController virtual_device_controller_;
mojo::ReceiverSet<cros::mojom::CameraAppDeviceBridge> receivers_;
base::flat_map<std::string, std::unique_ptr<media::CameraAppDeviceImpl>>
......@@ -62,4 +74,4 @@ class CAPTURE_EXPORT CameraAppDeviceBridgeImpl
} // namespace media
#endif // MEDIA_CAPTURE_VIDEO_CHROMEOS_CAMERA_APP_DEVICE_BRIDGE_IMPL_H_
\ No newline at end of file
#endif // MEDIA_CAPTURE_VIDEO_CHROMEOS_CAMERA_APP_DEVICE_BRIDGE_IMPL_H_
......@@ -54,4 +54,27 @@ void CameraAppDeviceProviderImpl::IsSupported(IsSupportedCallback callback) {
bridge_->IsSupported(std::move(callback));
}
} // namespace media
\ No newline at end of file
void CameraAppDeviceProviderImpl::SetMultipleStreamsEnabled(
const std::string& source_id,
bool enabled,
SetMultipleStreamsEnabledCallback callback) {
mapping_callback_.Run(
source_id,
media::BindToCurrentLoop(base::BindOnce(
&CameraAppDeviceProviderImpl::SetMultipleStreamsEnabledWithDeviceId,
weak_ptr_factory_.GetWeakPtr(), enabled, std::move(callback))));
}
void CameraAppDeviceProviderImpl::SetMultipleStreamsEnabledWithDeviceId(
bool enabled,
SetMultipleStreamsEnabledCallback callback,
const base::Optional<std::string>& device_id) {
if (!device_id.has_value()) {
std::move(callback).Run(false);
return;
}
bridge_->SetMultipleStreamsEnabled(*device_id, enabled, std::move(callback));
}
} // namespace media
......@@ -32,12 +32,21 @@ class CAPTURE_EXPORT CameraAppDeviceProviderImpl
void GetCameraAppDevice(const std::string& source_id,
GetCameraAppDeviceCallback callback) override;
void IsSupported(IsSupportedCallback callback) override;
void SetMultipleStreamsEnabled(
const std::string& device_id,
bool enabled,
SetMultipleStreamsEnabledCallback callback) override;
private:
void GetCameraAppDeviceWithDeviceId(
GetCameraAppDeviceCallback callback,
const base::Optional<std::string>& device_id);
void SetMultipleStreamsEnabledWithDeviceId(
bool enable,
SetMultipleStreamsEnabledCallback callback,
const base::Optional<std::string>& device_id);
mojo::Remote<cros::mojom::CameraAppDeviceBridge> bridge_;
DeviceIdMappingCallback mapping_callback_;
......@@ -51,4 +60,4 @@ class CAPTURE_EXPORT CameraAppDeviceProviderImpl
} // namespace media
#endif // MEDIA_CAPTURE_VIDEO_CHROMEOS_CAMERA_APP_DEVICE_PROVIDER_IMPL_H_
\ No newline at end of file
#endif // MEDIA_CAPTURE_VIDEO_CHROMEOS_CAMERA_APP_DEVICE_PROVIDER_IMPL_H_
......@@ -19,6 +19,7 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/system/system_monitor.h"
#include "base/unguessable_token.h"
#include "media/capture/video/chromeos/camera_app_device_bridge_impl.h"
......@@ -33,6 +34,7 @@ namespace media {
namespace {
constexpr int32_t kDefaultFps = 30;
constexpr char kVirtualPrefix[] = "VIRTUAL_";
constexpr base::TimeDelta kEventWaitTimeoutSecs =
base::TimeDelta::FromSeconds(1);
......@@ -196,7 +198,8 @@ std::unique_ptr<VideoCaptureDevice> CameraHalDelegate::CreateDevice(
auto* delegate = GetVCDDelegate(task_runner_for_screen_observer,
device_descriptor, camera_app_device_bridge);
return std::make_unique<VideoCaptureDeviceChromeOSHalv3>(delegate);
return std::make_unique<VideoCaptureDeviceChromeOSHalv3>(delegate,
device_descriptor);
}
void CameraHalDelegate::GetSupportedFormats(
......@@ -292,6 +295,7 @@ void CameraHalDelegate::GetDevicesInfo(
{
base::AutoLock info_lock(camera_info_lock_);
base::AutoLock id_map_lock(device_id_to_camera_id_lock_);
base::AutoLock virtual_lock(enable_virtual_device_lock_);
for (const auto& it : camera_info_) {
int camera_id = it.first;
const cros::mojom::CameraInfoPtr& camera_info = it.second;
......@@ -339,6 +343,12 @@ void CameraHalDelegate::GetDevicesInfo(
// Mojo validates the input parameters for us so we don't need to
// worry about malformed values.
}
case cros::mojom::CameraFacing::CAMERA_FACING_VIRTUAL_BACK:
case cros::mojom::CameraFacing::CAMERA_FACING_VIRTUAL_FRONT:
case cros::mojom::CameraFacing::CAMERA_FACING_VIRTUAL_EXTERNAL:
// |camera_info_| should not have these facing types.
LOG(ERROR) << "Invalid facing type: " << camera_info->facing;
break;
}
auto* vid = get_vendor_string("com.google.usb.vendorId");
auto* pid = get_vendor_string("com.google.usb.productId");
......@@ -350,9 +360,20 @@ void CameraHalDelegate::GetDevicesInfo(
devices_info.emplace_back(desc);
GetSupportedFormats(camera_info_[camera_id],
&devices_info.back().supported_formats);
// Create a virtual device when multiple streams are enabled.
if (enable_virtual_device_[camera_id]) {
desc.facing = VideoFacingMode::MEDIA_VIDEO_FACING_NONE;
desc.device_id =
std::string(kVirtualPrefix) + base::NumberToString(camera_id);
desc.set_display_name("Virtual Camera");
device_id_to_camera_id_[desc.device_id] = camera_id;
devices_info.emplace_back(desc);
GetSupportedFormats(camera_info_[camera_id],
&devices_info.back().supported_formats);
}
}
}
// TODO(shik): Report external camera first when lid is closed.
// TODO(jcliang): Remove this after JS API supports query camera facing
// (http://crbug.com/543997).
......@@ -410,7 +431,36 @@ cros::mojom::CameraInfoPtr CameraHalDelegate::GetCameraInfoFromDeviceId(
if (it == camera_info_.end()) {
return {};
}
return it->second.Clone();
auto info = it->second.Clone();
if (base::StartsWith(device_id, std::string(kVirtualPrefix))) {
switch (it->second->facing) {
case cros::mojom::CameraFacing::CAMERA_FACING_BACK:
info->facing = cros::mojom::CameraFacing::CAMERA_FACING_VIRTUAL_BACK;
break;
case cros::mojom::CameraFacing::CAMERA_FACING_FRONT:
info->facing = cros::mojom::CameraFacing::CAMERA_FACING_VIRTUAL_FRONT;
break;
case cros::mojom::CameraFacing::CAMERA_FACING_EXTERNAL:
info->facing =
cros::mojom::CameraFacing::CAMERA_FACING_VIRTUAL_EXTERNAL;
break;
default:
break;
}
}
return info;
}
void CameraHalDelegate::EnableVirtualDevice(const std::string& device_id,
bool enable) {
if (base::StartsWith(device_id, std::string(kVirtualPrefix))) {
return;
}
auto camera_id = GetCameraIdFromDeviceId(device_id);
if (camera_id != -1) {
base::AutoLock lock(enable_virtual_device_lock_);
enable_virtual_device_[camera_id] = enable;
}
}
const VendorTagInfo* CameraHalDelegate::GetVendorTagInfoByName(
......
......@@ -93,6 +93,8 @@ class CAPTURE_EXPORT CameraHalDelegate final
const VendorTagInfo* GetVendorTagInfoByName(const std::string& full_name);
void EnableVirtualDevice(const std::string& device_id, bool enable);
private:
friend class base::RefCountedThreadSafe<CameraHalDelegate>;
......@@ -193,6 +195,10 @@ class CAPTURE_EXPORT CameraHalDelegate final
base::Lock device_id_to_camera_id_lock_;
std::map<std::string, int> device_id_to_camera_id_
GUARDED_BY(device_id_to_camera_id_lock_);
// A virtual device is enabled/disabled for camera id.
base::Lock enable_virtual_device_lock_;
base::flat_map<int, bool> enable_virtual_device_
GUARDED_BY(enable_virtual_device_lock_);
SEQUENCE_CHECKER(sequence_checker_);
......@@ -214,6 +220,7 @@ class CAPTURE_EXPORT CameraHalDelegate final
// information of vendor tags. Bound to |ipc_task_runner_|.
VendorTagOpsDelegate vendor_tag_ops_delegate_;
// A map from camera id to corresponding delegate instance.
base::flat_map<int, std::unique_ptr<VideoCaptureDeviceChromeOSDelegate>>
vcd_delegate_map_;
......
......@@ -53,6 +53,11 @@ interface CameraAppDeviceProvider {
// and camera app. Currently only devices running camera HAL v3 support this
// feature.
IsSupported() => (bool is_supported);
// Add/Remove a virtual device for recording stream according to |enabled|.
// The virtual device has the same config as |device_id| except facing
// attribute.
SetMultipleStreamsEnabled(string device_id, bool enabled) => (bool success);
};
// Inner interface that used to communicate between browser process (Remote) and
......@@ -68,6 +73,11 @@ interface CameraAppDeviceBridge {
// and camera app. Currently only devices running camera HAL v3 support this
// feature.
IsSupported() => (bool is_supported);
// Add/Remove a virtual device for recording stream according to |enabled|.
// The virtual device has the same config as |device_id| except facing
// attribute.
SetMultipleStreamsEnabled(string device_id, bool enabled) => (bool success);
};
// Interface for communication between Chrome Camera App (Remote) and camera
......
......@@ -13,6 +13,9 @@ enum CameraFacing {
CAMERA_FACING_BACK = 0,
CAMERA_FACING_FRONT = 1,
CAMERA_FACING_EXTERNAL = 2,
CAMERA_FACING_VIRTUAL_BACK = 3,
CAMERA_FACING_VIRTUAL_FRONT = 4,
CAMERA_FACING_VIRTUAL_EXTERNAL = 5,
};
struct CameraResourceCost {
......
......@@ -4,13 +4,21 @@
#include "media/capture/video/chromeos/video_capture_device_chromeos_halv3.h"
#include "base/strings/string_util.h"
#include "media/capture/video/chromeos/video_capture_device_chromeos_delegate.h"
namespace media {
constexpr char kVirtualPrefix[] = "VIRTUAL_";
VideoCaptureDeviceChromeOSHalv3::VideoCaptureDeviceChromeOSHalv3(
VideoCaptureDeviceChromeOSDelegate* delegate)
: vcd_delegate_(delegate), client_type_(ClientType::kPreviewClient) {}
VideoCaptureDeviceChromeOSDelegate* delegate,
const VideoCaptureDeviceDescriptor& vcd_descriptor)
: vcd_delegate_(delegate) {
client_type_ = base::StartsWith(vcd_descriptor.device_id, kVirtualPrefix)
? ClientType::kVideoClient
: ClientType::kPreviewClient;
}
VideoCaptureDeviceChromeOSHalv3::~VideoCaptureDeviceChromeOSHalv3() {
vcd_delegate_->Shutdown();
......
......@@ -19,8 +19,9 @@ class VideoCaptureDeviceChromeOSDelegate;
class CAPTURE_EXPORT VideoCaptureDeviceChromeOSHalv3 final
: public VideoCaptureDevice {
public:
explicit VideoCaptureDeviceChromeOSHalv3(
VideoCaptureDeviceChromeOSDelegate* delegate);
VideoCaptureDeviceChromeOSHalv3(
VideoCaptureDeviceChromeOSDelegate* delegate,
const VideoCaptureDeviceDescriptor& vcd_descriptor);
~VideoCaptureDeviceChromeOSHalv3() final;
......
......@@ -95,6 +95,9 @@ bool VideoCaptureDeviceFactoryChromeOS::Init() {
camera_app_device_bridge_->SetCameraInfoGetter(
base::BindRepeating(&CameraHalDelegate::GetCameraInfoFromDeviceId,
base::Unretained(camera_hal_delegate_.get())));
camera_app_device_bridge_->SetVirtualDeviceController(
base::BindRepeating(&CameraHalDelegate::EnableVirtualDevice,
base::Unretained(camera_hal_delegate_.get())));
}
return true;
}
......
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