[{"id":14509,"web_url":"https://patchwork.libcamera.org/comment/14509/","msgid":"<X/uWAogoZLmiKgn1@pendragon.ideasonboard.com>","date":"2021-01-11T00:04:18","subject":"Re: [libcamera-devel] [PATCH 10/12] android: camera_device: Handle\n\tSCALER_CROP_REGION","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Jacopo,\n\nThank you for the patch.\n\nOn Tue, Jan 05, 2021 at 08:05:20PM +0100, Jacopo Mondi wrote:\n> Handle the SCALER_CROP_REGION control and dynamic metadata by\n> translating it from the Android format to the associated libcamera\n> control when processing a request, and the other way around when\n> handling a request completion.\n> \n> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>\n> ---\n>  src/android/camera_device.cpp | 52 +++++++++++++++++++++++++++++++----\n>  src/android/camera_device.h   |  2 ++\n>  src/android/camera_worker.h   |  1 +\n>  3 files changed, 49 insertions(+), 6 deletions(-)\n> \n> diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp\n> index 99297270598f..5f5e6576365b 100644\n> --- a/src/android/camera_device.cpp\n> +++ b/src/android/camera_device.cpp\n> @@ -1586,6 +1586,35 @@ FrameBuffer *CameraDevice::createFrameBuffer(const buffer_handle_t camera3buffer\n>  \treturn new FrameBuffer(std::move(planes));\n>  }\n>  \n> +int CameraDevice::processControls(camera3_capture_request_t *camera3Request,\n\nShould the first argument be const ?\n\n> +\t\t\t\t  Camera3RequestDescriptor *descriptor)\n> +{\n> +\tif (!camera3Request->settings)\n> +\t\treturn 0;\n> +\n> +\t/*\n> +\t * Translate the Android controls to libcamera.\n> +\t *\n> +\t * \\todo As soon as more controls are handled, this part should be\n> +\t * broke out to a dedicated function.\n\ns/broke/broken/\n\n> +\t */\n> +\tconst camera_metadata_t *camera3Settings = camera3Request->settings;\n> +\tcamera_metadata_ro_entry_t entry;\n> +\tint ret = find_camera_metadata_ro_entry(camera3Settings,\n> +\t\t\t\t\t\tANDROID_SCALER_CROP_REGION,\n> +\t\t\t\t\t\t&entry);\n> +\tif (!ret) {\n> +\t\tconst int32_t *data = entry.data.i32;\n> +\t\tRectangle cropRegion = { data[0], data[1],\n> +\t\t\t\t\t static_cast<unsigned int>(data[2]),\n> +\t\t\t\t\t static_cast<unsigned int>(data[3]) };\n\nYou could s/ = //, up to you.\n\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\n> +\t\tControlList &controls = descriptor->request_->controls();\n> +\t\tcontrols.set(controls::ScalerCrop, cropRegion);\n> +\t}\n> +\n> +\treturn 0;\n> +}\n> +\n>  int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Request)\n>  {\n>  \tif (!camera3Request) {\n> @@ -1697,7 +1726,14 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques\n>  \t\t\t\t\t\tcamera3Buffers[i].acquire_fence);\n>  \t}\n>  \n> -\t/* Queue the request to the CameraWorker. */\n> +\t/*\n> +\t * Translate controls from Android to libcamera and queue the request\n> +\t * to the CameraWorker thread.\n> +\t */\n> +\tint ret = processControls(camera3Request, descriptor);\n> +\tif (ret)\n> +\t\treturn ret;\n> +\n>  \tworker_.queueRequest(descriptor->request_.get());\n>  \n>  \treturn 0;\n> @@ -1876,11 +1912,6 @@ CameraDevice::getResultMetadata(Camera3RequestDescriptor *descriptor,\n>  \tconst uint8_t lens_state = ANDROID_LENS_STATE_STATIONARY;\n>  \tresultMetadata->addEntry(ANDROID_LENS_STATE, &lens_state, 1);\n>  \n> -\tint32_t sensorSizes[] = {\n> -\t\t0, 0, 2560, 1920,\n> -\t};\n> -\tresultMetadata->addEntry(ANDROID_SCALER_CROP_REGION, sensorSizes, 4);\n> -\n>  \tresultMetadata->addEntry(ANDROID_SENSOR_TIMESTAMP, &timestamp, 1);\n>  \n>  \t/* 33.3 msec */\n> @@ -1911,6 +1942,15 @@ CameraDevice::getResultMetadata(Camera3RequestDescriptor *descriptor,\n>  \t\t\t\t\t &exposure, 1);\n>  \t}\n>  \n> +\tif (metadata.contains(controls::ScalerCrop)) {\n> +\t\tRectangle crop = metadata.get(controls::ScalerCrop);\n> +\t\tint32_t cropRect[] = {\n> +\t\t\tcrop.x, crop.y, static_cast<int32_t>(crop.width),\n> +\t\t\tstatic_cast<int32_t>(crop.height),\n> +\t\t};\n> +\t\tresultMetadata->addEntry(ANDROID_SCALER_CROP_REGION, cropRect, 4);\n> +\t}\n> +\n>  \t/*\n>  \t * Return the result metadata pack even is not valid: get() will return\n>  \t * nullptr.\n> diff --git a/src/android/camera_device.h b/src/android/camera_device.h\n> index 07d3a846f8e1..0874c80f1e66 100644\n> --- a/src/android/camera_device.h\n> +++ b/src/android/camera_device.h\n> @@ -105,6 +105,8 @@ private:\n>  \tvoid notifyError(uint32_t frameNumber, camera3_stream_t *stream);\n>  \tCameraMetadata *requestTemplatePreview();\n>  \tlibcamera::PixelFormat toPixelFormat(int format) const;\n> +\tint processControls(camera3_capture_request_t *camera3Request,\n> +\t\t\t    Camera3RequestDescriptor *descriptor);\n>  \tstd::unique_ptr<CameraMetadata> getResultMetadata(\n>  \t\tCamera3RequestDescriptor *descriptor, int64_t timestamp);\n>  \n> diff --git a/src/android/camera_worker.h b/src/android/camera_worker.h\n> index 847a2fc4bd7c..6522f1d68a20 100644\n> --- a/src/android/camera_worker.h\n> +++ b/src/android/camera_worker.h\n> @@ -25,6 +25,7 @@ public:\n>  \tCaptureRequest(libcamera::Camera *camera, uint64_t cookie);\n>  \n>  \tconst std::vector<int> &fences() const { return acquireFences_; }\n> +\tlibcamera::ControlList &controls() { return request_->controls(); }\n>  \tconst libcamera::ControlList &metadata() const\n>  \t{\n>  \t\treturn request_->metadata();","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 A9943BD808\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 11 Jan 2021 00:04:35 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 2A95968088;\n\tMon, 11 Jan 2021 01:04:35 +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 56DEE60317\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 11 Jan 2021 01:04:33 +0100 (CET)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 0414DEC;\n\tMon, 11 Jan 2021 01:04:31 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"t/801cxM\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1610323472;\n\tbh=29uKHcL5bV2EBHzxyd0xgi40z1Xo7KANzzw7cEHc1Lg=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=t/801cxMs3P/iyS343oZVaVcRbS3X+PwkAVP+vw78jC47P/WkjiaKpYOauHrhnsKM\n\tQLsBpGV91bgQE0n3YLhM7VLwaYjJDksW6HGCJBM7xfC986sfUt3+ca3XTHASwJ5sjY\n\tyM3Y8Fb5UI+4ih0dmtevkt5Fn9+rfCKUDt+kluFM=","Date":"Mon, 11 Jan 2021 02:04:18 +0200","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Jacopo Mondi <jacopo@jmondi.org>","Message-ID":"<X/uWAogoZLmiKgn1@pendragon.ideasonboard.com>","References":"<20210105190522.682324-1-jacopo@jmondi.org>\n\t<20210105190522.682324-11-jacopo@jmondi.org>","MIME-Version":"1.0","Content-Disposition":"inline","In-Reply-To":"<20210105190522.682324-11-jacopo@jmondi.org>","Subject":"Re: [libcamera-devel] [PATCH 10/12] android: camera_device: Handle\n\tSCALER_CROP_REGION","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>","Cc":"libcamera-devel@lists.libcamera.org","Content-Type":"text/plain; charset=\"us-ascii\"","Content-Transfer-Encoding":"7bit","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":14586,"web_url":"https://patchwork.libcamera.org/comment/14586/","msgid":"<YAWrpiOljdLYTUE7@oden.dyn.berto.se>","date":"2021-01-18T15:39:18","subject":"Re: [libcamera-devel] [PATCH 10/12] android: camera_device: Handle\n\tSCALER_CROP_REGION","submitter":{"id":5,"url":"https://patchwork.libcamera.org/api/people/5/","name":"Niklas Söderlund","email":"niklas.soderlund@ragnatech.se"},"content":"Hi Jacopo,\n\nThanks for your work.\n\nOn 2021-01-05 20:05:20 +0100, Jacopo Mondi wrote:\n> Handle the SCALER_CROP_REGION control and dynamic metadata by\n> translating it from the Android format to the associated libcamera\n> control when processing a request, and the other way around when\n> handling a request completion.\n> \n> Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>\n> ---\n>  src/android/camera_device.cpp | 52 +++++++++++++++++++++++++++++++----\n>  src/android/camera_device.h   |  2 ++\n>  src/android/camera_worker.h   |  1 +\n>  3 files changed, 49 insertions(+), 6 deletions(-)\n> \n> diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp\n> index 99297270598f..5f5e6576365b 100644\n> --- a/src/android/camera_device.cpp\n> +++ b/src/android/camera_device.cpp\n> @@ -1586,6 +1586,35 @@ FrameBuffer *CameraDevice::createFrameBuffer(const buffer_handle_t camera3buffer\n>  \treturn new FrameBuffer(std::move(planes));\n>  }\n>  \n> +int CameraDevice::processControls(camera3_capture_request_t *camera3Request,\n> +\t\t\t\t  Camera3RequestDescriptor *descriptor)\n> +{\n> +\tif (!camera3Request->settings)\n> +\t\treturn 0;\n> +\n> +\t/*\n> +\t * Translate the Android controls to libcamera.\n> +\t *\n> +\t * \\todo As soon as more controls are handled, this part should be\n> +\t * broke out to a dedicated function.\n> +\t */\n> +\tconst camera_metadata_t *camera3Settings = camera3Request->settings;\n> +\tcamera_metadata_ro_entry_t entry;\n> +\tint ret = find_camera_metadata_ro_entry(camera3Settings,\n> +\t\t\t\t\t\tANDROID_SCALER_CROP_REGION,\n> +\t\t\t\t\t\t&entry);\n> +\tif (!ret) {\n> +\t\tconst int32_t *data = entry.data.i32;\n> +\t\tRectangle cropRegion = { data[0], data[1],\n> +\t\t\t\t\t static_cast<unsigned int>(data[2]),\n> +\t\t\t\t\t static_cast<unsigned int>(data[3]) };\n> +\t\tControlList &controls = descriptor->request_->controls();\n> +\t\tcontrols.set(controls::ScalerCrop, cropRegion);\n> +\t}\n> +\n> +\treturn 0;\n> +}\n> +\n>  int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Request)\n>  {\n>  \tif (!camera3Request) {\n> @@ -1697,7 +1726,14 @@ int CameraDevice::processCaptureRequest(camera3_capture_request_t *camera3Reques\n>  \t\t\t\t\t\tcamera3Buffers[i].acquire_fence);\n>  \t}\n>  \n> -\t/* Queue the request to the CameraWorker. */\n> +\t/*\n> +\t * Translate controls from Android to libcamera and queue the request\n> +\t * to the CameraWorker thread.\n> +\t */\n> +\tint ret = processControls(camera3Request, descriptor);\n> +\tif (ret)\n> +\t\treturn ret;\n\nI like how the different blocks are falling into place, nice!\n\nReviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n\n> +\n>  \tworker_.queueRequest(descriptor->request_.get());\n>  \n>  \treturn 0;\n> @@ -1876,11 +1912,6 @@ CameraDevice::getResultMetadata(Camera3RequestDescriptor *descriptor,\n>  \tconst uint8_t lens_state = ANDROID_LENS_STATE_STATIONARY;\n>  \tresultMetadata->addEntry(ANDROID_LENS_STATE, &lens_state, 1);\n>  \n> -\tint32_t sensorSizes[] = {\n> -\t\t0, 0, 2560, 1920,\n> -\t};\n> -\tresultMetadata->addEntry(ANDROID_SCALER_CROP_REGION, sensorSizes, 4);\n> -\n>  \tresultMetadata->addEntry(ANDROID_SENSOR_TIMESTAMP, &timestamp, 1);\n>  \n>  \t/* 33.3 msec */\n> @@ -1911,6 +1942,15 @@ CameraDevice::getResultMetadata(Camera3RequestDescriptor *descriptor,\n>  \t\t\t\t\t &exposure, 1);\n>  \t}\n>  \n> +\tif (metadata.contains(controls::ScalerCrop)) {\n> +\t\tRectangle crop = metadata.get(controls::ScalerCrop);\n> +\t\tint32_t cropRect[] = {\n> +\t\t\tcrop.x, crop.y, static_cast<int32_t>(crop.width),\n> +\t\t\tstatic_cast<int32_t>(crop.height),\n> +\t\t};\n> +\t\tresultMetadata->addEntry(ANDROID_SCALER_CROP_REGION, cropRect, 4);\n> +\t}\n> +\n>  \t/*\n>  \t * Return the result metadata pack even is not valid: get() will return\n>  \t * nullptr.\n> diff --git a/src/android/camera_device.h b/src/android/camera_device.h\n> index 07d3a846f8e1..0874c80f1e66 100644\n> --- a/src/android/camera_device.h\n> +++ b/src/android/camera_device.h\n> @@ -105,6 +105,8 @@ private:\n>  \tvoid notifyError(uint32_t frameNumber, camera3_stream_t *stream);\n>  \tCameraMetadata *requestTemplatePreview();\n>  \tlibcamera::PixelFormat toPixelFormat(int format) const;\n> +\tint processControls(camera3_capture_request_t *camera3Request,\n> +\t\t\t    Camera3RequestDescriptor *descriptor);\n>  \tstd::unique_ptr<CameraMetadata> getResultMetadata(\n>  \t\tCamera3RequestDescriptor *descriptor, int64_t timestamp);\n>  \n> diff --git a/src/android/camera_worker.h b/src/android/camera_worker.h\n> index 847a2fc4bd7c..6522f1d68a20 100644\n> --- a/src/android/camera_worker.h\n> +++ b/src/android/camera_worker.h\n> @@ -25,6 +25,7 @@ public:\n>  \tCaptureRequest(libcamera::Camera *camera, uint64_t cookie);\n>  \n>  \tconst std::vector<int> &fences() const { return acquireFences_; }\n> +\tlibcamera::ControlList &controls() { return request_->controls(); }\n>  \tconst libcamera::ControlList &metadata() const\n>  \t{\n>  \t\treturn request_->metadata();\n> -- \n> 2.29.2\n> \n> _______________________________________________\n> libcamera-devel mailing list\n> libcamera-devel@lists.libcamera.org\n> https://lists.libcamera.org/listinfo/libcamera-devel","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 18243C0F1C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon, 18 Jan 2021 15:39:22 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id DB1EB6812E;\n\tMon, 18 Jan 2021 16:39:21 +0100 (CET)","from mail-lf1-x133.google.com (mail-lf1-x133.google.com\n\t[IPv6:2a00:1450:4864:20::133])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 709856010B\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 18 Jan 2021 16:39:20 +0100 (CET)","by mail-lf1-x133.google.com with SMTP id o13so24711894lfr.3\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 18 Jan 2021 07:39:20 -0800 (PST)","from localhost (h-209-203.A463.priv.bahnhof.se. [155.4.209.203])\n\tby smtp.gmail.com with ESMTPSA id\n\tx186sm1930893lff.76.2021.01.18.07.39.19\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tMon, 18 Jan 2021 07:39:19 -0800 (PST)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=ragnatech-se.20150623.gappssmtp.com\n\theader.i=@ragnatech-se.20150623.gappssmtp.com\n\theader.b=\"Fd2e5+Mb\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=ragnatech-se.20150623.gappssmtp.com; s=20150623;\n\th=date:from:to:cc:subject:message-id:references:mime-version\n\t:content-disposition:content-transfer-encoding:in-reply-to;\n\tbh=y0ZNiGIiuMRnXrquUcdaE56oYRpd23twW8el86uMDdw=;\n\tb=Fd2e5+MbbYPuJQrDHb1t643jt7YptUmYuFg49OzJS1LuwSobP1iuPWYPeQPDysiaac\n\t+TbDYGppotuwepgIxS0lzfPaHaBm1L+4f2/ATRYMPHP6I8isBdpqDBx6jh6WOGxMjOb+\n\tSFXfV9QzlfO0ajjbmP7zUz7esEx0joA2oopA5olb/pKY8WTdzCrloI+jUlIpmHOvQ67t\n\tXdUeJlyNrxK5676ZZ02LoFlJxZ7QSZcRD/s85sCiObLwkil/UxXVnmFkvYup10/b/efl\n\tdq6L+nnXfrLd1KQamXJ9G2eEwRwwvhy+efEaaKH+027hayx8bincciHrxs1eX7E5vDA5\n\t3Iog==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:date:from:to:cc:subject:message-id:references\n\t:mime-version:content-disposition:content-transfer-encoding\n\t:in-reply-to;\n\tbh=y0ZNiGIiuMRnXrquUcdaE56oYRpd23twW8el86uMDdw=;\n\tb=jslLazd7nNVJK3xPhdsjBPSqBkwFr+jXvxhyb1DhdnIim9aueZ2Hs5Ke+Ly6wWD2aW\n\t1c0v22jQqDfRsS8pHoykgyX9Qh/cFKNdCYMk/Bam8LWusQ5GrYi5hQG1+kJ7iXK+lvAK\n\t0/t0lo30pyo9T1N7g09pUDoEbmYc8P6l/bCM9rxlDdUOnMAdaNb6wKjWveIR8nTk6MvU\n\tX54LkKeS5DNAipslOkTgySmPCyYymAdQIQUv5gFXqq/Zf/yGETKAzPkjyB5iQd0l7Crp\n\trViDCbZYs4cqImIFpU7Bt4GtHbnt8CORqmgXiT6Qh+8EROdF+2BYffclyw+/JV+24OfZ\n\tsGOA==","X-Gm-Message-State":"AOAM532fZPSbB6wMqyIAEs3VJKi25PHX4mUJP2DAoWRxg+UWsNxlPx1d\n\tD30XyCAexfhQCVqsT5viOhvYCw==","X-Google-Smtp-Source":"ABdhPJziX7rgD9jwBQF3QQurv0bQgIdq2hbRO1EBfKYHjtpWqvQaAl/41VT66wrK5LMO7DNRsg270g==","X-Received":"by 2002:a05:6512:3321:: with SMTP id\n\tl1mr11634460lfe.473.1610984359923; \n\tMon, 18 Jan 2021 07:39:19 -0800 (PST)","Date":"Mon, 18 Jan 2021 16:39:18 +0100","From":"Niklas =?iso-8859-1?q?S=F6derlund?= <niklas.soderlund@ragnatech.se>","To":"Jacopo Mondi <jacopo@jmondi.org>","Message-ID":"<YAWrpiOljdLYTUE7@oden.dyn.berto.se>","References":"<20210105190522.682324-1-jacopo@jmondi.org>\n\t<20210105190522.682324-11-jacopo@jmondi.org>","MIME-Version":"1.0","Content-Disposition":"inline","In-Reply-To":"<20210105190522.682324-11-jacopo@jmondi.org>","Subject":"Re: [libcamera-devel] [PATCH 10/12] android: camera_device: Handle\n\tSCALER_CROP_REGION","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>","Cc":"libcamera-devel@lists.libcamera.org","Content-Type":"text/plain; charset=\"iso-8859-1\"","Content-Transfer-Encoding":"quoted-printable","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]