Show a patch.

GET /api/1.1/patches/16472/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 16472,
    "url": "https://patchwork.libcamera.org/api/1.1/patches/16472/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/16472/",
    "project": {
        "id": 1,
        "url": "https://patchwork.libcamera.org/api/1.1/projects/1/?format=api",
        "name": "libcamera",
        "link_name": "libcamera",
        "list_id": "libcamera_core",
        "list_email": "libcamera-devel@lists.libcamera.org",
        "web_url": "",
        "scm_url": "",
        "webscm_url": ""
    },
    "msgid": "<20220630133902.321099-14-jacopo@jmondi.org>",
    "date": "2022-06-30T13:38:52",
    "name": "[libcamera-devel,v3,13/23] libcamera: camera_sensor: Cache the sensor configuration",
    "commit_ref": null,
    "pull_url": null,
    "state": "not-applicable",
    "archived": true,
    "hash": "92fcaf7892af874dde409d6aea3a337305abd6a0",
    "submitter": {
        "id": 3,
        "url": "https://patchwork.libcamera.org/api/1.1/people/3/?format=api",
        "name": "Jacopo Mondi",
        "email": "jacopo@jmondi.org"
    },
    "delegate": null,
    "mbox": "https://patchwork.libcamera.org/patch/16472/mbox/",
    "series": [
        {
            "id": 3238,
            "url": "https://patchwork.libcamera.org/api/1.1/series/3238/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=3238",
            "date": "2022-06-30T13:38:39",
            "name": "Internal controls, sensor delays and IPA rework",
            "version": 3,
            "mbox": "https://patchwork.libcamera.org/series/3238/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/16472/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/16472/checks/",
    "tags": {},
    "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 3D6DCC3275\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 30 Jun 2022 13:39:44 +0000 (UTC)",
            "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id DFA3E656AA;\n\tThu, 30 Jun 2022 15:39:41 +0200 (CEST)",
            "from relay1-d.mail.gandi.net (relay1-d.mail.gandi.net\n\t[IPv6:2001:4b98:dc4:8::221])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id CB7BB65658\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 30 Jun 2022 15:39:35 +0200 (CEST)",
            "(Authenticated sender: jacopo@jmondi.org)\n\tby mail.gandi.net (Postfix) with ESMTPSA id CBFA2240010;\n\tThu, 30 Jun 2022 13:39:34 +0000 (UTC)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org;\n\ts=mail; t=1656596382;\n\tbh=9E+htababTQRwiAXk97E3/6MTUzUihKkQXjRjDhKrec=;\n\th=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe:\n\tList-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:\n\tFrom;\n\tb=AhMLkuOJPozAg16ySDICfLdpz1j/9MG8FkBmCDxwaXaqWCPfStL0DG1T6p6BZJHi9\n\tD+5Cp2NOaT3MbJ9y02nypCBJex2l37b0AJEykPiD9DnK6VfCA+Zqd+tDj3D4ed+CEP\n\tXJRkZDYoPTDOl3jEINOocKCupCNLg8urAk1mldfd6aSj/sN3+6kmNAQTNvWPAcQoTd\n\tnUPTNhDlLflnW15IX7GL6oshrot6DPbbsuj4mjbFWQ0Ln2KMoocdxf3yjMhkMssiho\n\tsScFU1NibWlT13m/QW3wKlEhtwONwqz1sjLndh960FQFNp5JgDkYv4HvfOLNl1E1R5\n\tyP4akI2OP8bTA==",
        "To": "libcamera-devel@lists.libcamera.org",
        "Date": "Thu, 30 Jun 2022 15:38:52 +0200",
        "Message-Id": "<20220630133902.321099-14-jacopo@jmondi.org>",
        "X-Mailer": "git-send-email 2.36.1",
        "In-Reply-To": "<20220630133902.321099-1-jacopo@jmondi.org>",
        "References": "<20220630133902.321099-1-jacopo@jmondi.org>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Subject": "[libcamera-devel] [PATCH v3 13/23] libcamera: camera_sensor: Cache\n\tthe sensor configuration",
        "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>",
        "From": "Jacopo Mondi via libcamera-devel <libcamera-devel@lists.libcamera.org>",
        "Reply-To": "Jacopo Mondi <jacopo@jmondi.org>",
        "Errors-To": "libcamera-devel-bounces@lists.libcamera.org",
        "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"
    },
    "content": "The sensor configuration parameters, which include the output format\nthe blanking lengths and the current pixel rate, are updated everytime\na new format is set on the sensor.\n\nThe sensor configuration parameters will be used in order to\ntranslate libcamera controls in the corresponding V4L2 control values\n(and vice-versa).\n\nThe same parameters are also used to populate the CameraSensorInfo\nto pass it to IPA modules.\n\nIn order to avoid re-querying the V4L2 subdevice for the control\nvalues and the output format everytime, cache the current sensor\nconfiguration in a class member field, updated when a new format\nis set on the sensor and at initialization time.\n\nAs the function that updates the configuration was originally only\nmeant to update the CameraSensor ControlInfoMap limits, rename it\nfrom updateControls() to updateConfiguration().\n\nSigned-off-by: Jacopo Mondi <jacopo@jmondi.org>\n---\n include/libcamera/internal/camera_sensor.h    |  9 ++-\n src/libcamera/camera_sensor/camera_sensor.cpp | 69 +++++++------------\n 2 files changed, 32 insertions(+), 46 deletions(-)",
    "diff": "diff --git a/include/libcamera/internal/camera_sensor.h b/include/libcamera/internal/camera_sensor.h\nindex a606bc5d1cb5..bb9327646bc1 100644\n--- a/include/libcamera/internal/camera_sensor.h\n+++ b/include/libcamera/internal/camera_sensor.h\n@@ -81,6 +81,13 @@ protected:\n private:\n \tLIBCAMERA_DISABLE_COPY(CameraSensor)\n \n+\tstruct {\n+\t\tV4L2SubdeviceFormat outputFormat;\n+\t\tuint64_t pixelRate;\n+\t\tuint32_t hblank;\n+\t\tdouble lineDuration;\n+\t} config_;\n+\n \tint generateId();\n \tint validateSensorDriver();\n \tvoid initVimcDefaultProperties();\n@@ -88,7 +95,7 @@ private:\n \tvoid initTestPatternModes();\n \tint initProperties();\n \tint initDelayedControls();\n-\tint updateControls();\n+\tint updateConfiguration();\n \tint applyTestPatternMode(controls::draft::TestPatternModeEnum mode);\n \tint discoverAncillaryDevices();\n \ndiff --git a/src/libcamera/camera_sensor/camera_sensor.cpp b/src/libcamera/camera_sensor/camera_sensor.cpp\nindex e1770e8fa130..cc4cbd4ad509 100644\n--- a/src/libcamera/camera_sensor/camera_sensor.cpp\n+++ b/src/libcamera/camera_sensor/camera_sensor.cpp\n@@ -181,7 +181,7 @@ int CameraSensor::init()\n \t\treturn -ENODEV;\n \t}\n \n-\tret = updateControls();\n+\tret = updateConfiguration();\n \tif (ret)\n \t\treturn ret;\n \n@@ -501,7 +501,7 @@ int CameraSensor::initDelayedControls()\n \treturn 0;\n }\n \n-int CameraSensor::updateControls()\n+int CameraSensor::updateConfiguration()\n {\n \tif (!bayerFormat_)\n \t\treturn 0;\n@@ -511,12 +511,11 @@ int CameraSensor::updateControls()\n \t/* The subdev driver has been validate already, the controls are there! */\n \tControlList subdevControls = subdev_->getControls({ V4L2_CID_PIXEL_RATE,\n \t\t\t\t\t\t\t    V4L2_CID_HBLANK });\n-\tuint64_t pixelRate = subdevControls.get(V4L2_CID_PIXEL_RATE).get<int64_t>();\n-\tuint32_t hblank = subdevControls.get(V4L2_CID_HBLANK).get<int32_t>();\n+\tconfig_.pixelRate = subdevControls.get(V4L2_CID_PIXEL_RATE).get<int64_t>();\n+\tconfig_.hblank = subdevControls.get(V4L2_CID_HBLANK).get<int32_t>();\n \n \t/*  Assume the sensor has a single source pad #0. */\n-\tV4L2SubdeviceFormat subdevFormat;\n-\tsubdev_->getFormat(0, &subdevFormat);\n+\tsubdev_->getFormat(0, &config_.outputFormat);\n \n \tconst ControlInfoMap &subdevControlsInfo = subdev_->controls();\n \n@@ -526,12 +525,14 @@ int CameraSensor::updateControls()\n \t * get exposure min, max and default and convert it from lines to\n \t * microseconds.\n \t */\n-\tuint32_t lineLength = subdevFormat.size.width + hblank;\n-\tdouble lineDuration = lineLength / (pixelRate / 1000000.0F);\n-\tconst ControlInfo &v4l2Exposure = subdevControlsInfo.at(V4L2_CID_EXPOSURE);\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+\tconst Size &outputSize = config_.outputFormat.size;\n+\tuint32_t lineLength = outputSize.width + config_.hblank;\n+\tconfig_.lineDuration = lineLength / (config_.pixelRate / 1000000.0F);\n+\n+\tControlInfo v4l2Exposure = subdevControlsInfo.at(V4L2_CID_EXPOSURE);\n+\tint32_t minExposure = v4l2Exposure.min().get<int32_t>() * config_.lineDuration;\n+\tint32_t maxExposure = v4l2Exposure.max().get<int32_t>() * config_.lineDuration;\n+\tint32_t defExposure = v4l2Exposure.def().get<int32_t>() * config_.lineDuration;\n \n \tcontrolsMap[&controls::internal::ExposureTime] =\n \t\tControlInfo(minExposure, maxExposure, defExposure);\n@@ -544,15 +545,15 @@ int CameraSensor::updateControls()\n \t */\n \tconst ControlInfo &v4l2VBlank = subdevControlsInfo.at(V4L2_CID_VBLANK);\n \tstd::array<uint32_t, 3> frameHeights{\n-\t\tv4l2VBlank.min().get<int32_t>() + subdevFormat.size.height,\n-\t\tv4l2VBlank.max().get<int32_t>() + subdevFormat.size.height,\n-\t\tv4l2VBlank.def().get<int32_t>() + subdevFormat.size.height,\n+\t\tv4l2VBlank.min().get<int32_t>() + outputSize.height,\n+\t\tv4l2VBlank.max().get<int32_t>() + outputSize.height,\n+\t\tv4l2VBlank.def().get<int32_t>() + outputSize.height,\n \t};\n \n \tstd::array<int64_t, 3> frameDurations;\n \tfor (unsigned int i = 0; i < frameHeights.size(); ++i) {\n \t\tuint64_t frameSize = lineLength * frameHeights[i];\n-\t\tframeDurations[i] = frameSize / (pixelRate / 1000000.0F);\n+\t\tframeDurations[i] = frameSize / (config_.pixelRate / 1000000.0F);\n \t}\n \n \tcontrolsMap[&controls::internal::FrameDuration] =\n@@ -989,6 +990,8 @@ int CameraSensor::sensorInfo(IPACameraSensorInfo *info) const\n \t\t\t<< \"The analogue crop rectangle has been defaulted to the active area size\";\n \t}\n \n+\tconst ControlInfo vblank = subdev_->controls().at(V4L2_CID_VBLANK);\n+\n \t/*\n \t * IPACameraSensorInfo::analogCrop::x and IPACameraSensorInfo::analogCrop::y\n \t * are defined relatively to the active pixel area, while V4L2's\n@@ -998,34 +1001,10 @@ int CameraSensor::sensorInfo(IPACameraSensorInfo *info) const\n \t */\n \tinfo->analogCrop.x -= activeArea_.x;\n \tinfo->analogCrop.y -= activeArea_.y;\n-\n-\t/* The bit depth and image size depend on the currently applied format. */\n-\tV4L2SubdeviceFormat format{};\n-\tret = subdev_->getFormat(pad_, &format);\n-\tif (ret)\n-\t\treturn ret;\n-\tinfo->bitsPerPixel = format.bitsPerPixel();\n-\tinfo->outputSize = format.size;\n-\n-\t/*\n-\t * Retrieve the pixel rate, line length and minimum/maximum frame\n-\t * duration through V4L2 controls. Support for the V4L2_CID_PIXEL_RATE,\n-\t * V4L2_CID_HBLANK and V4L2_CID_VBLANK controls is mandatory.\n-\t */\n-\tControlList ctrls = subdev_->getControls({ V4L2_CID_PIXEL_RATE,\n-\t\t\t\t\t\t   V4L2_CID_HBLANK,\n-\t\t\t\t\t\t   V4L2_CID_VBLANK });\n-\tif (ctrls.empty()) {\n-\t\tLOG(CameraSensor, Error)\n-\t\t\t<< \"Failed to retrieve camera info controls\";\n-\t\treturn -EINVAL;\n-\t}\n-\n-\tint32_t hblank = ctrls.get(V4L2_CID_HBLANK).get<int32_t>();\n-\tinfo->lineLength = info->outputSize.width + hblank;\n-\tinfo->pixelRate = ctrls.get(V4L2_CID_PIXEL_RATE).get<int64_t>();\n-\n-\tconst ControlInfo vblank = ctrls.infoMap()->at(V4L2_CID_VBLANK);\n+\tinfo->bitsPerPixel = config_.outputFormat.bitsPerPixel();\n+\tinfo->outputSize = config_.outputFormat.size;\n+\tinfo->lineLength = info->outputSize.width + config_.hblank;\n+\tinfo->pixelRate = config_.pixelRate;\n \tinfo->minFrameLength = info->outputSize.height + vblank.min().get<int32_t>();\n \tinfo->maxFrameLength = info->outputSize.height + vblank.max().get<int32_t>();\n \n@@ -1040,7 +1019,7 @@ int CameraSensor::sensorInfo(IPACameraSensorInfo *info) const\n void CameraSensor::updateControlInfo()\n {\n \tsubdev_->updateControlInfo();\n-\tupdateControls();\n+\tupdateConfiguration();\n }\n \n /**\n",
    "prefixes": [
        "libcamera-devel",
        "v3",
        "13/23"
    ]
}