Show a patch.

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

{
    "id": 25460,
    "url": "https://patchwork.libcamera.org/api/1.1/patches/25460/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/25460/",
    "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": "<20251210-mali-cru-v2-3-e26421de202b@ideasonboard.com>",
    "date": "2025-12-10T14:39:19",
    "name": "[v2,3/7] libcamera: mali-c55: Register memory input camera",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": false,
    "hash": "01ad28c93a73455e3d2424cfd79962a085c1b839",
    "submitter": {
        "id": 143,
        "url": "https://patchwork.libcamera.org/api/1.1/people/143/?format=api",
        "name": "Jacopo Mondi",
        "email": "jacopo.mondi@ideasonboard.com"
    },
    "delegate": null,
    "mbox": "https://patchwork.libcamera.org/patch/25460/mbox/",
    "series": [
        {
            "id": 5649,
            "url": "https://patchwork.libcamera.org/api/1.1/series/5649/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=5649",
            "date": "2025-12-10T14:39:16",
            "name": "libcamera: mali-c55: Add support for memory-to-memory",
            "version": 2,
            "mbox": "https://patchwork.libcamera.org/series/5649/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/25460/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/25460/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 EB8DEC326B\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 10 Dec 2025 14:39:38 +0000 (UTC)",
            "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id A78BC61491;\n\tWed, 10 Dec 2025 15:39:37 +0100 (CET)",
            "from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 1E2E361489\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 10 Dec 2025 15:39:33 +0100 (CET)",
            "from [192.168.1.106] (mob-5-90-55-146.net.vodafone.it\n\t[5.90.55.146])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id ACE9310C4;\n\tWed, 10 Dec 2025 15:39:31 +0100 (CET)"
        ],
        "Authentication-Results": "lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"dxFz8J9n\"; dkim-atps=neutral",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1765377571;\n\tbh=t25rGKH/UyqsD/vjAyQ7tCb32tcmFGJ1n8U13MRNpkE=;\n\th=From:Date:Subject:References:In-Reply-To:To:Cc:From;\n\tb=dxFz8J9ngkzaWHxa73Gyo5BhDaxBQwlNonkW35seVFo+5S1ehuUO0XXgg48QPerzr\n\t5cvQm1u0cTLiTwBoWZw/q76VbahJqtb1zrKSf35YvRn0FPrcF9pdQINVSncWN1sdCa\n\tgvGQcHhXCE1QZedPcdcZMWBg26tbrCQmbG5Qxzzc=",
        "From": "Jacopo Mondi <jacopo.mondi@ideasonboard.com>",
        "Date": "Wed, 10 Dec 2025 15:39:19 +0100",
        "Subject": "[PATCH v2 3/7] libcamera: mali-c55: Register memory input camera",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=\"utf-8\"",
        "Content-Transfer-Encoding": "7bit",
        "Message-Id": "<20251210-mali-cru-v2-3-e26421de202b@ideasonboard.com>",
        "References": "<20251210-mali-cru-v2-0-e26421de202b@ideasonboard.com>",
        "In-Reply-To": "<20251210-mali-cru-v2-0-e26421de202b@ideasonboard.com>",
        "To": "Daniel Scally <dan.scally@ideasonboard.com>, \n\tlibcamera-devel@lists.libcamera.org",
        "Cc": "Jacopo Mondi <jacopo.mondi@ideasonboard.com>",
        "X-Mailer": "b4 0.14.2",
        "X-Developer-Signature": "v=1; a=openpgp-sha256; l=14098;\n\ti=jacopo.mondi@ideasonboard.com; h=from:subject:message-id;\n\tbh=I2zhK9XmPmyRoJdqHwcIVL1RAhvX2ns7rhneW2H7+3I=;\n\tb=owEBbQKS/ZANAwAKAXI0Bo8WoVY8AcsmYgBpOYYixUPnbOrBTKZzBowmNMYhPP05PnqkSd9gt\n\tBScniYwQcyJAjMEAAEKAB0WIQS1xD1IgJogio9YOMByNAaPFqFWPAUCaTmGIgAKCRByNAaPFqFW\n\tPHQxD/0bK5yanMhXc/1+25HbB8tuwdH9daC34V5x1C8FuKAEV8G0WTdAWy30l8xpr7lSjTlROjB\n\trTG7oCqzw5WqUZc7SHQAV8UPgUgFn5uZ+8ZGvEBIlPq8xS/i1I+5HOUK8fwBhsKb0OYtF5dvF2F\n\tC5foS1yJyeAJ/jPoJqdw1Y9xvbaKbMchgE5FrMzA71S489ds0YW9NdaRqSxnsQCdJ1eSIG9+4Xc\n\t5463xmr1dOppYI+cy1b2rO30DDcwSVCVIUiOeYrKHzqszVKy5mxv1HGBDOdhuUPiRgldiQwzCoE\n\tqxl/02Yeqm4EZrCzxOTKrN6EE7/OA4R7u4g8KvgGEaulHZc/+P855+sJ6sU5Z4B+gFGfuXseMuG\n\tfJXWcTzkYXPRmdWFWWXZkqPL1KXhH/RUSxmP6U+UU3JBWUHG9ia6D7mCD8aPzTsPD2DriPwZw48\n\tRWnX6EYoBvxveyqaqyQK7d1mWHkjHZS46/NvvZPtw8KjBTt+LIAGYRyKMuVH/G6e0FB6rUJxblT\n\tvav6y2kCXYMpMdNBR0knehEGI91jc/5MPK7RjF59Ix0ZV7JhNViexy7ffvNCPd85MIyIi3W0C5i\n\tkef5pdQopfYvPRafQiF1lieJ2CP40ZytY6M6+eB26wdzqYQkY1RW0H/BhozEsrHkU7qjJZ+phNp\n\tM0PHbXByDjDvreA==",
        "X-Developer-Key": "i=jacopo.mondi@ideasonboard.com; a=openpgp;\n\tfpr=72392EDC88144A65C701EA9BA5826A2587AD026B",
        "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: Daniel Scally <dan.scally@ideasonboard.com>\n\nAdd support to Mali C55 pipeline handler for memory-to-memory camera\nmode.\n\nThe Mali-C55, as integrated in the Renesas RZ/V2H(P) SoC, is fed with\nimages saved to memory by the CRU unit and read on behalf of the ISP\nby the IVC.\n\nUpdate the pipeline handler's match() function to search for the CRU\nmedia entity necessary to register a memory input camera. Create and\ninitialize a CameraData instance for the memory camera use case if a\nvalid CRU is found and initialize the IVC components used to feed the\nISP with images read from memory.\n\nThe MaliC55CameraData class is now derived by a templated base class\nwhich allows, by using the CRTP pattern, to template the argument of the\ninit() function which would have otherwise required to implement\nplaceholders in all derived classes.\n\nSigned-off-by: Daniel Scally <dan.scally@ideasonboard.com>\nSigned-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>\n---\n src/libcamera/pipeline/mali-c55/mali-c55.cpp | 245 ++++++++++++++++++++++-----\n 1 file changed, 205 insertions(+), 40 deletions(-)",
    "diff": "diff --git a/src/libcamera/pipeline/mali-c55/mali-c55.cpp b/src/libcamera/pipeline/mali-c55/mali-c55.cpp\nindex 552a258a6b849a2518fa6c83226cf9ab4e657717..c0c14338ddb3f1d0075df3b3d3d154bc1b5d678a 100644\n--- a/src/libcamera/pipeline/mali-c55/mali-c55.cpp\n+++ b/src/libcamera/pipeline/mali-c55/mali-c55.cpp\n@@ -42,6 +42,8 @@\n #include \"libcamera/internal/v4l2_subdevice.h\"\n #include \"libcamera/internal/v4l2_videodevice.h\"\n \n+#include \"rzg2l-cru.h\"\n+\n namespace {\n \n bool isFormatRaw(const libcamera::PixelFormat &pixFmt)\n@@ -95,6 +97,7 @@ public:\n \tenum CameraType {\n \t\tTpg,\n \t\tInline,\n+\t\tMemory,\n \t};\n \n \tMaliC55CameraData(PipelineHandler *pipe)\n@@ -107,13 +110,12 @@ public:\n \tCameraType type() const { return type_; }\n \n \t/* Deflect these functionalities to either TPG or CameraSensor. */\n-\tvirtual int init(MediaEntity *entity) = 0;\n-\n \tvirtual std::vector<Size> sizes(unsigned int mbusCode) const = 0;\n \tvirtual V4L2Subdevice *subdev() const = 0;\n \tvirtual CameraSensor *sensor() const = 0;\n \tvirtual V4L2Subdevice *csi2() const = 0;\n \tvirtual Size resolution() const = 0;\n+\tvirtual RZG2LCRU *cru() const = 0;\n \n \tint pixfmtToMbusCode(const PixelFormat &pixFmt) const;\n \tconst PixelFormat &bestRawFormat() const;\n@@ -140,12 +142,34 @@ private:\n \tstd::string id_;\n };\n \n-class MaliC55TpgCameraData : public MaliC55CameraData\n+template<typename Derived>\n+class MaliC55TemplatedCameraData : public MaliC55CameraData\n+{\n+public:\n+\tMaliC55TemplatedCameraData(PipelineHandler *pipe)\n+\t\t: MaliC55CameraData(pipe)\n+\t{\n+\t}\n+\n+\t/*\n+\t * The signature of the init() functions is different between the\n+\t * Tpg, Inline and Memory camera use cases. Use CRTP to deflect to the\n+\t * right implementation the templated argument and avoid polluting the\n+\t * interface of the base class.\n+\t */\n+\ttemplate<typename MediaType>\n+\tint init(MediaType *media)\n+\t{\n+\t\treturn static_cast<Derived *>(this)->init(media);\n+\t}\n+};\n+\n+class MaliC55TpgCameraData : public MaliC55TemplatedCameraData<MaliC55TpgCameraData>\n {\n public:\n \tMaliC55TpgCameraData(PipelineHandler *pipe);\n \n-\tint init(MediaEntity *entity) override;\n+\tint init(MediaEntity *entity);\n \n \tstd::vector<Size> sizes(unsigned int mbusCode) const override;\n \n@@ -171,17 +195,23 @@ public:\n \t\treturn nullptr;\n \t}\n \n+\tRZG2LCRU *cru() const override\n+\t{\n+\t\tASSERT(false);\n+\t\treturn nullptr;\n+\t}\n+\n private:\n \tSize resolution_;\n \tstd::unique_ptr<V4L2Subdevice> sd_;\n };\n \n-class MaliC55InlineCameraData : public MaliC55CameraData\n+class MaliC55InlineCameraData : public MaliC55TemplatedCameraData<MaliC55InlineCameraData>\n {\n public:\n \tMaliC55InlineCameraData(PipelineHandler *pipe);\n \n-\tint init(MediaEntity *entity) override;\n+\tint init(MediaEntity *entity);\n \n \tstd::vector<Size> sizes(unsigned int mbusCode) const override\n \t{\n@@ -208,13 +238,62 @@ public:\n \t\treturn csi2_.get();\n \t}\n \n+\tRZG2LCRU *cru() const override\n+\t{\n+\t\tASSERT(false);\n+\t\treturn nullptr;\n+\t}\n+\n private:\n \tstd::unique_ptr<V4L2Subdevice> csi2_;\n \tstd::unique_ptr<CameraSensor> sensor_;\n };\n \n+class MaliC55MemoryCameraData\n+\t: public MaliC55TemplatedCameraData<MaliC55MemoryCameraData>\n+{\n+public:\n+\tMaliC55MemoryCameraData(PipelineHandler *pipe);\n+\n+\tint init(MediaDevice *cruMedia);\n+\n+\tstd::vector<Size>\n+\tsizes([[maybe_unused]] unsigned int mbusCode) const override\n+\t{\n+\t\treturn cru_->sizes();\n+\t}\n+\n+\tSize resolution() const override\n+\t{\n+\t\treturn cru_->resolution();\n+\t}\n+\n+\tV4L2Subdevice *subdev() const override\n+\t{\n+\t\treturn cru_->sensor()->device();\n+\t}\n+\n+\tCameraSensor *sensor() const override\n+\t{\n+\t\treturn cru_->sensor();\n+\t}\n+\n+\tV4L2Subdevice *csi2() const override\n+\t{\n+\t\treturn cru_->csi2();\n+\t}\n+\n+\tRZG2LCRU *cru() const override\n+\t{\n+\t\treturn cru_.get();\n+\t}\n+\n+private:\n+\tstd::unique_ptr<RZG2LCRU> cru_;\n+};\n+\n MaliC55TpgCameraData::MaliC55TpgCameraData(PipelineHandler *pipe)\n-\t: MaliC55CameraData(pipe)\n+\t: MaliC55TemplatedCameraData(pipe)\n {\n \ttype_ = CameraType::Tpg;\n }\n@@ -267,7 +346,7 @@ std::vector<Size> MaliC55TpgCameraData::sizes(unsigned int mbusCode) const\n }\n \n MaliC55InlineCameraData::MaliC55InlineCameraData(PipelineHandler *pipe)\n-\t: MaliC55CameraData(pipe)\n+\t: MaliC55TemplatedCameraData(pipe)\n {\n \ttype_ = CameraType::Inline;\n }\n@@ -292,6 +371,18 @@ int MaliC55InlineCameraData::init(MediaEntity *sensor)\n \treturn ret;\n }\n \n+MaliC55MemoryCameraData::MaliC55MemoryCameraData(PipelineHandler *pipe)\n+\t: MaliC55TemplatedCameraData(pipe)\n+{\n+\ttype_ = CameraType::Memory;\n+}\n+\n+int MaliC55MemoryCameraData::init(MediaDevice *cruMedia)\n+{\n+\tcru_ = std::make_unique<RZG2LCRU>();\n+\treturn cru_->init(cruMedia);\n+}\n+\n void MaliC55CameraData::setSensorControls(const ControlList &sensorControls)\n {\n \tdelayedCtrls_->push(sensorControls);\n@@ -752,11 +843,15 @@ private:\n \t\t\t\tconst std::string &name);\n \tbool registerTPGCamera(MediaLink *link);\n \tbool registerSensorCamera(MediaLink *link);\n+\tbool registerMemoryInputCamera();\n \n \tstd::shared_ptr<MediaDevice> media_;\n+\tstd::shared_ptr<MediaDevice> cruMedia_;\n \tstd::unique_ptr<V4L2Subdevice> isp_;\n \tstd::unique_ptr<V4L2VideoDevice> stats_;\n \tstd::unique_ptr<V4L2VideoDevice> params_;\n+\tstd::unique_ptr<V4L2Subdevice> ivc_;\n+\tstd::unique_ptr<V4L2VideoDevice> input_;\n \n \tstd::vector<std::unique_ptr<FrameBuffer>> statsBuffers_;\n \tstd::queue<FrameBuffer *> availableStatsBuffers_;\n@@ -1009,6 +1104,8 @@ int PipelineHandlerMaliC55::configure(Camera *camera,\n \t\tret = csi2Entity->getPadByIndex(1)->links()[0]->setEnabled(true);\n \t\tbreak;\n \t}\n+\tcase MaliC55CameraData::Memory:\n+\t\tbreak;\n \t}\n \tif (ret)\n \t\treturn ret;\n@@ -1035,6 +1132,8 @@ int PipelineHandlerMaliC55::configure(Camera *camera,\n \n \t\tret = data->csi2()->getFormat(1, &subdevFormat);\n \n+\t\tbreak;\n+\tcase MaliC55CameraData::Memory:\n \t\tbreak;\n \t}\n \t}\n@@ -1110,6 +1209,7 @@ int PipelineHandlerMaliC55::configure(Camera *camera,\n \t\tpipe->stream = stream;\n \t}\n \n+\t/* TPG doesn't support the IPA, so stop here. */\n \tif (!data->ipa_)\n \t\treturn 0;\n \n@@ -1651,13 +1751,14 @@ bool PipelineHandlerMaliC55::registerTPGCamera(MediaLink *link)\n \t\treturn true;\n \t}\n \n-\tstd::unique_ptr<MaliC55CameraData> data =\n-\t\tstd::make_unique<MaliC55TpgCameraData>(this);\n-\n-\tint ret = data->init(link->source()->entity());\n-\tif (ret)\n+\tMaliC55TpgCameraData *tpgData = new MaliC55TpgCameraData(this);\n+\tint ret = tpgData->init(link->source()->entity());\n+\tif (ret) {\n+\t\tdelete tpgData;\n \t\treturn ret;\n+\t}\n \n+\tstd::unique_ptr<MaliC55CameraData> data(tpgData);\n \treturn registerMaliCamera(std::move(data), name);\n }\n \n@@ -1679,30 +1780,33 @@ bool PipelineHandlerMaliC55::registerSensorCamera(MediaLink *ispLink)\n \t\tif (function != MEDIA_ENT_F_CAM_SENSOR)\n \t\t\tcontinue;\n \n-\t\tstd::unique_ptr<MaliC55CameraData> data =\n-\t\t\tstd::make_unique<MaliC55InlineCameraData>(this);\n-\n-\t\tint ret = data->init(sensor);\n-\t\tif (ret)\n+\t\tMaliC55InlineCameraData *inlineData =\n+\t\t\tnew MaliC55InlineCameraData(this);\n+\t\tint ret = inlineData->init(sensor);\n+\t\tif (ret) {\n+\t\t\tdelete inlineData;\n \t\t\treturn ret;\n+\t\t}\n \n-\t\tdata->properties_ = data->sensor()->properties();\n+\t\tinlineData->properties_ = inlineData->sensor()->properties();\n \n \t\tconst CameraSensorProperties::SensorDelays &delays =\n-\t\t\tdata->sensor()->sensorDelays();\n+\t\t\tinlineData->sensor()->sensorDelays();\n \t\tstd::unordered_map<uint32_t, DelayedControls::ControlParams> params = {\n \t\t\t{ V4L2_CID_ANALOGUE_GAIN, { delays.gainDelay, false } },\n \t\t\t{ V4L2_CID_EXPOSURE, { delays.exposureDelay, false } },\n \t\t};\n \n-\t\tV4L2Subdevice *sensorSubdev = data->sensor()->device();\n-\t\tdata->delayedCtrls_ = std::make_unique<DelayedControls>(sensorSubdev,\n-\t\t\t\t\t\t\t\t\tparams);\n-\t\tisp_->frameStart.connect(data->delayedCtrls_.get(),\n+\t\tV4L2Subdevice *sensorSubdev = inlineData->sensor()->device();\n+\t\tinlineData->delayedCtrls_ =\n+\t\t\tstd::make_unique<DelayedControls>(sensorSubdev,\n+\t\t\t\t\t\t\t  params);\n+\t\tisp_->frameStart.connect(inlineData->delayedCtrls_.get(),\n \t\t\t\t\t &DelayedControls::applyControls);\n \n \t\t/* \\todo Init properties. */\n \n+\t\tstd::unique_ptr<MaliC55CameraData> data(inlineData);\n \t\tif (!registerMaliCamera(std::move(data), sensor->name()))\n \t\t\treturn false;\n \t}\n@@ -1710,6 +1814,39 @@ bool PipelineHandlerMaliC55::registerSensorCamera(MediaLink *ispLink)\n \treturn true;\n }\n \n+bool PipelineHandlerMaliC55::registerMemoryInputCamera()\n+{\n+\tMaliC55MemoryCameraData *memoryData = new MaliC55MemoryCameraData(this);\n+\n+\tint ret = memoryData->init(cruMedia_.get());\n+\tif (ret) {\n+\t\tdelete memoryData;\n+\t\treturn false;\n+\t}\n+\n+\tCameraSensor *sensor = memoryData->sensor();\n+\tmemoryData->properties_ = sensor->properties();\n+\n+\tconst CameraSensorProperties::SensorDelays &delays = sensor->sensorDelays();\n+\tstd::unordered_map<uint32_t, DelayedControls::ControlParams> params = {\n+\t\t{ V4L2_CID_ANALOGUE_GAIN, { delays.gainDelay, false } },\n+\t\t{ V4L2_CID_EXPOSURE, { delays.exposureDelay, false } },\n+\t};\n+\n+\tmemoryData->delayedCtrls_ =\n+\t\tstd::make_unique<DelayedControls>(sensor->device(), params);\n+\tisp_->frameStart.connect(memoryData->delayedCtrls_.get(),\n+\t\t\t\t &DelayedControls::applyControls);\n+\n+\tinput_->bufferReady.connect(memoryData->cru(), &RZG2LCRU::cruReturnBuffer);\n+\n+\tstd::unique_ptr<MaliC55CameraData> data(memoryData);\n+\tif (!registerMaliCamera(std::move(data), sensor->device()->entity()->name()))\n+\t\treturn false;\n+\n+\treturn true;\n+}\n+\n bool PipelineHandlerMaliC55::match(DeviceEnumerator *enumerator)\n {\n \tconst MediaPad *ispSink;\n@@ -1719,14 +1856,14 @@ bool PipelineHandlerMaliC55::match(DeviceEnumerator *enumerator)\n \t * The TPG and the downscale pipe are both optional blocks and may not\n \t * be fitted.\n \t */\n-\tDeviceMatch dm(\"mali-c55\");\n-\tdm.add(\"mali-c55 isp\");\n-\tdm.add(\"mali-c55 resizer fr\");\n-\tdm.add(\"mali-c55 fr\");\n-\tdm.add(\"mali-c55 3a stats\");\n-\tdm.add(\"mali-c55 3a params\");\n-\n-\tmedia_ = acquireMediaDevice(enumerator, dm);\n+\tDeviceMatch c55_dm(\"mali-c55\");\n+\tc55_dm.add(\"mali-c55 isp\");\n+\tc55_dm.add(\"mali-c55 resizer fr\");\n+\tc55_dm.add(\"mali-c55 fr\");\n+\tc55_dm.add(\"mali-c55 3a stats\");\n+\tc55_dm.add(\"mali-c55 3a params\");\n+\n+\tmedia_ = acquireMediaDevice(enumerator, c55_dm);\n \tif (!media_)\n \t\treturn false;\n \n@@ -1786,6 +1923,25 @@ bool PipelineHandlerMaliC55::match(DeviceEnumerator *enumerator)\n \tstats_->bufferReady.connect(this, &PipelineHandlerMaliC55::statsBufferReady);\n \tparams_->bufferReady.connect(this, &PipelineHandlerMaliC55::paramsBufferReady);\n \n+\t/*\n+\t * We also need to search for the rzg2l-cru CSI-2 receiver. If we find\n+\t * that then we need to work in memory input mode instead of the inline\n+\t * mode. The absence of this match is not necessarily a failure at this\n+\t * point...it depends on the media links that we investigate momentarily.\n+\t *\n+\t * This is a bit hacky, because there could be multiple of these media\n+\t * devices and we're just taking the first. We need modular pipelines to\n+\t * properly solve the issue.\n+\t */\n+\tstatic const std::regex cruCsi2Regex(\"csi-[0-9a-f]{8}.csi2\");\n+\tstatic const std::regex cruIpRegex(\"cru-ip-[0-9a-f]{8}.cru[0-9]\");\n+\n+\tDeviceMatch cruDm(\"rzg2l_cru\");\n+\tcruDm.add(cruCsi2Regex);\n+\tcruDm.add(cruIpRegex);\n+\tcruDm.add(\"CRU output\");\n+\tcruMedia_ = acquireMediaDevice(enumerator, cruDm);\n+\n \tispSink = isp_->entity()->getPadByIndex(0);\n \tif (!ispSink || ispSink->links().empty()) {\n \t\tLOG(MaliC55, Error) << \"ISP sink pad error\";\n@@ -1799,13 +1955,6 @@ bool PipelineHandlerMaliC55::match(DeviceEnumerator *enumerator)\n \t * MEDIA_ENT_F_CAM_SENSOR - The test pattern generator\n \t * MEDIA_ENT_F_VID_IF_BRIDGE - A CSI-2 receiver\n \t * MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER - An input device\n-\t *\n-\t * The last one will be unsupported for now. The TPG is relatively easy,\n-\t * we just register a Camera for it. If we have a CSI-2 receiver we need\n-\t * to check its sink pad and register Cameras for anything connected to\n-\t * it (probably...there are some complex situations in which that might\n-\t * not be true but let's pretend they don't exist until we come across\n-\t * them)\n \t */\n \tbool registered;\n \tfor (MediaLink *link : ispSink->links()) {\n@@ -1825,7 +1974,23 @@ bool PipelineHandlerMaliC55::match(DeviceEnumerator *enumerator)\n \n \t\t\tbreak;\n \t\tcase MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER:\n-\t\t\tLOG(MaliC55, Warning) << \"Memory input not yet supported\";\n+\t\t\tif (!cruMedia_)\n+\t\t\t\treturn false;\n+\n+\t\t\tivc_ = V4L2Subdevice::fromEntityName(media_.get(),\n+\t\t\t\t\t\t\t     \"rzv2h ivc block\");\n+\t\t\tif (ivc_->open() < 0)\n+\t\t\t\treturn false;\n+\n+\t\t\tinput_ = V4L2VideoDevice::fromEntityName(media_.get(),\n+\t\t\t\t\t\t\t\t \"rzv2h-ivc\");\n+\t\t\tif (input_->open() < 0)\n+\t\t\t\treturn false;\n+\n+\t\t\tregistered = registerMemoryInputCamera();\n+\t\t\tif (!registered)\n+\t\t\t\treturn registered;\n+\n \t\t\tbreak;\n \t\tdefault:\n \t\t\tLOG(MaliC55, Error) << \"Unsupported entity function\";\n",
    "prefixes": [
        "v2",
        "3/7"
    ]
}