From patchwork Tue Jan 5 19:05:11 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 10815 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 6B4A5C0F1A for ; Tue, 5 Jan 2021 19:05:16 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 47714630BB; Tue, 5 Jan 2021 20:05:16 +0100 (CET) Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id E47EA6220D for ; Tue, 5 Jan 2021 20:05:13 +0100 (CET) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id A6F54100002 for ; Tue, 5 Jan 2021 19:05:13 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 5 Jan 2021 20:05:11 +0100 Message-Id: <20210105190522.682324-2-jacopo@jmondi.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210105190522.682324-1-jacopo@jmondi.org> References: <20210105190522.682324-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 01/12] libcamera: CameraSensor: Mention V4L2 in get/setControls() 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" The current CameraSensor interface for reading and writing controls is currently based on V4L2 controls. Mention that more clearly in the documentation and, while at it, re-sort the documentation to match the methods declaration order. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart Reviewed-by: Niklas Söderlund --- src/libcamera/camera_sensor.cpp | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/libcamera/camera_sensor.cpp b/src/libcamera/camera_sensor.cpp index 046474c03f4a..05a1d7c22e97 100644 --- a/src/libcamera/camera_sensor.cpp +++ b/src/libcamera/camera_sensor.cpp @@ -593,11 +593,12 @@ const ControlInfoMap &CameraSensor::controls() const } /** - * \brief Read controls from the sensor + * \brief Read V4L2 controls from the sensor * \param[in] ids The list of controls to read, specified by their ID * * This method reads the value of all controls contained in \a ids, and returns - * their values as a ControlList. + * their values as a ControlList. The control identifiers are defined by the + * V4L2 specification (V4L2_CID_*). * * If any control in \a ids is not supported by the device, is disabled (i.e. * has the V4L2_CTRL_FLAG_DISABLED flag set), or if any other error occurs @@ -615,18 +616,13 @@ ControlList CameraSensor::getControls(const std::vector &ids) } /** - * \fn CameraSensor::properties() - * \brief Retrieve the camera sensor properties - * \return The list of camera sensor properties - */ - -/** - * \brief Write controls to the sensor + * \brief Write V4L2 controls to the sensor * \param[in] ctrls The list of controls to write * * This method writes the value of all controls contained in \a ctrls, and - * stores the values actually applied to the device in the corresponding - * \a ctrls entry. + * stores the values actually applied to the device in the corresponding \a + * ctrls entry. The control identifiers are defined by the V4L2 specification + * (V4L2_CID_*). * * If any control in \a ctrls is not supported by the device, is disabled (i.e. * has the V4L2_CTRL_FLAG_DISABLED flag set), is read-only, or if any other @@ -649,6 +645,12 @@ int CameraSensor::setControls(ControlList *ctrls) return subdev_->setControls(ctrls); } +/** + * \fn CameraSensor::properties() + * \brief Retrieve the camera sensor properties + * \return The list of camera sensor properties + */ + /** * \brief Assemble and return the camera sensor info * \param[out] info The camera sensor info From patchwork Tue Jan 5 19:05:12 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 10816 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 BC3B8C0F1A for ; Tue, 5 Jan 2021 19:05:17 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 6517663171; Tue, 5 Jan 2021 20:05:16 +0100 (CET) Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 4FD046297D for ; Tue, 5 Jan 2021 20:05:14 +0100 (CET) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id 18445100002 for ; Tue, 5 Jan 2021 19:05:13 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 5 Jan 2021 20:05:12 +0100 Message-Id: <20210105190522.682324-3-jacopo@jmondi.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210105190522.682324-1-jacopo@jmondi.org> References: <20210105190522.682324-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 02/12] libcamera: camera_sensor: Make V4L2_CID_EXPOSURE mandatory 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" Add the V4L2_CID_EXPOSURE control to the list of mandatory controls the sensor driver has to report and document this new requirement. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart Reviewed-by: Niklas Söderlund --- Documentation/sensor_driver_requirements.rst | 11 ++++++++++- src/libcamera/camera_sensor.cpp | 1 + 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/Documentation/sensor_driver_requirements.rst b/Documentation/sensor_driver_requirements.rst index 0e658aaa03b5..97e98b9e12ef 100644 --- a/Documentation/sensor_driver_requirements.rst +++ b/Documentation/sensor_driver_requirements.rst @@ -26,11 +26,20 @@ The sensor driver shall support the following V4L2 controls: * `V4L2_CID_HBLANK`_ * `V4L2_CID_PIXEL_RATE`_ +* `V4L2_CID_EXPOSURE`_ .. _V4L2_CID_HBLANK: https://www.kernel.org/doc/html/latest/userspace-api/media/v4l/ext-ctrls-image-source.html .. _V4L2_CID_PIXEL_RATE: https://www.kernel.org/doc/html/latest/userspace-api/media/v4l/ext-ctrls-image-process.html +.. _V4L2_CID_EXPOSURE: https://www.kernel.org/doc/html/latest/userspace-api/media/v4l/control.html + +The `HBLANK` and `PIXEL_RATE` controls are used to compute the sensor +output timings. + +The `EXPOSURE` control shall report the image integration time in number of +lines. The V4L2 documentation does not specify a unit for this control, drivers +compliant with the V4L2 specification might need to be changed to be used by +libcamera. -Both controls are used to compute the sensor output timings. Optional Requirements --------------------- diff --git a/src/libcamera/camera_sensor.cpp b/src/libcamera/camera_sensor.cpp index 05a1d7c22e97..f7939b94d2f8 100644 --- a/src/libcamera/camera_sensor.cpp +++ b/src/libcamera/camera_sensor.cpp @@ -245,6 +245,7 @@ int CameraSensor::validateSensorDriver() const std::vector mandatoryControls{ V4L2_CID_PIXEL_RATE, V4L2_CID_HBLANK, + V4L2_CID_EXPOSURE, }; ControlList ctrls = subdev_->getControls(mandatoryControls); From patchwork Tue Jan 5 19:05:13 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 10817 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 580D8C0F1A for ; Tue, 5 Jan 2021 19:05:18 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 7EAC9631B9; Tue, 5 Jan 2021 20:05:16 +0100 (CET) Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id B56576220D for ; Tue, 5 Jan 2021 20:05:14 +0100 (CET) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id 7D352100003 for ; Tue, 5 Jan 2021 19:05:14 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 5 Jan 2021 20:05:13 +0100 Message-Id: <20210105190522.682324-4-jacopo@jmondi.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210105190522.682324-1-jacopo@jmondi.org> References: <20210105190522.682324-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 03/12] libcamera: ipu3: Register Exposure control 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" Calculate the controls::Exposure limits at camera registration time and register it in the list of camera supported controls. Cache the default exposure value to report it in the request metadata. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart Reviewed-by: Niklas Söderlund --- src/libcamera/pipeline/ipu3/ipu3.cpp | 67 ++++++++++++++++++++++++++-- 1 file changed, 63 insertions(+), 4 deletions(-) diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index f1151733d9fe..879057dab328 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -41,7 +41,7 @@ static constexpr unsigned int IMGU_OUTPUT_HEIGHT_ALIGN = 4; static constexpr unsigned int IMGU_OUTPUT_WIDTH_MARGIN = 64; static constexpr unsigned int IMGU_OUTPUT_HEIGHT_MARGIN = 32; -static const ControlInfoMap IPU3Controls = { +static const ControlInfoMap::Map IPU3Controls = { { &controls::draft::PipelineDepth, ControlInfo(2, 3) }, }; @@ -49,7 +49,7 @@ class IPU3CameraData : public CameraData { public: IPU3CameraData(PipelineHandler *pipe) - : CameraData(pipe) + : CameraData(pipe), exposureTime_(0) { } @@ -62,6 +62,8 @@ public: Stream outStream_; Stream vfStream_; Stream rawStream_; + + int32_t exposureTime_; }; class IPU3CameraConfiguration : public CameraConfiguration @@ -119,6 +121,7 @@ private: PipelineHandler::cameraData(camera)); } + int initControls(IPU3CameraData *data); int registerCameras(); int allocateBuffers(Camera *camera); @@ -731,6 +734,60 @@ bool PipelineHandlerIPU3::match(DeviceEnumerator *enumerator) return ret == 0; } +/* + * \brief Initialize the camera controls + * \param[in] data The camera data + * + * Initialize the camera controls by registering the pipeline handler + * ones along with the controls assembled by inspecting the sensor + * capabilities. + * + * \return 0 on success or a negative error code for error + */ +int PipelineHandlerIPU3::initControls(IPU3CameraData *data) +{ + const CameraSensor *sensor = data->cio2_.sensor(); + CameraSensorInfo sensorInfo{}; + + int ret = sensor->sensorInfo(&sensorInfo); + if (ret) + return ret; + + ControlInfoMap::Map controls = IPU3Controls; + + /* + * Compute exposure time limits. + * + * \todo The exposure limits depend on the sensor configuration. + * Initialize the control using the line lenght and pixel rate of the + * current configurtion, as reported by the CameraSensorInfo. Use the + * V4L2_CID_EXPOSURE control to get exposure min and max and convert it + * from lines into micro-seconds. + */ + float pixelRate = sensorInfo.pixelRate / 1e6f; + const ControlInfoMap &sensorControls = sensor->controls(); + const ControlInfo &v4l2Exposure = sensorControls.find(V4L2_CID_EXPOSURE)->second; + int32_t minExposure = v4l2Exposure.min().get() + * sensorInfo.lineLength / pixelRate; + int32_t maxExposure = v4l2Exposure.max().get() + * sensorInfo.lineLength / pixelRate; + int32_t defExposure = v4l2Exposure.def().get() + * sensorInfo.lineLength / pixelRate; + + /* + * \todo Report the actual exposure time, use the default for the + * moment. + */ + data->exposureTime_ = defExposure; + + controls[&controls::ExposureTime] = ControlInfo(minExposure, maxExposure, + defExposure); + + data->controlInfo_ = std::move(controls); + + return 0; +} + /** * \brief Initialise ImgU and CIO2 devices associated with cameras * @@ -776,8 +833,9 @@ int PipelineHandlerIPU3::registerCameras() /* Initialize the camera properties. */ data->properties_ = cio2->sensor()->properties(); - /* Initialze the camera controls. */ - data->controlInfo_ = IPU3Controls; + ret = initControls(data.get()); + if (ret) + continue; /** * \todo Dynamically assign ImgU and output devices to each @@ -842,6 +900,7 @@ void IPU3CameraData::imguOutputBufferReady(FrameBuffer *buffer) /* Mark the request as complete. */ request->metadata().set(controls::draft::PipelineDepth, 3); + request->metadata().set(controls::ExposureTime, exposureTime_); pipe_->completeRequest(request); } From patchwork Tue Jan 5 19:05:14 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 10818 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 A11D9C0F1D for ; Tue, 5 Jan 2021 19:05:18 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D8570631D0; Tue, 5 Jan 2021 20:05:16 +0100 (CET) Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 1FFDD62012 for ; Tue, 5 Jan 2021 20:05:15 +0100 (CET) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id DBBF3100002 for ; Tue, 5 Jan 2021 19:05:14 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 5 Jan 2021 20:05:14 +0100 Message-Id: <20210105190522.682324-5-jacopo@jmondi.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210105190522.682324-1-jacopo@jmondi.org> References: <20210105190522.682324-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 04/12] android: camera_device: Register EXPOSURE_TIME_RANGE 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" Register the EXPOSURE_TIME_RANGE static metadata inspecting the ExposureTime control limits as reported by the camera. If such information is not available, do not register the property. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart Reviewed-by: Niklas Söderlund --- src/android/camera_device.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index a136f8e33843..de3ead275e91 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -888,11 +888,15 @@ const camera_metadata_t *CameraDevice::getStaticMetadata() &filterArr, 1); } - int64_t exposureTimeRange[] = { - 100000, 200000000, - }; - staticMetadata_->addEntry(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE, - &exposureTimeRange, 2); + const auto &exposureInfo = controlsInfo.find(&controls::ExposureTime); + if (exposureInfo != controlsInfo.end()) { + int64_t exposureTimeRange[2] = { + exposureInfo->second.min().get() * 1000, + exposureInfo->second.max().get() * 1000, + }; + staticMetadata_->addEntry(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE, + &exposureTimeRange, 2); + } staticMetadata_->addEntry(ANDROID_SENSOR_ORIENTATION, &orientation_, 1); From patchwork Tue Jan 5 19:05:15 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 10819 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 E5C88C0F1A for ; Tue, 5 Jan 2021 19:05:18 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 2EE98632E1; Tue, 5 Jan 2021 20:05:17 +0100 (CET) Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id B38E962012 for ; Tue, 5 Jan 2021 20:05:15 +0100 (CET) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id 469B0100002 for ; Tue, 5 Jan 2021 19:05:15 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 5 Jan 2021 20:05:15 +0100 Message-Id: <20210105190522.682324-6-jacopo@jmondi.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210105190522.682324-1-jacopo@jmondi.org> References: <20210105190522.682324-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 05/12] android: camera_device: Report EXPOSURE_TIME 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" Instead of reporting a fake value in the dynamic metadata for the EXPOSURE_TIME control, use the value provided by the pipeline. The metadata is only meaningfull in FULL mode. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart Reviewed-by: Niklas Söderlund --- src/android/camera_device.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index de3ead275e91..e6cee75581f2 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -1871,11 +1871,6 @@ CameraDevice::getResultMetadata(Camera3RequestDescriptor *descriptor, resultMetadata->addEntry(ANDROID_SENSOR_ROLLING_SHUTTER_SKEW, &rolling_shutter_skew, 1); - /* 16.6 msec */ - const int64_t exposure_time = 16600000; - resultMetadata->addEntry(ANDROID_SENSOR_EXPOSURE_TIME, - &exposure_time, 1); - const uint8_t lens_shading_map_mode = ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF; resultMetadata->addEntry(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE, @@ -1893,6 +1888,12 @@ CameraDevice::getResultMetadata(Camera3RequestDescriptor *descriptor, &pipeline_depth, 1); } + if (metadata.contains(controls::ExposureTime)) { + int32_t exposure = metadata.get(controls::ExposureTime); + resultMetadata->addEntry(ANDROID_SENSOR_EXPOSURE_TIME, + &exposure, 1); + } + /* * Return the result metadata pack even is not valid: get() will return * nullptr. From patchwork Tue Jan 5 19:05:16 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 10820 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 92A1AC0F1A for ; Tue, 5 Jan 2021 19:05:19 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 6A00163400; Tue, 5 Jan 2021 20:05:19 +0100 (CET) Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 203BF62D2C for ; Tue, 5 Jan 2021 20:05:16 +0100 (CET) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id D9CF4100003 for ; Tue, 5 Jan 2021 19:05:15 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 5 Jan 2021 20:05:16 +0100 Message-Id: <20210105190522.682324-7-jacopo@jmondi.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210105190522.682324-1-jacopo@jmondi.org> References: <20210105190522.682324-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 06/12] libcamera: ipu3: Initialize ScalerCropMaximum property 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" Initialize the camera properties by registering the sensor provided ones and the ScalerCropMaximum property computed by the pipeline handler by using the analogue crop rectangle of the sensor resolution. Signed-off-by: Jacopo Mondi --- src/libcamera/pipeline/ipu3/ipu3.cpp | 43 +++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 879057dab328..418301b33a5e 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -121,6 +122,7 @@ private: PipelineHandler::cameraData(camera)); } + int initProperties(IPU3CameraData *data); int initControls(IPU3CameraData *data); int registerCameras(); @@ -734,6 +736,43 @@ bool PipelineHandlerIPU3::match(DeviceEnumerator *enumerator) return ret == 0; } +/* + * \brief Initialize the camera properties + * \param[in] data The camera data + * + * Initialize the camera properties by registering the pipeline handler + * ones along with the properties assembled by inspecting the sensor + * capabilities. + * + * \return 0 on success or a negative error code for error + */ +int PipelineHandlerIPU3::initProperties(IPU3CameraData *data) +{ + CameraSensor *sensor = data->cio2_.sensor(); + data->properties_ = sensor->properties(); + + /* + * \todo The ScalerCropMaximum property depends on the sensor + * configuration. Initialize the property using the analogue crop + * rectangle of the largest sensor resolution. To be updated later when + * a new one is applied. + */ + V4L2SubdeviceFormat format; + format.size = sensor->resolution(); + int ret = sensor->setFormat(&format); + if (ret) + return ret; + + CameraSensorInfo sensorInfo{}; + ret = sensor->sensorInfo(&sensorInfo); + if (ret) + return ret; + + data->properties_.set(properties::ScalerCropMaximum, sensorInfo.analogCrop); + + return 0; +} + /* * \brief Initialize the camera controls * \param[in] data The camera data @@ -831,7 +870,9 @@ int PipelineHandlerIPU3::registerCameras() continue; /* Initialize the camera properties. */ - data->properties_ = cio2->sensor()->properties(); + ret = initProperties(data.get()); + if (ret) + continue; ret = initControls(data.get()); if (ret) From patchwork Tue Jan 5 19:05:17 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 10821 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 02379C0F1A for ; Tue, 5 Jan 2021 19:05:20 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id C0C6F630BA; Tue, 5 Jan 2021 20:05:19 +0100 (CET) Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id AC9316308C for ; Tue, 5 Jan 2021 20:05:16 +0100 (CET) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id 49730100003 for ; Tue, 5 Jan 2021 19:05:16 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 5 Jan 2021 20:05:17 +0100 Message-Id: <20210105190522.682324-8-jacopo@jmondi.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210105190522.682324-1-jacopo@jmondi.org> References: <20210105190522.682324-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 07/12] libcamera: ipu3: Register ScalerCrop control 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" Register the ScalerCrop control in the ImgU pipeline handler computed by using the Viewfinder [1280x720] pipeline output configuration and the sensor resolution as parameters. The ScalerCrop control limits should be updated everytime a new configuration is applied to the sensor. Signed-off-by: Jacopo Mondi --- src/libcamera/pipeline/ipu3/ipu3.cpp | 53 ++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 418301b33a5e..f1329ffb0463 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -41,6 +41,7 @@ static constexpr unsigned int IMGU_OUTPUT_WIDTH_ALIGN = 64; static constexpr unsigned int IMGU_OUTPUT_HEIGHT_ALIGN = 4; static constexpr unsigned int IMGU_OUTPUT_WIDTH_MARGIN = 64; static constexpr unsigned int IMGU_OUTPUT_HEIGHT_MARGIN = 32; +static constexpr Size IPU3ViewfinderSize(1280, 720); static const ControlInfoMap::Map IPU3Controls = { { &controls::draft::PipelineDepth, ControlInfo(2, 3) }, @@ -378,7 +379,7 @@ CameraConfiguration *PipelineHandlerIPU3::generateConfiguration(Camera *camera, * capped to the maximum sensor resolution and aligned * to the ImgU output constraints. */ - size = sensorResolution.boundedTo({ 1280, 720 }) + size = sensorResolution.boundedTo(IPU3ViewfinderSize) .alignedDownTo(IMGU_OUTPUT_WIDTH_ALIGN, IMGU_OUTPUT_HEIGHT_ALIGN); pixelFormat = formats::NV12; @@ -785,7 +786,7 @@ int PipelineHandlerIPU3::initProperties(IPU3CameraData *data) */ int PipelineHandlerIPU3::initControls(IPU3CameraData *data) { - const CameraSensor *sensor = data->cio2_.sensor(); + CameraSensor *sensor = data->cio2_.sensor(); CameraSensorInfo sensorInfo{}; int ret = sensor->sensorInfo(&sensorInfo); @@ -822,6 +823,54 @@ int PipelineHandlerIPU3::initControls(IPU3CameraData *data) controls[&controls::ExposureTime] = ControlInfo(minExposure, maxExposure, defExposure); + /* + * Compute the scaler crop limits. + * + * \todo The scaler crop limits depend on the sensor configuration. It + * should be updated when a new configuration is applied. To initialize + * the control use the 'Viewfinder' configuration (1280x720) as the + * pipeline output resolution and the full sensor size as input frame + * (see the todo note in the validation function). + */ + + /* + * The maximum scaler crop rectangle is the analogue crop used to + * produce the maximum frame size. + */ + V4L2SubdeviceFormat sensorFormat; + sensorFormat.size = sensor->resolution(); + ret = sensor->setFormat(&sensorFormat); + if (ret) + return ret; + + /* Re-fetch the sensor info updated to use the largest resolution. */ + ret = sensor->sensorInfo(&sensorInfo); + if (ret) + return ret; + + const Rectangle &analogueCrop = sensorInfo.analogCrop; + Rectangle maxCrop = analogueCrop; + + /* + * The minimum crop rectangle is the default viewfinder configuration + * (or the sensor resolution, if smaller) re-scaled in the sensor's pixel + * array coordinates. As the ImgU cannot up-scale, the minimum selection + * rectangle has to be as large as the desired pipeline output size. + * + * The top-left corner position is not relevant as the minimum crop + * rectangle can be placed anywhere inside the analogue crop region. + */ + const Size &sensorOutput = sensorInfo.outputSize; + Size minCropSize = sensorOutput.boundedTo(IPU3ViewfinderSize) + .alignedDownTo(IMGU_OUTPUT_WIDTH_ALIGN, + IMGU_OUTPUT_HEIGHT_ALIGN); + Rectangle minCrop(minCropSize); + minCrop.scaledBy(analogueCrop.size(), sensorOutput); + minCrop.x = analogueCrop.x; + minCrop.y = analogueCrop.y; + + controls[&controls::ScalerCrop] = ControlInfo(minCrop, maxCrop, maxCrop); + data->controlInfo_ = std::move(controls); return 0; From patchwork Tue Jan 5 19:05:18 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 10822 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 6E663C0F1A for ; Tue, 5 Jan 2021 19:05:20 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 11FEA63411; Tue, 5 Jan 2021 20:05:20 +0100 (CET) Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id F307162D3E for ; Tue, 5 Jan 2021 20:05:16 +0100 (CET) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id B0B7B100003 for ; Tue, 5 Jan 2021 19:05:16 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 5 Jan 2021 20:05:18 +0100 Message-Id: <20210105190522.682324-9-jacopo@jmondi.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210105190522.682324-1-jacopo@jmondi.org> References: <20210105190522.682324-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 08/12] android: camera_device: Register MAX_DIGITAL_ZOOM 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" Register the ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM static metadata inspecting the ScalerCrop control's limits. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart Reviewed-by: Niklas Söderlund --- src/android/camera_device.cpp | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index e6cee75581f2..99297270598f 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -1011,9 +1011,26 @@ const camera_metadata_t *CameraDevice::getStaticMetadata() } /* Scaler static metadata. */ - float maxDigitalZoom = 1; - staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM, - &maxDigitalZoom, 1); + { + /* + * \todo The digital zoom factor is a property that depends + * on the desired output configuration and the sensor frame size + * input to the ISP. These information are not available to the + * Android HAL, not at initialization time at least. + * + * Rely on pipeline handlers initializing the ScalerCrop control + * with the camera default configuration and use the maximum + * and minimum crop rectangles to calculate the digital zoom + * factor. + */ + const auto info = controlsInfo.find(&controls::ScalerCrop); + Rectangle min = info->second.min().get(); + Rectangle max = info->second.max().get(); + float maxZoom = std::min(1.0f * max.width / min.width, + 1.0f * max.height / min.height); + staticMetadata_->addEntry(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM, + &maxZoom, 1); + } std::vector availableStreamConfigurations; availableStreamConfigurations.reserve(streamConfigurations_.size() * 4); From patchwork Tue Jan 5 19:05:19 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 10823 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 80686C0F1A for ; Tue, 5 Jan 2021 19:05:21 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 54DDA6345C; Tue, 5 Jan 2021 20:05:21 +0100 (CET) Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 5D2FC633EF for ; Tue, 5 Jan 2021 20:05:17 +0100 (CET) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id 20692100002 for ; Tue, 5 Jan 2021 19:05:16 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 5 Jan 2021 20:05:19 +0100 Message-Id: <20210105190522.682324-10-jacopo@jmondi.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210105190522.682324-1-jacopo@jmondi.org> References: <20210105190522.682324-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 09/12] libcamera: ipu3: Handle ScalerCrop 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" Add support for caching the value of control::ScalerCrop to return it in the request metadata. No cropping is currently applied on the input video device, the control value is returned in the metadata pack as it is received. Signed-off-by: Jacopo Mondi --- src/libcamera/pipeline/ipu3/ipu3.cpp | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index f1329ffb0463..381524bb3499 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -66,6 +66,7 @@ public: Stream rawStream_; int32_t exposureTime_; + Rectangle scalerCrop_; }; class IPU3CameraConfiguration : public CameraConfiguration @@ -75,6 +76,7 @@ public: Status validate() override; + const Size &cio2Size() const { return cio2Configuration_.size; } const StreamConfiguration &cio2Format() const { return cio2Configuration_; } const ImgUDevice::PipeConfig imguConfig() const { return pipeConfig_; } @@ -468,12 +470,19 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c) * Pass the requested stream size to the CIO2 unit and get back the * adjusted format to be propagated to the ImgU output devices. */ - const Size &sensorSize = config->cio2Format().size; V4L2DeviceFormat cio2Format; - ret = cio2->configure(sensorSize, &cio2Format); + ret = cio2->configure(config->cio2Size(), &cio2Format); if (ret) return ret; + /* Initialize the scaler crop using the sensor's analogue crop. */ + CameraSensorInfo sensorInfo; + ret = cio2->sensor()->sensorInfo(&sensorInfo); + if (ret) + /* Use the requested CIO2 output size as fallback. */ + sensorInfo.analogCrop = Rectangle(config->cio2Size()); + data->scalerCrop_ = sensorInfo.analogCrop; + /* * If the ImgU gets configured, its driver seems to expect that * buffers will be queued to its outputs, as otherwise the next @@ -656,6 +665,14 @@ int PipelineHandlerIPU3::queueRequestDevice(Camera *camera, Request *request) IPU3CameraData *data = cameraData(camera); int error = 0; + ControlList &controls = request->controls(); + if (controls.contains(controls::ScalerCrop)) + /* + * \todo No scaling is applied. Just return the value in the + * request metadata as it is. + */ + data->scalerCrop_ = controls.get(controls::ScalerCrop); + /* * Queue a buffer on the CIO2, using the raw stream buffer provided in * the request, if any, or a CIO2 internal buffer otherwise. @@ -991,6 +1008,7 @@ void IPU3CameraData::imguOutputBufferReady(FrameBuffer *buffer) /* Mark the request as complete. */ request->metadata().set(controls::draft::PipelineDepth, 3); request->metadata().set(controls::ExposureTime, exposureTime_); + request->metadata().set(controls::ScalerCrop, scalerCrop_); pipe_->completeRequest(request); } From patchwork Tue Jan 5 19:05:20 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 10824 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 C99E9C0F1D for ; Tue, 5 Jan 2021 19:05:21 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 9D55563494; Tue, 5 Jan 2021 20:05:21 +0100 (CET) Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C5FDD6220D for ; Tue, 5 Jan 2021 20:05:17 +0100 (CET) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id 85775100002 for ; Tue, 5 Jan 2021 19:05:17 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 5 Jan 2021 20:05:20 +0100 Message-Id: <20210105190522.682324-11-jacopo@jmondi.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210105190522.682324-1-jacopo@jmondi.org> References: <20210105190522.682324-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 10/12] 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. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart Reviewed-by: Niklas Söderlund --- 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 99297270598f..5f5e6576365b 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(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 + * broke 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..0874c80f1e66 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(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(); From patchwork Tue Jan 5 19:05:21 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 10825 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 11197C0F1A for ; Tue, 5 Jan 2021 19:05:22 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id DDF60633F6; Tue, 5 Jan 2021 20:05:21 +0100 (CET) Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 2DA0462B8F for ; Tue, 5 Jan 2021 20:05:18 +0100 (CET) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id E8718100002 for ; Tue, 5 Jan 2021 19:05:17 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 5 Jan 2021 20:05:21 +0100 Message-Id: <20210105190522.682324-12-jacopo@jmondi.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210105190522.682324-1-jacopo@jmondi.org> References: <20210105190522.682324-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 11/12] android: camera_device: Support AWB_AUTO 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" Claim support for the AWB_AUTO mode in the ANDROID_CONTROL_AWB_AVAILABLE_MODES static metadata. This fixes the CTS test error: android.hardware.camera2.cts.CaptureRequestTest#testAwbModeAndLock fail The static info key 'android.control.awbAvailableModes' All camera devices must support AUTO mode Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart Reviewed-by: Niklas Söderlund --- src/android/camera_device.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index 5f5e6576365b..6eb3404739e8 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -802,7 +802,7 @@ const camera_metadata_t *CameraDevice::getStaticMetadata() availableStabilizationModes.size()); std::vector availableAwbModes = { - ANDROID_CONTROL_AWB_MODE_OFF, + ANDROID_CONTROL_AWB_MODE_AUTO, }; staticMetadata_->addEntry(ANDROID_CONTROL_AWB_AVAILABLE_MODES, availableAwbModes.data(), From patchwork Tue Jan 5 19:05:22 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 10826 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 3C9BCC0F1A for ; Tue, 5 Jan 2021 19:05:23 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 142B3635AE; Tue, 5 Jan 2021 20:05:23 +0100 (CET) Received: from relay11.mail.gandi.net (relay11.mail.gandi.net [217.70.178.231]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9807D632B0 for ; Tue, 5 Jan 2021 20:05:18 +0100 (CET) Received: from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101]) (Authenticated sender: jacopo@jmondi.org) by relay11.mail.gandi.net (Postfix) with ESMTPSA id 54B39100002 for ; Tue, 5 Jan 2021 19:05:18 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 5 Jan 2021 20:05:22 +0100 Message-Id: <20210105190522.682324-13-jacopo@jmondi.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210105190522.682324-1-jacopo@jmondi.org> References: <20210105190522.682324-1-jacopo@jmondi.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 12/12] android: camera_device: Report the required dynamic metadata 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" The list of dynamic metadata reported by the Camera HAL is currently very limited. Augment the number of reported metadata in order to fix errors reported by the android.hardware.camera2.cts.CaptureRequestTest test module. The test module still fails in 2 tests because of the missing android.sensor.info.maxFrameDuration static metadata. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart Reviewed-by: Niklas Söderlund --- src/android/camera_device.cpp | 134 ++++++++++++++++++++++++++-------- 1 file changed, 105 insertions(+), 29 deletions(-) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index 6eb3404739e8..d2a8e876eccc 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -675,10 +675,10 @@ std::tuple CameraDevice::calculateStaticMetadataSize() { /* * \todo Keep this in sync with the actual number of entries. - * Currently: 53 entries, 714 bytes of static metadata + * Currently: 53 entries, 786 bytes of static metadata */ uint32_t numEntries = 53; - uint32_t byteSize = 714; + uint32_t byteSize = 786; /* * Calculate space occupation in bytes for dynamically built metadata @@ -1200,19 +1200,37 @@ const camera_metadata_t *CameraDevice::getStaticMetadata() availableRequestKeys.size()); std::vector availableResultKeys = { - ANDROID_CONTROL_AE_STATE, + ANDROID_CONTROL_AE_ANTIBANDING_MODE, ANDROID_CONTROL_AE_LOCK, + ANDROID_CONTROL_AE_MODE, + ANDROID_CONTROL_AE_TARGET_FPS_RANGE, + ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER, + ANDROID_CONTROL_AE_STATE, + ANDROID_CONTROL_AF_MODE, ANDROID_CONTROL_AF_STATE, - ANDROID_CONTROL_AWB_STATE, + ANDROID_CONTROL_AF_TRIGGER, + ANDROID_CONTROL_AWB_MODE, ANDROID_CONTROL_AWB_LOCK, + ANDROID_CONTROL_AWB_STATE, + ANDROID_CONTROL_CAPTURE_INTENT, + ANDROID_CONTROL_EFFECT_MODE, + ANDROID_CONTROL_MODE, + ANDROID_CONTROL_SCENE_MODE, + ANDROID_CONTROL_VIDEO_STABILIZATION_MODE, + ANDROID_FLASH_MODE, + ANDROID_FLASH_STATE, ANDROID_LENS_STATE, - ANDROID_REQUEST_PIPELINE_DEPTH, - ANDROID_SCALER_CROP_REGION, + ANDROID_LENS_OPTICAL_STABILIZATION_MODE, ANDROID_SENSOR_TIMESTAMP, ANDROID_SENSOR_ROLLING_SHUTTER_SKEW, ANDROID_SENSOR_EXPOSURE_TIME, + ANDROID_STATISTICS_FACE_DETECT_MODE, + ANDROID_NOISE_REDUCTION_MODE, ANDROID_STATISTICS_LENS_SHADING_MAP_MODE, ANDROID_STATISTICS_SCENE_FLICKER, + ANDROID_NOISE_REDUCTION_MODE, + ANDROID_REQUEST_PIPELINE_DEPTH, + ANDROID_SCALER_CROP_REGION, ANDROID_JPEG_SIZE, ANDROID_JPEG_QUALITY, ANDROID_JPEG_ORIENTATION, @@ -1885,48 +1903,106 @@ CameraDevice::getResultMetadata(Camera3RequestDescriptor *descriptor, /* * \todo Keep this in sync with the actual number of entries. - * Currently: 18 entries, 62 bytes + * Currently: 33 entries, 75 bytes + * + * Reserve more space for the JPEG metadata set by the post-processor. + * Currently: ANDROID_JPEG_SIZE (int32_t), ANDROID_JPEG_QUALITY (byte), + * ANDROID_JPEG_ORIENTATION (int32_t) = 3 entries, 9 bytes. */ std::unique_ptr resultMetadata = - std::make_unique(19, 63); + std::make_unique(33, 75); if (!resultMetadata->isValid()) { LOG(HAL, Error) << "Failed to allocate static metadata"; return nullptr; } - const uint8_t ae_state = ANDROID_CONTROL_AE_STATE_CONVERGED; - resultMetadata->addEntry(ANDROID_CONTROL_AE_STATE, &ae_state, 1); + uint8_t value = ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF; + resultMetadata->addEntry(ANDROID_CONTROL_AE_ANTIBANDING_MODE, &value, 1); + + value = ANDROID_CONTROL_AE_LOCK_OFF; + resultMetadata->addEntry(ANDROID_CONTROL_AE_LOCK, &value, 1); + + value = ANDROID_CONTROL_AE_MODE_ON; + resultMetadata->addEntry(ANDROID_CONTROL_AE_MODE, &value, 1); - const uint8_t ae_lock = ANDROID_CONTROL_AE_LOCK_OFF; - resultMetadata->addEntry(ANDROID_CONTROL_AE_LOCK, &ae_lock, 1); + std::vector aeFpsTarget = { 30, 30 }; + resultMetadata->addEntry(ANDROID_CONTROL_AE_TARGET_FPS_RANGE, + aeFpsTarget.data(), aeFpsTarget.size()); - uint8_t af_state = ANDROID_CONTROL_AF_STATE_INACTIVE; - resultMetadata->addEntry(ANDROID_CONTROL_AF_STATE, &af_state, 1); + value = ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE; + resultMetadata->addEntry(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER, + &value, 1); - const uint8_t awb_state = ANDROID_CONTROL_AWB_STATE_CONVERGED; - resultMetadata->addEntry(ANDROID_CONTROL_AWB_STATE, &awb_state, 1); + value = ANDROID_CONTROL_AE_STATE_CONVERGED; + resultMetadata->addEntry(ANDROID_CONTROL_AE_STATE, &value, 1); - const uint8_t awb_lock = ANDROID_CONTROL_AWB_LOCK_OFF; - resultMetadata->addEntry(ANDROID_CONTROL_AWB_LOCK, &awb_lock, 1); + value = ANDROID_CONTROL_AF_MODE_OFF; + resultMetadata->addEntry(ANDROID_CONTROL_AF_MODE, &value, 1); - const uint8_t lens_state = ANDROID_LENS_STATE_STATIONARY; - resultMetadata->addEntry(ANDROID_LENS_STATE, &lens_state, 1); + value = ANDROID_CONTROL_AF_STATE_INACTIVE; + resultMetadata->addEntry(ANDROID_CONTROL_AF_STATE, &value, 1); + + value = ANDROID_CONTROL_AF_TRIGGER_IDLE; + resultMetadata->addEntry(ANDROID_CONTROL_AF_TRIGGER, &value, 1); + + value = ANDROID_CONTROL_AWB_MODE_AUTO; + resultMetadata->addEntry(ANDROID_CONTROL_AWB_MODE, &value, 1); + + value = ANDROID_CONTROL_AWB_LOCK_OFF; + resultMetadata->addEntry(ANDROID_CONTROL_AWB_LOCK, &value, 1); + + value = ANDROID_CONTROL_AWB_STATE_CONVERGED; + resultMetadata->addEntry(ANDROID_CONTROL_AWB_STATE, &value, 1); + + value = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW; + resultMetadata->addEntry(ANDROID_CONTROL_CAPTURE_INTENT, &value, 1); + + value = ANDROID_CONTROL_EFFECT_MODE_OFF; + resultMetadata->addEntry(ANDROID_CONTROL_EFFECT_MODE, &value, 1); + + value = ANDROID_CONTROL_MODE_AUTO; + resultMetadata->addEntry(ANDROID_CONTROL_MODE, &value, 1); + + value = ANDROID_CONTROL_SCENE_MODE_DISABLED; + resultMetadata->addEntry(ANDROID_CONTROL_SCENE_MODE, &value, 1); + + value = ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF; + resultMetadata->addEntry(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE, &value, 1); + + value = ANDROID_FLASH_MODE_OFF; + resultMetadata->addEntry(ANDROID_FLASH_MODE, &value, 1); + + value = ANDROID_FLASH_STATE_UNAVAILABLE; + resultMetadata->addEntry(ANDROID_FLASH_STATE, &value, 1); + + value = ANDROID_LENS_STATE_STATIONARY; + resultMetadata->addEntry(ANDROID_LENS_STATE, &value, 1); + + value = ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF; + resultMetadata->addEntry(ANDROID_LENS_OPTICAL_STABILIZATION_MODE, + &value, 1); resultMetadata->addEntry(ANDROID_SENSOR_TIMESTAMP, ×tamp, 1); - /* 33.3 msec */ - const int64_t rolling_shutter_skew = 33300000; - resultMetadata->addEntry(ANDROID_SENSOR_ROLLING_SHUTTER_SKEW, - &rolling_shutter_skew, 1); + value = ANDROID_STATISTICS_FACE_DETECT_MODE_OFF; + resultMetadata->addEntry(ANDROID_STATISTICS_FACE_DETECT_MODE, + &value, 1); - const uint8_t lens_shading_map_mode = - ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF; + value = ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF; resultMetadata->addEntry(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE, - &lens_shading_map_mode, 1); + &value, 1); - const uint8_t scene_flicker = ANDROID_STATISTICS_SCENE_FLICKER_NONE; + value = ANDROID_STATISTICS_SCENE_FLICKER_NONE; resultMetadata->addEntry(ANDROID_STATISTICS_SCENE_FLICKER, - &scene_flicker, 1); + &value, 1); + + value = ANDROID_NOISE_REDUCTION_MODE_OFF; + resultMetadata->addEntry(ANDROID_NOISE_REDUCTION_MODE, &value, 1); + + /* 33.3 msec */ + const int64_t rolling_shutter_skew = 33300000; + resultMetadata->addEntry(ANDROID_SENSOR_ROLLING_SHUTTER_SKEW, + &rolling_shutter_skew, 1); /* Add metadata tags reported by libcamera. */ if (metadata.contains(controls::draft::PipelineDepth)) {