[{"id":14502,"web_url":"https://patchwork.libcamera.org/comment/14502/","msgid":"<X/t+Pvl5tnu0CcL3@pendragon.ideasonboard.com>","date":"2021-01-10T22:22:54","subject":"Re: [libcamera-devel] [PATCH 03/12] libcamera: ipu3: Register\n\tExposure control","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Jacopo,\n\nThank you for the patch.\n\nOn Tue, Jan 05, 2021 at 08:05:13PM +0100, Jacopo Mondi wrote:\n> Calculate the controls::Exposure limits at camera registration time\n> and register it in the list of camera supported controls.\n> \n> Cache the default exposure value to report it in the request metadata.\n> \n> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>\n> ---\n>  src/libcamera/pipeline/ipu3/ipu3.cpp | 67 ++++++++++++++++++++++++++--\n>  1 file changed, 63 insertions(+), 4 deletions(-)\n> \n> diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp\n> index f1151733d9fe..879057dab328 100644\n> --- a/src/libcamera/pipeline/ipu3/ipu3.cpp\n> +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp\n> @@ -41,7 +41,7 @@ static constexpr unsigned int IMGU_OUTPUT_HEIGHT_ALIGN = 4;\n>  static constexpr unsigned int IMGU_OUTPUT_WIDTH_MARGIN = 64;\n>  static constexpr unsigned int IMGU_OUTPUT_HEIGHT_MARGIN = 32;\n>  \n> -static const ControlInfoMap IPU3Controls = {\n> +static const ControlInfoMap::Map IPU3Controls = {\n>  \t{ &controls::draft::PipelineDepth, ControlInfo(2, 3) },\n>  };\n>  \n> @@ -49,7 +49,7 @@ class IPU3CameraData : public CameraData\n>  {\n>  public:\n>  \tIPU3CameraData(PipelineHandler *pipe)\n> -\t\t: CameraData(pipe)\n> +\t\t: CameraData(pipe), exposureTime_(0)\n>  \t{\n>  \t}\n>  \n> @@ -62,6 +62,8 @@ public:\n>  \tStream outStream_;\n>  \tStream vfStream_;\n>  \tStream rawStream_;\n> +\n> +\tint32_t exposureTime_;\n\nThis can't be negative, unsigned int would do.\n\n>  };\n>  \n>  class IPU3CameraConfiguration : public CameraConfiguration\n> @@ -119,6 +121,7 @@ private:\n>  \t\t\tPipelineHandler::cameraData(camera));\n>  \t}\n>  \n> +\tint initControls(IPU3CameraData *data);\n>  \tint registerCameras();\n>  \n>  \tint allocateBuffers(Camera *camera);\n> @@ -731,6 +734,60 @@ bool PipelineHandlerIPU3::match(DeviceEnumerator *enumerator)\n>  \treturn ret == 0;\n>  }\n>  \n> +/*\n\n/**\n\n> + * \\brief Initialize the camera controls\n> + * \\param[in] data The camera data\n> + *\n> + * Initialize the camera controls by registering the pipeline handler\n> + * ones along with the controls assembled by inspecting the sensor\n> + * capabilities.\n\nShould this mention IPU3Controls ? Maybe the following ?\n\n * Initialize the camera controls as the union of the static pipeline handler\n * controls (IPU3Controls) and controls created dynamically from the sensor\n * capabilities.\n\n> + *\n> + * \\return 0 on success or a negative error code for error\n\ns/for error/otherwise/\n\n> + */\n> +int PipelineHandlerIPU3::initControls(IPU3CameraData *data)\n> +{\n> +\tconst CameraSensor *sensor = data->cio2_.sensor();\n> +\tCameraSensorInfo sensorInfo{};\n> +\n> +\tint ret = sensor->sensorInfo(&sensorInfo);\n> +\tif (ret)\n> +\t\treturn ret;\n> +\n> +\tControlInfoMap::Map controls = IPU3Controls;\n> +\n> +\t/*\n> +\t * Compute exposure time limits.\n> +\t *\n> +\t * \\todo The exposure limits depend on the sensor configuration.\n> +\t * Initialize the control using the line lenght and pixel rate of the\n\ns/lenght/length/\n\n> +\t * current configurtion, as reported by the CameraSensorInfo. Use the\n\ns/configurtion/configuration/\n\n> +\t * V4L2_CID_EXPOSURE control to get exposure min and max and convert it\n> +\t * from lines into micro-seconds.\n\ns/into/to/\ns/micro-seconds/microseconds/\n\n> +\t */\n> +\tfloat pixelRate = sensorInfo.pixelRate / 1e6f;\n> +\tconst ControlInfoMap &sensorControls = sensor->controls();\n> +\tconst ControlInfo &v4l2Exposure = sensorControls.find(V4L2_CID_EXPOSURE)->second;\n> +\tint32_t minExposure = v4l2Exposure.min().get<int32_t>()\n> +\t\t\t    * sensorInfo.lineLength / pixelRate;\n> +\tint32_t maxExposure = v4l2Exposure.max().get<int32_t>()\n> +\t\t\t    * sensorInfo.lineLength / pixelRate;\n> +\tint32_t defExposure = v4l2Exposure.def().get<int32_t>()\n> +\t\t\t    * sensorInfo.lineLength / pixelRate;\n\nFor long exposure time this will overflow as the first two operands are\n32-bit integers. How about the following ?\n\n\tdouble lineDuration = sensorInfo.pixelRate / 1e6f /pixelRate;\n\t...\n\tint32_t minExposure = v4l2Exposure.min().get<int32_t>() * lineDuration;\n\tint32_t maxExposure = v4l2Exposure.max().get<int32_t>() * lineDuration;\n\tint32_t defExposure = v4l2Exposure.def().get<int32_t>() * lineDuration;\n\n> +\n> +\t/*\n> +\t * \\todo Report the actual exposure time, use the default for the\n> +\t * moment.\n> +\t */\n> +\tdata->exposureTime_ = defExposure;\n> +\n> +\tcontrols[&controls::ExposureTime] = ControlInfo(minExposure, maxExposure,\n> +\t\t\t\t\t\t\tdefExposure);\n> +\n> +\tdata->controlInfo_ = std::move(controls);\n> +\n> +\treturn 0;\n> +}\n> +\n>  /**\n>   * \\brief Initialise ImgU and CIO2 devices associated with cameras\n>   *\n> @@ -776,8 +833,9 @@ int PipelineHandlerIPU3::registerCameras()\n>  \t\t/* Initialize the camera properties. */\n>  \t\tdata->properties_ = cio2->sensor()->properties();\n>  \n> -\t\t/* Initialze the camera controls. */\n> -\t\tdata->controlInfo_ = IPU3Controls;\n> +\t\tret = initControls(data.get());\n> +\t\tif (ret)\n> +\t\t\tcontinue;\n>  \n>  \t\t/**\n>  \t\t * \\todo Dynamically assign ImgU and output devices to each\n> @@ -842,6 +900,7 @@ void IPU3CameraData::imguOutputBufferReady(FrameBuffer *buffer)\n>  \n>  \t/* Mark the request as complete. */\n>  \trequest->metadata().set(controls::draft::PipelineDepth, 3);\n\n\t/* \\todo Move the ExposureTime control to the IPA */\n\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\n> +\trequest->metadata().set(controls::ExposureTime, exposureTime_);\n>  \tpipe_->completeRequest(request);\n>  }\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 164AABD80C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tSun, 10 Jan 2021 22:23:10 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 93A806807C;\n\tSun, 10 Jan 2021 23:23:09 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 0593160523\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSun, 10 Jan 2021 23:23:09 +0100 (CET)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 73B3DDA;\n\tSun, 10 Jan 2021 23:23:08 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"aM2VAEbb\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1610317388;\n\tbh=pBMYUkzFSzu9BTm+ETmWqlzEVV0PihARuUDS1X6BxSM=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=aM2VAEbbyOKDMr1SlMudMMH8wCEPi4zOtLkLddXwBvNlnviv4p2MKg7yivOzlvsH0\n\tlFXpNWPsNehn2llQNM9dzrpXmPBnJRTtKZ+hi7Cd9qybPhvPKYjv0TNSPEK1r3rUQ/\n\tN8toHKUHhDrau0c36d+Xd4z3TgSpoBAWvFGa2fcc=","Date":"Mon, 11 Jan 2021 00:22:54 +0200","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Jacopo Mondi <jacopo@jmondi.org>","Message-ID":"<X/t+Pvl5tnu0CcL3@pendragon.ideasonboard.com>","References":"<20210105190522.682324-1-jacopo@jmondi.org>\n\t<20210105190522.682324-4-jacopo@jmondi.org>","MIME-Version":"1.0","Content-Disposition":"inline","In-Reply-To":"<20210105190522.682324-4-jacopo@jmondi.org>","Subject":"Re: [libcamera-devel] [PATCH 03/12] libcamera: ipu3: Register\n\tExposure control","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Cc":"libcamera-devel@lists.libcamera.org","Content-Type":"text/plain; charset=\"us-ascii\"","Content-Transfer-Encoding":"7bit","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":14577,"web_url":"https://patchwork.libcamera.org/comment/14577/","msgid":"<20210118122732.pvenasx2omwvzbdq@uno.localdomain>","date":"2021-01-18T12:27:32","subject":"Re: [libcamera-devel] [PATCH 03/12] libcamera: ipu3: Register\n\tExposure control","submitter":{"id":3,"url":"https://patchwork.libcamera.org/api/people/3/","name":"Jacopo Mondi","email":"jacopo@jmondi.org"},"content":"Hi Laurent,\n\nOn Mon, Jan 11, 2021 at 12:22:54AM +0200, Laurent Pinchart wrote:\n> Hi Jacopo,\n>\n> Thank you for the patch.\n>\n> > +\t */\n> > +\tfloat pixelRate = sensorInfo.pixelRate / 1e6f;\n> > +\tconst ControlInfoMap &sensorControls = sensor->controls();\n> > +\tconst ControlInfo &v4l2Exposure = sensorControls.find(V4L2_CID_EXPOSURE)->second;\n> > +\tint32_t minExposure = v4l2Exposure.min().get<int32_t>()\n> > +\t\t\t    * sensorInfo.lineLength / pixelRate;\n> > +\tint32_t maxExposure = v4l2Exposure.max().get<int32_t>()\n> > +\t\t\t    * sensorInfo.lineLength / pixelRate;\n> > +\tint32_t defExposure = v4l2Exposure.def().get<int32_t>()\n> > +\t\t\t    * sensorInfo.lineLength / pixelRate;\n>\n> For long exposure time this will overflow as the first two operands are\n> 32-bit integers. How about the following ?\n>\n> \tdouble lineDuration = sensorInfo.pixelRate / 1e6f /pixelRate;\n\ndid you mean:\n        sensorInfo.lineLength / (sensorInfo.pixelRate / 1e6f)\nor rather\n        sensorInfo.lineLength * 1e6f / sensorInfo.pixelRate\n\nbut there's an overflow risk as well here.\n\n> \t...\n> \tint32_t minExposure = v4l2Exposure.min().get<int32_t>() * lineDuration;\n> \tint32_t maxExposure = v4l2Exposure.max().get<int32_t>() * lineDuration;\n> \tint32_t defExposure = v4l2Exposure.def().get<int32_t>() * lineDuration;\n>\n> > +\n> > +\t/*\n> > +\t * \\todo Report the actual exposure time, use the default for the\n> > +\t * moment.\n> > +\t */\n> > +\tdata->exposureTime_ = defExposure;\n> > +\n> > +\tcontrols[&controls::ExposureTime] = ControlInfo(minExposure, maxExposure,\n> > +\t\t\t\t\t\t\tdefExposure);\n> > +\n> > +\tdata->controlInfo_ = std::move(controls);\n> > +\n> > +\treturn 0;\n> > +}\n> > +\n> >  /**\n> >   * \\brief Initialise ImgU and CIO2 devices associated with cameras\n> >   *\n> > @@ -776,8 +833,9 @@ int PipelineHandlerIPU3::registerCameras()\n> >  \t\t/* Initialize the camera properties. */\n> >  \t\tdata->properties_ = cio2->sensor()->properties();\n> >\n> > -\t\t/* Initialze the camera controls. */\n> > -\t\tdata->controlInfo_ = IPU3Controls;\n> > +\t\tret = initControls(data.get());\n> > +\t\tif (ret)\n> > +\t\t\tcontinue;\n> >\n> >  \t\t/**\n> >  \t\t * \\todo Dynamically assign ImgU and output devices to each\n> > @@ -842,6 +900,7 @@ void IPU3CameraData::imguOutputBufferReady(FrameBuffer *buffer)\n> >\n> >  \t/* Mark the request as complete. */\n> >  \trequest->metadata().set(controls::draft::PipelineDepth, 3);\n>\n> \t/* \\todo Move the ExposureTime control to the IPA */\n>\n> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n>\n\nThanks\n  j\n\n> > +\trequest->metadata().set(controls::ExposureTime, exposureTime_);\n> >  \tpipe_->completeRequest(request);\n> >  }\n> >\n>\n> --\n> Regards,\n>\n> Laurent Pinchart","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id C607FC0F1C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 18 Jan 2021 12:27:16 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 19BA568123;\n\tMon, 18 Jan 2021 13:27:16 +0100 (CET)","from relay9-d.mail.gandi.net (relay9-d.mail.gandi.net\n\t[217.70.183.199])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 190486010B\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 18 Jan 2021 13:27:14 +0100 (CET)","from uno.localdomain (93-34-118-233.ip49.fastwebnet.it\n\t[93.34.118.233]) (Authenticated sender: jacopo@jmondi.org)\n\tby relay9-d.mail.gandi.net (Postfix) with ESMTPSA id A434BFF807;\n\tMon, 18 Jan 2021 12:27:13 +0000 (UTC)"],"X-Originating-IP":"93.34.118.233","Date":"Mon, 18 Jan 2021 13:27:32 +0100","From":"Jacopo Mondi <jacopo@jmondi.org>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Message-ID":"<20210118122732.pvenasx2omwvzbdq@uno.localdomain>","References":"<20210105190522.682324-1-jacopo@jmondi.org>\n\t<20210105190522.682324-4-jacopo@jmondi.org>\n\t<X/t+Pvl5tnu0CcL3@pendragon.ideasonboard.com>","MIME-Version":"1.0","Content-Disposition":"inline","In-Reply-To":"<X/t+Pvl5tnu0CcL3@pendragon.ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH 03/12] libcamera: ipu3: Register\n\tExposure control","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Cc":"libcamera-devel@lists.libcamera.org","Content-Type":"text/plain; charset=\"us-ascii\"","Content-Transfer-Encoding":"7bit","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":14581,"web_url":"https://patchwork.libcamera.org/comment/14581/","msgid":"<YAWmQzWbYhNIVisY@oden.dyn.berto.se>","date":"2021-01-18T15:16:19","subject":"Re: [libcamera-devel] [PATCH 03/12] libcamera: ipu3: Register\n\tExposure control","submitter":{"id":5,"url":"https://patchwork.libcamera.org/api/people/5/","name":"Niklas Söderlund","email":"niklas.soderlund@ragnatech.se"},"content":"Hi Jacopo,\n\nThanks for your work.\n\nOn 2021-01-05 20:05:13 +0100, Jacopo Mondi wrote:\n> Calculate the controls::Exposure limits at camera registration time\n> and register it in the list of camera supported controls.\n> \n> Cache the default exposure value to report it in the request metadata.\n> \n> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>\n> ---\n>  src/libcamera/pipeline/ipu3/ipu3.cpp | 67 ++++++++++++++++++++++++++--\n>  1 file changed, 63 insertions(+), 4 deletions(-)\n> \n> diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp\n> index f1151733d9fe..879057dab328 100644\n> --- a/src/libcamera/pipeline/ipu3/ipu3.cpp\n> +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp\n> @@ -41,7 +41,7 @@ static constexpr unsigned int IMGU_OUTPUT_HEIGHT_ALIGN = 4;\n>  static constexpr unsigned int IMGU_OUTPUT_WIDTH_MARGIN = 64;\n>  static constexpr unsigned int IMGU_OUTPUT_HEIGHT_MARGIN = 32;\n>  \n> -static const ControlInfoMap IPU3Controls = {\n> +static const ControlInfoMap::Map IPU3Controls = {\n>  \t{ &controls::draft::PipelineDepth, ControlInfo(2, 3) },\n>  };\n>  \n> @@ -49,7 +49,7 @@ class IPU3CameraData : public CameraData\n>  {\n>  public:\n>  \tIPU3CameraData(PipelineHandler *pipe)\n> -\t\t: CameraData(pipe)\n> +\t\t: CameraData(pipe), exposureTime_(0)\n>  \t{\n>  \t}\n>  \n> @@ -62,6 +62,8 @@ public:\n>  \tStream outStream_;\n>  \tStream vfStream_;\n>  \tStream rawStream_;\n> +\n> +\tint32_t exposureTime_;\n>  };\n>  \n>  class IPU3CameraConfiguration : public CameraConfiguration\n> @@ -119,6 +121,7 @@ private:\n>  \t\t\tPipelineHandler::cameraData(camera));\n>  \t}\n>  \n> +\tint initControls(IPU3CameraData *data);\n>  \tint registerCameras();\n>  \n>  \tint allocateBuffers(Camera *camera);\n> @@ -731,6 +734,60 @@ bool PipelineHandlerIPU3::match(DeviceEnumerator *enumerator)\n>  \treturn ret == 0;\n>  }\n>  \n> +/*\n> + * \\brief Initialize the camera controls\n> + * \\param[in] data The camera data\n> + *\n> + * Initialize the camera controls by registering the pipeline handler\n> + * ones along with the controls assembled by inspecting the sensor\n> + * capabilities.\n> + *\n> + * \\return 0 on success or a negative error code for error\n> + */\n> +int PipelineHandlerIPU3::initControls(IPU3CameraData *data)\n> +{\n> +\tconst CameraSensor *sensor = data->cio2_.sensor();\n> +\tCameraSensorInfo sensorInfo{};\n> +\n> +\tint ret = sensor->sensorInfo(&sensorInfo);\n> +\tif (ret)\n> +\t\treturn ret;\n> +\n> +\tControlInfoMap::Map controls = IPU3Controls;\n> +\n> +\t/*\n> +\t * Compute exposure time limits.\n> +\t *\n> +\t * \\todo The exposure limits depend on the sensor configuration.\n> +\t * Initialize the control using the line lenght and pixel rate of the\n> +\t * current configurtion, as reported by the CameraSensorInfo. Use the\n> +\t * V4L2_CID_EXPOSURE control to get exposure min and max and convert it\n> +\t * from lines into micro-seconds.\n> +\t */\n> +\tfloat pixelRate = sensorInfo.pixelRate / 1e6f;\n> +\tconst ControlInfoMap &sensorControls = sensor->controls();\n> +\tconst ControlInfo &v4l2Exposure = sensorControls.find(V4L2_CID_EXPOSURE)->second;\n> +\tint32_t minExposure = v4l2Exposure.min().get<int32_t>()\n> +\t\t\t    * sensorInfo.lineLength / pixelRate;\n> +\tint32_t maxExposure = v4l2Exposure.max().get<int32_t>()\n> +\t\t\t    * sensorInfo.lineLength / pixelRate;\n> +\tint32_t defExposure = v4l2Exposure.def().get<int32_t>()\n> +\t\t\t    * sensorInfo.lineLength / pixelRate;\n> +\n> +\t/*\n> +\t * \\todo Report the actual exposure time, use the default for the\n> +\t * moment.\n> +\t */\n> +\tdata->exposureTime_ = defExposure;\n> +\n> +\tcontrols[&controls::ExposureTime] = ControlInfo(minExposure, maxExposure,\n> +\t\t\t\t\t\t\tdefExposure);\n\nnit: This is the only usage of of the local 'controls' variable, would \nit make sens to remove it and use 'data->controlInfo_' directly and \navoid the std::move() below? While reading the code I thought there more \nthings going on here then an advance optimization ;-)\n\nWith or without this fix, but with the issues Laurent points out fixed,\n\nReviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n\n> +\n> +\tdata->controlInfo_ = std::move(controls);\n> +\n> +\treturn 0;\n> +}\n> +\n>  /**\n>   * \\brief Initialise ImgU and CIO2 devices associated with cameras\n>   *\n> @@ -776,8 +833,9 @@ int PipelineHandlerIPU3::registerCameras()\n>  \t\t/* Initialize the camera properties. */\n>  \t\tdata->properties_ = cio2->sensor()->properties();\n>  \n> -\t\t/* Initialze the camera controls. */\n> -\t\tdata->controlInfo_ = IPU3Controls;\n> +\t\tret = initControls(data.get());\n> +\t\tif (ret)\n> +\t\t\tcontinue;\n>  \n>  \t\t/**\n>  \t\t * \\todo Dynamically assign ImgU and output devices to each\n> @@ -842,6 +900,7 @@ void IPU3CameraData::imguOutputBufferReady(FrameBuffer *buffer)\n>  \n>  \t/* Mark the request as complete. */\n>  \trequest->metadata().set(controls::draft::PipelineDepth, 3);\n> +\trequest->metadata().set(controls::ExposureTime, exposureTime_);\n>  \tpipe_->completeRequest(request);\n>  }\n>  \n> -- \n> 2.29.2\n> \n> _______________________________________________\n> libcamera-devel mailing list\n> libcamera-devel@lists.libcamera.org\n> https://lists.libcamera.org/listinfo/libcamera-devel","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id E4426BD808\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 18 Jan 2021 15:16:23 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 73BE268126;\n\tMon, 18 Jan 2021 16:16:23 +0100 (CET)","from mail-lf1-x133.google.com (mail-lf1-x133.google.com\n\t[IPv6:2a00:1450:4864:20::133])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 397BA6010B\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 18 Jan 2021 16:16:21 +0100 (CET)","by mail-lf1-x133.google.com with SMTP id a12so24600099lfl.6\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 18 Jan 2021 07:16:21 -0800 (PST)","from localhost (h-209-203.A463.priv.bahnhof.se. [155.4.209.203])\n\tby smtp.gmail.com with ESMTPSA id\n\tr9sm1723422ljj.127.2021.01.18.07.16.19\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tMon, 18 Jan 2021 07:16:19 -0800 (PST)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=ragnatech-se.20150623.gappssmtp.com\n\theader.i=@ragnatech-se.20150623.gappssmtp.com\n\theader.b=\"A5XXN4IB\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=ragnatech-se.20150623.gappssmtp.com; s=20150623;\n\th=date:from:to:cc:subject:message-id:references:mime-version\n\t:content-disposition:content-transfer-encoding:in-reply-to;\n\tbh=uAIlpuPvaPqJOZhOHl2QXXzzsWtGAEOSbw0DAqqVjOA=;\n\tb=A5XXN4IBNbaDjzO3ebprweD9oGKtMduUtnlk9wgRlCa3M5Kv+lOIJ0p6vLJfIPNRRc\n\t+bG3ng7uH6dWrZ5CGN65CjzfRLlnD9vUwUYwR75uw2ZEbwUB8PlxPrHxnwuC7cg7n3xv\n\t1udC797BbE1C1gxRHWZXeT8aY9w1Ta1Og7UAtH2HdxDn8xP23hf/kEsPvLZ2sQxF680P\n\tBe6Rr+k5fJ9uWtwulO2S3vOVPL6eUIF6hkDGJ50IVpHg/Yn8d3ce2EbVYnVJ9075Eif0\n\tFLknZPoeka5pT9/fHMEE//W25DL/xgWjpSDZS6WtCq03UNIFTjUUQFcdjA4jaFkZrool\n\tvGuw==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:date:from:to:cc:subject:message-id:references\n\t:mime-version:content-disposition:content-transfer-encoding\n\t:in-reply-to;\n\tbh=uAIlpuPvaPqJOZhOHl2QXXzzsWtGAEOSbw0DAqqVjOA=;\n\tb=DsyEVL0auYPKkg9O+EUo8QrBTucOxsz2hZ325AL7H/l9SbiuIzu57L/joeFuu9YSLA\n\t+lmZ5PoV8MovTYYhsyjAj0Hzu2oawuXtXMVe9HiijBT+nebzKBCPyjdfpR8cZEySoVa0\n\tFxqm/fZ3212y0gIdvWzmH6hn5/SBJzMB4aQrx18RML/P125fZQz0KFBBfUc8nnI0lyxl\n\tR7C2f1bO0lJCenThRynR/yFC9Hl1qtBpXap8QYSInXSdq0Vs48wjt5tIVPE8r4YGA9Hh\n\te1tl2o076PrV0tOJkOaNGz7b2VLhhY9iinOaSzX5xsOIGPzDDA/zWpLUK4ivXHsdnknJ\n\t9BWw==","X-Gm-Message-State":"AOAM532CHF1IMAxF1KLBWd5KSdGjL71TfL5UXGM235c8Q7MelHUfhCWv\n\tOGbYLdMjgkCxdqGs5DfFEGlBRQ==","X-Google-Smtp-Source":"ABdhPJxOKep9c509RiBd0TP/4d5h5PufmsKfuln6wtgiUuat3RVIjCnFJPcQA6QMv3Ww4anZ7Ynbfg==","X-Received":"by 2002:a19:228b:: with SMTP id\n\ti133mr11523063lfi.365.1610982980625; \n\tMon, 18 Jan 2021 07:16:20 -0800 (PST)","Date":"Mon, 18 Jan 2021 16:16:19 +0100","From":"Niklas =?iso-8859-1?q?S=F6derlund?= <niklas.soderlund@ragnatech.se>","To":"Jacopo Mondi <jacopo@jmondi.org>","Message-ID":"<YAWmQzWbYhNIVisY@oden.dyn.berto.se>","References":"<20210105190522.682324-1-jacopo@jmondi.org>\n\t<20210105190522.682324-4-jacopo@jmondi.org>","MIME-Version":"1.0","Content-Disposition":"inline","In-Reply-To":"<20210105190522.682324-4-jacopo@jmondi.org>","Subject":"Re: [libcamera-devel] [PATCH 03/12] libcamera: ipu3: Register\n\tExposure control","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Cc":"libcamera-devel@lists.libcamera.org","Content-Type":"text/plain; charset=\"iso-8859-1\"","Content-Transfer-Encoding":"quoted-printable","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":14585,"web_url":"https://patchwork.libcamera.org/comment/14585/","msgid":"<20210118153841.2guum4xoxqs4dztu@uno.localdomain>","date":"2021-01-18T15:38:41","subject":"Re: [libcamera-devel] [PATCH 03/12] libcamera: ipu3: Register\n\tExposure control","submitter":{"id":3,"url":"https://patchwork.libcamera.org/api/people/3/","name":"Jacopo Mondi","email":"jacopo@jmondi.org"},"content":"Hi Niklas,\n\nOn Mon, Jan 18, 2021 at 04:16:19PM +0100, Niklas Söderlund wrote:\n> Hi Jacopo,\n>\n> Thanks for your work.\n>\n> On 2021-01-05 20:05:13 +0100, Jacopo Mondi wrote:\n> > Calculate the controls::Exposure limits at camera registration time\n> > and register it in the list of camera supported controls.\n> >\n> > Cache the default exposure value to report it in the request metadata.\n> >\n> > Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>\n> > ---\n> >  src/libcamera/pipeline/ipu3/ipu3.cpp | 67 ++++++++++++++++++++++++++--\n> >  1 file changed, 63 insertions(+), 4 deletions(-)\n> >\n> > diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp\n> > index f1151733d9fe..879057dab328 100644\n> > --- a/src/libcamera/pipeline/ipu3/ipu3.cpp\n> > +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp\n> > @@ -41,7 +41,7 @@ static constexpr unsigned int IMGU_OUTPUT_HEIGHT_ALIGN = 4;\n> >  static constexpr unsigned int IMGU_OUTPUT_WIDTH_MARGIN = 64;\n> >  static constexpr unsigned int IMGU_OUTPUT_HEIGHT_MARGIN = 32;\n> >\n> > -static const ControlInfoMap IPU3Controls = {\n> > +static const ControlInfoMap::Map IPU3Controls = {\n> >  \t{ &controls::draft::PipelineDepth, ControlInfo(2, 3) },\n> >  };\n> >\n> > @@ -49,7 +49,7 @@ class IPU3CameraData : public CameraData\n> >  {\n> >  public:\n> >  \tIPU3CameraData(PipelineHandler *pipe)\n> > -\t\t: CameraData(pipe)\n> > +\t\t: CameraData(pipe), exposureTime_(0)\n> >  \t{\n> >  \t}\n> >\n> > @@ -62,6 +62,8 @@ public:\n> >  \tStream outStream_;\n> >  \tStream vfStream_;\n> >  \tStream rawStream_;\n> > +\n> > +\tint32_t exposureTime_;\n> >  };\n> >\n> >  class IPU3CameraConfiguration : public CameraConfiguration\n> > @@ -119,6 +121,7 @@ private:\n> >  \t\t\tPipelineHandler::cameraData(camera));\n> >  \t}\n> >\n> > +\tint initControls(IPU3CameraData *data);\n> >  \tint registerCameras();\n> >\n> >  \tint allocateBuffers(Camera *camera);\n> > @@ -731,6 +734,60 @@ bool PipelineHandlerIPU3::match(DeviceEnumerator *enumerator)\n> >  \treturn ret == 0;\n> >  }\n> >\n> > +/*\n> > + * \\brief Initialize the camera controls\n> > + * \\param[in] data The camera data\n> > + *\n> > + * Initialize the camera controls by registering the pipeline handler\n> > + * ones along with the controls assembled by inspecting the sensor\n> > + * capabilities.\n> > + *\n> > + * \\return 0 on success or a negative error code for error\n> > + */\n> > +int PipelineHandlerIPU3::initControls(IPU3CameraData *data)\n> > +{\n> > +\tconst CameraSensor *sensor = data->cio2_.sensor();\n> > +\tCameraSensorInfo sensorInfo{};\n> > +\n> > +\tint ret = sensor->sensorInfo(&sensorInfo);\n> > +\tif (ret)\n> > +\t\treturn ret;\n> > +\n> > +\tControlInfoMap::Map controls = IPU3Controls;\n> > +\n> > +\t/*\n> > +\t * Compute exposure time limits.\n> > +\t *\n> > +\t * \\todo The exposure limits depend on the sensor configuration.\n> > +\t * Initialize the control using the line lenght and pixel rate of the\n> > +\t * current configurtion, as reported by the CameraSensorInfo. Use the\n> > +\t * V4L2_CID_EXPOSURE control to get exposure min and max and convert it\n> > +\t * from lines into micro-seconds.\n> > +\t */\n> > +\tfloat pixelRate = sensorInfo.pixelRate / 1e6f;\n> > +\tconst ControlInfoMap &sensorControls = sensor->controls();\n> > +\tconst ControlInfo &v4l2Exposure = sensorControls.find(V4L2_CID_EXPOSURE)->second;\n> > +\tint32_t minExposure = v4l2Exposure.min().get<int32_t>()\n> > +\t\t\t    * sensorInfo.lineLength / pixelRate;\n> > +\tint32_t maxExposure = v4l2Exposure.max().get<int32_t>()\n> > +\t\t\t    * sensorInfo.lineLength / pixelRate;\n> > +\tint32_t defExposure = v4l2Exposure.def().get<int32_t>()\n> > +\t\t\t    * sensorInfo.lineLength / pixelRate;\n> > +\n> > +\t/*\n> > +\t * \\todo Report the actual exposure time, use the default for the\n> > +\t * moment.\n> > +\t */\n> > +\tdata->exposureTime_ = defExposure;\n> > +\n> > +\tcontrols[&controls::ExposureTime] = ControlInfo(minExposure, maxExposure,\n> > +\t\t\t\t\t\t\tdefExposure);\n>\n> nit: This is the only usage of of the local 'controls' variable, would\n> it make sens to remove it and use 'data->controlInfo_' directly and\n> avoid the std::move() below? While reading the code I thought there more\n> things going on here then an advance optimization ;-)\n\nIf I'm not mistaken that's actually how the ControlInfoMap API\nrequires an instance to be intialized, to trigger the generation of\nthe numerical ids map and support access by numerical index.\n\n>\n> With or without this fix, but with the issues Laurent points out fixed,\n>\n> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n>\n\nThanks\n  j\n\n> > +\n> > +\tdata->controlInfo_ = std::move(controls);\n> > +\n> > +\treturn 0;\n> > +}\n> > +\n> >  /**\n> >   * \\brief Initialise ImgU and CIO2 devices associated with cameras\n> >   *\n> > @@ -776,8 +833,9 @@ int PipelineHandlerIPU3::registerCameras()\n> >  \t\t/* Initialize the camera properties. */\n> >  \t\tdata->properties_ = cio2->sensor()->properties();\n> >\n> > -\t\t/* Initialze the camera controls. */\n> > -\t\tdata->controlInfo_ = IPU3Controls;\n> > +\t\tret = initControls(data.get());\n> > +\t\tif (ret)\n> > +\t\t\tcontinue;\n> >\n> >  \t\t/**\n> >  \t\t * \\todo Dynamically assign ImgU and output devices to each\n> > @@ -842,6 +900,7 @@ void IPU3CameraData::imguOutputBufferReady(FrameBuffer *buffer)\n> >\n> >  \t/* Mark the request as complete. */\n> >  \trequest->metadata().set(controls::draft::PipelineDepth, 3);\n> > +\trequest->metadata().set(controls::ExposureTime, exposureTime_);\n> >  \tpipe_->completeRequest(request);\n> >  }\n> >\n> > --\n> > 2.29.2\n> >\n> > _______________________________________________\n> > libcamera-devel mailing list\n> > libcamera-devel@lists.libcamera.org\n> > https://lists.libcamera.org/listinfo/libcamera-devel\n>\n> --\n> Regards,\n> Niklas Söderlund","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id E046CC0F1C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 18 Jan 2021 15:38:24 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 6CA2E6812F;\n\tMon, 18 Jan 2021 16:38:24 +0100 (CET)","from relay8-d.mail.gandi.net (relay8-d.mail.gandi.net\n\t[217.70.183.201])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 708966010B\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 18 Jan 2021 16:38:23 +0100 (CET)","from uno.localdomain (93-61-96-190.ip145.fastwebnet.it\n\t[93.61.96.190]) (Authenticated sender: jacopo@jmondi.org)\n\tby relay8-d.mail.gandi.net (Postfix) with ESMTPSA id D978E1BF208;\n\tMon, 18 Jan 2021 15:38:22 +0000 (UTC)"],"X-Originating-IP":"93.61.96.190","Date":"Mon, 18 Jan 2021 16:38:41 +0100","From":"Jacopo Mondi <jacopo@jmondi.org>","To":"Niklas =?utf-8?q?S=C3=B6derlund?= <niklas.soderlund@ragnatech.se>","Message-ID":"<20210118153841.2guum4xoxqs4dztu@uno.localdomain>","References":"<20210105190522.682324-1-jacopo@jmondi.org>\n\t<20210105190522.682324-4-jacopo@jmondi.org>\n\t<YAWmQzWbYhNIVisY@oden.dyn.berto.se>","MIME-Version":"1.0","Content-Disposition":"inline","In-Reply-To":"<YAWmQzWbYhNIVisY@oden.dyn.berto.se>","Subject":"Re: [libcamera-devel] [PATCH 03/12] libcamera: ipu3: Register\n\tExposure control","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Cc":"libcamera-devel@lists.libcamera.org","Content-Type":"text/plain; charset=\"utf-8\"","Content-Transfer-Encoding":"base64","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":14589,"web_url":"https://patchwork.libcamera.org/comment/14589/","msgid":"<YAZ1DbeP6dJ53jh+@pendragon.ideasonboard.com>","date":"2021-01-19T05:58:37","subject":"Re: [libcamera-devel] [PATCH 03/12] libcamera: ipu3: Register\n\tExposure control","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Jacopo,\n\nOn Mon, Jan 18, 2021 at 01:27:32PM +0100, Jacopo Mondi wrote:\n> On Mon, Jan 11, 2021 at 12:22:54AM +0200, Laurent Pinchart wrote:\n> > Hi Jacopo,\n> >\n> > Thank you for the patch.\n> >\n> > > +\t */\n> > > +\tfloat pixelRate = sensorInfo.pixelRate / 1e6f;\n> > > +\tconst ControlInfoMap &sensorControls = sensor->controls();\n> > > +\tconst ControlInfo &v4l2Exposure = sensorControls.find(V4L2_CID_EXPOSURE)->second;\n> > > +\tint32_t minExposure = v4l2Exposure.min().get<int32_t>()\n> > > +\t\t\t    * sensorInfo.lineLength / pixelRate;\n> > > +\tint32_t maxExposure = v4l2Exposure.max().get<int32_t>()\n> > > +\t\t\t    * sensorInfo.lineLength / pixelRate;\n> > > +\tint32_t defExposure = v4l2Exposure.def().get<int32_t>()\n> > > +\t\t\t    * sensorInfo.lineLength / pixelRate;\n> >\n> > For long exposure time this will overflow as the first two operands are\n> > 32-bit integers. How about the following ?\n> >\n> > \tdouble lineDuration = sensorInfo.pixelRate / 1e6f /pixelRate;\n> \n> did you mean:\n>         sensorInfo.lineLength / (sensorInfo.pixelRate / 1e6f)\n> or rather\n>         sensorInfo.lineLength * 1e6f / sensorInfo.pixelRate\n\nYes, that's what I meant, sorry.\n\n> but there's an overflow risk as well here.\n\nIn your code v4l2Exposure.min().get<int32_t>() is an int32_t, and\nsensorInfo.lineLength is an uint32_t. Multiplying the two has a high\nrisk of overflow. Computing lineDuration as \n\n\tdouble lineDuration = sensorInfo.lineLength * 1e6f\n\t\t\t    / sensorInfo.pixelRate;\n\nwon't overflow as multiplying by 1e6f first will produce a float value.\n\n> > \t...\n> > \tint32_t minExposure = v4l2Exposure.min().get<int32_t>() * lineDuration;\n> > \tint32_t maxExposure = v4l2Exposure.max().get<int32_t>() * lineDuration;\n> > \tint32_t defExposure = v4l2Exposure.def().get<int32_t>() * lineDuration;\n\nThen these multiplications may overflow only if the result doesn't fit\nin an int32_t, which would happen if the exposure time is larger than\n~35 minutes. I think that's unlikely.\n\n> > > +\n> > > +\t/*\n> > > +\t * \\todo Report the actual exposure time, use the default for the\n> > > +\t * moment.\n> > > +\t */\n> > > +\tdata->exposureTime_ = defExposure;\n> > > +\n> > > +\tcontrols[&controls::ExposureTime] = ControlInfo(minExposure, maxExposure,\n> > > +\t\t\t\t\t\t\tdefExposure);\n> > > +\n> > > +\tdata->controlInfo_ = std::move(controls);\n> > > +\n> > > +\treturn 0;\n> > > +}\n> > > +\n> > >  /**\n> > >   * \\brief Initialise ImgU and CIO2 devices associated with cameras\n> > >   *\n> > > @@ -776,8 +833,9 @@ int PipelineHandlerIPU3::registerCameras()\n> > >  \t\t/* Initialize the camera properties. */\n> > >  \t\tdata->properties_ = cio2->sensor()->properties();\n> > >\n> > > -\t\t/* Initialze the camera controls. */\n> > > -\t\tdata->controlInfo_ = IPU3Controls;\n> > > +\t\tret = initControls(data.get());\n> > > +\t\tif (ret)\n> > > +\t\t\tcontinue;\n> > >\n> > >  \t\t/**\n> > >  \t\t * \\todo Dynamically assign ImgU and output devices to each\n> > > @@ -842,6 +900,7 @@ void IPU3CameraData::imguOutputBufferReady(FrameBuffer *buffer)\n> > >\n> > >  \t/* Mark the request as complete. */\n> > >  \trequest->metadata().set(controls::draft::PipelineDepth, 3);\n> >\n> > \t/* \\todo Move the ExposureTime control to the IPA */\n> >\n> > Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> >\n> > > +\trequest->metadata().set(controls::ExposureTime, exposureTime_);\n> > >  \tpipe_->completeRequest(request);\n> > >  }","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 0814FC0F1C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 19 Jan 2021 05:58:57 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 8314368134;\n\tTue, 19 Jan 2021 06:58:56 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 1B53D60310\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 19 Jan 2021 06:58:55 +0100 (CET)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 7D5C34FB;\n\tTue, 19 Jan 2021 06:58:54 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"Fd4zJi42\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1611035934;\n\tbh=KeI6TnYzcS+n6g2Ow/Z2dMKtRjnmhIo9QfLJlu0ccPU=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=Fd4zJi42caqfydaXWszCqw6k25SkeT4q63KWfsiTodPBdIBluPJr2uZhuld/X1+kY\n\tr5sAciewfCnHRN4XHfCfOqyCWywJ9cKpr0AcqOGYBxZNep4WnCfiDkvJCG3pTsOpHy\n\tOWyFnMvJjep3LdILkY5WTx9ODepbliLGd3JxD2hM=","Date":"Tue, 19 Jan 2021 07:58:37 +0200","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Jacopo Mondi <jacopo@jmondi.org>","Message-ID":"<YAZ1DbeP6dJ53jh+@pendragon.ideasonboard.com>","References":"<20210105190522.682324-1-jacopo@jmondi.org>\n\t<20210105190522.682324-4-jacopo@jmondi.org>\n\t<X/t+Pvl5tnu0CcL3@pendragon.ideasonboard.com>\n\t<20210118122732.pvenasx2omwvzbdq@uno.localdomain>","MIME-Version":"1.0","Content-Disposition":"inline","In-Reply-To":"<20210118122732.pvenasx2omwvzbdq@uno.localdomain>","Subject":"Re: [libcamera-devel] [PATCH 03/12] libcamera: ipu3: Register\n\tExposure control","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Cc":"libcamera-devel@lists.libcamera.org","Content-Type":"text/plain; charset=\"us-ascii\"","Content-Transfer-Encoding":"7bit","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]