From patchwork Tue Jan 19 14:37:09 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 10897 X-Patchwork-Delegate: jacopo@jmondi.org Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 5FB79BD808 for ; Tue, 19 Jan 2021 14:37:06 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 28BAF68163; Tue, 19 Jan 2021 15:37:06 +0100 (CET) Received: from relay6-d.mail.gandi.net (relay6-d.mail.gandi.net [217.70.183.198]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id EB33568151 for ; Tue, 19 Jan 2021 15:37:00 +0100 (CET) X-Originating-IP: 93.61.96.190 Received: from uno.LocalDomain (93-61-96-190.ip145.fastwebnet.it [93.61.96.190]) (Authenticated sender: jacopo@jmondi.org) by relay6-d.mail.gandi.net (Postfix) with ESMTPSA id A98F1C0007 for ; Tue, 19 Jan 2021 14:37:00 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 19 Jan 2021 15:37:09 +0100 Message-Id: <20210119143711.153517-10-jacopo@jmondi.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210119143711.153517-1-jacopo@jmondi.org> References: <20210119143711.153517-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 09/11] android: camera_device: Handle SCALER_CROP_REGION X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Handle the SCALER_CROP_REGION control and dynamic metadata by translating it from the Android format to the associated libcamera control when processing a request, and the other way around when handling a request completion. Reviewed-by: Niklas Söderlund Reviewed-by: Laurent Pinchart Signed-off-by: Jacopo Mondi --- src/android/camera_device.cpp | 52 +++++++++++++++++++++++++++++++---- src/android/camera_device.h | 2 ++ src/android/camera_worker.h | 1 + 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index 14068e313f74..5600d32cd2b9 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -1586,6 +1586,35 @@ FrameBuffer *CameraDevice::createFrameBuffer(const buffer_handle_t camera3buffer return new FrameBuffer(std::move(planes)); } +int CameraDevice::processControls(const camera3_capture_request_t *camera3Request, + Camera3RequestDescriptor *descriptor) +{ + if (!camera3Request->settings) + return 0; + + /* + * Translate the Android controls to libcamera. + * + * \todo As soon as more controls are handled, this part should be + * broken out to a dedicated function. + */ + const camera_metadata_t *camera3Settings = camera3Request->settings; + camera_metadata_ro_entry_t entry; + int ret = find_camera_metadata_ro_entry(camera3Settings, + ANDROID_SCALER_CROP_REGION, + &entry); + if (!ret) { + const int32_t *data = entry.data.i32; + Rectangle cropRegion{ data[0], data[1], + static_cast(data[2]), + static_cast(data[3]) }; + ControlList &controls = descriptor->request_->controls(); + controls.set(controls::ScalerCrop, cropRegion); + } + + return 0; +} + int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Request) { if (!camera3Request) { @@ -1697,7 +1726,14 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques camera3Buffers[i].acquire_fence); } - /* Queue the request to the CameraWorker. */ + /* + * Translate controls from Android to libcamera and queue the request + * to the CameraWorker thread. + */ + int ret = processControls(camera3Request, descriptor); + if (ret) + return ret; + worker_.queueRequest(descriptor->request_.get()); return 0; @@ -1876,11 +1912,6 @@ CameraDevice::getResultMetadata(Camera3RequestDescriptor *descriptor, const uint8_t lens_state = ANDROID_LENS_STATE_STATIONARY; resultMetadata->addEntry(ANDROID_LENS_STATE, &lens_state, 1); - int32_t sensorSizes[] = { - 0, 0, 2560, 1920, - }; - resultMetadata->addEntry(ANDROID_SCALER_CROP_REGION, sensorSizes, 4); - resultMetadata->addEntry(ANDROID_SENSOR_TIMESTAMP, ×tamp, 1); /* 33.3 msec */ @@ -1911,6 +1942,15 @@ CameraDevice::getResultMetadata(Camera3RequestDescriptor *descriptor, &exposure, 1); } + if (metadata.contains(controls::ScalerCrop)) { + Rectangle crop = metadata.get(controls::ScalerCrop); + int32_t cropRect[] = { + crop.x, crop.y, static_cast(crop.width), + static_cast(crop.height), + }; + resultMetadata->addEntry(ANDROID_SCALER_CROP_REGION, cropRect, 4); + } + /* * Return the result metadata pack even is not valid: get() will return * nullptr. diff --git a/src/android/camera_device.h b/src/android/camera_device.h index 07d3a846f8e1..912e54a60d4b 100644 --- a/src/android/camera_device.h +++ b/src/android/camera_device.h @@ -105,6 +105,8 @@ private: void notifyError(uint32_t frameNumber, camera3_stream_t *stream); CameraMetadata *requestTemplatePreview(); libcamera::PixelFormat toPixelFormat(int format) const; + int processControls(const camera3_capture_request_t *camera3Request, + Camera3RequestDescriptor *descriptor); std::unique_ptr getResultMetadata( Camera3RequestDescriptor *descriptor, int64_t timestamp); diff --git a/src/android/camera_worker.h b/src/android/camera_worker.h index 847a2fc4bd7c..6522f1d68a20 100644 --- a/src/android/camera_worker.h +++ b/src/android/camera_worker.h @@ -25,6 +25,7 @@ public: CaptureRequest(libcamera::Camera *camera, uint64_t cookie); const std::vector &fences() const { return acquireFences_; } + libcamera::ControlList &controls() { return request_->controls(); } const libcamera::ControlList &metadata() const { return request_->metadata();