Show a patch.

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

{
    "id": 11196,
    "url": "https://patchwork.libcamera.org/api/patches/11196/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/11196/",
    "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": "<20210208151558.5697-1-laurent.pinchart@ideasonboard.com>",
    "date": "2021-02-08T15:15:58",
    "name": "[libcamera-devel,PATCH/RFC] libcamera: pipeline: simple: Support camera sensors that contain an ISP",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": false,
    "hash": "8b38a72d5b5c58884d8e67e8755d9b87def9dd6c",
    "submitter": {
        "id": 2,
        "url": "https://patchwork.libcamera.org/api/people/2/?format=api",
        "name": "Laurent Pinchart",
        "email": "laurent.pinchart@ideasonboard.com"
    },
    "delegate": {
        "id": 14,
        "url": "https://patchwork.libcamera.org/api/users/14/?format=api",
        "username": "pinchartl",
        "first_name": "Laurent",
        "last_name": "Pinchart",
        "email": "laurent.pinchart@ideasonboard.com"
    },
    "mbox": "https://patchwork.libcamera.org/patch/11196/mbox/",
    "series": [
        {
            "id": 1667,
            "url": "https://patchwork.libcamera.org/api/series/1667/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=1667",
            "date": "2021-02-08T15:15:58",
            "name": "[libcamera-devel,PATCH/RFC] libcamera: pipeline: simple: Support camera sensors that contain an ISP",
            "version": 1,
            "mbox": "https://patchwork.libcamera.org/series/1667/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/11196/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/11196/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 8B73ABD160\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon,  8 Feb 2021 15:16:28 +0000 (UTC)",
            "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 1D68860D2A;\n\tMon,  8 Feb 2021 16:16:28 +0100 (CET)",
            "from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 2C16860D24\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon,  8 Feb 2021 16:16:26 +0100 (CET)",
            "from pendragon.lan (62-78-145-57.bb.dnainternet.fi [62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id B3CB03D7\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon,  8 Feb 2021 16:16:25 +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=\"nutuLZoN\"; dkim-atps=neutral",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1612797385;\n\tbh=kv/9vIvEBkzMqzaQF8cSyDqz/ri4Dm8t3ZH/uXyc7uc=;\n\th=From:To:Subject:Date:From;\n\tb=nutuLZoN2CjVuUwC+2TAmJ/YbE0TjwXvrfZLR5uFFP4Xgqhvr80rYOx7S5GtqwyJt\n\ttqbI+bDyUGknix6mSNmMQ2hO8XlxD7owE6cR917k24X+v2rAuJZAbzSE3DaRuBIXqt\n\trYYdjFF8mSbcv/dltJMVgyisEI7mQVHX1g1gOVuk=",
        "From": "Laurent Pinchart <laurent.pinchart@ideasonboard.com>",
        "To": "libcamera-devel@lists.libcamera.org",
        "Date": "Mon,  8 Feb 2021 17:15:58 +0200",
        "Message-Id": "<20210208151558.5697-1-laurent.pinchart@ideasonboard.com>",
        "X-Mailer": "git-send-email 2.28.0",
        "MIME-Version": "1.0",
        "Subject": "[libcamera-devel] [PATCH/RFC] libcamera: pipeline: simple: Support\n\tcamera sensors that contain an ISP",
        "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": "Camera sensors can include an ISP. For instance, the AP1302 external ISP\ncan be connected to up to two raw camera sensors, and the combination of\nthe sensors and ISP is considered as a (smart) camera sensor from\nlibcamera's point of view.\n\nThe CameraSensor class has limited support for this already. Extend the\nsimple pipeline handler to support such sensors, by using the media\nentity corresponding to the ISP instead of the raw camera sensor's\nentity.\n\nWe don't need to handle the case where an entity in the SoC would expose\nthe MEDIA_ENT_F_PROC_VIDEO_ISP function, as pipeline containing an ISP\nwould have a dedicated pipeline handler.\n\nThe implementation is limited as it won't support other multi-entity\ncamera sensors (such as CCS). While this would be worth supporting, we\ndon't have a test platform with a CCS-compatible sensor at this point,\nso let's not over-engineer the solution. Extending support to CCS (and\npossibly other sensor topologies) will likely involve helpers that can\nbe used by other pipeline handlers (such as generic graph walk helpers\nfor instance) and extensions to the CameraSensor class.\n\nSigned-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n---\n src/libcamera/pipeline/simple/simple.cpp | 87 ++++++++++++++++++++----\n 1 file changed, 74 insertions(+), 13 deletions(-)\n\nThis patch depends on \"[PATCH/RFC] libcamera: camera_sensor: Accept\nentities exposing the ISP function\" ([1]). It has been tested on a\nMediaTek Pumpkin i500 board with an ON Semiconductor AP1302 and AR0330\nand AR0144 sensors.\n\n[1] https://patchwork.libcamera.org/patch/11182/",
    "diff": "diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp\nindex 9d468f7c9cc4..2df33a3a79ea 100644\n--- a/src/libcamera/pipeline/simple/simple.cpp\n+++ b/src/libcamera/pipeline/simple/simple.cpp\n@@ -240,6 +240,8 @@ private:\n \t\t\tPipelineHandler::cameraData(camera));\n \t}\n \n+\tstd::vector<MediaEntity *> locateSensors();\n+\n \tvoid bufferReady(FrameBuffer *buffer);\n \tvoid converterInputDone(FrameBuffer *buffer);\n \tvoid converterOutputDone(FrameBuffer *buffer);\n@@ -865,6 +867,77 @@ int SimplePipelineHandler::queueRequestDevice(Camera *camera, Request *request)\n  * Match and Setup\n  */\n \n+std::vector<MediaEntity *> SimplePipelineHandler::locateSensors()\n+{\n+\tstd::vector<MediaEntity *> entities;\n+\n+\t/*\n+\t * Gather all the camera sensor entities based on the function they\n+\t * expose.\n+\t */\n+\tfor (MediaEntity *entity : media_->entities()) {\n+\t\tif (entity->function() == MEDIA_ENT_F_CAM_SENSOR)\n+\t\t\tentities.push_back(entity);\n+\t}\n+\n+\tif (entities.empty())\n+\t\treturn {};\n+\n+\t/*\n+\t * Sensors can be made of multiple entities. For instance, a raw sensor\n+\t * can be connected to an ISP, and the combination of both should be\n+\t * treated as one sensor. To support this, as a crude heuristic, check\n+\t * the downstream entity from the camera sensor, and if it is an ISP,\n+\t * use it instead of the sensor.\n+\t */\n+\tstd::vector<MediaEntity *> sensors;\n+\n+\tfor (MediaEntity *entity : entities) {\n+\t\t/*\n+\t\t * Locate the downstream entity by following the first enabled\n+\t\t * link from a source pad.\n+\t\t */\n+\t\tconst MediaPad *pad = nullptr;\n+\t\tconst MediaLink *link = nullptr;\n+\n+\t\tfor (const MediaPad *p : entity->pads()) {\n+\t\t\tif (p->flags() & MEDIA_PAD_FL_SOURCE) {\n+\t\t\t\tpad = p;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\n+\t\tif (!pad)\n+\t\t\tcontinue;\n+\n+\t\tfor (const MediaLink *l : pad->links()) {\n+\t\t\tif (l->flags() & MEDIA_LNK_FL_ENABLED) {\n+\t\t\t\tlink = l;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\n+\t\tif (!link)\n+\t\t\tcontinue;\n+\n+\t\tMediaEntity *remote = link->sink()->entity();\n+\t\tif (remote->function() == MEDIA_ENT_F_PROC_VIDEO_ISP)\n+\t\t\tsensors.push_back(remote);\n+\t\telse\n+\t\t\tsensors.push_back(entity);\n+\t}\n+\n+\t/*\n+\t * Remove duplicates, in case multiple sensors are connected to the\n+\t * same ISP.\n+\t */\n+\tstd::sort(sensors.begin(), sensors.end());\n+\tauto last = std::unique(sensors.begin(), sensors.end());\n+\tsensors.erase(last, sensors.end());\n+\n+\treturn sensors;\n+}\n+\n bool SimplePipelineHandler::match(DeviceEnumerator *enumerator)\n {\n \tconst SimplePipelineInfo *info = nullptr;\n@@ -888,19 +961,7 @@ bool SimplePipelineHandler::match(DeviceEnumerator *enumerator)\n \t}\n \n \t/* Locate the sensors. */\n-\tstd::vector<MediaEntity *> sensors;\n-\n-\tfor (MediaEntity *entity : media_->entities()) {\n-\t\tswitch (entity->function()) {\n-\t\tcase MEDIA_ENT_F_CAM_SENSOR:\n-\t\t\tsensors.push_back(entity);\n-\t\t\tbreak;\n-\n-\t\tdefault:\n-\t\t\tbreak;\n-\t\t}\n-\t}\n-\n+\tstd::vector<MediaEntity *> sensors = locateSensors();\n \tif (sensors.empty()) {\n \t\tLOG(SimplePipeline, Error) << \"No sensor found\";\n \t\treturn false;\n",
    "prefixes": [
        "libcamera-devel",
        "PATCH/RFC"
    ]
}