[{"id":34953,"web_url":"https://patchwork.libcamera.org/comment/34953/","msgid":"<nt74pdhkdathkzo5hadzb7yhmpvu4t7zup2sbakhdc6pmai2lh@kric67zig3a7>","date":"2025-07-21T05:26:39","subject":"Re: [PATCH v10 4/8] libcamera: simple: Handle processed and raw\n\tformats separately","submitter":{"id":232,"url":"https://patchwork.libcamera.org/api/people/232/","name":"Umang Jain","email":"uajain@igalia.com"},"content":"Hi Milan\n\nOn Fri, Jul 11, 2025 at 07:53:37PM +0200, Milan Zamazal wrote:\n> Let's handle both processed and/or raw output configurations, depending\n> on the requested stream roles.  In addition to the already handled\n> processed formats and sizes, this patch adds handling of raw formats and\n> sizes, which correspond to the capture formats and sizes.\n> \n> Raw and processed formats are handled separately.  The intention is that\n> in case both raw and processed formats are requested then the raw\n> formats should be left intact to the extent possible and not be\n> influenced by the processed formats (implying that raw parameters\n> compatible with the processed output requirements must be requested by\n> the application).\n> \n> Accompanying checks for invalid role specifications are introduced.\n> \n> This is another preparatory patch without making raw outputs working.\n> \n> Signed-off-by: Milan Zamazal <mzamazal@redhat.com>\n> ---\n>  src/libcamera/pipeline/simple/simple.cpp | 80 +++++++++++++++++-------\n>  1 file changed, 57 insertions(+), 23 deletions(-)\n> \n> diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp\n> index 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\nYou can simply try to iterate over data->formats_\ndata->formats_ contain both raw and processed formats already, so we can\npopulate the local formats map from that.\n\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\nYou can simply keep one formats map locally. No need to split between\nthe raw and processed. Depending on the role requested, you can simply\npick appropriate configurations from the formats map.\n\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\nWhat I have done is the following:\n\n\tfor (StreamRole role : roles) {\n\t\tStreamConfiguration cfg{ StreamFormats{ formats } };\n\n\t\tswitch (role) {\n\t\tcase StreamRole::Raw:\n\t\t\tfor (auto &[format, sizes] : formats) {\n\t\t\t\tif (!isFormatRaw(format))\n\t\t\t\t\tcontinue;\n\t\t\t\tcfg.pixelFormat = format;\n\t\t\t\tcfg.size = sizes.back().max;\n\t\t\t\tcfg.colorSpace = ColorSpace::Raw;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tfor (auto &[format, sizes] : formats) {\n\t\t\t\tif (isFormatRaw(format))\n\t\t\t\t\tcontinue;\n\t\t\t\tcfg.pixelFormat = format;\n\t\t\t\tcfg.size = sizes[0].max;\n\t\t\t}\n\t\t}\n\n\t\tconfig->addConfiguration(cfg);\n\t}\n\nI have `formats` which contain both the RAW and processed formats\n(populated from data->formats_). Hence in this loop, I simply pick up\nthe first entry - which would satisfy the role.\n\n> -- \n> 2.50.1\n>","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 8E6BFBDCC1\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 21 Jul 2025 05:26:40 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 9A3C568FC0;\n\tMon, 21 Jul 2025 07:26:39 +0200 (CEST)","from fanzine2.igalia.com (fanzine2.igalia.com [213.97.179.56])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id D34B7614F6\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 21 Jul 2025 07:26:36 +0200 (CEST)","from [49.36.71.87] (helo=uajain) by fanzine2.igalia.com with\n\tesmtpsa \n\t(Cipher TLS1.3:ECDHE_SECP256R1__RSA_PSS_RSAE_SHA256__AES_256_GCM:256)\n\t(Exim) id 1udj2p-001ZbI-4k; Mon, 21 Jul 2025 07:26:35 +0200"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=igalia.com header.i=@igalia.com\n\theader.b=\"qgGb6xF9\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com;\n\ts=20170329;\n\th=In-Reply-To:Content-Type:MIME-Version:References:Message-ID:\n\tSubject:Cc:To:From:Date:Sender:Reply-To:Content-Transfer-Encoding:Content-ID:\n\tContent-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc\n\t:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe:\n\tList-Post:List-Owner:List-Archive;\n\tbh=P6jAEQrdJkKAcTjfHs7pR4+1h1t3FDrvgE8ccVmZXlo=;\n\tb=qgGb6xF9wu2v3zzGow3NN2lLky\n\tJBX3vAIpLAHnNTyHnMuJOvU/fvftoxEAttdYW8LycIRA/7+5tLfV8pRybuMxv/6zCPzmsaZFyNcQK\n\tWEF4WTGrMyXVC+JEWVDNnYmvZZkwjzbK0QL5TfXbdxlRi0vEfAWO3e9bn8d8+DyH7NLmPWH6RDBsw\n\tPFx91iSTqMm/22n7byRN1gRRJkdKHF5hHDn3vJH3MvcYXarhZO1bbyRXhgMTLNEnPk0zE3kWthTlt\n\t+SqhY7XAXpWUgFHIxK5pHQ+JCWCXw+PCeC50fuWWQObEJBu2fgkC8Ow0nODbSzU0eDmb13J2/rPzZ\n\tjERp7kfg==;","Date":"Mon, 21 Jul 2025 10:56:39 +0530","From":"Umang Jain <uajain@igalia.com>","To":"Milan Zamazal <mzamazal@redhat.com>","Cc":"libcamera-devel@lists.libcamera.org, 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":"Re: [PATCH v10 4/8] libcamera: simple: Handle processed and raw\n\tformats separately","Message-ID":"<nt74pdhkdathkzo5hadzb7yhmpvu4t7zup2sbakhdc6pmai2lh@kric67zig3a7>","References":"<20250711175345.90318-1-mzamazal@redhat.com>\n\t<20250711175345.90318-5-mzamazal@redhat.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=us-ascii","Content-Disposition":"inline","In-Reply-To":"<20250711175345.90318-5-mzamazal@redhat.com>","User-Agent":"NeoMutt/20250510-dirty","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>"}},{"id":35014,"web_url":"https://patchwork.libcamera.org/comment/35014/","msgid":"<851pq8qzbp.fsf@mzamazal-thinkpadp1gen7.tpbc.csb>","date":"2025-07-22T10:44:58","subject":"Re: [PATCH v10 4/8] libcamera: simple: Handle processed and raw\n\tformats separately","submitter":{"id":177,"url":"https://patchwork.libcamera.org/api/people/177/","name":"Milan Zamazal","email":"mzamazal@redhat.com"},"content":"Hi Umang,\n\nUmang Jain <uajain@igalia.com> writes:\n\n> Hi Milan\n>\n> On Fri, Jul 11, 2025 at 07:53:37PM +0200, Milan Zamazal wrote:\n>> Let's handle both processed and/or raw output configurations, depending\n>> on the requested stream roles.  In addition to the already handled\n>> processed formats and sizes, this patch adds handling of raw formats and\n>> sizes, which correspond to the capture formats and sizes.\n>> \n>> Raw and processed formats are handled separately.  The intention is that\n>> in case both raw and processed formats are requested then the raw\n>> formats should be left intact to the extent possible and not be\n>> influenced by the processed formats (implying that raw parameters\n>> compatible with the processed output requirements must be requested by\n>> the application).\n>> \n>> Accompanying checks for invalid role specifications are introduced.\n>> \n>> This is another preparatory patch without making raw outputs working.\n>> \n>> Signed-off-by: Milan Zamazal <mzamazal@redhat.com>\n>> ---\n>>  src/libcamera/pipeline/simple/simple.cpp | 80 +++++++++++++++++-------\n>>  1 file changed, 57 insertions(+), 23 deletions(-)\n>> \n>> diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp\n>> index 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>\n> You can simply try to iterate over data->formats_\n> data->formats_ contain both raw and processed formats already, so we can\n> populate the local formats map from that.\n>\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> You can simply keep one formats map locally. No need to split between\n> the raw and processed. Depending on the role requested, you can simply\n> pick appropriate configurations from the formats map.\n\nI'm not sure this is correct.  I'd think that if a raw role is\nrequested, it means an unprocessed input from the camera.  Which may or\nmay not be a format for which isFormatRaw returns true.  And a processed\noutput can, at least in theory, produce a format for which isFormatRaw\nreturns true.\n\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>\n> What I have done is the following:\n>\n> \tfor (StreamRole role : roles) {\n> \t\tStreamConfiguration cfg{ StreamFormats{ formats } };\n>\n> \t\tswitch (role) {\n> \t\tcase StreamRole::Raw:\n> \t\t\tfor (auto &[format, sizes] : formats) {\n> \t\t\t\tif (!isFormatRaw(format))\n> \t\t\t\t\tcontinue;\n> \t\t\t\tcfg.pixelFormat = format;\n> \t\t\t\tcfg.size = sizes.back().max;\n> \t\t\t\tcfg.colorSpace = ColorSpace::Raw;\n> \t\t\t\tbreak;\n> \t\t\t}\n> \t\t\tbreak;\n> \t\tdefault:\n> \t\t\tfor (auto &[format, sizes] : formats) {\n> \t\t\t\tif (isFormatRaw(format))\n> \t\t\t\t\tcontinue;\n> \t\t\t\tcfg.pixelFormat = format;\n> \t\t\t\tcfg.size = sizes[0].max;\n> \t\t\t}\n> \t\t}\n>\n> \t\tconfig->addConfiguration(cfg);\n> \t}\n>\n> I have `formats` which contain both the RAW and processed formats\n> (populated from data->formats_). Hence in this loop, I simply pick up\n> the first entry - which would satisfy the role.\n>\n>> -- \n>> 2.50.1\n>>","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 6487EBDCC1\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 22 Jul 2025 10:45:09 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 651E968F93;\n\tTue, 22 Jul 2025 12:45:08 +0200 (CEST)","from us-smtp-delivery-124.mimecast.com\n\t(us-smtp-delivery-124.mimecast.com [170.10.129.124])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id EBB7A68F93\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 22 Jul 2025 12:45:05 +0200 (CEST)","from mail-wm1-f70.google.com (mail-wm1-f70.google.com\n\t[209.85.128.70]) by relay.mimecast.com with ESMTP with STARTTLS\n\t(version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id\n\tus-mta-477-9ENyyBr4OESs0R1A9dK3iA-1; Tue, 22 Jul 2025 06:45:01 -0400","by mail-wm1-f70.google.com with SMTP id\n\t5b1f17b1804b1-4538f375e86so49257155e9.3\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 22 Jul 2025 03:45:01 -0700 (PDT)","from mzamazal-thinkpadp1gen7.tpbc.csb ([85.93.96.130])\n\tby smtp.gmail.com with ESMTPSA id\n\tffacd0b85a97d-3b61ca4897bsm13142290f8f.53.2025.07.22.03.44.58\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tTue, 22 Jul 2025 03:44:58 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=redhat.com header.i=@redhat.com\n\theader.b=\"E6G95KfS\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com;\n\ts=mimecast20190719; t=1753181104;\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\tin-reply-to:in-reply-to:references:references;\n\tbh=KhfXAZ70w6MIEtfkXyIPq9wvlEky5xyrteTjtYxdHxA=;\n\tb=E6G95KfSBSYPktFDioxY4J5tLsGJ6FstZHLXagDHxh44YKal7ebGqymWzHHcSmNsybwpQJ\n\tEuNE7RzF3bp7ZEkWvY/Ocx6x1/9EPS9fwMEQKcE8wPHyGHpzDhI9uIOdoZR8gkeuG+Xd9K\n\tQa5PeqReuOTJe7FtVqG2LEYN7yZ/M9g=","X-MC-Unique":"9ENyyBr4OESs0R1A9dK3iA-1","X-Mimecast-MFC-AGG-ID":"9ENyyBr4OESs0R1A9dK3iA_1753181100","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20230601; t=1753181100; x=1753785900;\n\th=mime-version:user-agent:message-id:date:references:in-reply-to\n\t:subject:cc:to:from:x-gm-message-state:from:to:cc:subject:date\n\t:message-id:reply-to;\n\tbh=KhfXAZ70w6MIEtfkXyIPq9wvlEky5xyrteTjtYxdHxA=;\n\tb=kWFE0EnqvWG2IUh62VyFXgm7LieZTFsAX++vwgS51i6aiGwfESwGboZRKSlGsqYxq3\n\t1NeF7AKB/BI6+O5pyLW7QcgCQUjyxMSyd9JgPaijKoncQs6hFFqRz23NeEeXcgraqnFR\n\tKvAvjyabq2sG78psSyDQzwrMirwTgoO0pkhYY3DQ9VlirGI8o3BxJAi8mRH9sCqpEfti\n\trQzR8kM+VwD0J+EfOPrPDqDyt9S0SFovnlcqqG4dXcgdJ8v8A8dWaVkxcGoMB/IkxtjS\n\tX5CpTZcH72yYKVD11IyiUiIcAog7v8ItE0azYFAtAAHqnofg+VBqYKOIJsS30nlwWdFe\n\tYaeQ==","X-Gm-Message-State":"AOJu0YwYZx2b1C55QfvPgWg+txeiCGKxwOIrG1wHy2No9Vm8YdbRkhYr\n\tH2LhCph6GPprexdSAZshwu8/BO3rHERfJx5ApEjOgxQ/5xSGHAmLkksXK03g55OO7v5otF9pZTw\n\tTwS7tbYP+EOvqjqVH/cxb7FeBr2Ws2ZfAnQhmPtef08z9ylCySRGmUBCbdsVNnv8Y4Miva0rEI4\n\tc=","X-Gm-Gg":"ASbGncuAX2TmYPk0RyBd/3uc+yCgKBHZcW9ukC/PheApTva10eSaomY6T16ejAOp3Qc\n\tOV7uuSuqBriu5leWvrx1o91lhpnpYfr4En2gkcPnTNwIyz0+3jAuMhfvc5glrqaRCv7qEB6yvvn\n\tAwTBbxZ3BOl8tvhTISeoT6q1O47vnLEPFuVnWMt7rMu3BMtFMZzF7FtNMhWkcF59N3wM5PYwq9k\n\tNjAgSHXPlPlJQjn+kmowBdVnTcM4KgF476JtOAN5Ax/tdfo9T09WS3HYVxx+POCBcepQ0DCEv2v\n\tgMftx3rtfss+q9VgZ0vsKmxwaA1tdfLmbwvtnWn1QuOiIGXl2VgRFLe9FfI0OKSF","X-Received":["by 2002:a05:6000:2b01:b0:3b1:9259:3ead with SMTP id\n\tffacd0b85a97d-3b60dd7332dmr13913705f8f.28.1753181100198; \n\tTue, 22 Jul 2025 03:45:00 -0700 (PDT)","by 2002:a05:6000:2b01:b0:3b1:9259:3ead with SMTP id\n\tffacd0b85a97d-3b60dd7332dmr13913678f8f.28.1753181099557; \n\tTue, 22 Jul 2025 03:44:59 -0700 (PDT)"],"X-Google-Smtp-Source":"AGHT+IFBLLLBvQVJV7lsz0E8NS9xHTs1WNH0tsinl5QzGzPT/VDyKOTLHCqr3G8qRdTC5mFWI0i82A==","From":"Milan Zamazal <mzamazal@redhat.com>","To":"Umang Jain <uajain@igalia.com>","Cc":"libcamera-devel@lists.libcamera.org,  Laurent Pinchart\n\t<laurent.pinchart@ideasonboard.com>,\n\tKieran Bingham <kieran.bingham@ideasonboard.com>, =?utf-8?q?Barnab?=\n\t=?utf-8?b?w6FzIFDFkWN6ZQ==?=\n\t<barnabas.pocze@ideasonboard.com>, Paul Elder\n\t<paul.elder@ideasonboard.com>","Subject":"Re: [PATCH v10 4/8] libcamera: simple: Handle processed and raw\n\tformats separately","In-Reply-To":"<nt74pdhkdathkzo5hadzb7yhmpvu4t7zup2sbakhdc6pmai2lh@kric67zig3a7>\n\t(Umang Jain's message of \"Mon, 21 Jul 2025 10:56:39 +0530\")","References":"<20250711175345.90318-1-mzamazal@redhat.com>\n\t<20250711175345.90318-5-mzamazal@redhat.com>\n\t<nt74pdhkdathkzo5hadzb7yhmpvu4t7zup2sbakhdc6pmai2lh@kric67zig3a7>","Date":"Tue, 22 Jul 2025 12:44:58 +0200","Message-ID":"<851pq8qzbp.fsf@mzamazal-thinkpadp1gen7.tpbc.csb>","User-Agent":"Gnus/5.13 (Gnus v5.13)","MIME-Version":"1.0","X-Mimecast-Spam-Score":"0","X-Mimecast-MFC-PROC-ID":"Gu82WcqpdQL_QxrnGnDjQPnC8I397i8GKad_pZPLla0_1753181100","X-Mimecast-Originator":"redhat.com","Content-Type":"text/plain","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>"}}]