From patchwork Tue Jan 19 14:37:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 10889 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 B76B8BD808 for ; Tue, 19 Jan 2021 14:36:59 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 4C96B68152; Tue, 19 Jan 2021 15:36:59 +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 7B21E68140 for ; Tue, 19 Jan 2021 15:36:57 +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 3D2B4C000E for ; Tue, 19 Jan 2021 14:36:57 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 19 Jan 2021 15:37:01 +0100 Message-Id: <20210119143711.153517-2-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 01/11] 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. Reviewed-by: Niklas Söderlund Reviewed-by: Laurent Pinchart Signed-off-by: Jacopo Mondi --- 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 251691aedfa3..9abb9d330664 100644 --- a/src/libcamera/camera_sensor.cpp +++ b/src/libcamera/camera_sensor.cpp @@ -590,11 +590,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 @@ -612,18 +613,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 @@ -646,6 +642,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 19 14:37:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 10890 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 B6A23BD808 for ; Tue, 19 Jan 2021 14:37:00 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 8A9406815A; Tue, 19 Jan 2021 15:37:00 +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 0AE9568140 for ; Tue, 19 Jan 2021 15:36:58 +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 AF004C001E for ; Tue, 19 Jan 2021 14:36:57 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 19 Jan 2021 15:37:02 +0100 Message-Id: <20210119143711.153517-3-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 02/11] 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. While at it, re-sort the mandatory V4L2 controls in alphabetical order in the CameraSensor class. Reviewed-by: Laurent Pinchart Signed-off-by: Jacopo Mondi --- Documentation/sensor_driver_requirements.rst | 11 ++++++++++- src/libcamera/camera_sensor.cpp | 3 ++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Documentation/sensor_driver_requirements.rst b/Documentation/sensor_driver_requirements.rst index 0e658aaa03b5..187f1c921dbf 100644 --- a/Documentation/sensor_driver_requirements.rst +++ b/Documentation/sensor_driver_requirements.rst @@ -24,13 +24,22 @@ The sensor driver is assumed to be fully compliant with the V4L2 specification. The sensor driver shall support the following V4L2 controls: +* `V4L2_CID_EXPOSURE`_ * `V4L2_CID_HBLANK`_ * `V4L2_CID_PIXEL_RATE`_ +.. _V4L2_CID_EXPOSURE: https://www.kernel.org/doc/html/latest/userspace-api/media/v4l/control.html .. _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 -Both controls are used to compute the sensor output timings. +The `EXPOSURE` control shall report the image integration time in number of +lines. While V4L2 doesn't specify a unit for the `EXPOSURE` control, libcamera +requires it to be expressed as a number of image lines. Camera sensor drivers +that do not comply with this requirement will need to be adapted or will produce +incorrect results. + +The `HBLANK` and `PIXEL_RATE` 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 9abb9d330664..5774578fe61f 100644 --- a/src/libcamera/camera_sensor.cpp +++ b/src/libcamera/camera_sensor.cpp @@ -243,8 +243,9 @@ int CameraSensor::validateSensorDriver() * - V4L2_CID_HBLANK is used to calculate the line length */ const std::vector mandatoryControls{ - V4L2_CID_PIXEL_RATE, + V4L2_CID_EXPOSURE, V4L2_CID_HBLANK, + V4L2_CID_PIXEL_RATE, }; ControlList ctrls = subdev_->getControls(mandatoryControls); From patchwork Tue Jan 19 14:37:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 10891 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 7143CBD808 for ; Tue, 19 Jan 2021 14:37:01 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B3FF96815D; Tue, 19 Jan 2021 15:37:00 +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 726C368146 for ; Tue, 19 Jan 2021 15:36:58 +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 365FFC001F for ; Tue, 19 Jan 2021 14:36:58 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 19 Jan 2021 15:37:03 +0100 Message-Id: <20210119143711.153517-4-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 03/11] 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. Reviewed-by: Laurent Pinchart Signed-off-by: Jacopo Mondi --- src/libcamera/pipeline/ipu3/ipu3.cpp | 66 ++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 4 deletions(-) diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 73304ea73050..f928af4d92a2 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_; + + uint32_t exposureTime_; }; class IPU3CameraConfiguration : public CameraConfiguration @@ -119,6 +121,7 @@ private: PipelineHandler::cameraData(camera)); } + int initControls(IPU3CameraData *data); int registerCameras(); int allocateBuffers(Camera *camera); @@ -730,6 +733,58 @@ bool PipelineHandlerIPU3::match(DeviceEnumerator *enumerator) return ret == 0; } +/** + * \brief Initialize the camera controls + * \param[in] data The camera data + * + * Initialize the camera controls as the union of the static pipeline handler + * controls (IPU3Controls) and controls created dynamically from the sensor + * capabilities. + * + * \return 0 on success or a negative error code otherwise + */ +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 length and pixel rate of the + * current configuration converted to microseconds. Use the + * V4L2_CID_EXPOSURE control to get exposure min, max and default and + * convert it from lines to microseconds. + */ + double lineDuration = sensorInfo.lineLength + / (sensorInfo.pixelRate / 1e6f); + const ControlInfoMap &sensorControls = sensor->controls(); + const ControlInfo &v4l2Exposure = sensorControls.find(V4L2_CID_EXPOSURE)->second; + int32_t minExposure = v4l2Exposure.min().get() * lineDuration; + int32_t maxExposure = v4l2Exposure.max().get() * lineDuration; + int32_t defExposure = v4l2Exposure.def().get() * lineDuration; + + /* + * \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 * @@ -775,8 +830,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 @@ -841,6 +897,8 @@ void IPU3CameraData::imguOutputBufferReady(FrameBuffer *buffer) /* Mark the request as complete. */ request->metadata().set(controls::draft::PipelineDepth, 3); + /* \todo Move the ExposureTime control to the IPA. */ + request->metadata().set(controls::ExposureTime, exposureTime_); pipe_->completeRequest(request); } From patchwork Tue Jan 19 14:37:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 10892 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 0AB54BD808 for ; Tue, 19 Jan 2021 14:37:03 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id DA6DB68161; Tue, 19 Jan 2021 15:37:02 +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 D5F0068151 for ; Tue, 19 Jan 2021 15:36:58 +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 9B89EC0007 for ; Tue, 19 Jan 2021 14:36:58 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 19 Jan 2021 15:37:04 +0100 Message-Id: <20210119143711.153517-5-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 04/11] 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. Reviewed-by: Laurent Pinchart Signed-off-by: Jacopo Mondi --- 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..d22142337d04 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() * 1000LL, + exposureInfo->second.max().get() * 1000LL, + }; + staticMetadata_->addEntry(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE, + &exposureTimeRange, 2); + } staticMetadata_->addEntry(ANDROID_SENSOR_ORIENTATION, &orientation_, 1); From patchwork Tue Jan 19 14:37:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 10893 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 7B670BD808 for ; Tue, 19 Jan 2021 14:37:03 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 328D268169; Tue, 19 Jan 2021 15:37:03 +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 497676814B for ; Tue, 19 Jan 2021 15:36:59 +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 0A1CAC0007 for ; Tue, 19 Jan 2021 14:36:58 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 19 Jan 2021 15:37:05 +0100 Message-Id: <20210119143711.153517-6-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 05/11] 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. Reviewed-by: Laurent Pinchart Signed-off-by: Jacopo Mondi --- 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 d22142337d04..0484bb9a6557 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 19 14:37:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 10894 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 DF995BD808 for ; Tue, 19 Jan 2021 14:37:03 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id ADF5F6815F; Tue, 19 Jan 2021 15:37:03 +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 A9B6E68140 for ; Tue, 19 Jan 2021 15:36:59 +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 6F0F2C0007 for ; Tue, 19 Jan 2021 14:36:59 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 19 Jan 2021 15:37:06 +0100 Message-Id: <20210119143711.153517-7-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 06/11] 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 Reviewed-by: Laurent Pinchart --- src/libcamera/pipeline/ipu3/ipu3.cpp | 73 +++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 2 deletions(-) diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index f928af4d92a2..fc5592f33032 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -40,6 +40,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) }, @@ -376,7 +377,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; @@ -745,7 +746,7 @@ bool PipelineHandlerIPU3::match(DeviceEnumerator *enumerator) */ int PipelineHandlerIPU3::initControls(IPU3CameraData *data) { - const CameraSensor *sensor = data->cio2_.sensor(); + CameraSensor *sensor = data->cio2_.sensor(); CameraSensorInfo sensorInfo{}; int ret = sensor->sensorInfo(&sensorInfo); @@ -780,6 +781,74 @@ 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 validate() function about the usage of the + * sensor's full frame as ImgU input). + */ + + /* Re-fetch the sensor info updated to use the largest resolution. */ + V4L2SubdeviceFormat sensorFormat; + sensorFormat.size = sensor->resolution(); + ret = sensor->setFormat(&sensorFormat); + if (ret) + return ret; + + ret = sensor->sensorInfo(&sensorInfo); + if (ret) + return ret; + + /* + * The maximum scaler crop rectangle is the analogue crop used to + * produce the maximum frame size. + */ + const Rectangle &analogueCrop = sensorInfo.analogCrop; + Rectangle maxCrop = analogueCrop; + + /* + * As the ImgU cannot up-scale, the minimum selection rectangle has to + * be as large as the pipeline output size. Use the default viewfinder + * configuration as the desired output size and calculate the minimum + * rectangle required to satisfy the ImgU processing margins, unless the + * sensor resolution is smaller. + * + * \todo This implementation is based on the same assumptions about the + * ImgU pipeline configuration described in then viewfinder and main + * output sizes calculation in the validate() function. + */ + + /* The strictly smaller size than the sensor resolution, aligned to margins. */ + Size minSize = Size(sensor->resolution().width - 1, + sensor->resolution().height - 1) + .alignedDownTo(IMGU_OUTPUT_WIDTH_MARGIN, + IMGU_OUTPUT_HEIGHT_MARGIN); + + /* + * Either the smallest margin-aligned size larger than the viewfinder + * size or the adjusted sensor resolution. + */ + minSize = Size(IPU3ViewfinderSize.width + 1, + IPU3ViewfinderSize.height + 1) + .alignedUpTo(IMGU_OUTPUT_WIDTH_MARGIN, + IMGU_OUTPUT_HEIGHT_MARGIN) + .boundedTo(minSize); + + /* + * Re-scale in the sensor's native coordinates. Report (0,0) as + * top-left corner as we allow application to feely pan the crop area. + */ + Rectangle minCrop(minSize); + minCrop.scaledBy(analogueCrop.size(), sensorInfo.outputSize); + minCrop.x = 0; + minCrop.y = 0; + + controls[&controls::ScalerCrop] = ControlInfo(minCrop, maxCrop, maxCrop); + data->controlInfo_ = std::move(controls); return 0; From patchwork Tue Jan 19 14:37:07 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 10895 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 61E20BD808 for ; Tue, 19 Jan 2021 14:37:04 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 2F03B6814F; Tue, 19 Jan 2021 15:37:04 +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 18A7B68148 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 D09A0C001A for ; Tue, 19 Jan 2021 14:36:59 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 19 Jan 2021 15:37:07 +0100 Message-Id: <20210119143711.153517-8-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 07/11] 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. Reviewed-by: Niklas Söderlund Reviewed-by: Laurent Pinchart Signed-off-by: Jacopo Mondi --- 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 0484bb9a6557..14068e313f74 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. This information are not available to the + * Android HAL, not at initialization time at least. + * + * As a workaround 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 19 14:37:08 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 10896 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 E9E3EBD808 for ; Tue, 19 Jan 2021 14:37:05 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id C020A6815D; Tue, 19 Jan 2021 15:37:05 +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 7DD4B68155 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 449E0C0007 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:08 +0100 Message-Id: <20210119143711.153517-9-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 08/11] libcamera: ipu3: Report ScalerCrop in 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" Report in the Request metadata the scaler crop region as requested by application through the request controls. No actual scaling is applied in the pipeline at the moment. Signed-off-by: Jacopo Mondi Reviewed-by: Laurent Pinchart --- src/libcamera/pipeline/ipu3/ipu3.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index fc5592f33032..329b9d51cf1b 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -968,6 +968,11 @@ void IPU3CameraData::imguOutputBufferReady(FrameBuffer *buffer) request->metadata().set(controls::draft::PipelineDepth, 3); /* \todo Move the ExposureTime control to the IPA. */ request->metadata().set(controls::ExposureTime, exposureTime_); + /* \todo Handle the scaler crop region for each request. */ + if (request->controls().contains(controls::ScalerCrop)) { + Rectangle cropRegion = request->controls().get(controls::ScalerCrop); + request->metadata().set(controls::ScalerCrop, cropRegion); + } pipe_->completeRequest(request); } 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(); From patchwork Tue Jan 19 14:37:10 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jacopo Mondi X-Patchwork-Id: 10898 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 CE2FFBD808 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 93EEA6814E; 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 5961468156 for ; Tue, 19 Jan 2021 15:37:01 +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 20F52C0007 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:10 +0100 Message-Id: <20210119143711.153517-11-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 10/11] 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 Reviewed-by: Niklas Söderlund Reviewed-by: Laurent Pinchart Signed-off-by: Jacopo Mondi --- src/android/camera_device.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index 5600d32cd2b9..759625b35963 100644 --- a/src/android/camera_device.cpp +++ b/src/android/camera_device.cpp @@ -801,8 +801,12 @@ const camera_metadata_t *CameraDevice::getStaticMetadata() availableStabilizationModes.data(), availableStabilizationModes.size()); + /* + * \todo Inspect the Camera capabilities to report the available + * AWB modes. Default to AUTO as CTS tests require it. + */ 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 19 14:37: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: 10899 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 44B01BD808 for ; Tue, 19 Jan 2021 14:37:07 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 0CE5E68174; Tue, 19 Jan 2021 15:37:07 +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 C27EE68161 for ; Tue, 19 Jan 2021 15:37:01 +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 839C0C0007 for ; Tue, 19 Jan 2021 14:37:01 +0000 (UTC) From: Jacopo Mondi To: libcamera-devel@lists.libcamera.org Date: Tue, 19 Jan 2021 15:37:11 +0100 Message-Id: <20210119143711.153517-12-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 11/11] 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. Reviewed-by: Laurent Pinchart Reviewed-by: Niklas Söderlund Signed-off-by: Jacopo Mondi --- src/android/camera_device.cpp | 133 ++++++++++++++++++++++++++-------- 1 file changed, 104 insertions(+), 29 deletions(-) diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp index 759625b35963..d41c16cdf3ae 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, 782 bytes of static metadata */ uint32_t numEntries = 53; - uint32_t byteSize = 714; + uint32_t byteSize = 782; /* * Calculate space occupation in bytes for dynamically built metadata @@ -1204,19 +1204,36 @@ 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_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, @@ -1889,48 +1906,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)) {