Show a patch.

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

{
    "id": 10780,
    "url": "https://patchwork.libcamera.org/api/patches/10780/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/10780/",
    "project": {
        "id": 1,
        "url": "https://patchwork.libcamera.org/api/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": "<20201230180120.78407-3-jacopo@jmondi.org>",
    "date": "2020-12-30T18:01:16",
    "name": "[libcamera-devel,v3,2/6] libcamera: camera_sensor: Validate driver support",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": false,
    "hash": "fef6d7f21eae80013b616448f61691a819e07ad6",
    "submitter": {
        "id": 3,
        "url": "https://patchwork.libcamera.org/api/people/3/?format=api",
        "name": "Jacopo Mondi",
        "email": "jacopo@jmondi.org"
    },
    "delegate": null,
    "mbox": "https://patchwork.libcamera.org/patch/10780/mbox/",
    "series": [
        {
            "id": 1560,
            "url": "https://patchwork.libcamera.org/api/series/1560/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=1560",
            "date": "2020-12-30T18:01:14",
            "name": "libcamera: camera_sensor: Make validation more strict",
            "version": 3,
            "mbox": "https://patchwork.libcamera.org/series/1560/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/10780/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/10780/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 F0B0CC0F1C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 30 Dec 2020 18:01:15 +0000 (UTC)",
            "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 1742462007;\n\tWed, 30 Dec 2020 19:01:15 +0100 (CET)",
            "from relay7-d.mail.gandi.net (relay7-d.mail.gandi.net\n\t[217.70.183.200])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 1E440615B2\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 30 Dec 2020 19:01:12 +0100 (CET)",
            "from uno.lan (2-224-242-101.ip172.fastwebnet.it [2.224.242.101])\n\t(Authenticated sender: jacopo@jmondi.org)\n\tby relay7-d.mail.gandi.net (Postfix) with ESMTPSA id A45E020003;\n\tWed, 30 Dec 2020 18:01:11 +0000 (UTC)"
        ],
        "X-Originating-IP": "2.224.242.101",
        "From": "Jacopo Mondi <jacopo@jmondi.org>",
        "To": "libcamera-devel@lists.libcamera.org",
        "Date": "Wed, 30 Dec 2020 19:01:16 +0100",
        "Message-Id": "<20201230180120.78407-3-jacopo@jmondi.org>",
        "X-Mailer": "git-send-email 2.29.2",
        "In-Reply-To": "<20201230180120.78407-1-jacopo@jmondi.org>",
        "References": "<20201230180120.78407-1-jacopo@jmondi.org>",
        "MIME-Version": "1.0",
        "Subject": "[libcamera-devel] [PATCH v3 2/6] libcamera: camera_sensor: Validate\n\tdriver support",
        "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>",
        "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>"
    },
    "content": "The CameraSensor class requires the sensor driver to report\ninformation through V4L2 controls and through the V4L2 selection API,\nand uses that information to register Camera properties and to\nconstruct CameraSensorInfo class instances to provide them to the IPA.\n\nCurrently, validation of the kernel support happens each time a\nfeature is requested, with slighly similar debug/error messages\noutput to the user in case a feature is not supported.\n\nRationalize this by:\n- Validate the sensor driver requirements in a single function\n- Expand the debug output when a property gets defaulted to a value\n- Be more verbose when constructing CameraSensorInfo is not possible\n\nReviewed-by: Paul Elder <paul.elder@ideasonboard.com>\nSigned-off-by: Jacopo Mondi <jacopo@jmondi.org>\n---\n include/libcamera/internal/camera_sensor.h |   1 +\n src/libcamera/camera_sensor.cpp            | 117 ++++++++++++++++++---\n 2 files changed, 102 insertions(+), 16 deletions(-)",
    "diff": "diff --git a/include/libcamera/internal/camera_sensor.h b/include/libcamera/internal/camera_sensor.h\nindex f80d836161a5..aee10aa6e3c7 100644\n--- a/include/libcamera/internal/camera_sensor.h\n+++ b/include/libcamera/internal/camera_sensor.h\n@@ -69,6 +69,7 @@ protected:\n \n private:\n \tint generateId();\n+\tint validateSensorDriver();\n \tint initProperties();\n \n \tconst MediaEntity *entity_;\ndiff --git a/src/libcamera/camera_sensor.cpp b/src/libcamera/camera_sensor.cpp\nindex e786821d4ba2..a1f1256bd6f4 100644\n--- a/src/libcamera/camera_sensor.cpp\n+++ b/src/libcamera/camera_sensor.cpp\n@@ -207,6 +207,10 @@ int CameraSensor::init()\n \t */\n \tresolution_ = sizes_.back();\n \n+\tret = validateSensorDriver();\n+\tif (ret)\n+\t\treturn ret;\n+\n \tret = initProperties();\n \tif (ret)\n \t\treturn ret;\n@@ -214,6 +218,86 @@ int CameraSensor::init()\n \treturn 0;\n }\n \n+int CameraSensor::validateSensorDriver()\n+{\n+\t/*\n+\t * Make sure the sensor driver supports the mandatory controls\n+\t * required by the CameraSensor class.\n+\t * - V4L2_CID_PIXEL_RATE is used to calculate the sensor timings\n+\t * - V4L2_CID_HBLANK is used to calculate the line length\n+\t */\n+\tconst std::vector<uint32_t> mandatoryControls{\n+\t\tV4L2_CID_PIXEL_RATE,\n+\t\tV4L2_CID_HBLANK,\n+\t};\n+\n+\tControlList ctrls = subdev_->getControls(mandatoryControls);\n+\tif (ctrls.empty()) {\n+\t\tLOG(CameraSensor, Error)\n+\t\t\t<< \"Mandatory V4L2 controls not available\";\n+\t\tLOG(CameraSensor, Error)\n+\t\t\t<< \"The sensor kernel driver needs to be fixed\";\n+\t\tLOG(CameraSensor, Error)\n+\t\t\t<< \"See Documentation/sensor_driver_requirements.rst in the libcamera sources for more information\";\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tint err = 0;\n+\t/*\n+\t * Optional controls are used to register optional sensor\n+\t * properties. If not present, some values will be defaulted.\n+\t */\n+\tconst std::vector<uint32_t> optionalControls{\n+\t\tV4L2_CID_CAMERA_ORIENTATION,\n+\t\tV4L2_CID_CAMERA_SENSOR_ROTATION,\n+\t};\n+\n+\tctrls = subdev_->getControls(optionalControls);\n+\tif (ctrls.empty()) {\n+\t\tLOG(CameraSensor, Info)\n+\t\t\t<< \"Optional V4L2 controls not supported\";\n+\t\terr = -EINVAL;\n+\t}\n+\n+\t/*\n+\t * Make sure the required selection targets are supported.\n+\t *\n+\t * Failures in reading any of the targets are not deemed to be fatal,\n+\t * but some properties and features, like constructing a\n+\t * CameraSensorInfo for the IPA module, won't be supported.\n+\t */\n+\tRectangle rect;\n+\tint ret = subdev_->getSelection(pad_, V4L2_SEL_TGT_CROP_BOUNDS, &rect);\n+\tif (ret) {\n+\t\tLOG(CameraSensor, Info)\n+\t\t\t<< \"Failed to retrieve the readable pixel area size\";\n+\t\terr = -EINVAL;\n+\t}\n+\n+\tret = subdev_->getSelection(pad_, V4L2_SEL_TGT_CROP_DEFAULT, &rect);\n+\tif (ret) {\n+\t\tLOG(CameraSensor, Info)\n+\t\t\t<< \"Failed to retrieve the active pixel area size\";\n+\t\terr = -EINVAL;\n+\t}\n+\n+\tret = subdev_->getSelection(pad_, V4L2_SEL_TGT_CROP, &rect);\n+\tif (ret) {\n+\t\tLOG(CameraSensor, Info)\n+\t\t\t<< \"Failed to retreive the sensor crop rectangle\";\n+\t\terr = -EINVAL;\n+\t}\n+\n+\tif (err) {\n+\t\tLOG(CameraSensor, Info)\n+\t\t\t<< \"The sensor kernel driver needs to be fixed\";\n+\t\tLOG(CameraSensor, Info)\n+\t\t\t<< \"See Documentation/sensor_driver_requirements.rst in the libcamera sources for more information\";\n+\t}\n+\n+\treturn 0;\n+}\n+\n int CameraSensor::initProperties()\n {\n \t/*\n@@ -278,21 +362,29 @@ int CameraSensor::initProperties()\n \t\t}\n \t} else {\n \t\tpropertyValue = properties::CameraLocationFront;\n+\t\tLOG(CameraSensor, Debug)\n+\t\t\t<< \"Location property defaulted to 'Front Camera'\";\n \t}\n \tproperties_.set(properties::Location, propertyValue);\n \n \t/* Camera Rotation: default is 0 degrees. */\n \tconst auto &rotationControl = controls.find(V4L2_CID_CAMERA_SENSOR_ROTATION);\n-\tif (rotationControl != controls.end())\n+\tif (rotationControl != controls.end()) {\n \t\tpropertyValue = rotationControl->second.def().get<int32_t>();\n-\telse\n+\t} else {\n \t\tpropertyValue = 0;\n+\t\tLOG(CameraSensor, Debug)\n+\t\t\t<< \"Rotation property defaulted to 0 degrees\";\n+\t}\n \tproperties_.set(properties::Rotation, propertyValue);\n \n \tRectangle bounds;\n \tret = subdev_->getSelection(pad_, V4L2_SEL_TGT_CROP_BOUNDS, &bounds);\n \tif (!ret)\n \t\tproperties_.set(properties::PixelArraySize, bounds.size());\n+\telse\n+\t\tLOG(CameraSensor, Debug)\n+\t\t\t<< \"PixelArraySize property not registered\";\n \n \tRectangle crop;\n \tret = subdev_->getSelection(pad_, V4L2_SEL_TGT_CROP_DEFAULT, &crop);\n@@ -306,6 +398,9 @@ int CameraSensor::initProperties()\n \t\tcrop.x -= bounds.x;\n \t\tcrop.y -= bounds.y;\n \t\tproperties_.set(properties::PixelArrayActiveAreas, { crop });\n+\t} else {\n+\t\tLOG(CameraSensor, Debug)\n+\t\t\t<< \"PixelArrayActiveAreas property not registered\";\n \t}\n \n \t/* Color filter array pattern, register only for RAW sensors. */\n@@ -566,10 +661,7 @@ int CameraSensor::sensorInfo(CameraSensorInfo *info) const\n \tRectangle rect;\n \tint ret = subdev_->getSelection(pad_, V4L2_SEL_TGT_CROP_DEFAULT, &rect);\n \tif (ret) {\n-\t\tLOG(CameraSensor, Error)\n-\t\t\t<< \"Failed to construct camera sensor info: \"\n-\t\t\t<< \"the camera sensor does not report the active area\";\n-\n+\t\tLOG(CameraSensor, Error) << \"Failed to get the active area\";\n \t\treturn ret;\n \t}\n \tinfo->activeAreaSize = { rect.width, rect.height };\n@@ -577,9 +669,7 @@ int CameraSensor::sensorInfo(CameraSensorInfo *info) const\n \t/* It's mandatory for the subdevice to report its crop rectangle. */\n \tret = subdev_->getSelection(pad_, V4L2_SEL_TGT_CROP, &info->analogCrop);\n \tif (ret) {\n-\t\tLOG(CameraSensor, Error)\n-\t\t\t<< \"Failed to construct camera sensor info: \"\n-\t\t\t<< \"the camera sensor does not report the crop rectangle\";\n+\t\tLOG(CameraSensor, Error) << \"Failed to get the crop rectangle\";\n \t\treturn ret;\n \t}\n \n@@ -601,16 +691,11 @@ int CameraSensor::sensorInfo(CameraSensorInfo *info) const\n \tinfo->bitsPerPixel = format.bitsPerPixel();\n \tinfo->outputSize = format.size;\n \n-\t/*\n-\t * Retrieve the pixel rate and the line length through V4L2 controls.\n-\t * Support for the V4L2_CID_PIXEL_RATE and V4L2_CID_HBLANK controls is\n-\t * mandatory.\n-\t */\n+\t/* Retrieve the pixel rate and the line length through V4L2 controls. */\n \tControlList ctrls = subdev_->getControls({ V4L2_CID_PIXEL_RATE,\n \t\t\t\t\t\t   V4L2_CID_HBLANK });\n \tif (ctrls.empty()) {\n-\t\tLOG(CameraSensor, Error)\n-\t\t\t<< \"Failed to retrieve camera info controls\";\n+\t\tLOG(CameraSensor, Error) << \"Failed to retrieve camera controls\";\n \t\treturn -EINVAL;\n \t}\n \n",
    "prefixes": [
        "libcamera-devel",
        "v3",
        "2/6"
    ]
}