Show a patch.

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

{
    "id": 23910,
    "url": "https://patchwork.libcamera.org/api/1.1/patches/23910/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/23910/",
    "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": "<20250723180815.82450-5-mzamazal@redhat.com>",
    "date": "2025-07-23T18:08:09",
    "name": "[v11,4/8] libcamera: simple: Handle processed and raw formats separately",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": false,
    "hash": "1dcae36cad632d12aae7799833e0e7f3dac0fa33",
    "submitter": {
        "id": 177,
        "url": "https://patchwork.libcamera.org/api/1.1/people/177/?format=api",
        "name": "Milan Zamazal",
        "email": "mzamazal@redhat.com"
    },
    "delegate": null,
    "mbox": "https://patchwork.libcamera.org/patch/23910/mbox/",
    "series": [
        {
            "id": 5316,
            "url": "https://patchwork.libcamera.org/api/1.1/series/5316/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=5316",
            "date": "2025-07-23T18:08:05",
            "name": "Enable raw streams with software ISP",
            "version": 11,
            "mbox": "https://patchwork.libcamera.org/series/5316/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/23910/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/23910/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 195D7C3237\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 23 Jul 2025 18:08:53 +0000 (UTC)",
            "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id B634A69076;\n\tWed, 23 Jul 2025 20:08:52 +0200 (CEST)",
            "from us-smtp-delivery-124.mimecast.com\n\t(us-smtp-delivery-124.mimecast.com [170.10.133.124])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id EF11B69067\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 23 Jul 2025 20:08:50 +0200 (CEST)",
            "from mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com\n\t(ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63])\n\tby relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3,\n\tcipher=TLS_AES_256_GCM_SHA384) id us-mta-606-Yjox-6U3NQ-dVYI3etO32A-1;\n\tWed, 23 Jul 2025 14:08:46 -0400",
            "from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com\n\t(mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com\n\t[10.30.177.17])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\tkey-exchange X25519 server-signature RSA-PSS (2048 bits)\n\tserver-digest SHA256) (No client certificate requested)\n\tby mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix)\n\twith ESMTPS id 8D4F619560BC; Wed, 23 Jul 2025 18:08:44 +0000 (UTC)",
            "from mzamazal-thinkpadp1gen7.tpbc.com (unknown [10.44.32.15])\n\tby mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix)\n\twith ESMTP id 0C976195608D; Wed, 23 Jul 2025 18:08:41 +0000 (UTC)"
        ],
        "Authentication-Results": "lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=redhat.com header.i=@redhat.com\n\theader.b=\"dkWhdhsj\"; dkim-atps=neutral",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n\ts=mimecast20190719; t=1753294130;\n\th=from:from:reply-to:subject:subject:date:date:message-id:message-id:\n\tto:to:cc:cc:mime-version:mime-version:content-type:content-type:\n\tcontent-transfer-encoding:content-transfer-encoding:\n\tin-reply-to:in-reply-to:references:references;\n\tbh=jl9xfCAU03T6MQZe9LMyGoUEEt/fHSLHEoM66+PGXiM=;\n\tb=dkWhdhsjBep09H8umiYUKoV8Di7Cyhl8GpTjIURVf6TLW9uqzfGYjSgKjuB8nwZOqvCBKc\n\twvQpzWKycYtD4S8PUZ4L10lVFtKbHJW+VnSQBnGhUF4AepkXqXMkOgtwp1oJVsx7Lixp0V\n\toW9zamzYyb/v+whQLg3wPVcjXfh5Zh0=",
        "X-MC-Unique": "Yjox-6U3NQ-dVYI3etO32A-1",
        "X-Mimecast-MFC-AGG-ID": "Yjox-6U3NQ-dVYI3etO32A_1753294124",
        "From": "Milan Zamazal <mzamazal@redhat.com>",
        "To": "libcamera-devel@lists.libcamera.org",
        "Cc": "Milan Zamazal <mzamazal@redhat.com>, Laurent Pinchart\n\t<laurent.pinchart@ideasonboard.com>, Kieran Bingham\n\t<kieran.bingham@ideasonboard.com>, =?utf-8?q?Barnab=C3=A1s_P=C5=91cze?=\n\t<barnabas.pocze@ideasonboard.com>, Paul Elder\n\t<paul.elder@ideasonboard.com>, Umang Jain <uajain@igalia.com>",
        "Subject": "[PATCH v11 4/8] libcamera: simple: Handle processed and raw formats\n\tseparately",
        "Date": "Wed, 23 Jul 2025 20:08:09 +0200",
        "Message-ID": "<20250723180815.82450-5-mzamazal@redhat.com>",
        "In-Reply-To": "<20250723180815.82450-1-mzamazal@redhat.com>",
        "References": "<20250723180815.82450-1-mzamazal@redhat.com>",
        "MIME-Version": "1.0",
        "X-Scanned-By": "MIMEDefang 3.0 on 10.30.177.17",
        "X-Mimecast-Spam-Score": "0",
        "X-Mimecast-MFC-PROC-ID": "Tp3GMOvil2Bn9NVbNwrPMOGo4u8GcLQ8gAMDcLQ0bEo_1753294124",
        "X-Mimecast-Originator": "redhat.com",
        "Content-Transfer-Encoding": "8bit",
        "content-type": "text/plain; charset=\"US-ASCII\"; x-default=true",
        "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": "Let's handle both processed and/or raw output configurations, depending\non the requested stream roles.  In addition to the already handled\nprocessed formats and sizes, this patch adds handling of raw formats and\nsizes, which correspond to the capture formats and sizes.\n\nRaw and processed formats are handled separately.  The intention is that\nin case both raw and processed formats are requested then the raw\nformats should be left intact to the extent possible and not be\ninfluenced by the processed formats (implying that raw parameters\ncompatible with the processed output requirements must be requested by\nthe application).\n\nAccompanying checks for invalid role specifications are introduced.\n\nThis is another preparatory patch without making raw outputs working.\n\nSigned-off-by: Milan Zamazal <mzamazal@redhat.com>\n---\n src/libcamera/pipeline/simple/simple.cpp | 80 +++++++++++++++++-------\n 1 file changed, 57 insertions(+), 23 deletions(-)",
    "diff": "diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp\nindex 87b26d4a2..37abaa0e0 100644\n--- a/src/libcamera/pipeline/simple/simple.cpp\n+++ b/src/libcamera/pipeline/simple/simple.cpp\n@@ -1310,35 +1310,67 @@ SimplePipelineHandler::generateConfiguration(Camera *camera, Span<const StreamRo\n \tif (roles.empty())\n \t\treturn config;\n \n-\t/* Create the formats map. */\n-\tstd::map<PixelFormat, std::vector<SizeRange>> formats;\n+\tbool processedRequested = false;\n+\tbool rawRequested = false;\n+\tfor (const auto &role : roles)\n+\t\tif (role == StreamRole::Raw) {\n+\t\t\tif (rawRequested) {\n+\t\t\t\tLOG(SimplePipeline, Error)\n+\t\t\t\t\t<< \"Can't capture multiple raw streams\";\n+\t\t\t\treturn nullptr;\n+\t\t\t}\n+\t\t\trawRequested = true;\n+\t\t} else {\n+\t\t\tprocessedRequested = true;\n+\t\t}\n+\n+\t/* Create the formats maps. */\n+\tstd::map<PixelFormat, std::vector<SizeRange>> processedFormats;\n+\tstd::map<PixelFormat, std::vector<SizeRange>> rawFormats;\n \n \tfor (const SimpleCameraData::Configuration &cfg : data->configs_) {\n+\t\trawFormats[cfg.captureFormat].push_back(cfg.captureSize);\n \t\tfor (PixelFormat format : cfg.outputFormats)\n-\t\t\tformats[format].push_back(cfg.outputSizes);\n+\t\t\tprocessedFormats[format].push_back(cfg.outputSizes);\n \t}\n \n-\t/* Sort the sizes and merge any consecutive overlapping ranges. */\n-\tfor (auto &[format, sizes] : formats) {\n-\t\tstd::sort(sizes.begin(), sizes.end(),\n-\t\t\t  [](SizeRange &a, SizeRange &b) {\n-\t\t\t\t  return a.min < b.min;\n-\t\t\t  });\n-\n-\t\tauto cur = sizes.begin();\n-\t\tauto next = cur;\n-\n-\t\twhile (++next != sizes.end()) {\n-\t\t\tif (cur->max.width >= next->min.width &&\n-\t\t\t    cur->max.height >= next->min.height)\n-\t\t\t\tcur->max = next->max;\n-\t\t\telse if (++cur != next)\n-\t\t\t\t*cur = *next;\n-\t\t}\n-\n-\t\tsizes.erase(++cur, sizes.end());\n+\tif (processedRequested && processedFormats.empty()) {\n+\t\tLOG(SimplePipeline, Error)\n+\t\t\t<< \"Processed stream requsted but no corresponding output configuration found\";\n+\t\treturn nullptr;\n+\t}\n+\tif (rawRequested && rawFormats.empty()) {\n+\t\tLOG(SimplePipeline, Error)\n+\t\t\t<< \"Raw stream requsted but no corresponding output configuration found\";\n+\t\treturn nullptr;\n \t}\n \n+\tauto setUpFormatSizes = [](std::map<PixelFormat, std::vector<SizeRange>> &formats) {\n+\t\t/* Sort the sizes and merge any consecutive overlapping ranges. */\n+\n+\t\tfor (auto &[format, sizes] : formats) {\n+\t\t\tstd::sort(sizes.begin(), sizes.end(),\n+\t\t\t\t  [](SizeRange &a, SizeRange &b) {\n+\t\t\t\t\t  return a.min < b.min;\n+\t\t\t\t  });\n+\n+\t\t\tauto cur = sizes.begin();\n+\t\t\tauto next = cur;\n+\n+\t\t\twhile (++next != sizes.end()) {\n+\t\t\t\tif (cur->max.width >= next->min.width &&\n+\t\t\t\t    cur->max.height >= next->min.height)\n+\t\t\t\t\tcur->max = next->max;\n+\t\t\t\telse if (++cur != next)\n+\t\t\t\t\t*cur = *next;\n+\t\t\t}\n+\n+\t\t\tsizes.erase(++cur, sizes.end());\n+\t\t}\n+\t};\n+\tsetUpFormatSizes(processedFormats);\n+\tsetUpFormatSizes(rawFormats);\n+\n \t/*\n \t * Create the stream configurations. Take the first entry in the formats\n \t * map as the default, for lack of a better option.\n@@ -1346,11 +1378,13 @@ SimplePipelineHandler::generateConfiguration(Camera *camera, Span<const StreamRo\n \t * \\todo Implement a better way to pick the default format\n \t */\n \tfor (StreamRole role : roles) {\n+\t\tbool raw = (role == StreamRole::Raw);\n+\t\tconst auto &formats = (raw ? rawFormats : processedFormats);\n \t\tStreamConfiguration cfg{ StreamFormats{ formats } };\n \t\tcfg.pixelFormat = formats.begin()->first;\n \t\tcfg.size = formats.begin()->second[0].max;\n \n-\t\tif (role == StreamRole::Raw) {\n+\t\tif (raw) {\n \t\t\t/* Enforce raw colour space for raw roles. */\n \t\t\tcfg.colorSpace = ColorSpace::Raw;\n \t\t} else if (data->swIsp_) {\n",
    "prefixes": [
        "v11",
        "4/8"
    ]
}