Show a patch.

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

{
    "id": 25074,
    "url": "https://patchwork.libcamera.org/api/1.1/patches/25074/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/25074/",
    "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": "<20251114154341.654850-3-antoine.bouyer@nxp.com>",
    "date": "2025-11-14T15:43:41",
    "name": "[v2,2/2] pipeline: imx8-isi: Integrating MediaPipeline class",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": false,
    "hash": "d2cd557450334d4a99fe5b39feda9514480ab828",
    "submitter": {
        "id": 218,
        "url": "https://patchwork.libcamera.org/api/1.1/people/218/?format=api",
        "name": "Antoine Bouyer",
        "email": "antoine.bouyer@nxp.com"
    },
    "delegate": null,
    "mbox": "https://patchwork.libcamera.org/patch/25074/mbox/",
    "series": [
        {
            "id": 5591,
            "url": "https://patchwork.libcamera.org/api/1.1/series/5591/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=5591",
            "date": "2025-11-14T15:43:39",
            "name": "imx8-isi: Use MediaPipeline",
            "version": 2,
            "mbox": "https://patchwork.libcamera.org/series/5591/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/25074/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/25074/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 8257FC3241\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 14 Nov 2025 15:41:57 +0000 (UTC)",
            "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 6126460AA3;\n\tFri, 14 Nov 2025 16:41:56 +0100 (CET)",
            "from MRWPR03CU001.outbound.protection.outlook.com\n\t(mail-francesouthazlp170110003.outbound.protection.outlook.com\n\t[IPv6:2a01:111:f403:c207::3])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id CAA77609D8\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 14 Nov 2025 16:41:52 +0100 (CET)",
            "from GVXPR04MB9831.eurprd04.prod.outlook.com (2603:10a6:150:11c::8)\n\tby GV1PR04MB10108.eurprd04.prod.outlook.com (2603:10a6:150:1a2::5)\n\twith Microsoft SMTP Server (version=TLS1_2,\n\tcipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9320.16;\n\tFri, 14 Nov 2025 15:41:51 +0000",
            "from GVXPR04MB9831.eurprd04.prod.outlook.com\n\t([fe80::4634:3d9c:c4a:641a]) by\n\tGVXPR04MB9831.eurprd04.prod.outlook.com\n\t([fe80::4634:3d9c:c4a:641a%6]) with mapi id 15.20.9320.018;\n\tFri, 14 Nov 2025 15:41:51 +0000"
        ],
        "Authentication-Results": [
            "lancelot.ideasonboard.com; dkim=pass (2048-bit key;\n\tunprotected) header.d=nxp.com header.i=@nxp.com header.b=\"YSsQDyYk\";\n\tdkim-atps=neutral",
            "dkim=none (message not signed)\n\theader.d=none;dmarc=none action=none header.from=nxp.com;"
        ],
        "ARC-Seal": "i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none;\n\tb=OhA24JWRkj9hFXiayUsBiPT5Fg/aCOKKiUAyvENH4fDHJ6OlS10/NbLLdaGpqsGtNIm2gNGpcCdmYVa94YzfVZ7LCVig4gvHaOHAL7WsyYbBo+2xR6RCkaXRRYSLzGfeb0ZPERSi4YBh/kF/mhyUU/I2u5EsFbY792H2gdCUieXrY8zq+GYF08//w6P+3Dl8K2gms6vtTZeO0IiinMftK6zrvPHi8DOPnMN6LBZtaVc9MbmM+PvhuNRxzQd0To75SPQxw36pMA+u/Sk9v3V6pAZ8fGLVi1R2bHbomZT4wfrqXaSpWT5CddpmMh4NK/Mz1FpHGL9ty5yF82R6a9ARpA==",
        "ARC-Message-Signature": "i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com;\n\ts=arcselector10001;\n\th=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1;\n\tbh=SpUqncjHtUOgBWdmD8IwRZZJxhKUyakQtneBrT0pEwc=;\n\tb=mWeRjE0FDMUjDrm5L6VdjtVWhvPNuoOSRkTUVnUNIsxnySYtZQceoan0HXIipz7534/CAByKn6r25r5Yr8mk6mya8yTq0QW9htCqL9k9QQUu3nrjvbZCxl6hVOLPM8X58Pu7EuvJ/Skv6Gsh9YOAAl1ki3eivaWtVxDCiybEbv4a7GgbGCT0/T0M7f5T8/NUHykg0V8mmzOSVs+xG3aJvs6cIrAaVH96ISXo9pdRug7eQSRWxRCk9X+ayto597fLjb74hMOOmtA9sZABaTU3Zo4uBtOj50n+mHsNoDvOo0dcQyk/UJJAnEL4ITwIV15SFVxcjUQTfbKKNk7L3d8i+Q==",
        "ARC-Authentication-Results": "i=1; mx.microsoft.com 1; spf=pass\n\tsmtp.mailfrom=nxp.com; dmarc=pass action=none header.from=nxp.com;\n\tdkim=pass header.d=nxp.com; arc=none",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector1;\n\th=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;\n\tbh=SpUqncjHtUOgBWdmD8IwRZZJxhKUyakQtneBrT0pEwc=;\n\tb=YSsQDyYkd11wO8Os3L/63MBV1QvQjujW294vLVnrzDwQChHGS89OiF3mKLuMNoUHzFGnxVjbNpMc1zOwpsv0pZNCOfS0Sxyi9p/eqdLwAhcuTjulURes9sRiZu5Z+wTqHk9NUiutoTPy7brdwcvUrgzCBVFtDagVq0as7QLalT8pjMDQIjm9Xnt9qsLlUNrB5aDmeLgsKB9NoSRTK39fvdvXCwgPaKN3OyS+52NLgR4Cg5PwbMdejex+VaduMUK+6kzQzqlGyR9Y2hF3xlsbNNXql05JfSiulRvUmhCqScFBnvwgHo8zlQBEKT0LMu2zEvjDT/ZBRyeycKsLbe/nzg==",
        "From": "Antoine Bouyer <antoine.bouyer@nxp.com>",
        "To": "libcamera-devel@lists.libcamera.org",
        "Cc": "julien.vuillaumier@nxp.com, jacopo.mondi@ideasonboard.com,\n\tbarnabas.pocze@ideasonboard.com,\n\tAndrei Gansari <andrei.gansari@nxp.com>, \n\tAntoine Bouyer <antoine.bouyer@nxp.com>",
        "Subject": "[PATCH v2 2/2] pipeline: imx8-isi: Integrating MediaPipeline class",
        "Date": "Fri, 14 Nov 2025 16:43:41 +0100",
        "Message-Id": "<20251114154341.654850-3-antoine.bouyer@nxp.com>",
        "X-Mailer": "git-send-email 2.34.1",
        "In-Reply-To": "<20251114154341.654850-1-antoine.bouyer@nxp.com>",
        "References": "<20251114154341.654850-1-antoine.bouyer@nxp.com>",
        "Content-Transfer-Encoding": "8bit",
        "Content-Type": "text/plain",
        "X-ClientProxiedBy": "AS4P192CA0039.EURP192.PROD.OUTLOOK.COM\n\t(2603:10a6:20b:658::20) To GVXPR04MB9831.eurprd04.prod.outlook.com\n\t(2603:10a6:150:11c::8)",
        "MIME-Version": "1.0",
        "X-MS-PublicTrafficType": "Email",
        "X-MS-TrafficTypeDiagnostic": "GVXPR04MB9831:EE_|GV1PR04MB10108:EE_",
        "X-MS-Office365-Filtering-Correlation-Id": "e18d2fb9-574c-4edc-43f8-08de239454a9",
        "X-MS-Exchange-SenderADCheck": "1",
        "X-MS-Exchange-AntiSpam-Relay": "0",
        "X-Microsoft-Antispam": "BCL:0;\n\tARA:13230040|52116014|19092799006|376014|1800799024|366016|38350700014;",
        "X-Microsoft-Antispam-Message-Info": "YT7VLeyT5N7qUJK4LQw64+o01GVlT7WEKg7M9N/p7mIX7Aoh0PEiRKKeqr81RFAVJwdK8latJmscImVck+sthxMHFY9fD4Otv/uY87DqY2+RrRPU1d5SgPL32CO0cMLE1gEhkIpR7urF+KgoDofhq8QyFxXFmJGjxHwT7McKDTfSO+cS11pT3HgBtK6Ry0VQ2wl1fuHNNaEShFJJ3dcqEmgZ0ofQvjj7SZ9q9WtusdZEqPNdcmf1/6ZUe8NxTIodEaXLg8aEUg0Y440dumv8qiWwv1ML8CyXni4Uij1qUhlqONo6wM0wK56u11Atb/tJF1PYb2QsF1YYmKXZlawhg1r5SV1mxA2Hhpp9KviH2F0ScqirND4t/aMajM2zgaY6AOMBy9n1Bsi5mw7b1XB7DlkvKG28ZuW0b5tTIjdYTUBH9FwhV4tvO13iDdGJD6jVIMx5eE61pbcWJ5HUeaTlETFV1rBJLi2gFuNsydj7vsmTEfKir1N4VZ/1TUFNLlFz6JizExx+RoLXJkjtXqphwpy+oOzRJXkJfdyxEdMQjDcFtGMnwGLPHCM62AsTv8OCaAYdRYMEmFm7nsFUdbXEcuDVhVRkIVLSdsHv6L11c+Sfj3Wn0zwGbhLnKWMZWSbSCLqD1ftn1+sBG+ApR7XV1R2AzNyd+o/+1ab/wfaKAIs6YwIF30fUX8Y07liBwntMX3SIz+VWAhqktbo0hJUJVwoTriqh9xRmbfIOYH2kEaL4DbEgDbM02zPfmt5TbAWNDl/2rsIeNeOuG92MMJxQ5008Z31ibiW2m7iW1zUXr2pKssqR82uGMuwJ0Le+pntsYFPyzicGIlW+6nrBwEJfVs1DwD5kB4KP2Cn4jaeY7M0DCeVXI+51nOqyv9LZsUhNREeX1mdDxMnv6t0328sc2NXs3eCPUhy/FKq9+AV3lRwcOZkwp8ESwRnsK8xRjC5gfJdZO3/n9OiYLmqgK77IseyTWj6mqvUoZ+ACfDYeJP56FQX0W6xPhSBuEDDS81GnHqAai9EL1e1DUjzgQwbs9/kyHNBDV3pBo8s9/cu4JNSWglgktTQ3z3LMfymyOJAVVnX0zoRM9ggogDU25kGHZr13rYfMfv7vFBe+Rqwusn+GBTxeUznnNPHlLqTAJptBPFY1weppZ7rJ1/jwMS1jKbHBwW1q280MaZLyXyzR6a4f1HyNHXHfxctVJ5ZXn4MZT+CpVwf5QXfHLkgeCyOwgocvbAxYXDSIVARrvsnE/qB0oPbX8q46+9qrAZBYYUG+X1YbBig08aISW7aIR2Ho3P9dXdbmBw47qClXIy8X85MwolGG718nyF4pS9PwA48hx0kuWsHmGpJWPFDYYk1ARB3o7AJ7FNHhK1jTYRr5zJeT/8OnYqxNB0cevwT1HHDF/ztmQVo23ZoPn6zhXZqyt+9+X+ruh/1acKzAE7SzuTl7EZBRCE4a2SIRB6p3xVoAUNa8uUowgSFSI1SZ41bZ69obZErBd2I++lZuvjIvrau0iBY8J9JxAFFTpccOVZwz",
        "X-Forefront-Antispam-Report": "CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:;\n\tIPV:NLI; SFV:NSPM; H:GVXPR04MB9831.eurprd04.prod.outlook.com; PTR:;\n\tCAT:NONE; \n\tSFS:(13230040)(52116014)(19092799006)(376014)(1800799024)(366016)(38350700014);\n\tDIR:OUT; SFP:1101; ",
        "X-MS-Exchange-AntiSpam-MessageData-ChunkCount": "1",
        "X-MS-Exchange-AntiSpam-MessageData-0": "a+1Ot1M5qwJTHF7c+hak7SahZ77YbJgdIlB0RgqQCQJIul55qUvuTACF6MV0nIJqhH9D9lMgpNyTMf/6Hc2mgxF3+Ntc2ZEk06fJhdvamuQh2h080K6XsCyKq0TO4isjOHYqItzJ3/tMRFn7aASm3mLouozjQqr9WMXk0A+iSArrv6zheFL9zuKdNYZ7WDjWXmVZTr7kuc4sApv5/W8dF4//mZSXQeByVBRBKkKKg6nGHIQLGZwRF7yAtQbduDC0cKCRDEeCEaYlejFph4qS21ATFwC5/nYXS34ZEpBuhWlRh+09oyZoupcuKfTJUVgs11D90GzSxZM4W+KSb/bBy2cjEEwK9Yj6M0ysKMmH6tTnacDmio7isBgUnJsB8sI228+Ckw0axcjCFhGtDxEhjzeMVLz59Yhx5YnNZR15N8Em477V5tUVxeO+t4ECmclxa/sMNHQKPrW2LT1Xi66bY7TRea1A1LEB9g3vlycExouwskZGdZoFqDfxXXa+MoSwUjpfd4Ji3s1JGIACB2BqtxLMClMlKwtNz6Tu2D9wxIrBNRTZksrZDIsvZ8F9fpY4ttDLZq/4y7bgX1kGAU3MvSagjVTNhc6XggiGWxN8iNFgiunrftVn8lNq6fmc3tP4DwWoHYQTJA0EkW07LVkFycXPP91cfdxFaiiLhljtfcwr9lLLM5Ensd56zTDL93jdBa86NfuvmceLTyJxuf7N0ZBr7/y/bGkhf1S/jNexVSVX/p27mcq2vsAvmaiqTsryO9+z94i+jNJnrVM2n25RaZDj5kds4c+ZxNUzuEZzizmAX01S4GbKPmz7fuTzj9olMKLTz7wM6POBAyUN6Yd5VCLU/lO4QBVOsv3/yFSLhr20WssjLPRaERTVoMMLWIUEBjv40+eyjg9QphAmxfJaFQfK1l+hngs+XV+YXOHAYEQ/T/7XMQN4pAGrvd+XyoDOisSIcYNaj26la4WM1pGwV1OTjHUeNdXtKlgjArm8P8zT5OeaU97EncOmrS4+H0ovHO3JU6X5+qHU3DNrIn50rS5roFMy5q5ZWt31IyQY/TBeqPsLztYCMNa0t4wdTbe+kwSaiz8X+l576GIco525kT0+PnZtTxKlHVZjW2MajcsUp16JIecMVpCFn1+wGlqSkl/OFob9JKarleOjuBqTctM0UHNn/YJIu9n/KCFMJNJ5HYfsTMfhJjtgI1Hxfd687u8dLTEpSrhYctZZ5ZjVfGKpVa3hJoJ93RI9G2DmC3BqsWOTrsX/MB6cgpaiYbnDbUIq0fPw+fa6mkOKMqa2jW/ufb6nD7SUQlo4NUmA0iE/97+BIR1PXfwTl58MfwowUNttGtC/PJbQTZoyx6WZ6IqsWdHsifbmj/w29zUZYY8DWkRw2RHNPrDC5yDDqCkOg6oCUPPzbTmAGHDZSe30xknmHxytw+5+mwHJcaGMo6TQuExrIcKzYfopx4LhFJSLEc0lzrHBwypbR07tS3N8S2YwiU5quPy5UgMdeKN1agm1US4Qm7HIjX+K638mZ/NHOAm9d9khTCemYoxgmw22J2qkkxu3i+8GLUXwyNL3nO+P0fq3U/uRp8CxjOwJ6kles3h5ETJ+PEV0pbifDWaDxw==",
        "X-OriginatorOrg": "nxp.com",
        "X-MS-Exchange-CrossTenant-Network-Message-Id": "e18d2fb9-574c-4edc-43f8-08de239454a9",
        "X-MS-Exchange-CrossTenant-AuthSource": "GVXPR04MB9831.eurprd04.prod.outlook.com",
        "X-MS-Exchange-CrossTenant-AuthAs": "Internal",
        "X-MS-Exchange-CrossTenant-OriginalArrivalTime": "14 Nov 2025 15:41:51.7090\n\t(UTC)",
        "X-MS-Exchange-CrossTenant-FromEntityHeader": "Hosted",
        "X-MS-Exchange-CrossTenant-Id": "686ea1d3-bc2b-4c6f-a92c-d99c5c301635",
        "X-MS-Exchange-CrossTenant-MailboxType": "HOSTED",
        "X-MS-Exchange-CrossTenant-UserPrincipalName": "Rg3qXaa1r/yn7D4mU4pY2CIhhHV2mo1HHcOl6fDMJLKb3RtImpy5sy3v6vuXhdnmY6yM4REB12GbzhXmAn3VMw==",
        "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "GV1PR04MB10108",
        "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>",
        "Errors-To": "libcamera-devel-bounces@lists.libcamera.org",
        "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"
    },
    "content": "From: Andrei Gansari <andrei.gansari@nxp.com>\n\nThis change integrates the MediaPipeline class into the imx8-isi\npipeline handler. Purpose is to allow a dynamic discovery and\nconfiguration of the actual subdevices graph between the sensor and\nthe ISI crossbar. This brings support for more complex topologies and\nsimplifies the implementation.\n\nSigned-off-by: Andrei Gansari <andrei.gansari@nxp.com>\nSigned-off-by: Antoine Bouyer <antoine.bouyer@nxp.com>\n---\n src/libcamera/pipeline/imx8-isi/imx8-isi.cpp | 159 ++++++++++++-------\n 1 file changed, 98 insertions(+), 61 deletions(-)",
    "diff": "diff --git a/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp b/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp\nindex 9550f54600c4..aefc0ee60a11 100644\n--- a/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp\n+++ b/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp\n@@ -25,6 +25,7 @@\n #include \"libcamera/internal/camera_sensor.h\"\n #include \"libcamera/internal/device_enumerator.h\"\n #include \"libcamera/internal/media_device.h\"\n+#include \"libcamera/internal/media_pipeline.h\"\n #include \"libcamera/internal/pipeline_handler.h\"\n #include \"libcamera/internal/v4l2_subdevice.h\"\n #include \"libcamera/internal/v4l2_videodevice.h\"\n@@ -62,14 +63,15 @@ public:\n \tunsigned int getYuvMediaBusFormat(const PixelFormat &pixelFormat) const;\n \tunsigned int getMediaBusFormat(PixelFormat *pixelFormat) const;\n \n+\t/* All entities, from the sensor to the ISI. */\n+\tMediaPipeline mediaPipeline_;\n+\n \tstd::unique_ptr<CameraSensor> sensor_;\n-\tstd::unique_ptr<V4L2Subdevice> csis_;\n \n \tstd::vector<Stream> streams_;\n \n \tstd::vector<Stream *> enabledStreams_;\n \n-\tunsigned int xbarSink_ = 0;\n \tunsigned int xbarSourceOffset_ = 0;\n };\n \n@@ -141,6 +143,8 @@ private:\n \n \tvoid bufferReady(FrameBuffer *buffer);\n \n+\tstd::vector<MediaEntity *> locateSensors(MediaDevice *media);\n+\n \tMediaDevice *isiDev_;\n \n \tstd::unique_ptr<V4L2Subdevice> crossbar_;\n@@ -164,10 +168,6 @@ int ISICameraData::init()\n \tif (!sensor_)\n \t\treturn -ENODEV;\n \n-\tint ret = csis_->open();\n-\tif (ret)\n-\t\treturn ret;\n-\n \tproperties_ = sensor_->properties();\n \n \treturn 0;\n@@ -811,18 +811,29 @@ int PipelineHandlerISI::configure(Camera *camera, CameraConfiguration *c)\n {\n \tISICameraConfiguration *camConfig = static_cast<ISICameraConfiguration *>(c);\n \tISICameraData *data = cameraData(camera);\n+\tCameraSensor *sensor = data->sensor_.get();\n+\tint ret;\n \n-\t/* Apply format to the sensor, CSIS receiver and crossbar sink pad. */\n-\tV4L2SubdeviceFormat format = camConfig->sensorFormat_;\n-\tint ret = data->sensor_->setFormat(&format);\n-\tif (ret)\n+\t/*\n+\t * Enable the links all the way up to the ISI, through any connected CSI\n+\t * receiver and optional formatter.\n+\t */\n+\tret = data->mediaPipeline_.initLinks();\n+\tif (ret) {\n+\t\tLOG(ISI, Error) << \"Failed to set up pipe links\";\n \t\treturn ret;\n+\t}\n \n-\tret = data->csis_->setFormat(0, &format);\n+\t/*\n+\t * Configure the format on the sensor output and propagate it through\n+\t * the pipeline.\n+\t */\n+\tV4L2SubdeviceFormat format = camConfig->sensorFormat_;\n+\tret = sensor->setFormat(&format);\n \tif (ret)\n \t\treturn ret;\n \n-\tret = crossbar_->setFormat(data->xbarSink_, &format);\n+\tret = data->mediaPipeline_.configure(sensor, &format);\n \tif (ret)\n \t\treturn ret;\n \n@@ -979,13 +990,8 @@ bool PipelineHandlerISI::match(DeviceEnumerator *enumerator)\n \t\treturn false;\n \n \t/* Count the number of sensors, to create one camera per sensor. */\n-\tunsigned cameraCount = 0;\n-\tfor (MediaEntity *entity : isiDev_->entities()) {\n-\t\tif (entity->function() != MEDIA_ENT_F_CAM_SENSOR)\n-\t\t\tcontinue;\n-\n-\t\tcameraCount++;\n-\t}\n+\tstd::vector<MediaEntity *> sensorEntities = locateSensors(isiDev_);\n+\tunsigned cameraCount = sensorEntities.size();\n \n \tif (!cameraCount) {\n \t\tLOG(ISI, Error) << \"No camera sensor found\";\n@@ -1048,60 +1054,28 @@ bool PipelineHandlerISI::match(DeviceEnumerator *enumerator)\n \t * sensors to get at least one dedicated pipe.\n \t */\n \tunsigned int numCameras = 0;\n-\tunsigned int numSinks = 0;\n \tconst unsigned int xbarFirstSource = crossbar_->entity()->pads().size() - pipes_.size();\n \tconst unsigned int maxStreams = pipes_.size() / cameraCount;\n \n-\tfor (MediaPad *pad : crossbar_->entity()->pads()) {\n-\t\tunsigned int sink = numSinks;\n-\n-\t\tif (!(pad->flags() & MEDIA_PAD_FL_SINK))\n-\t\t\tcontinue;\n-\n-\t\t/*\n-\t\t * Count each crossbar sink pad to correctly configure\n-\t\t * routing and format for this camera.\n-\t\t */\n-\t\tnumSinks++;\n-\n-\t\tif (pad->links().empty())\n-\t\t\tcontinue;\n-\n-\t\tMediaEntity *csi = pad->links()[0]->source()->entity();\n-\t\tif (csi->pads().size() != 2) {\n-\t\t\tLOG(ISI, Debug) << \"Skip unsupported CSI-2 receiver \"\n-\t\t\t\t\t<< csi->name();\n-\t\t\tcontinue;\n-\t\t}\n-\n-\t\tpad = csi->pads()[0];\n-\t\tif (!(pad->flags() & MEDIA_PAD_FL_SINK) || pad->links().empty())\n-\t\t\tcontinue;\n-\n-\t\tMediaEntity *sensor = pad->links()[0]->source()->entity();\n-\t\tif (sensor->function() != MEDIA_ENT_F_CAM_SENSOR) {\n-\t\t\tLOG(ISI, Debug) << \"Skip unsupported subdevice \"\n-\t\t\t\t\t<< sensor->name();\n-\t\t\tcontinue;\n-\t\t}\n-\n-\t\t/* All links are immutable except the sensor -> csis link. */\n-\t\tconst MediaPad *sensorSrc = sensor->getPadByIndex(0);\n-\t\tsensorSrc->links()[0]->setEnabled(true);\n-\n+\tfor (MediaEntity *sensor : sensorEntities) {\n \t\t/* Create the camera data. */\n \t\tstd::unique_ptr<ISICameraData> data =\n \t\t\tstd::make_unique<ISICameraData>(this, maxStreams);\n \n+\t\tret = data->mediaPipeline_.init(sensor, \"crossbar\");\n+\t\tif (ret)\n+\t\t\tcontinue;\n+\n+\t\tconst MediaPipeline::Entity *xbarEntity = &data->mediaPipeline_.entities().back();\n+\t\tunsigned int xbarSinkIndex = xbarEntity->sink->index();\n+\n \t\tdata->sensor_ = CameraSensorFactoryBase::create(sensor);\n-\t\tdata->csis_ = std::make_unique<V4L2Subdevice>(csi);\n-\t\tdata->xbarSink_ = sink;\n \t\tdata->xbarSourceOffset_ = numCameras * data->streams_.size();\n \n \t\tLOG(ISI, Debug)\n \t\t\t<< \"cam\" << numCameras\n \t\t\t<< \" streams \" << data->streams_.size()\n-\t\t\t<< \" sink \" << data->xbarSink_\n+\t\t\t<< \" sink \" << xbarSinkIndex\n \t\t\t<< \" offset \" << data->xbarSourceOffset_;\n \n \t\tret = data->init();\n@@ -1120,7 +1094,7 @@ bool PipelineHandlerISI::match(DeviceEnumerator *enumerator)\n \t\t/*  Add routes to the crossbar switch routing table. */\n \t\tfor (unsigned i = 0; i < data->streams_.size(); i++) {\n \t\t\tunsigned int sourcePad = xbarFirstSource + data->xbarSourceOffset_ + i;\n-\t\t\trouting_.emplace_back(V4L2Subdevice::Stream{ data->xbarSink_, 0 },\n+\t\t\trouting_.emplace_back(V4L2Subdevice::Stream{ xbarSinkIndex, 0 },\n \t\t\t\t\t     V4L2Subdevice::Stream{ sourcePad, 0 },\n \t\t\t\t\t     V4L2_SUBDEV_ROUTE_FL_ACTIVE);\n \t\t}\n@@ -1163,6 +1137,69 @@ void PipelineHandlerISI::bufferReady(FrameBuffer *buffer)\n \tcompleteRequest(request);\n }\n \n+/* Original function taken from simple.cpp */\n+std::vector<MediaEntity *>\n+PipelineHandlerISI::locateSensors(MediaDevice *media)\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 link\n+\t\t * from a source pad.\n+\t\t */\n+\t\tconst MediaLink *link = nullptr;\n+\n+\t\tfor (const MediaPad *pad : entity->pads()) {\n+\t\t\tif ((pad->flags() & MEDIA_PAD_FL_SOURCE) &&\n+\t\t\t    !pad->links().empty()) {\n+\t\t\t\tlink = pad->links()[0];\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 REGISTER_PIPELINE_HANDLER(PipelineHandlerISI, \"imx8-isi\")\n \n } /* namespace libcamera */\n",
    "prefixes": [
        "v2",
        "2/2"
    ]
}