[{"id":4582,"web_url":"https://patchwork.libcamera.org/comment/4582/","msgid":"<20200427144401.34ci3vyx4hhwfauh@uno.localdomain>","date":"2020-04-27T14:44:01","subject":"Re: [libcamera-devel] [PATCH v5.2 4/7] libcamera: controls: Updates\n\tto gain and exposure controls","submitter":{"id":3,"url":"https://patchwork.libcamera.org/api/people/3/","name":"Jacopo Mondi","email":"jacopo@jmondi.org"},"content":"Hi Laurent,\n\nOn Sun, Apr 26, 2020 at 03:23:28AM +0300, Laurent Pinchart wrote:\n> From: Naushir Patuck <naush@raspberrypi.com>\n>\n> Rename:\n> ManualExposure -> ExposureTime\n> ManualGain -> AnalogueGain\n>\n> Use micro-seconds units for ExposureTime. This is changed from milli-\n> seconds. The latter would not allow very low exposure times.\n> AnalogueGain switch to use a float to allow fractional gain adjustments.\n>\n> Update the uvcvideo pipeline handler to use the new exposure and gain\n> units. For ExposureTime, UVC uses units of 100 micro-seconds, so map\n> the values before setting V4L2_CID_EXPOSURE_ABSOLUTE. For AnalogueGain,\n> UVC has no explicit gain units, so map the default gain value to 1.0\n> and linearly scale to the requested value.\n>\n> Signed-off-by: Naushir Patuck <naush@raspberrypi.com>\n> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\nReviewed-by: Jacopo Mondi <jacopo@jmondi.org>\n\nThanks\n  j\n\n> ---\n> Changes since v5:\n>\n> - Include math.h in uvcvideo.cpp\n> ---\n>  src/libcamera/control_ids.yaml               | 22 ++++--\n>  src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 78 +++++++++++++++++++-\n>  2 files changed, 88 insertions(+), 12 deletions(-)\n>\n> diff --git a/src/libcamera/control_ids.yaml b/src/libcamera/control_ids.yaml\n> index bcbab195a374..d8bdb3829be4 100644\n> --- a/src/libcamera/control_ids.yaml\n> +++ b/src/libcamera/control_ids.yaml\n> @@ -12,7 +12,7 @@ controls:\n>        description: |\n>          Enable or disable the AE.\n>\n> -        \\sa ManualExposure\n> +        \\sa ExposureTime AnalogueGain\n>\n>    - AeLocked:\n>        type: bool\n> @@ -30,8 +30,6 @@ controls:\n>        description: |\n>          Enable or disable the AWB.\n>\n> -        \\sa ManualGain\n> -\n>    - Brightness:\n>        type: int32_t\n>        description: Specify a fixed brightness parameter\n> @@ -44,12 +42,20 @@ controls:\n>        type: int32_t\n>        description: Specify a fixed saturation parameter\n>\n> -  - ManualExposure:\n> +  - ExposureTime:\n>        type: int32_t\n> -      description: Specify a fixed exposure time in milli-seconds\n> +      description: |\n> +        Exposure time (shutter speed) for the frame applied in the sensor\n> +        device. This value is specified in micro-seconds.\n>\n> -  - ManualGain:\n> -      type: int32_t\n> -      description: Specify a fixed gain parameter\n> +        \\sa AnalogueGain AeEnable\n> +\n> +  - AnalogueGain:\n> +      type: float\n> +      description: |\n> +        Analogue gain value applied in the sensor device.\n> +        The value of the control specifies the gain multiplier applied to all\n> +        colour channels. This value cannot be lower than 1.0.\n>\n> +        \\sa ExposureTime AeEnable\n>  ...\n> diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp\n> index b040f2460b1c..08462542a79b 100644\n> --- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp\n> +++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp\n> @@ -7,6 +7,7 @@\n>\n>  #include <algorithm>\n>  #include <iomanip>\n> +#include <math.h>\n>  #include <sys/sysmacros.h>\n>  #include <tuple>\n>\n> @@ -254,13 +255,19 @@ int PipelineHandlerUVC::processControl(ControlList *controls, unsigned int id,\n>  \t\tcid = V4L2_CID_SATURATION;\n>  \telse if (id == controls::AeEnable)\n>  \t\tcid = V4L2_CID_EXPOSURE_AUTO;\n> -\telse if (id == controls::ManualExposure)\n> +\telse if (id == controls::ExposureTime)\n>  \t\tcid = V4L2_CID_EXPOSURE_ABSOLUTE;\n> -\telse if (id == controls::ManualGain)\n> +\telse if (id == controls::AnalogueGain)\n>  \t\tcid = V4L2_CID_GAIN;\n>  \telse\n>  \t\treturn -EINVAL;\n>\n> +\tconst ControlInfo &v4l2Info = controls->infoMap()->at(cid);\n> +\n> +\t/*\n> +\t * See UVCCameraData::addControl() for explanations of the different\n> +\t * value mappings.\n> +\t */\n>  \tswitch (cid) {\n>  \tcase V4L2_CID_EXPOSURE_AUTO: {\n>  \t\tint32_t ivalue = value.get<bool>()\n> @@ -270,6 +277,28 @@ int PipelineHandlerUVC::processControl(ControlList *controls, unsigned int id,\n>  \t\tbreak;\n>  \t}\n>\n> +\tcase V4L2_CID_EXPOSURE_ABSOLUTE:\n> +\t\tcontrols->set(cid, value.get<int32_t>() / 100);\n> +\t\tbreak;\n> +\n> +\tcase V4L2_CID_GAIN: {\n> +\t\tint32_t min = v4l2Info.min().get<int32_t>();\n> +\t\tint32_t max = v4l2Info.max().get<int32_t>();\n> +\t\tint32_t def = v4l2Info.def().get<int32_t>();\n> +\n> +\t\tfloat m = (4.0f - 1.0f) / (max - def);\n> +\t\tfloat p = 1.0f - m * def;\n> +\n> +\t\tif (m * min + p < 0.5f) {\n> +\t\t\tm = (1.0f - 0.5f) / (def - min);\n> +\t\t\tp = 1.0f - m * def;\n> +\t\t}\n> +\n> +\t\tfloat fvalue = (value.get<float>() - p) / m;\n> +\t\tcontrols->set(cid, static_cast<int32_t>(lroundf(fvalue)));\n> +\t\tbreak;\n> +\t}\n> +\n>  \tdefault: {\n>  \t\tint32_t ivalue = value.get<int32_t>();\n>  \t\tcontrols->set(cid, ivalue);\n> @@ -413,21 +442,62 @@ void UVCCameraData::addControl(uint32_t cid, const ControlInfo &v4l2Info,\n>  \t\tid = &controls::AeEnable;\n>  \t\tbreak;\n>  \tcase V4L2_CID_EXPOSURE_ABSOLUTE:\n> -\t\tid = &controls::ManualExposure;\n> +\t\tid = &controls::ExposureTime;\n>  \t\tbreak;\n>  \tcase V4L2_CID_GAIN:\n> -\t\tid = &controls::ManualGain;\n> +\t\tid = &controls::AnalogueGain;\n>  \t\tbreak;\n>  \tdefault:\n>  \t\treturn;\n>  \t}\n>\n>  \t/* Map the control info. */\n> +\tint32_t min = v4l2Info.min().get<int32_t>();\n> +\tint32_t max = v4l2Info.max().get<int32_t>();\n> +\tint32_t def = v4l2Info.def().get<int32_t>();\n> +\n>  \tswitch (cid) {\n>  \tcase V4L2_CID_EXPOSURE_AUTO:\n>  \t\tinfo = ControlInfo{ false, true, true };\n>  \t\tbreak;\n>\n> +\tcase V4L2_CID_EXPOSURE_ABSOLUTE:\n> +\t\t/*\n> +\t\t * ExposureTime is in units of 1 µs, and UVC expects\n> +\t\t * V4L2_CID_EXPOSURE_ABSOLUTE in units of 100 µs.\n> +\t\t */\n> +\t\tinfo = ControlInfo{\n> +\t\t\t{ min * 100 },\n> +\t\t\t{ max * 100 },\n> +\t\t\t{ def * 100 }\n> +\t\t};\n> +\t\tbreak;\n> +\n> +\tcase V4L2_CID_GAIN: {\n> +\t\t/*\n> +\t\t * The AnalogueGain control is a float, with 1.0 mapped to the\n> +\t\t * default value. UVC doesn't specify units, and cameras have\n> +\t\t * been seen to expose very different ranges for the gain\n> +\t\t * control. Arbitrarily assume that the minimum and maximum\n> +\t\t * values are respectively no lower than 0.5 and no higher than\n> +\t\t * 4.0.\n> +\t\t */\n> +\t\tfloat m = (4.0f - 1.0f) / (max - def);\n> +\t\tfloat p = 1.0f - m * def;\n> +\n> +\t\tif (m * min + p < 0.5f) {\n> +\t\t\tm = (1.0f - 0.5f) / (def - min);\n> +\t\t\tp = 1.0f - m * def;\n> +\t\t}\n> +\n> +\t\tinfo = ControlInfo{\n> +\t\t\t{ m * min + p },\n> +\t\t\t{ m * max + p },\n> +\t\t\t{ 1.0f }\n> +\t\t};\n> +\t\tbreak;\n> +\t}\n> +\n>  \tdefault:\n>  \t\tinfo = v4l2Info;\n>  \t\tbreak;\n> --\n> Regards,\n>\n> Laurent Pinchart\n>\n> _______________________________________________\n> libcamera-devel mailing list\n> libcamera-devel@lists.libcamera.org\n> https://lists.libcamera.org/listinfo/libcamera-devel","headers":{"Return-Path":"<jacopo@jmondi.org>","Received":["from relay3-d.mail.gandi.net (relay3-d.mail.gandi.net\n\t[217.70.183.195])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id BADE9603F9\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 27 Apr 2020 16:40:51 +0200 (CEST)","from uno.localdomain (a-ur1-85.tin.it [212.216.150.148])\n\t(Authenticated sender: jacopo@jmondi.org)\n\tby relay3-d.mail.gandi.net (Postfix) with ESMTPSA id C8D4D60016;\n\tMon, 27 Apr 2020 14:40:50 +0000 (UTC)"],"X-Originating-IP":"212.216.150.148","Date":"Mon, 27 Apr 2020 16:44:01 +0200","From":"Jacopo Mondi <jacopo@jmondi.org>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Message-ID":"<20200427144401.34ci3vyx4hhwfauh@uno.localdomain>","References":"<20200425004533.26907-5-laurent.pinchart@ideasonboard.com>\n\t<20200426002328.15500-1-laurent.pinchart@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<20200426002328.15500-1-laurent.pinchart@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH v5.2 4/7] libcamera: controls: Updates\n\tto gain and exposure controls","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>","X-List-Received-Date":"Mon, 27 Apr 2020 14:40:51 -0000"}}]