Patch Detail
Show a patch.
GET /api/patches/25373/?format=api
{ "id": 25373, "url": "https://patchwork.libcamera.org/api/patches/25373/?format=api", "web_url": "https://patchwork.libcamera.org/patch/25373/", "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": "<20251205-mali-cru-v1-2-d81bb5ffe73a@ideasonboard.com>", "date": "2025-12-05T14:52:08", "name": "[2/7] libcamera: mali-c55: Split TPG and Inline camera handling", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": false, "hash": "d38df9e3376eba4da649008003ba0bbe74d6979b", "submitter": { "id": 143, "url": "https://patchwork.libcamera.org/api/people/143/?format=api", "name": "Jacopo Mondi", "email": "jacopo.mondi@ideasonboard.com" }, "delegate": null, "mbox": "https://patchwork.libcamera.org/patch/25373/mbox/", "series": [ { "id": 5640, "url": "https://patchwork.libcamera.org/api/series/5640/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=5640", "date": "2025-12-05T14:52:06", "name": "libcamera: mali-c55: Add support for memory-to-memory", "version": 1, "mbox": "https://patchwork.libcamera.org/series/5640/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/25373/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/25373/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 B20B8BD80A\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 5 Dec 2025 14:52:39 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id BD467613DA;\n\tFri, 5 Dec 2025 15:52:34 +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 3D9EB611BA\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 5 Dec 2025 15:52:31 +0100 (CET)", "from [192.168.1.4] (net-93-65-100-155.cust.vodafonedsl.it\n\t[93.65.100.155])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 9CE9AE7C;\n\tFri, 5 Dec 2025 15:50:14 +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=\"k/m5f48R\"; dkim-atps=neutral", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1764946214;\n\tbh=/1F1iRZXbLowSjqdNb+I6FehS3zf86nbjM1hxdB7mRM=;\n\th=From:Date:Subject:References:In-Reply-To:To:Cc:From;\n\tb=k/m5f48RIAGaCFAihc3D4SbCRwcyCSXaKr9mJTwYzz0J+nv2tt7fgE5GAPVw/mLfD\n\twxJwyxh80wPIOa0nmIn5GotygEeb2Rm1NOT2PpwmKG81NcK2DtcZ84VuJX9iRk7fr2\n\t9yNOwjyuvPPBTrwrjmfRq0dv+VKGq6ANdPt8o50c=", "From": "Jacopo Mondi <jacopo.mondi@ideasonboard.com>", "Date": "Fri, 05 Dec 2025 15:52:08 +0100", "Subject": "[PATCH 2/7] libcamera: mali-c55: Split TPG and Inline camera\n\thandling", "MIME-Version": "1.0", "Content-Type": "text/plain; charset=\"utf-8\"", "Content-Transfer-Encoding": "7bit", "Message-Id": "<20251205-mali-cru-v1-2-d81bb5ffe73a@ideasonboard.com>", "References": "<20251205-mali-cru-v1-0-d81bb5ffe73a@ideasonboard.com>", "In-Reply-To": "<20251205-mali-cru-v1-0-d81bb5ffe73a@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=15652;\n\ti=jacopo.mondi@ideasonboard.com; h=from:subject:message-id;\n\tbh=/1F1iRZXbLowSjqdNb+I6FehS3zf86nbjM1hxdB7mRM=;\n\tb=owEBbQKS/ZANAwAKAXI0Bo8WoVY8AcsmYgBpMvGsvazwL5+i78/vL5P+m8gDxyGW+XQcELwRQ\n\tEu6yyIgDzuJAjMEAAEKAB0WIQS1xD1IgJogio9YOMByNAaPFqFWPAUCaTLxrAAKCRByNAaPFqFW\n\tPOwtD/9wVRlRMrBS4vBukOWDvgRVVgB/kdL+b+7pmkYDWsYVsN4naSV7aXoXk8FUN/ML+Z3FDME\n\t00iG7FEcPyGruH5Jc7CqiulVG3I7FIbTN99DAzDsJeM/KeI7YjzthH4QjgeEheImLn0XyC4IcYJ\n\tjlmdMfvfy/vmN/wYaD9+jJUK4iZWlj01CQnENyEB0YTflLEuQb47rVZye/WfAq96fPC2jq7APfq\n\tzysvm+qSdG+MpDynAX3YYAF/7TnJd5sD+mr7rxAliDzn6XPE9KmoUIsTlxmChPn6aJ3XRHKFJqj\n\tbnXdqcyUdCCPPBjvfCwe5gbEiuKvWEvSe/cKC4JYI+vDfWrQHOVTRUkLnCmXCQW+CeMTiLYFMiV\n\thLEAKGrYFMeIB8dHvRrANBrBMEgRlBzzJhOrVVQnxgYVLOJKA8/jG4GZzkssThyW2mUYAa8DN+o\n\t6bDfWGLdqn7YhdLiiPjd3l7nSyAXBo/w9weAmWWJgWl58tEIJhX8HG2TtKvMNT9T1F97seaO8rK\n\tJbbgMwBIyYxrcBDk8bhbcbsguZ+aAY7GPrvMdqBJDbgTN091v2c+f68Jwgb6SY6gNOn/C22LEyo\n\tlT0g+h2SRMKQPgGyxZHfhXYKZ63f7WJ4I6VKImctbetiL5DOZ80Gnj3XQTaaxGhAZM5UZYY0ROg\n\tiGGSjS4HhoQSXxw==", "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": "In order to prepare to support memory input cameras, split the handling of\nthe TPG and Inline camera cases.\n\nThe Mali C55 pipeline handler uses the entity and subdevice stored in the\nCameraData to support both the handling of the TPG and of the [CSI-2 +\nsensor] use cases. Adding support for memory cameras by using the CRU unit\nwould add yet-another special case making the code harder to follow and\nmore prone to errors.\n\nSplit the handling of the TPG and inline cameras by introducing an\nenumeration for the camera operation modes, separating data into anonymous\nstructures and handling the configuration and linking of the media graphs\nseparately.\n\nSigned-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>\n---\n src/libcamera/pipeline/mali-c55/mali-c55.cpp | 236 +++++++++++++++------------\n 1 file changed, 135 insertions(+), 101 deletions(-)", "diff": "diff --git a/src/libcamera/pipeline/mali-c55/mali-c55.cpp b/src/libcamera/pipeline/mali-c55/mali-c55.cpp\nindex cf0cb15f8bb39143eea38aa8acb8d2b1268f5530..801067ce00fe4e0fd6b81db699fcaed2ebb840b6 100644\n--- a/src/libcamera/pipeline/mali-c55/mali-c55.cpp\n+++ b/src/libcamera/pipeline/mali-c55/mali-c55.cpp\n@@ -92,17 +92,22 @@ struct MaliC55FrameInfo {\n class MaliC55CameraData : public Camera::Private\n {\n public:\n-\tMaliC55CameraData(PipelineHandler *pipe, MediaEntity *entity)\n-\t\t: Camera::Private(pipe), entity_(entity)\n+\tenum CameraType {\n+\t\tTPG,\n+\t\tInline,\n+\t};\n+\n+\tMaliC55CameraData(PipelineHandler *pipe)\n+\t\t: Camera::Private(pipe)\n \t{\n \t}\n \n-\tint init();\n \tint loadIPA();\n \n \t/* Deflect these functionalities to either TPG or CameraSensor. */\n \tstd::vector<Size> sizes(unsigned int mbusCode) const;\n \tSize resolution() const;\n+\tV4L2Subdevice *subdev() const;\n \n \tint pixfmtToMbusCode(const PixelFormat &pixFmt) const;\n \tconst PixelFormat &bestRawFormat() const;\n@@ -112,11 +117,9 @@ public:\n \tPixelFormat adjustRawFormat(const PixelFormat &pixFmt) const;\n \tSize adjustRawSizes(const PixelFormat &pixFmt, const Size &rawSize) const;\n \n-\tstd::unique_ptr<CameraSensor> sensor_;\n+\tint initTPG(MediaEntity *tpg);\n+\tint initInlineCamera(MediaEntity *sensor);\n \n-\tMediaEntity *entity_;\n-\tstd::unique_ptr<V4L2Subdevice> csi_;\n-\tstd::unique_ptr<V4L2Subdevice> sd_;\n \tStream frStream_;\n \tStream dsStream_;\n \n@@ -126,68 +129,71 @@ public:\n \n \tstd::unique_ptr<DelayedControls> delayedCtrls_;\n \n+\tstruct {\n+\t\tSize resolution_;\n+\t\tstd::unique_ptr<V4L2Subdevice> sd_;\n+\t} tpgInput;\n+\n+\tstruct {\n+\t\tstd::unique_ptr<V4L2Subdevice> csi2_;\n+\t\tstd::unique_ptr<CameraSensor> sensor_;\n+\t} inlineInput;\n+\n+\tCameraType input_;\n+\n private:\n-\tvoid initTPGData();\n \tvoid setSensorControls(const ControlList &sensorControls);\n-\n \tstd::string id_;\n-\tSize tpgResolution_;\n };\n \n-int MaliC55CameraData::init()\n+int MaliC55CameraData::initTPG(MediaEntity *tpg)\n {\n-\tint ret;\n-\n-\tsd_ = std::make_unique<V4L2Subdevice>(entity_);\n-\tret = sd_->open();\n+\ttpgInput.sd_ = std::make_unique<V4L2Subdevice>(tpg);\n+\tint ret = tpgInput.sd_->open();\n \tif (ret) {\n-\t\tLOG(MaliC55, Error) << \"Failed to open sensor subdevice\";\n+\t\tLOG(MaliC55, Error) << \"Failed to open TPG subdevice\";\n \t\treturn ret;\n \t}\n \n-\t/* If this camera is created from TPG, we return here. */\n-\tif (entity_->name() == \"mali-c55 tpg\") {\n-\t\tinitTPGData();\n-\t\treturn 0;\n-\t}\n-\n-\t/*\n-\t * Register a CameraSensor if we connect to a sensor and create\n-\t * an entity for the connected CSI-2 receiver.\n-\t */\n-\tsensor_ = CameraSensorFactoryBase::create(entity_);\n-\tif (!sensor_)\n-\t\treturn -ENODEV;\n+\t/* Replicate the CameraSensor implementation for TPG. */\n+\tV4L2Subdevice::Formats formats = tpgInput.sd_->formats(0);\n+\tif (formats.empty())\n+\t\treturn -EINVAL;\n \n-\tconst MediaPad *sourcePad = entity_->getPadByIndex(0);\n-\tMediaEntity *csiEntity = sourcePad->links()[0]->sink()->entity();\n+\tstd::vector<Size> tpgSizes;\n \n-\tcsi_ = std::make_unique<V4L2Subdevice>(csiEntity);\n-\tret = csi_->open();\n-\tif (ret) {\n-\t\tLOG(MaliC55, Error) << \"Failed to open CSI-2 subdevice\";\n-\t\treturn ret;\n+\tfor (const auto &format : formats) {\n+\t\tconst std::vector<SizeRange> &ranges = format.second;\n+\t\tstd::transform(ranges.begin(), ranges.end(), std::back_inserter(tpgSizes),\n+\t\t\t [](const SizeRange &range) { return range.max; });\n \t}\n \n+\ttpgInput.resolution_ = tpgSizes.back();\n+\tinput_ = TPG;\n+\n \treturn 0;\n }\n \n-void MaliC55CameraData::initTPGData()\n+int MaliC55CameraData::initInlineCamera(MediaEntity *sensor)\n {\n-\t/* Replicate the CameraSensor implementation for TPG. */\n-\tV4L2Subdevice::Formats formats = sd_->formats(0);\n-\tif (formats.empty())\n-\t\treturn;\n+\t/* Register a CameraSensor create an entity for the CSI-2 receiver. */\n+\tinlineInput.sensor_ = CameraSensorFactoryBase::create(sensor);\n+\tif (!inlineInput.sensor_)\n+\t\treturn -ENODEV;\n \n-\tstd::vector<Size> tpgSizes;\n+\tconst MediaPad *sourcePad = sensor->getPadByIndex(0);\n+\tMediaEntity *csiEntity = sourcePad->links()[0]->sink()->entity();\n \n-\tfor (const auto &format : formats) {\n-\t\tconst std::vector<SizeRange> &ranges = format.second;\n-\t\tstd::transform(ranges.begin(), ranges.end(), std::back_inserter(tpgSizes),\n-\t\t\t [](const SizeRange &range) { return range.max; });\n+\tinlineInput.csi2_ = std::make_unique<V4L2Subdevice>(csiEntity);\n+\tint ret = inlineInput.csi2_->open();\n+\tif (ret) {\n+\t\tLOG(MaliC55, Error) << \"Failed to open CSI-2 subdevice\";\n+\t\treturn ret;\n \t}\n \n-\ttpgResolution_ = tpgSizes.back();\n+\tinput_ = Inline;\n+\n+\treturn 0;\n }\n \n void MaliC55CameraData::setSensorControls(const ControlList &sensorControls)\n@@ -197,10 +203,10 @@ void MaliC55CameraData::setSensorControls(const ControlList &sensorControls)\n \n std::vector<Size> MaliC55CameraData::sizes(unsigned int mbusCode) const\n {\n-\tif (sensor_)\n-\t\treturn sensor_->sizes(mbusCode);\n+\tif (input_ == Inline)\n+\t\treturn inlineInput.sensor_->sizes(mbusCode);\n \n-\tV4L2Subdevice::Formats formats = sd_->formats(0);\n+\tV4L2Subdevice::Formats formats = tpgInput.sd_->formats(0);\n \tif (formats.empty())\n \t\treturn {};\n \n@@ -220,10 +226,28 @@ std::vector<Size> MaliC55CameraData::sizes(unsigned int mbusCode) const\n \n Size MaliC55CameraData::resolution() const\n {\n-\tif (sensor_)\n-\t\treturn sensor_->resolution();\n+\tswitch (input_) {\n+\tcase TPG:\n+\t\treturn tpgInput.resolution_;\n+\tcase Inline:\n+\t\treturn inlineInput.sensor_->resolution();\n+\t}\n+\n+\tassert(false);\n+\treturn {};\n+}\n+\n+V4L2Subdevice *MaliC55CameraData::subdev() const\n+{\n+\tswitch (input_) {\n+\tcase TPG:\n+\t\treturn tpgInput.sd_.get();\n+\tcase Inline:\n+\t\treturn inlineInput.sensor_->device();\n+\t}\n \n-\treturn tpgResolution_;\n+\tassert(false);\n+\treturn nullptr;\n }\n \n /*\n@@ -242,7 +266,8 @@ int MaliC55CameraData::pixfmtToMbusCode(const PixelFormat &pixFmt) const\n \tif (!bayerFormat.isValid())\n \t\treturn -EINVAL;\n \n-\tV4L2Subdevice::Formats formats = sd_->formats(0);\n+\tV4L2Subdevice *sd = subdev();\n+\tV4L2Subdevice::Formats formats = sd->formats(0);\n \tunsigned int sensorMbusCode = 0;\n \tunsigned int bitDepth = 0;\n \n@@ -280,7 +305,8 @@ const PixelFormat &MaliC55CameraData::bestRawFormat() const\n {\n \tstatic const PixelFormat invalidPixFmt = {};\n \n-\tfor (const auto &fmt : sd_->formats(0)) {\n+\tV4L2Subdevice *sd = subdev();\n+\tfor (const auto &fmt : sd->formats(0)) {\n \t\tBayerFormat sensorBayer = BayerFormat::fromMbusCode(fmt.first);\n \n \t\tif (!sensorBayer.isValid())\n@@ -302,11 +328,11 @@ const PixelFormat &MaliC55CameraData::bestRawFormat() const\n \n void MaliC55CameraData::updateControls(const ControlInfoMap &ipaControls)\n {\n-\tif (!sensor_)\n+\tif (input_ == TPG)\n \t\treturn;\n \n \tIPACameraSensorInfo sensorInfo;\n-\tint ret = sensor_->sensorInfo(&sensorInfo);\n+\tint ret = inlineInput.sensor_->sensorInfo(&sensorInfo);\n \tif (ret) {\n \t\tLOG(MaliC55, Error) << \"Failed to retrieve sensor info\";\n \t\treturn;\n@@ -379,7 +405,7 @@ int MaliC55CameraData::loadIPA()\n \tint ret;\n \n \t/* Do not initialize IPA for TPG. */\n-\tif (!sensor_)\n+\tif (input_ == TPG)\n \t\treturn 0;\n \n \tipa_ = IPAManager::createIPA<ipa::mali_c55::IPAProxyMaliC55>(pipe(), 1, 1);\n@@ -388,20 +414,21 @@ int MaliC55CameraData::loadIPA()\n \n \tipa_->setSensorControls.connect(this, &MaliC55CameraData::setSensorControls);\n \n-\tstd::string ipaTuningFile = ipa_->configurationFile(sensor_->model() + \".yaml\",\n+\tCameraSensor *sensor = inlineInput.sensor_.get();\n+\tstd::string ipaTuningFile = ipa_->configurationFile(sensor->model() + \".yaml\",\n \t\t\t\t\t\t\t \"uncalibrated.yaml\");\n \n \t/* We need to inform the IPA of the sensor configuration */\n \tipa::mali_c55::IPAConfigInfo ipaConfig{};\n \n-\tret = sensor_->sensorInfo(&ipaConfig.sensorInfo);\n+\tret = sensor->sensorInfo(&ipaConfig.sensorInfo);\n \tif (ret)\n \t\treturn ret;\n \n-\tipaConfig.sensorControls = sensor_->controls();\n+\tipaConfig.sensorControls = sensor->controls();\n \n \tControlInfoMap ipaControls;\n-\tret = ipa_->init({ ipaTuningFile, sensor_->model() }, ipaConfig,\n+\tret = ipa_->init({ ipaTuningFile, sensor->model() }, ipaConfig,\n \t\t\t &ipaControls);\n \tif (ret) {\n \t\tLOG(MaliC55, Error) << \"Failed to initialise the Mali-C55 IPA\";\n@@ -444,13 +471,14 @@ CameraConfiguration::Status MaliC55CameraConfiguration::validate()\n \t * The TPG doesn't support flips, so we only need to calculate a\n \t * transform if we have a sensor.\n \t */\n-\tif (data_->sensor_) {\n+\tif (data_->input_ == MaliC55CameraData::TPG) {\n+\t\tcombinedTransform_ = Transform::Rot0;\n+\t} else {\n \t\tOrientation requestedOrientation = orientation;\n-\t\tcombinedTransform_ = data_->sensor_->computeTransform(&orientation);\n+\t\tcombinedTransform_ =\n+\t\t\tdata_->inlineInput.sensor_->computeTransform(&orientation);\n \t\tif (orientation != requestedOrientation)\n \t\t\tstatus = Adjusted;\n-\t} else {\n-\t\tcombinedTransform_ = Transform::Rot0;\n \t}\n \n \t/* Only 2 streams available. */\n@@ -927,11 +955,17 @@ int PipelineHandlerMaliC55::configure(Camera *camera,\n \n \t/* Link the graph depending if we are operating the TPG or a sensor. */\n \tMaliC55CameraData *data = cameraData(camera);\n-\tif (data->csi_) {\n-\t\tconst MediaEntity *csiEntity = data->csi_->entity();\n-\t\tret = csiEntity->getPadByIndex(1)->links()[0]->setEnabled(true);\n-\t} else {\n-\t\tret = data->entity_->getPadByIndex(0)->links()[0]->setEnabled(true);\n+\tswitch (data->input_) {\n+\tcase MaliC55CameraData::TPG: {\n+\t\tconst MediaEntity *tpgEntity = data->tpgInput.sd_->entity();\n+\t\tret = tpgEntity->getPadByIndex(0)->links()[0]->setEnabled(true);\n+\t\tbreak;\n+\t}\n+\tcase MaliC55CameraData::Inline: {\n+\t\tconst MediaEntity *csi2Entity = data->inlineInput.csi2_->entity();\n+\t\tret = csi2Entity->getPadByIndex(1)->links()[0]->setEnabled(true);\n+\t\tbreak;\n+\t}\n \t}\n \tif (ret)\n \t\treturn ret;\n@@ -939,26 +973,28 @@ int PipelineHandlerMaliC55::configure(Camera *camera,\n \tMaliC55CameraConfiguration *maliConfig =\n \t\tstatic_cast<MaliC55CameraConfiguration *>(config);\n \tV4L2SubdeviceFormat subdevFormat = maliConfig->sensorFormat_;\n-\tret = data->sd_->getFormat(0, &subdevFormat);\n-\tif (ret)\n-\t\treturn ret;\n \n-\tif (data->sensor_) {\n-\t\tret = data->sensor_->setFormat(&subdevFormat,\n-\t\t\t\t\t maliConfig->combinedTransform());\n+\t/* Apply format to the origin of the pipeline and propagate it. */\n+\tswitch (data->input_) {\n+\tcase MaliC55CameraData::TPG:\n+\t\tret = data->tpgInput.sd_->setFormat(0, &subdevFormat);\n+\t\tbreak;\n+\tcase MaliC55CameraData::Inline:\n+\t\tret = data->inlineInput.sensor_->setFormat(&subdevFormat,\n+\t\t\t\t\t\t\t maliConfig->combinedTransform());\n \t\tif (ret)\n \t\t\treturn ret;\n-\t}\n \n-\tif (data->csi_) {\n-\t\tret = data->csi_->setFormat(0, &subdevFormat);\n+\t\tret = data->inlineInput.csi2_->setFormat(0, &subdevFormat);\n \t\tif (ret)\n \t\t\treturn ret;\n \n-\t\tret = data->csi_->getFormat(1, &subdevFormat);\n-\t\tif (ret)\n-\t\t\treturn ret;\n+\t\tret = data->inlineInput.csi2_->getFormat(1, &subdevFormat);\n+\n+\t\tbreak;\n \t}\n+\tif (ret)\n+\t\treturn ret;\n \n \tV4L2DeviceFormat statsFormat;\n \tret = stats_->getFormat(&statsFormat);\n@@ -973,8 +1009,6 @@ int PipelineHandlerMaliC55::configure(Camera *camera,\n \t/*\n \t * Propagate the format to the ISP sink pad and configure the input\n \t * crop rectangle (no crop at the moment).\n-\t *\n-\t * \\todo Configure the CSI-2 receiver.\n \t */\n \tret = isp_->setFormat(0, &subdevFormat);\n \tif (ret)\n@@ -1058,18 +1092,19 @@ int PipelineHandlerMaliC55::configure(Camera *camera,\n \t/* We need to inform the IPA of the sensor configuration */\n \tipa::mali_c55::IPAConfigInfo ipaConfig{};\n \n-\tret = data->sensor_->sensorInfo(&ipaConfig.sensorInfo);\n+\tret = data->inlineInput.sensor_->sensorInfo(&ipaConfig.sensorInfo);\n \tif (ret)\n \t\treturn ret;\n \n-\tipaConfig.sensorControls = data->sensor_->controls();\n+\tipaConfig.sensorControls = data->inlineInput.sensor_->controls();\n \n \t/*\n \t * And we also need to tell the IPA the bayerOrder of the data (as\n \t * affected by any flips that we've configured)\n \t */\n \tconst Transform &combinedTransform = maliConfig->combinedTransform();\n-\tBayerFormat::Order bayerOrder = data->sensor_->bayerOrder(combinedTransform);\n+\tBayerFormat::Order bayerOrder =\n+\t\tdata->inlineInput.sensor_->bayerOrder(combinedTransform);\n \n \tControlInfoMap ipaControls;\n \tret = data->ipa_->configure(ipaConfig, utils::to_underlying(bayerOrder),\n@@ -1283,7 +1318,7 @@ void PipelineHandlerMaliC55::applyScalerCrop(Camera *camera,\n \tif (!scalerCrop)\n \t\treturn;\n \n-\tif (!data->sensor_) {\n+\tif (data->input_ == MaliC55CameraData::TPG) {\n \t\tLOG(MaliC55, Error) << \"ScalerCrop not supported for TPG\";\n \t\treturn;\n \t}\n@@ -1291,7 +1326,7 @@ void PipelineHandlerMaliC55::applyScalerCrop(Camera *camera,\n \tRectangle nativeCrop = *scalerCrop;\n \n \tIPACameraSensorInfo sensorInfo;\n-\tint ret = data->sensor_->sensorInfo(&sensorInfo);\n+\tint ret = data->inlineInput.sensor_->sensorInfo(&sensorInfo);\n \tif (ret) {\n \t\tLOG(MaliC55, Error) << \"Failed to retrieve sensor info\";\n \t\treturn;\n@@ -1572,10 +1607,8 @@ bool PipelineHandlerMaliC55::registerTPGCamera(MediaLink *link)\n \t\treturn true;\n \t}\n \n-\tstd::unique_ptr<MaliC55CameraData> data =\n-\t\tstd::make_unique<MaliC55CameraData>(this, link->source()->entity());\n-\n-\tif (data->init())\n+\tstd::unique_ptr<MaliC55CameraData> data = std::make_unique<MaliC55CameraData>(this);\n+\tif (data->initTPG(link->source()->entity()))\n \t\treturn false;\n \n \treturn registerMaliCamera(std::move(data), name);\n@@ -1600,21 +1633,22 @@ bool PipelineHandlerMaliC55::registerSensorCamera(MediaLink *ispLink)\n \t\t\tcontinue;\n \n \t\tstd::unique_ptr<MaliC55CameraData> data =\n-\t\t\tstd::make_unique<MaliC55CameraData>(this, sensor);\n-\t\tif (data->init())\n+\t\t\tstd::make_unique<MaliC55CameraData>(this);\n+\t\tif (data->initInlineCamera(sensor))\n \t\t\treturn false;\n \n-\t\tdata->properties_ = data->sensor_->properties();\n+\t\tdata->properties_ = data->inlineInput.sensor_->properties();\n \n-\t\tconst CameraSensorProperties::SensorDelays &delays = data->sensor_->sensorDelays();\n+\t\tconst CameraSensorProperties::SensorDelays &delays =\n+\t\t\tdata->inlineInput.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\tdata->delayedCtrls_ =\n-\t\t\tstd::make_unique<DelayedControls>(data->sensor_->device(),\n-\t\t\t\t\t\t\t params);\n+\t\tV4L2Subdevice *sensorSubdev = data->inlineInput.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\t\t\t\t &DelayedControls::applyControls);\n \n", "prefixes": [ "2/7" ] }