Skip to content

Commit

Permalink
CCA: Add mojo functions to set/reset crop region
Browse files Browse the repository at this point in the history
Add mojo functions to set and reset crop region value. These functions
will be called from CCA to implement pan-tilt-zoom functionality. The
value is stored in CameraAppDeviceImpl, and will be read by
RequestManager to set it as camera metadata ANDROID_SCALER_CROP_REGION
in the next capture request.

Bug: b:315740659
Test: Manually by checking cros_camera_service log
Change-Id: I5acf606d56d801a9cec5f7b15cdabb4892ffe5e6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5109597
Reviewed-by: Pi-Hsun Shih <pihsun@chromium.org>
Reviewed-by: Takashi Toyoshima <toyoshim@chromium.org>
Commit-Queue: Kam Kwankajornkiet <kamchonlathorn@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1236851}
  • Loading branch information
Kam Kwankajornkiet authored and Chromium LUCI CQ committed Dec 13, 2023
1 parent e84ee69 commit 03bd675
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 0 deletions.
19 changes: 19 additions & 0 deletions ash/webui/camera_app_ui/resources/js/mojo/device_operator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {isLocalDev} from '../models/load_time_data.js';
import * as state from '../state.js';
import {
CameraSuspendError,
CropRegionRect,
ErrorLevel,
ErrorType,
Facing,
Expand Down Expand Up @@ -814,6 +815,24 @@ export class DeviceOperator {
return supportedLevel.includes(level);
}

/**
* Sets the crop region for the configured stream on camera with |deviceId|.
*/
async setCropRegion(deviceId: string, cropRegion: CropRegionRect):
Promise<void> {
const device = await this.getDevice(deviceId);
await device.setCropRegion(cropRegion);
}

/**
* Resets the crop region for the camera with |deviceId| to let the camera
* stream back to full frame.
*/
async resetCropRegion(deviceId: string): Promise<void> {
const device = await this.getDevice(deviceId);
await device.resetCropRegion();
}

/**
* Initializes the singleton instance.
*
Expand Down
11 changes: 11 additions & 0 deletions ash/webui/camera_app_ui/resources/js/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -505,4 +505,15 @@ export enum LowStorageDialogType {
CANNOT_START = 'cannot-start',
}

/**
* A rectangle representing a crop region with size (width, height) and having
* the top-left coordinate at (x, y).
*/
export interface CropRegionRect {
height: number;
width: number;
x: number;
y: number;
}

export type Awaitable<T> = PromiseLike<T>|T;
29 changes: 29 additions & 0 deletions media/capture/video/chromeos/camera_app_device_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -485,4 +485,33 @@ CameraAppDeviceImpl::ConsumePortraitModeCallbacks() {
return callbacks;
}

void CameraAppDeviceImpl::SetCropRegion(const gfx::Rect& crop_region,
SetCropRegionCallback callback) {
CHECK(mojo_task_runner_->BelongsToCurrentThread());

base::AutoLock lock(crop_region_lock_);
crop_region_ = {
crop_region.x(),
crop_region.y(),
crop_region.width(),
crop_region.height(),
};

std::move(callback).Run();
}

void CameraAppDeviceImpl::ResetCropRegion(ResetCropRegionCallback callback) {
CHECK(mojo_task_runner_->BelongsToCurrentThread());

base::AutoLock lock(crop_region_lock_);
crop_region_.reset();

std::move(callback).Run();
}

std::optional<std::vector<int32_t>> CameraAppDeviceImpl::GetCropRegion() {
base::AutoLock lock(crop_region_lock_);
return crop_region_;
}

} // namespace media
8 changes: 8 additions & 0 deletions media/capture/video/chromeos/camera_app_device_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,10 @@ class CAPTURE_EXPORT CameraAppDeviceImpl : public cros::mojom::CameraAppDevice {
mojo::PendingRemote<cros::mojom::CameraInfoObserver> observer,
RegisterCameraInfoObserverCallback callback) override;
absl::optional<PortraitModeCallbacks> ConsumePortraitModeCallbacks();
void SetCropRegion(const gfx::Rect& crop_region,
SetCropRegionCallback callback) override;
void ResetCropRegion(ResetCropRegionCallback callback) override;
std::optional<std::vector<int32_t>> GetCropRegion();

private:
void OnMojoConnectionError();
Expand Down Expand Up @@ -226,6 +230,10 @@ class CAPTURE_EXPORT CameraAppDeviceImpl : public cros::mojom::CameraAppDevice {
base::Lock multi_stream_lock_;
bool multi_stream_enabled_ GUARDED_BY(multi_stream_lock_) = false;

base::Lock crop_region_lock_;
std::optional<std::vector<int32_t>> crop_region_
GUARDED_BY(crop_region_lock_);

// The weak pointers should be dereferenced and invalidated on camera device
// ipc thread.
base::WeakPtrFactory<CameraAppDeviceImpl> weak_ptr_factory_{this};
Expand Down
9 changes: 9 additions & 0 deletions media/capture/video/chromeos/mojom/camera_app.mojom
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,15 @@ interface CameraAppDevice {
// Registers the observer to monitor the camera info update.
RegisterCameraInfoObserver(
pending_remote<CameraInfoObserver> observer) => ();

// Sets the crop region to CameraAppDevice. The value will be consumed by
// RequestManager to set it to the capture request repeatedly on every frame,
// until the new crop region value is set, or reset to the full crop region.
SetCropRegion(gfx.mojom.Rect crop_region) => ();

// Resets the crop region set by |SetCropRegion|. It is no-ops if there is no
// crop region value set.
ResetCropRegion() => ();
};

// Interface for camera device to send camera metadata to Chrome Camera App.
Expand Down
14 changes: 14 additions & 0 deletions media/capture/video/chromeos/request_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,20 @@ void RequestManager::PrepareCaptureRequest() {
return;
}

// Sets crop region if there is a value set from Camera app.
auto camera_app_device =
CameraAppDeviceBridgeImpl::GetInstance()->GetWeakCameraAppDevice(
device_id_);
if (camera_app_device) {
auto crop_region = camera_app_device->GetCropRegion();
if (crop_region.has_value()) {
SetCaptureMetadata(
cros::mojom::CameraMetadataTag::ANDROID_SCALER_CROP_REGION,
cros::mojom::EntryType::TYPE_INT32, crop_region->size(),
SerializeMetadataValueFromSpan<int32_t>(*crop_region));
}
}

auto capture_request = request_builder_->BuildRequest(std::move(stream_types),
std::move(settings));
CHECK_GT(capture_request->output_buffers.size(), 0u);
Expand Down

0 comments on commit 03bd675

Please sign in to comment.