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( ...@@ -39,6 +39,11 @@ void CameraAppDeviceBridgeImpl::SetCameraInfoGetter(
camera_info_getter_ = std::move(camera_info_getter); 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() { void CameraAppDeviceBridgeImpl::UnsetCameraInfoGetter() {
camera_info_getter_ = {}; camera_info_getter_ = {};
} }
...@@ -81,4 +86,12 @@ void CameraAppDeviceBridgeImpl::IsSupported(IsSupportedCallback callback) { ...@@ -81,4 +86,12 @@ void CameraAppDeviceBridgeImpl::IsSupported(IsSupportedCallback callback) {
std::move(callback).Run(is_supported_); 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 } // namespace media
...@@ -21,6 +21,8 @@ class CAPTURE_EXPORT CameraAppDeviceBridgeImpl ...@@ -21,6 +21,8 @@ class CAPTURE_EXPORT CameraAppDeviceBridgeImpl
public: public:
using CameraInfoGetter = using CameraInfoGetter =
base::RepeatingCallback<cros::mojom::CameraInfoPtr(const std::string&)>; base::RepeatingCallback<cros::mojom::CameraInfoPtr(const std::string&)>;
using VirtualDeviceController =
base::RepeatingCallback<void(const std::string&, bool)>;
CameraAppDeviceBridgeImpl(); CameraAppDeviceBridgeImpl();
...@@ -37,6 +39,9 @@ class CAPTURE_EXPORT CameraAppDeviceBridgeImpl ...@@ -37,6 +39,9 @@ class CAPTURE_EXPORT CameraAppDeviceBridgeImpl
void UnsetCameraInfoGetter(); void UnsetCameraInfoGetter();
void SetVirtualDeviceController(
VirtualDeviceController virtual_device_controller);
CameraAppDeviceImpl* GetCameraAppDevice(const std::string& device_id); CameraAppDeviceImpl* GetCameraAppDevice(const std::string& device_id);
// cros::mojom::CameraAppDeviceBridge implementations. // cros::mojom::CameraAppDeviceBridge implementations.
...@@ -45,6 +50,11 @@ class CAPTURE_EXPORT CameraAppDeviceBridgeImpl ...@@ -45,6 +50,11 @@ class CAPTURE_EXPORT CameraAppDeviceBridgeImpl
void IsSupported(IsSupportedCallback callback) override; void IsSupported(IsSupportedCallback callback) override;
void SetMultipleStreamsEnabled(
const std::string& device_id,
bool enabled,
SetMultipleStreamsEnabledCallback callback) override;
private: private:
CameraAppDeviceImpl* CreateCameraAppDevice(const std::string& device_id); CameraAppDeviceImpl* CreateCameraAppDevice(const std::string& device_id);
...@@ -52,6 +62,8 @@ class CAPTURE_EXPORT CameraAppDeviceBridgeImpl ...@@ -52,6 +62,8 @@ class CAPTURE_EXPORT CameraAppDeviceBridgeImpl
CameraInfoGetter camera_info_getter_; CameraInfoGetter camera_info_getter_;
VirtualDeviceController virtual_device_controller_;
mojo::ReceiverSet<cros::mojom::CameraAppDeviceBridge> receivers_; mojo::ReceiverSet<cros::mojom::CameraAppDeviceBridge> receivers_;
base::flat_map<std::string, std::unique_ptr<media::CameraAppDeviceImpl>> base::flat_map<std::string, std::unique_ptr<media::CameraAppDeviceImpl>>
...@@ -62,4 +74,4 @@ class CAPTURE_EXPORT CameraAppDeviceBridgeImpl ...@@ -62,4 +74,4 @@ class CAPTURE_EXPORT CameraAppDeviceBridgeImpl
} // namespace media } // namespace media
#endif // MEDIA_CAPTURE_VIDEO_CHROMEOS_CAMERA_APP_DEVICE_BRIDGE_IMPL_H_ #endif // MEDIA_CAPTURE_VIDEO_CHROMEOS_CAMERA_APP_DEVICE_BRIDGE_IMPL_H_
\ No newline at end of file
...@@ -54,4 +54,27 @@ void CameraAppDeviceProviderImpl::IsSupported(IsSupportedCallback callback) { ...@@ -54,4 +54,27 @@ void CameraAppDeviceProviderImpl::IsSupported(IsSupportedCallback callback) {
bridge_->IsSupported(std::move(callback)); bridge_->IsSupported(std::move(callback));
} }
} // namespace media void CameraAppDeviceProviderImpl::SetMultipleStreamsEnabled(
\ No newline at end of file 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 ...@@ -32,12 +32,21 @@ class CAPTURE_EXPORT CameraAppDeviceProviderImpl
void GetCameraAppDevice(const std::string& source_id, void GetCameraAppDevice(const std::string& source_id,
GetCameraAppDeviceCallback callback) override; GetCameraAppDeviceCallback callback) override;
void IsSupported(IsSupportedCallback callback) override; void IsSupported(IsSupportedCallback callback) override;
void SetMultipleStreamsEnabled(
const std::string& device_id,
bool enabled,
SetMultipleStreamsEnabledCallback callback) override;
private: private:
void GetCameraAppDeviceWithDeviceId( void GetCameraAppDeviceWithDeviceId(
GetCameraAppDeviceCallback callback, GetCameraAppDeviceCallback callback,
const base::Optional<std::string>& device_id); 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_; mojo::Remote<cros::mojom::CameraAppDeviceBridge> bridge_;
DeviceIdMappingCallback mapping_callback_; DeviceIdMappingCallback mapping_callback_;
...@@ -51,4 +60,4 @@ class CAPTURE_EXPORT CameraAppDeviceProviderImpl ...@@ -51,4 +60,4 @@ class CAPTURE_EXPORT CameraAppDeviceProviderImpl
} // namespace media } // namespace media
#endif // MEDIA_CAPTURE_VIDEO_CHROMEOS_CAMERA_APP_DEVICE_PROVIDER_IMPL_H_ #endif // MEDIA_CAPTURE_VIDEO_CHROMEOS_CAMERA_APP_DEVICE_PROVIDER_IMPL_H_
\ No newline at end of file
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "base/strings/string_number_conversions.h" #include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h" #include "base/strings/string_piece.h"
#include "base/strings/string_split.h" #include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/system/system_monitor.h" #include "base/system/system_monitor.h"
#include "base/unguessable_token.h" #include "base/unguessable_token.h"
#include "media/capture/video/chromeos/camera_app_device_bridge_impl.h" #include "media/capture/video/chromeos/camera_app_device_bridge_impl.h"
...@@ -33,6 +34,7 @@ namespace media { ...@@ -33,6 +34,7 @@ namespace media {
namespace { namespace {
constexpr int32_t kDefaultFps = 30; constexpr int32_t kDefaultFps = 30;
constexpr char kVirtualPrefix[] = "VIRTUAL_";
constexpr base::TimeDelta kEventWaitTimeoutSecs = constexpr base::TimeDelta kEventWaitTimeoutSecs =
base::TimeDelta::FromSeconds(1); base::TimeDelta::FromSeconds(1);
...@@ -196,7 +198,8 @@ std::unique_ptr<VideoCaptureDevice> CameraHalDelegate::CreateDevice( ...@@ -196,7 +198,8 @@ std::unique_ptr<VideoCaptureDevice> CameraHalDelegate::CreateDevice(
auto* delegate = GetVCDDelegate(task_runner_for_screen_observer, auto* delegate = GetVCDDelegate(task_runner_for_screen_observer,
device_descriptor, camera_app_device_bridge); device_descriptor, camera_app_device_bridge);
return std::make_unique<VideoCaptureDeviceChromeOSHalv3>(delegate); return std::make_unique<VideoCaptureDeviceChromeOSHalv3>(delegate,
device_descriptor);
} }
void CameraHalDelegate::GetSupportedFormats( void CameraHalDelegate::GetSupportedFormats(
...@@ -292,6 +295,7 @@ void CameraHalDelegate::GetDevicesInfo( ...@@ -292,6 +295,7 @@ void CameraHalDelegate::GetDevicesInfo(
{ {
base::AutoLock info_lock(camera_info_lock_); base::AutoLock info_lock(camera_info_lock_);
base::AutoLock id_map_lock(device_id_to_camera_id_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_) { for (const auto& it : camera_info_) {
int camera_id = it.first; int camera_id = it.first;
const cros::mojom::CameraInfoPtr& camera_info = it.second; const cros::mojom::CameraInfoPtr& camera_info = it.second;
...@@ -339,6 +343,12 @@ void CameraHalDelegate::GetDevicesInfo( ...@@ -339,6 +343,12 @@ void CameraHalDelegate::GetDevicesInfo(
// Mojo validates the input parameters for us so we don't need to // Mojo validates the input parameters for us so we don't need to
// worry about malformed values. // 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* vid = get_vendor_string("com.google.usb.vendorId");
auto* pid = get_vendor_string("com.google.usb.productId"); auto* pid = get_vendor_string("com.google.usb.productId");
...@@ -350,9 +360,20 @@ void CameraHalDelegate::GetDevicesInfo( ...@@ -350,9 +360,20 @@ void CameraHalDelegate::GetDevicesInfo(
devices_info.emplace_back(desc); devices_info.emplace_back(desc);
GetSupportedFormats(camera_info_[camera_id], GetSupportedFormats(camera_info_[camera_id],
&devices_info.back().supported_formats); &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(shik): Report external camera first when lid is closed.
// TODO(jcliang): Remove this after JS API supports query camera facing // TODO(jcliang): Remove this after JS API supports query camera facing
// (http://crbug.com/543997). // (http://crbug.com/543997).
...@@ -410,7 +431,36 @@ cros::mojom::CameraInfoPtr CameraHalDelegate::GetCameraInfoFromDeviceId( ...@@ -410,7 +431,36 @@ cros::mojom::CameraInfoPtr CameraHalDelegate::GetCameraInfoFromDeviceId(
if (it == camera_info_.end()) { if (it == camera_info_.end()) {
return {}; 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( const VendorTagInfo* CameraHalDelegate::GetVendorTagInfoByName(
......
...@@ -93,6 +93,8 @@ class CAPTURE_EXPORT CameraHalDelegate final ...@@ -93,6 +93,8 @@ class CAPTURE_EXPORT CameraHalDelegate final
const VendorTagInfo* GetVendorTagInfoByName(const std::string& full_name); const VendorTagInfo* GetVendorTagInfoByName(const std::string& full_name);
void EnableVirtualDevice(const std::string& device_id, bool enable);
private: private:
friend class base::RefCountedThreadSafe<CameraHalDelegate>; friend class base::RefCountedThreadSafe<CameraHalDelegate>;
...@@ -193,6 +195,10 @@ class CAPTURE_EXPORT CameraHalDelegate final ...@@ -193,6 +195,10 @@ class CAPTURE_EXPORT CameraHalDelegate final
base::Lock device_id_to_camera_id_lock_; base::Lock device_id_to_camera_id_lock_;
std::map<std::string, int> device_id_to_camera_id_ std::map<std::string, int> device_id_to_camera_id_
GUARDED_BY(device_id_to_camera_id_lock_); 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_); SEQUENCE_CHECKER(sequence_checker_);
...@@ -214,6 +220,7 @@ class CAPTURE_EXPORT CameraHalDelegate final ...@@ -214,6 +220,7 @@ class CAPTURE_EXPORT CameraHalDelegate final
// information of vendor tags. Bound to |ipc_task_runner_|. // information of vendor tags. Bound to |ipc_task_runner_|.
VendorTagOpsDelegate vendor_tag_ops_delegate_; VendorTagOpsDelegate vendor_tag_ops_delegate_;
// A map from camera id to corresponding delegate instance.
base::flat_map<int, std::unique_ptr<VideoCaptureDeviceChromeOSDelegate>> base::flat_map<int, std::unique_ptr<VideoCaptureDeviceChromeOSDelegate>>
vcd_delegate_map_; vcd_delegate_map_;
......
...@@ -53,6 +53,11 @@ interface CameraAppDeviceProvider { ...@@ -53,6 +53,11 @@ interface CameraAppDeviceProvider {
// and camera app. Currently only devices running camera HAL v3 support this // and camera app. Currently only devices running camera HAL v3 support this
// feature. // feature.
IsSupported() => (bool is_supported); 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 // Inner interface that used to communicate between browser process (Remote) and
...@@ -68,6 +73,11 @@ interface CameraAppDeviceBridge { ...@@ -68,6 +73,11 @@ interface CameraAppDeviceBridge {
// and camera app. Currently only devices running camera HAL v3 support this // and camera app. Currently only devices running camera HAL v3 support this
// feature. // feature.
IsSupported() => (bool is_supported); 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 // Interface for communication between Chrome Camera App (Remote) and camera
......
...@@ -13,6 +13,9 @@ enum CameraFacing { ...@@ -13,6 +13,9 @@ enum CameraFacing {
CAMERA_FACING_BACK = 0, CAMERA_FACING_BACK = 0,
CAMERA_FACING_FRONT = 1, CAMERA_FACING_FRONT = 1,
CAMERA_FACING_EXTERNAL = 2, CAMERA_FACING_EXTERNAL = 2,
CAMERA_FACING_VIRTUAL_BACK = 3,
CAMERA_FACING_VIRTUAL_FRONT = 4,
CAMERA_FACING_VIRTUAL_EXTERNAL = 5,
}; };
struct CameraResourceCost { struct CameraResourceCost {
......
...@@ -4,13 +4,21 @@ ...@@ -4,13 +4,21 @@
#include "media/capture/video/chromeos/video_capture_device_chromeos_halv3.h" #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" #include "media/capture/video/chromeos/video_capture_device_chromeos_delegate.h"
namespace media { namespace media {
constexpr char kVirtualPrefix[] = "VIRTUAL_";
VideoCaptureDeviceChromeOSHalv3::VideoCaptureDeviceChromeOSHalv3( VideoCaptureDeviceChromeOSHalv3::VideoCaptureDeviceChromeOSHalv3(
VideoCaptureDeviceChromeOSDelegate* delegate) VideoCaptureDeviceChromeOSDelegate* delegate,
: vcd_delegate_(delegate), client_type_(ClientType::kPreviewClient) {} const VideoCaptureDeviceDescriptor& vcd_descriptor)
: vcd_delegate_(delegate) {
client_type_ = base::StartsWith(vcd_descriptor.device_id, kVirtualPrefix)
? ClientType::kVideoClient
: ClientType::kPreviewClient;
}
VideoCaptureDeviceChromeOSHalv3::~VideoCaptureDeviceChromeOSHalv3() { VideoCaptureDeviceChromeOSHalv3::~VideoCaptureDeviceChromeOSHalv3() {
vcd_delegate_->Shutdown(); vcd_delegate_->Shutdown();
......
...@@ -19,8 +19,9 @@ class VideoCaptureDeviceChromeOSDelegate; ...@@ -19,8 +19,9 @@ class VideoCaptureDeviceChromeOSDelegate;
class CAPTURE_EXPORT VideoCaptureDeviceChromeOSHalv3 final class CAPTURE_EXPORT VideoCaptureDeviceChromeOSHalv3 final
: public VideoCaptureDevice { : public VideoCaptureDevice {
public: public:
explicit VideoCaptureDeviceChromeOSHalv3( VideoCaptureDeviceChromeOSHalv3(
VideoCaptureDeviceChromeOSDelegate* delegate); VideoCaptureDeviceChromeOSDelegate* delegate,
const VideoCaptureDeviceDescriptor& vcd_descriptor);
~VideoCaptureDeviceChromeOSHalv3() final; ~VideoCaptureDeviceChromeOSHalv3() final;
......
...@@ -95,6 +95,9 @@ bool VideoCaptureDeviceFactoryChromeOS::Init() { ...@@ -95,6 +95,9 @@ bool VideoCaptureDeviceFactoryChromeOS::Init() {
camera_app_device_bridge_->SetCameraInfoGetter( camera_app_device_bridge_->SetCameraInfoGetter(
base::BindRepeating(&CameraHalDelegate::GetCameraInfoFromDeviceId, base::BindRepeating(&CameraHalDelegate::GetCameraInfoFromDeviceId,
base::Unretained(camera_hal_delegate_.get()))); base::Unretained(camera_hal_delegate_.get())));
camera_app_device_bridge_->SetVirtualDeviceController(
base::BindRepeating(&CameraHalDelegate::EnableVirtualDevice,
base::Unretained(camera_hal_delegate_.get())));
} }
return true; 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