Show a patch.

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

{
    "id": 25011,
    "url": "https://patchwork.libcamera.org/api/patches/25011/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/25011/",
    "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": "<20251113100414.535550-3-antoine.bouyer@nxp.com>",
    "date": "2025-11-13T10:04:14",
    "name": "[v1,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/people/218/?format=api",
        "name": "Antoine Bouyer",
        "email": "antoine.bouyer@nxp.com"
    },
    "delegate": null,
    "mbox": "https://patchwork.libcamera.org/patch/25011/mbox/",
    "series": [
        {
            "id": 5585,
            "url": "https://patchwork.libcamera.org/api/series/5585/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=5585",
            "date": "2025-11-13T10:04:12",
            "name": "imx8-isi: Use MediaPipeline",
            "version": 1,
            "mbox": "https://patchwork.libcamera.org/series/5585/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/25011/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/25011/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 106ABC3263\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 13 Nov 2025 10:03:01 +0000 (UTC)",
            "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 3DE1B60A81;\n\tThu, 13 Nov 2025 11:02:57 +0100 (CET)",
            "from GVXPR05CU001.outbound.protection.outlook.com\n\t(mail-swedencentralazlp170130007.outbound.protection.outlook.com\n\t[IPv6:2a01:111:f403:c202::7])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 6C00A60A7B\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 13 Nov 2025 11:02:53 +0100 (CET)",
            "from GVXPR04MB9831.eurprd04.prod.outlook.com (2603:10a6:150:11c::8)\n\tby AM8PR04MB7235.eurprd04.prod.outlook.com (2603:10a6:20b:1d1::8)\n\twith Microsoft SMTP Server (version=TLS1_2,\n\tcipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9320.17;\n\tThu, 13 Nov 2025 10:02: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.013;\n\tThu, 13 Nov 2025 10:02:51 +0000"
        ],
        "Authentication-Results": [
            "lancelot.ideasonboard.com; dkim=pass (2048-bit key;\n\tunprotected) header.d=nxp.com header.i=@nxp.com header.b=\"SIdlMSl3\";\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=dzRkjIAmeIUEPsY1lfml6rkIvha+0Lh/zhWeNDgbkM++bvOzvsJjOPUatgMVt8cGa1vzDeuHlU6vSO0DX890lpFuCMLwqYdunNylm8yRaookkKlDYntBo7I6/R0+zM39CPY6T+nkJ5Ft6W7b0WkJ9XUA1I9GVD1rsXuy/mOZR0fjG9CQlTaZJwB+Snh3YgkrWSr153Z905h8mpV8P3vyOHRtex6qss6fjhPhjeFJIml+TFeo0SPsSKYflOXPOD1OJ3T43sqqVRj99T/31OPwSuWjC/e6QfsSrWm09+Ov05oZGrC9wSC6LJnUh3SC7C1ZSqBNfw4iJT4x3A+tB36KOQ==",
        "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=d9/cU3n5x3J6QQWP+/tWNSIIywG1sPrE+c3ptvfZfW8G2B3BCmOQddML6jekPrmnYXFQnyM9IYdJKks1WvWHz+pcANGjv3pz17BKRxSD7p29qHsaliIqOj+lpkloeUIrvnz2RPM7IBim8ZNN+BAv8skhtUOmlmJK1lmCLZCatgj+KaBjZMQTlvxNUAHZGqXNb6ST7zX11sotdQJtgOHQFetXc8VA5SBH4HyyozSN3sj/Zf36ggGblIlVxJ6tMf5VbvEK0Ep/p4EsxA2LHYkOHWKm5PrHr0vuwBhAlGuJCnNFeqT1cPJNtqrCORiugwROR8ZrLn8bUSf5RnTG5960DA==",
        "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=SIdlMSl3o08tGGtoc5TTA3zHTYuKWafRLUbG5S+RlCMIM0BIrAmb21CvttUcpSSx3is0IGsaLPT+fJixEXyFS2Cm2j4mcaajGitOC4QZvJQ4FTe0rBHvU8L6JZCAP0aJXuX58/xMRXS53UOSs3ijPhv1HX8WnbFOHM1viAonCNdu9ZJKOTn0eSz0CYlM2+xaLMmefclM5dmBSYvo3/p790yBkNDqor11wzG5RauTtsuvSUsr2ihrFwKw2cTsanAVBdL/7qtQLS8Aky2U4kSroPdqwJqROznrbWlC4M3v5aSrOfTWPPmHLBGy2WsUVzs+jJx1GbuyLqMeY8AXVSDM4g==",
        "From": "Antoine Bouyer <antoine.bouyer@nxp.com>",
        "To": "libcamera-devel@lists.libcamera.org",
        "Cc": "julien.vuillaumier@nxp.com, Andrei Gansari <andrei.gansari@nxp.com>,\n\tAntoine Bouyer <antoine.bouyer@nxp.com>",
        "Subject": "[PATCH v1 2/2] pipeline: imx8-isi: Integrating MediaPipeline class",
        "Date": "Thu, 13 Nov 2025 11:04:14 +0100",
        "Message-Id": "<20251113100414.535550-3-antoine.bouyer@nxp.com>",
        "X-Mailer": "git-send-email 2.34.1",
        "In-Reply-To": "<20251113100414.535550-1-antoine.bouyer@nxp.com>",
        "References": "<20251113100414.535550-1-antoine.bouyer@nxp.com>",
        "Content-Transfer-Encoding": "8bit",
        "Content-Type": "text/plain",
        "X-ClientProxiedBy": "AM0PR02CA0198.eurprd02.prod.outlook.com\n\t(2603:10a6:20b:28e::35) 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_|AM8PR04MB7235:EE_",
        "X-MS-Office365-Filtering-Correlation-Id": "8ad38cf3-a84c-4ff4-9015-08de229bce5f",
        "X-MS-Exchange-SenderADCheck": "1",
        "X-MS-Exchange-AntiSpam-Relay": "0",
        "X-Microsoft-Antispam": "BCL:0;\n\tARA:13230040|366016|376014|19092799006|1800799024|52116014|38350700014;",
        "X-Microsoft-Antispam-Message-Info": "+S+l1bTqoDCPwtPLJdITOV29RoV8eacXl1VbbXT9bITHWQvGosZJpx84pHuyQLKnGfRXjDivsxvsyxi1ThDoTMw9a/oLXN4lONaISsz0b47GFSGVsJ+aEWSmqLJAYEr+FVWr4Z2lSMexbhnAEzmTrst58mpe9kPxMJQrZZVPedBZWl2h9pFxLRXMH4iL0DFbVhLr4x3KHAb1mAar3JHIB2DBr7VMOvr00kQDN1KXDwFaYqcqBR0Ou8Jj8i6jVXeUTHU7+uUGWG4nfbQSRiU91yEFEapnoburTtC0CbEYSyi6CxG9QlepRf/put2U/KE2YsgtZdvJ8dTpuk2PLWxdibJmvj1UT08GXC+UajaP7yiCfoR8iXkex7RvEFx/zWdeGrYtBuRN5PcMR8ZZ97S2ijwvpE+Brv7USBQ00ymiZFDq7bk4INN00zSpIWfz4gKTprEod1NChtPfMshIR36mWq6wNiN7A8QIlPLdGJnArc/+5A4bntJVnLW8ZmcGNpH/pvvKgHBhHeMHQnjOf6xMN8HM24RqmNnB5JZ3wyljwc3N0sr+4l1rjtUp+jfMQ593+GWnmA84Pc4AxI/DHel8ISO7XK3dm244NyPw8RDOqKeEewgqXNsse5622lqXpFrFEYiQI8hN/AId/YtOHKc4Kpsh+keLvYt0xgqoWTEFC4/dlHkX2zQKwKpCWOTo0y5sTarjLg5FQcz1VzuHgYC0Gc2fbFC0FTypS/C6MTqf9Rbw7ohPZov6V+C1Ilcjk8/lap1L0/GAWVVAD6gMW+DFLAptkBfteueWBS3fwf3/Ka8CH+cr5t+SwicFTePqglRrBFAPqOlnKA2zsJU1CZ8NLRa2ArUsQthxNNgWOqfpRazakBaWE1gCo3Jv9rToldLGcaDZRo/KX+TWulLug38qCvYJ4OGxx8nld3iFCJVBghg5SmCdAY8UAhNbbmmqESMZDlaou5eEf+9gpz7Z22shfTk6H1EhBmQbkn3wwKSb+Uo6mVNxOK7Amg2HxKUWAmQarEzKJpXSalnr7XLlLhRyaWqzKz11ysnVMXHBW4AaBiCC+rntZV29cX3XGgY9Mo7dSvF92FGVxkKoxbN8iqGs/97VSkNkFlare6ZJLJtqvMR0kiIGXlgonye6nDQ1shpJkjbrBqFe/yfO4JbBjXzCT/fTk0EZRoORgFBjcwGW067pp8XUF5+JwRnuc4gQ86WrxfRHqkyt5mzR9yr7o4bSS/2GBxlOIc+l+vBPlig6cRKI6sGoDtny8oC6L4uxGYE91giv1+CvPgVeVewBeTq99WhaaV4OCfEO7eO4JTR6GKMNGkDYYCMbtVxcDRkA9C8gjl/NvH31DQi+1lKvGEmze7ZRPsXTc3BurmygB6vXHzohDO7cMTLD6Ea+/EDu005Qk8LRpN0arZGqfdxQBsT8HzJviadAvhPcBWg09NX07x7T/5NJjP6JwCWV7ZljsS3visq4emN3ZL5noYc8EyfoOfxh1bny/voTFEQNHpuI0f+QJdoieVTrIpg6C/yqvy+f",
        "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)(366016)(376014)(19092799006)(1800799024)(52116014)(38350700014);\n\tDIR:OUT; SFP:1101; ",
        "X-MS-Exchange-AntiSpam-MessageData-ChunkCount": "1",
        "X-MS-Exchange-AntiSpam-MessageData-0": "1RCT+NbVMpl91EaA2ioBlObEknRU7FZCYT3wU/8SRQr8pYJZO/uu+ugfp0wfe3bPK6AKFDLvaKk2FZqFaSixWGbTQB6oUkZckpkUkb13NfEvKH+MvVluFNJOqaFZjHks26IsGfKGqzcBplO5getRXEXQeQt1SLnAWpn9RGfgmL/CGeQf/UREyvKovARzVeIpxTdag+3SW+rogMtOPw7sdDYxSyv0/FLwOpgEUzn4Bc4R02ebQWJSwzfq7bO9/H6S35Z/k6PnfYp2u51QWOEqvKTKds4ziSilhv4NAyr5TQLdG0eJnRJmmhGxyOVCHCp4CKg1nSaI1D8QiEsNGCYnT9YEU6DYeTlW3BwrmO9hdg15k22LbCvKwCWQw0qYIiHFBLHW0ExHIiI6xMv5gfqwg7cCJ6WRK7aixNx/X877FZiNMsrfmotTtKhIoH2mLFvX3kstIM2q5SXckViCUIhyifH0WGbDumbyx+fWkNpzdc2GmaviAs8ObJ0j1o7gC+z3b9IaILEXTT4Ge+WU8ZjSAxCmFLval0jMVTSa419O+mkixgjUtOQqynlDlj6FOV0U44GDxUkS1YbLiwpEkAOXJNhc7c85oFoxJWSv0GlBMl8IzYHEfSpCGKZd5QuZf1xfns0Qa9JoKykp4kHz26mkv8F3LlDGqxSSO2141UlSbVCM3yKzZ6h4sNr5TH+g0JRQhogPdVk3nMKN2WExKsMPvm/RaabBaEnP1HyJjAhyuWdlavdtF8sBee0O3dWNHLN381Mndj6ATfk1/rHlSvcp28AYNfJrL62KL+mqxCBC/ReoEJ+lfhmTBGbd94iuvDXGhcB8oNUvw5n/zYM9skLu5sN1UjWxNDF5eMLXyb2gL6qUWzkc/MBDQ7TUFhWljX2anUomJJzZqNUmUkocbrDgzM5rEogBVVBku2EAf7tasCHaFc+g1+R3TR4l4xyO07AS6g18UAxXFhoz45J2PPvmbR70RJIQjpR1evndOMt0aQ27e+ZXVwHq04B1D20KJqlk2Eg34tT2MD30PCjnvXwIUeLzpxCLnX45M+zYGjYGbh5BuA0EQPFjTUS8khje4whx/R06cQelljMrsN4m4I7PPIZLmwOodJMSvUBu8L8Og2Bo+gsSGTA96mQ/aF8sBgZnZ77DyM72R/qilIrJfmqcLdawG0tPnO4kC+eGkYSRYrzYVBzTIMt1c/3DsgfEExqrZK6nBj2YV6OwAdyPz7YK2Y3H1CsjUPekjocmKZiixtcxGgQSzUWK7czMXER1oIhe1Sc3BBGXtpj0OfQbxUNfN+lSdPnacFwhN3aq8JPodBZ0ulGfGQVVOSfW1bD9/dovzXiknvBIujs7MXSK0TiHAo6rZcmP2VpItqvTuwjNVWgmzMD9/c434YFBFMA43K7BzsDrzXkGGRLDwkAfB5XUBJjg4Bx2ZByn/Ifyfp5Wmk1AShde7LOneb1jDCG6c30rYzycXV6A5V0MmkOLhpL94LqkYS6eLtWIOYUsEEzPsEnrhxiCXoSBMODjdTUz7l/WZalM5d7BvBbXAcEv+VfBlVXYIcSzi+iY14kxMXP4qUp5J41+ftHTmBMNa7mRuRXUuwe27KAiRQq/ZFMqTe00Bw==",
        "X-OriginatorOrg": "nxp.com",
        "X-MS-Exchange-CrossTenant-Network-Message-Id": "8ad38cf3-a84c-4ff4-9015-08de229bce5f",
        "X-MS-Exchange-CrossTenant-AuthSource": "GVXPR04MB9831.eurprd04.prod.outlook.com",
        "X-MS-Exchange-CrossTenant-AuthAs": "Internal",
        "X-MS-Exchange-CrossTenant-OriginalArrivalTime": "13 Nov 2025 10:02:51.2888\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": "vT1/IRQKFCNxTvBvaEvXih6JT8mjjneT83ERZwekO1xFip/Xet2i4yY3kY8G6nyJw0kwELRmf28jb4VFWi4BEA==",
        "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "AM8PR04MB7235",
        "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": [
        "v1",
        "2/2"
    ]
}