Show a patch.

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

{
    "id": 23403,
    "url": "https://patchwork.libcamera.org/api/patches/23403/?format=api",
    "web_url": "https://patchwork.libcamera.org/patch/23403/",
    "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": "<20250520123158.44237-9-mzamazal@redhat.com>",
    "date": "2025-05-20T12:31:53",
    "name": "[v5,08/12] libcamera: simple: Consider raw output configurations",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": false,
    "hash": "b06bd32e7ed7101aafc5c6e0398e14e3e847f50e",
    "submitter": {
        "id": 177,
        "url": "https://patchwork.libcamera.org/api/people/177/?format=api",
        "name": "Milan Zamazal",
        "email": "mzamazal@redhat.com"
    },
    "delegate": null,
    "mbox": "https://patchwork.libcamera.org/patch/23403/mbox/",
    "series": [
        {
            "id": 5184,
            "url": "https://patchwork.libcamera.org/api/series/5184/?format=api",
            "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=5184",
            "date": "2025-05-20T12:31:45",
            "name": "Enable raw streams with software ISP",
            "version": 5,
            "mbox": "https://patchwork.libcamera.org/series/5184/mbox/"
        }
    ],
    "comments": "https://patchwork.libcamera.org/api/patches/23403/comments/",
    "check": "pending",
    "checks": "https://patchwork.libcamera.org/api/patches/23403/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 7E9FDC322E\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 20 May 2025 12:32:52 +0000 (UTC)",
            "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id D594B68DA1;\n\tTue, 20 May 2025 14:32:51 +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 C574268D99\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 20 May 2025 14:32:37 +0200 (CEST)",
            "from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com\n\t(ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97])\n\tby relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3,\n\tcipher=TLS_AES_256_GCM_SHA384) id us-mta-590-MAcb5n4YPQaVQdLQ7TiQmg-1;\n\tTue, 20 May 2025 08:32:30 -0400",
            "from mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com\n\t(mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com\n\t[10.30.177.40])\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-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix)\n\twith ESMTPS id D10131800446; Tue, 20 May 2025 12:32:28 +0000 (UTC)",
            "from mzamazal-thinkpadp1gen7.tpbc.com (unknown [10.45.226.214])\n\tby mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix)\n\twith ESMTP id 7338719560B3; Tue, 20 May 2025 12:32:26 +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=\"GNfbRjq9\"; dkim-atps=neutral",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n\ts=mimecast20190719; t=1747744356;\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=rN5lOP/WqvmVYlNF+Kt7oCYjEUtTWoYBrpimDxUb+3o=;\n\tb=GNfbRjq9UtXv6eO8wIdYOVMz6nIUY4vER6npz8A8Kid/yVvTG2OP0rzfMTOqQDlLiqiKS4\n\tA39Ukf2Opf7+9ZQxZACgSsYyW847Cec2sweHV/S9M686BCD+nzZHTIbkOBeNH4MxXxogJY\n\t0iVC0lmQ4jzz6+tAbJC/ZbHMCLEGcrQ=",
        "X-MC-Unique": "MAcb5n4YPQaVQdLQ7TiQmg-1",
        "X-Mimecast-MFC-AGG-ID": "MAcb5n4YPQaVQdLQ7TiQmg_1747744348",
        "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>",
        "Subject": "[PATCH v5 08/12] libcamera: simple: Consider raw output\n\tconfigurations",
        "Date": "Tue, 20 May 2025 14:31:53 +0200",
        "Message-ID": "<20250520123158.44237-9-mzamazal@redhat.com>",
        "In-Reply-To": "<20250520123158.44237-1-mzamazal@redhat.com>",
        "References": "<20250520123158.44237-1-mzamazal@redhat.com>",
        "MIME-Version": "1.0",
        "X-Scanned-By": "MIMEDefang 3.0 on 10.30.177.40",
        "X-Mimecast-Spam-Score": "0",
        "X-Mimecast-MFC-PROC-ID": "Oeq8H_0tAW5IbgyXRkzwXBlonbjlTdxOmsaIdjvJlPE_1747744348",
        "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": "When generating simple pipeline configuration, raw output configurations\nare generated but later filtered out.  Let's include processed and/or\nraw output configurations depending on the requested stream roles.\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\nRaw output configurations are identified by colorSpace being set to\nColorSpace::Raw.\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 | 71 ++++++++++++++----------\n 1 file changed, 43 insertions(+), 28 deletions(-)",
    "diff": "diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp\nindex 78a76f34..12fd28fa 100644\n--- a/src/libcamera/pipeline/simple/simple.cpp\n+++ b/src/libcamera/pipeline/simple/simple.cpp\n@@ -1322,37 +1322,50 @@ SimplePipelineHandler::generateConfiguration(Camera *camera, Span<const StreamRo\n \t\t\tconfig->processedRequested_ = true;\n \t\t}\n \n-\t/* Create the formats map. */\n-\tstd::map<PixelFormat, std::vector<SizeRange>> formats;\n+\t/* Create the formats maps. */\n+\tstd::map<PixelFormat, std::vector<SizeRange>> processedFormats;\n+\tstd::map<PixelFormat, std::vector<SizeRange>> rawFormats;\n \n-\tconst bool rawOnly = std::all_of(data->configs_.cbegin(),\n-\t\t\t\t\t data->configs_.cend(),\n-\t\t\t\t\t [](const auto &c) { return c.raw; });\n \tfor (const SimpleCameraData::Configuration &cfg : data->configs_)\n-\t\tif (!cfg.raw || rawOnly)\n-\t\t\tfor (PixelFormat format : cfg.outputFormats)\n-\t\t\t\tformats[format].push_back(cfg.outputSizes);\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+\t\tfor (PixelFormat format : cfg.outputFormats)\n+\t\t\t(cfg.raw ? rawFormats : processedFormats)[format].push_back(cfg.outputSizes);\n \n-\t\tsizes.erase(++cur, sizes.end());\n+\tif (config->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 (config->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@@ -1361,11 +1374,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\tauto 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\tcfg.colorSpace = ColorSpace::Raw;\n \t\telse if (data->swIsp_)\n \t\t\tcfg.colorSpace = ColorSpace::Srgb;\n",
    "prefixes": [
        "v5",
        "08/12"
    ]
}