Show a patch.

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

{
    "id": 25475,
    "url": "https://patchwork.libcamera.org/api/patches/25475/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/25475/",
    "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": "<20251210164055.17856-11-david.plowman@raspberrypi.com>",
    "date": "2025-12-10T16:15:25",
    "name": "[10/11] pipeline: rpi: Support memory cameras",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "1aa919640fd7221dd5a951b9192267684acf4328",
    "submitter": {
        "id": 42,
        "url": "https://patchwork.libcamera.org/api/people/42/?format=api",
        "name": "David Plowman",
        "email": "david.plowman@raspberrypi.com"
    },
    "delegate": null,
    "mbox": "https://patchwork.libcamera.org/patch/25475/mbox/",
    "series": [
        {
            "id": 5650,
            "url": "https://patchwork.libcamera.org/api/series/5650/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=5650",
            "date": "2025-12-10T16:15:15",
            "name": "Bayer re-processing",
            "version": 1,
            "mbox": "https://patchwork.libcamera.org/series/5650/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/25475/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/25475/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 80693C32DE\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 10 Dec 2025 16:41:14 +0000 (UTC)",
            "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 3F42A61595;\n\tWed, 10 Dec 2025 17:41:14 +0100 (CET)",
            "from mail-wm1-x332.google.com (mail-wm1-x332.google.com\n\t[IPv6:2a00:1450:4864:20::332])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 0C2E0614B1\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 10 Dec 2025 17:41:08 +0100 (CET)",
            "by mail-wm1-x332.google.com with SMTP id\n\t5b1f17b1804b1-47795f6f5c0so46406035e9.1\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 10 Dec 2025 08:41:08 -0800 (PST)",
            "from davidp-pi5.pitowers.org\n\t([2a00:1098:3142:1f:88ea:c658:5b20:5e46])\n\tby smtp.gmail.com with ESMTPSA id\n\t5b1f17b1804b1-47a88371e13sm1270415e9.11.2025.12.10.08.41.06\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tWed, 10 Dec 2025 08:41:06 -0800 (PST)"
        ],
        "Authentication-Results": "lancelot.ideasonboard.com; dkim=pass (2048-bit key;\n\tunprotected) header.d=raspberrypi.com header.i=@raspberrypi.com\n\theader.b=\"iMgkf0wR\"; dkim-atps=neutral",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=raspberrypi.com; s=google; t=1765384867; x=1765989667;\n\tdarn=lists.libcamera.org; \n\th=content-transfer-encoding:mime-version:references:in-reply-to\n\t:message-id:date:subject:cc:to:from:from:to:cc:subject:date\n\t:message-id:reply-to;\n\tbh=4ltnT0SLnKxShoSiZLAZpMr3VNz5MfJiqnPTdurewV0=;\n\tb=iMgkf0wRD2/UvybjARqfItqdvLOqFBVuAnYV/qe6wmlXa/SP6By8PeJqdAxlOdfq4j\n\tJOdAzR8GFe7wyHhEOZNNZ5A3bhlx040sjiSixxpIoeDbimyq1CVX77WTG7Frmn4lf8mg\n\tcrOWhbwAstPf/lN5DZPw0gtALBxqebBGA6Pxep8EA/yKGUFh9FKgq+35y8IlbW4DsubC\n\tdLOUzsd0P50lktO2lSvzLkV82qLSH4WHZ3zZ+PzfTV6JOEaMajJVWvCzOKMghmpoiLWt\n\tIs/xVmpo4VYTGQWtbK/EFjibPXlvZvrxh8VpRc7gyWxXlzm2EAHSabb0DiP87riPiH4L\n\ttSrw==",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20230601; t=1765384867; x=1765989667;\n\th=content-transfer-encoding:mime-version:references:in-reply-to\n\t:message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from\n\t:to:cc:subject:date:message-id:reply-to;\n\tbh=4ltnT0SLnKxShoSiZLAZpMr3VNz5MfJiqnPTdurewV0=;\n\tb=ubrOZmdELWCZ5jRbDpagBCpeu9Sckx10r5gYHiAIlNskYRe9AEYMfxYKO4J2LiXRsl\n\tnxpST7tbWU7jGFEru9mn0XwyFT6A6Z/6tV2Vayafpo1WpBH9yRZU92EhKK2E4Nn61UHj\n\thdAbfKwgI6uUUCuW5wDWANd4d8de55tp4tdlTFDrWhlaMgEk3tAZLsmBzxNqCkA8CKGk\n\theakEhXBcX5G5+e80Uuq9u8BSStLf6v2SsMj8b5695QeaTf9BPS/sqW0KthSL7uhu/Dy\n\tUEJUpQnqXoAxBBOjY5JdmDTkSeEfU2jk0wXwnUOHyPlQ1TSTzy/EoWaRNCiWd9Xd+gXE\n\tRJTQ==",
        "X-Gm-Message-State": "AOJu0YxMV3s4UGoeVpx+TJl+r8e/EfZHhGeJOeJdW4MMxsA/ylN+3uYT\n\tSR27gq6ZRbjyel1JZooQBrBxOuu/aUyBcm7dlnTcDqlLyPudOUz+9ckS9tMsduYLB5izSkuoCV7\n\tiK8+/",
        "X-Gm-Gg": "ASbGncv9+dTw6T18tOmq6r7NJHVZqc9GfIKGN7jgnBzt/i/CMLdy72cYHL7u/wks1CY\n\tA+8pGhW08ulO7VonL47CcbNBidC2bt0Fxl1/V/KzDzUMySKLwQBIgIHQWyyUuBxV2HMhaf/7Ac2\n\tUn6oje5+o4b/Duzh5wsdg6En3AUmKb9PYHjYexcEb4Ns7Dh6kluPf9GNPMjljeCHArRxFcpVvYZ\n\tcmX3S2VxVGc/zUKe+ks33TXaDGFg51hbuuMzfAo0SkLAO6uY+SAZRaVM4YxHB/VT1BnxbRJOpap\n\t3crsRh0PdNetp2yuahgoPJXLwZ8122fsuVgEIGO8fQst8LcPLmZ128PGDkB4xrk2ncvLD6F5SY1\n\tzNrYqXmAgSQckOFFdzMftHmWdhsfpFbeVsFIpRFE0ftAKScZssyNxQEhDBOIoX0Zp8F6mQJ/PJ9\n\trUUKxnn7HcidXPcC5cLkxkY56zvqCUdZQaeSXif/CHPcQDKCp6yldHbiw67fAFIN7JJsyBPg6kb\n\t6eQUq3H4pXGIxarPe4z5dylVkOrFS4g2WthM/qm",
        "X-Google-Smtp-Source": "AGHT+IF1maZPO5gPAzBl4nUdrtf6FV1kCXUNsvAQCQP2+YJKs5CAypjFEHy4aW0NyeVnwfOPGPHFFA==",
        "X-Received": "by 2002:a05:600c:3587:b0:477:7b9a:bb0a with SMTP id\n\t5b1f17b1804b1-47a85ea3ff7mr14888085e9.21.1765384867116; \n\tWed, 10 Dec 2025 08:41:07 -0800 (PST)",
        "From": "David Plowman <david.plowman@raspberrypi.com>",
        "To": "libcamera-devel@lists.libcamera.org",
        "Cc": "David Plowman <david.plowman@raspberrypi.com>",
        "Subject": "[PATCH 10/11] pipeline: rpi: Support memory cameras",
        "Date": "Wed, 10 Dec 2025 16:15:25 +0000",
        "Message-ID": "<20251210164055.17856-11-david.plowman@raspberrypi.com>",
        "X-Mailer": "git-send-email 2.47.3",
        "In-Reply-To": "<20251210164055.17856-1-david.plowman@raspberrypi.com>",
        "References": "<20251210164055.17856-1-david.plowman@raspberrypi.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "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": "Mostly small changes to support memory cameras (for Bayer reprocessing)\nin the pipeline handler.\n\nFirstly, we make a \"CameraSensorMemory\" as the sensor as soon as we\nhave the raw input buffer configuration, which helps the rest of the\ncode to work with fewer changes.\n\nThe PiSP platformConfigure method is refactored to split the Cfe and\nIsp parts into separate functions. Memory cameras then omit\nplatformConfigureCfe but run platformConfigureIsp as before.\n\nSigned-off-by: David Plowman <david.plowman@raspberrypi.com>\n---\n .../pipeline/rpi/common/pipeline_base.cpp     |  36 ++++-\n .../pipeline/rpi/common/pipeline_base.h       |   4 +-\n src/libcamera/pipeline/rpi/pisp/pisp.cpp      | 141 ++++++++++++------\n 3 files changed, 124 insertions(+), 57 deletions(-)",
    "diff": "diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp\nindex 76bcb2a4..2f02ec4c 100644\n--- a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp\n+++ b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp\n@@ -20,6 +20,7 @@\n #include <libcamera/property_ids.h>\n \n #include \"libcamera/internal/camera_lens.h\"\n+#include \"libcamera/internal/camera_sensor_memory.h\"\n #include \"libcamera/internal/ipa_manager.h\"\n #include \"libcamera/internal/v4l2_subdevice.h\"\n \n@@ -170,15 +171,9 @@ CameraConfiguration::Status RPiCameraConfiguration::validate()\n \tstatus = validateColorSpaces(ColorSpaceFlag::StreamsShareColorSpace);\n \n \t/*\n-\t * Validate the requested transform against the sensor capabilities and\n-\t * rotation and store the final combined transform that configure() will\n-\t * need to apply to the sensor to save us working it out again.\n+\t * Separate the raw and output streams first, to make it easier to\n+\t * detect the raw reprocessing use case.\n \t */\n-\tOrientation requestedOrientation = orientation;\n-\tcombinedTransform_ = data_->sensor_->computeTransform(&orientation);\n-\tif (orientation != requestedOrientation)\n-\t\tstatus = Adjusted;\n-\n \trawStreams_.clear();\n \toutStreams_.clear();\n \tunsigned int rawStreamIndex = 0;\n@@ -191,6 +186,31 @@ CameraConfiguration::Status RPiCameraConfiguration::validate()\n \t\t\toutStreams_.emplace_back(outStreamIndex++, &cfg);\n \t}\n \n+\t/*\n+\t * For the reprocessing use case, make a \"memory camera\" to match the\n+\t * raw input buffer. This will make all the subsequent code run more like\n+\t * the regular sensor case.\n+\t */\n+\tif (!rawStreams_.empty() && rawStreams_[0].cfg->isInput()) {\n+\t\tLOG(RPI, Debug) << \"Raw reprocessing use case for \" << *rawStreams_[0].cfg;\n+\t\tconst StreamConfiguration &rawInput = *rawStreams_[0].cfg;\n+\t\tBayerFormat bayerFormat = BayerFormat::fromPixelFormat(rawInput.pixelFormat);\n+\t\tunsigned int mbusCode = PipelineHandlerBase::bayerToMbusCode(bayerFormat);\n+\t\tdata_->sensor_ = std::make_unique<CameraSensorMemory>(rawInput, mbusCode);\n+\t\t/* We can fill in the only sensor format we support! */\n+\t\tdata_->sensorFormats_.emplace(mbusCode, data_->sensor_->sizes(mbusCode));\n+\t}\n+\n+\t/*\n+\t * Validate the requested transform against the sensor capabilities and\n+\t * rotation and store the final combined transform that configure() will\n+\t * need to apply to the sensor to save us working it out again.\n+\t */\n+\tOrientation requestedOrientation = orientation;\n+\tcombinedTransform_ = data_->sensor_->computeTransform(&orientation);\n+\tif (orientation != requestedOrientation)\n+\t\tstatus = Adjusted;\n+\n \t/* Sort the streams so the highest resolution is first. */\n \tstd::sort(rawStreams_.begin(), rawStreams_.end(),\n \t\t  [](auto &l, auto &r) { return l.cfg->size > r.cfg->size; });\ndiff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.h b/src/libcamera/pipeline/rpi/common/pipeline_base.h\nindex 9453ae7e..76a269bd 100644\n--- a/src/libcamera/pipeline/rpi/common/pipeline_base.h\n+++ b/src/libcamera/pipeline/rpi/common/pipeline_base.h\n@@ -250,7 +250,7 @@ private:\n class RPiCameraConfiguration final : public CameraConfiguration\n {\n public:\n-\tRPiCameraConfiguration(const CameraData *data)\n+\tRPiCameraConfiguration(CameraData *data)\n \t\t: CameraConfiguration(), data_(data)\n \t{\n \t}\n@@ -292,7 +292,7 @@ public:\n \tstd::optional<ColorSpace> rgbColorSpace_;\n \n private:\n-\tconst CameraData *data_;\n+\tCameraData *data_;\n };\n \n } /* namespace RPi */\ndiff --git a/src/libcamera/pipeline/rpi/pisp/pisp.cpp b/src/libcamera/pipeline/rpi/pisp/pisp.cpp\nindex 726ab063..da3f5f40 100644\n--- a/src/libcamera/pipeline/rpi/pisp/pisp.cpp\n+++ b/src/libcamera/pipeline/rpi/pisp/pisp.cpp\n@@ -756,6 +756,10 @@ public:\n \tbool adjustDeviceFormat(V4L2DeviceFormat &format) const;\n \n private:\n+\tint platformConfigureCfe(const RPi::RPiCameraConfiguration *rpiConfig,\n+\t\t\t\t V4L2DeviceFormat &cfeFormat);\n+\tint platformConfigureIsp(const RPi::RPiCameraConfiguration *rpiConfig,\n+\t\t\t\t V4L2DeviceFormat cfeFormat);\n \tint platformConfigure(const RPi::RPiCameraConfiguration *rpiConfig) override;\n \n \tint platformConfigureIpa([[maybe_unused]] ipa::RPi::ConfigParams &params) override\n@@ -995,6 +999,12 @@ PipelineHandlerPiSP::createMemoryCamera(DeviceEnumerator *enumerator,\n \n \tstd::shared_ptr<Camera> camera = platformCreateCamera(cameraData, nullptr, ispDevice.get());\n \n+\tint ret = pisp->loadPipelineConfiguration();\n+\tif (ret) {\n+\t\tLOG(RPI, Error) << \"Unable to load pipeline configuration\";\n+\t\treturn nullptr;\n+\t}\n+\n \treturn camera;\n }\n \n@@ -1274,10 +1284,14 @@ PiSPCameraData::platformValidate(RPi::RPiCameraConfiguration *rpiConfig) const\n \t}\n \n \tif (!rawStreams.empty()) {\n-\t\trawStreams[0].dev = cfe_[Cfe::Output0].dev();\n-\n \t\tStreamConfiguration *rawStream = rawStreams[0].cfg;\n \t\tBayerFormat bayer = BayerFormat::fromPixelFormat(rawStream->pixelFormat);\n+\n+\t\tif (rawStream->isInput())\n+\t\t\trawStreams[0].dev = isp_[Isp::Input].dev();\n+\t\telse\n+\t\t\trawStreams[0].dev = cfe_[Cfe::Output0].dev();\n+\n \t\t/*\n \t\t * We cannot output CSI2 packed or non 16-bit output from the frontend,\n \t\t * so signal the output as unpacked 16-bits in these cases.\n@@ -1297,7 +1311,7 @@ PiSPCameraData::platformValidate(RPi::RPiCameraConfiguration *rpiConfig) const\n \t\t}\n \n \t\trawStreams[0].format =\n-\t\t\tRPi::PipelineHandlerBase::toV4L2DeviceFormat(cfe_[Cfe::Output0].dev(), rawStream);\n+\t\t\tRPi::PipelineHandlerBase::toV4L2DeviceFormat(rawStreams[0].dev, rawStream);\n \n \t\tcomputeOptimalStride(rawStreams[0].format);\n \t}\n@@ -1491,13 +1505,13 @@ bool PiSPCameraData::adjustDeviceFormat(V4L2DeviceFormat &format) const\n \treturn false;\n }\n \n-int PiSPCameraData::platformConfigure(const RPi::RPiCameraConfiguration *rpiConfig)\n+int PiSPCameraData::platformConfigureCfe(const RPi::RPiCameraConfiguration *rpiConfig,\n+\t\t\t\t\t V4L2DeviceFormat &cfeFormat)\n {\n \tconst std::vector<RPi::RPiCameraConfiguration::StreamParams> &rawStreams = rpiConfig->rawStreams_;\n-\tconst std::vector<RPi::RPiCameraConfiguration::StreamParams> &outStreams = rpiConfig->outStreams_;\n \tint ret;\n \tV4L2VideoDevice *cfe = cfe_[Cfe::Output0].dev();\n-\tV4L2DeviceFormat cfeFormat;\n+\tV4L2DeviceFormat format;\n \n \t/*\n \t * See which streams are requested, and route the user\n@@ -1542,8 +1556,59 @@ int PiSPCameraData::platformConfigure(const RPi::RPiCameraConfiguration *rpiConf\n \t}\n \n \tret = cfe->setFormat(&cfeFormat);\n-\tif (ret)\n+\n+\t/* CFE statistics output format. */\n+\tformat = {};\n+\tformat.fourcc = V4L2PixelFormat(V4L2_META_FMT_RPI_FE_STATS);\n+\tret = cfe_[Cfe::Stats].dev()->setFormat(&format);\n+\tif (ret) {\n+\t\tLOG(RPI, Error) << \"Failed to set format on CFE stats stream: \"\n+\t\t\t\t<< format.toString();\n+\t\treturn ret;\n+\t}\n+\n+\t/* CFE config format. */\n+\tformat = {};\n+\tformat.fourcc = V4L2PixelFormat(V4L2_META_FMT_RPI_FE_CFG);\n+\tret = cfe_[Cfe::Config].dev()->setFormat(&format);\n+\tif (ret) {\n+\t\tLOG(RPI, Error) << \"Failed to set format on CFE config stream: \"\n+\t\t\t\t<< format.toString();\n \t\treturn ret;\n+\t}\n+\n+\t/*\n+\t * Configure the CFE embedded data output format only if the sensor\n+\t * supports it.\n+\t */\n+\tV4L2SubdeviceFormat embeddedFormat;\n+\tif (sensorMetadata_) {\n+\t\tsensor_->device()->getFormat(1, &embeddedFormat);\n+\t\tformat = {};\n+\t\tformat.fourcc = V4L2PixelFormat(V4L2_META_FMT_SENSOR_DATA);\n+\t\tformat.planes[0].size = embeddedFormat.size.width * embeddedFormat.size.height;\n+\n+\t\tLOG(RPI, Debug) << \"Setting embedded data format \" << format.toString();\n+\t\tret = cfe_[Cfe::Embedded].dev()->setFormat(&format);\n+\t\tif (ret) {\n+\t\t\tLOG(RPI, Error) << \"Failed to set format on CFE embedded: \"\n+\t\t\t\t\t<< format;\n+\t\t\treturn ret;\n+\t\t}\n+\t}\n+\n+\tconfigureEntities(rpiConfig->sensorFormat_, embeddedFormat);\n+\tconfigureCfe();\n+\n+\treturn 0;\n+}\n+\n+int PiSPCameraData::platformConfigureIsp(const RPi::RPiCameraConfiguration *rpiConfig,\n+\t\t\t\t\t V4L2DeviceFormat cfeFormat)\n+{\n+\tint ret;\n+\n+\tconst std::vector<RPi::RPiCameraConfiguration::StreamParams> &outStreams = rpiConfig->outStreams_;\n \n \t/* Set the TDN and Stitch node formats in case they are turned on. */\n \tisp_[Isp::TdnOutput].dev()->setFormat(&cfeFormat);\n@@ -1679,53 +1744,35 @@ int PiSPCameraData::platformConfigure(const RPi::RPiCameraConfiguration *rpiConf\n \n \tbeEnabled_ = beEnables & (PISP_BE_RGB_ENABLE_OUTPUT0 | PISP_BE_RGB_ENABLE_OUTPUT1);\n \n-\t/* CFE statistics output format. */\n-\tformat = {};\n-\tformat.fourcc = V4L2PixelFormat(V4L2_META_FMT_RPI_FE_STATS);\n-\tret = cfe_[Cfe::Stats].dev()->setFormat(&format);\n-\tif (ret) {\n-\t\tLOG(RPI, Error) << \"Failed to set format on CFE stats stream: \"\n-\t\t\t\t<< format.toString();\n-\t\treturn ret;\n-\t}\n+\tif (beEnabled_)\n+\t\tconfigureBe(rpiConfig->yuvColorSpace_);\n \n-\t/* CFE config format. */\n-\tformat = {};\n-\tformat.fourcc = V4L2PixelFormat(V4L2_META_FMT_RPI_FE_CFG);\n-\tret = cfe_[Cfe::Config].dev()->setFormat(&format);\n-\tif (ret) {\n-\t\tLOG(RPI, Error) << \"Failed to set format on CFE config stream: \"\n-\t\t\t\t<< format.toString();\n-\t\treturn ret;\n-\t}\n+\treturn 0;\n+}\n+\n+int PiSPCameraData::platformConfigure(const RPi::RPiCameraConfiguration *rpiConfig)\n+{\n+\t/* What we call the cfeFormat here is also the input format for the ISP (Back End). */\n+\tV4L2DeviceFormat cfeFormat;\n \n \t/*\n-\t * Configure the CFE embedded data output format only if the sensor\n-\t * supports it.\n+\t * First configure the CFE (if it's being used). In the case of memory cameras\n+\t * (Bayer reprocessing), there's no CFE but the raw input stream should already\n+\t * contain the correct ISP input format.\n \t */\n-\tV4L2SubdeviceFormat embeddedFormat;\n-\tif (sensorMetadata_) {\n-\t\tsensor_->device()->getFormat(1, &embeddedFormat);\n-\t\tformat = {};\n-\t\tformat.fourcc = V4L2PixelFormat(V4L2_META_FMT_SENSOR_DATA);\n-\t\tformat.planes[0].size = embeddedFormat.size.width * embeddedFormat.size.height;\n-\n-\t\tLOG(RPI, Debug) << \"Setting embedded data format \" << format.toString();\n-\t\tret = cfe_[Cfe::Embedded].dev()->setFormat(&format);\n-\t\tif (ret) {\n-\t\t\tLOG(RPI, Error) << \"Failed to set format on CFE embedded: \"\n-\t\t\t\t\t<< format;\n+\tif (cfe_[Cfe::Output0].dev()) {\n+\t\t/* Regular sensor. */\n+\t\tint ret = platformConfigureCfe(rpiConfig, cfeFormat);\n+\t\tif (ret)\n \t\t\treturn ret;\n-\t\t}\n+\t} else {\n+\t\t/* Memory camera. */\n+\t\tcfeFormat = rpiConfig->rawStreams_[0].format;\n+\t\trpiConfig->rawStreams_[0].cfg->setStream(&isp_[Isp::Input]);\n \t}\n \n-\tconfigureEntities(rpiConfig->sensorFormat_, embeddedFormat);\n-\tconfigureCfe();\n-\n-\tif (beEnabled_)\n-\t\tconfigureBe(rpiConfig->yuvColorSpace_);\n-\n-\treturn 0;\n+\t/* Finally configure the back end ISP. */\n+\treturn platformConfigureIsp(rpiConfig, cfeFormat);\n }\n \n void PiSPCameraData::platformStart()\n",
    "prefixes": [
        "10/11"
    ]
}