{"id":22123,"url":"https://patchwork.libcamera.org/api/1.1/patches/22123/?format=json","web_url":"https://patchwork.libcamera.org/patch/22123/","project":{"id":1,"url":"https://patchwork.libcamera.org/api/1.1/projects/1/?format=json","name":"libcamera","link_name":"libcamera","list_id":"libcamera_core","list_email":"libcamera-devel@lists.libcamera.org","web_url":"","scm_url":"","webscm_url":""},"msgid":"<20241127133233.247977-3-dan.scally@ideasonboard.com>","date":"2024-11-27T13:32:33","name":"[2/2] libcamera: rpi: Draw sensor delays from CameraSensorProperties","commit_ref":null,"pull_url":null,"state":"accepted","archived":false,"hash":"c8a9dada1e55faf028e2bf92832401c56d3bd088","submitter":{"id":156,"url":"https://patchwork.libcamera.org/api/1.1/people/156/?format=json","name":"Dan Scally","email":"dan.scally@ideasonboard.com"},"delegate":null,"mbox":"https://patchwork.libcamera.org/patch/22123/mbox/","series":[{"id":4829,"url":"https://patchwork.libcamera.org/api/1.1/series/4829/?format=json","web_url":"https://patchwork.libcamera.org/project/libcamera/list/?series=4829","date":"2024-11-27T13:32:31","name":"Use Sensor Delays from CameraSensorProperties in RPi","version":1,"mbox":"https://patchwork.libcamera.org/series/4829/mbox/"}],"comments":"https://patchwork.libcamera.org/api/patches/22123/comments/","check":"pending","checks":"https://patchwork.libcamera.org/api/patches/22123/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 D4B68C3213\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 27 Nov 2024 13:32:54 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id A78B2660DC;\n\tWed, 27 Nov 2024 14:32:53 +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 04F2B660C4\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 27 Nov 2024 14:32:49 +0100 (CET)","from mail.ideasonboard.com\n\t(cpc141996-chfd3-2-0-cust928.12-3.cable.virginm.net [86.13.91.161])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id D6FB4842;\n\tWed, 27 Nov 2024 14:32:25 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"YX2CEON/\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1732714346;\n\tbh=Waz7+RBByPFUQtLsKJryVRhn8kjzPsULS0NCYeLvTvU=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=YX2CEON/1mILIPRWUc2+JmHrXGpvfIRr9VBm5XhaQ86ZPGM91mV6UASIGPSGZld0G\n\txSCXfIySiVLGHVfEdO12pXbNQsW+E/HvQaBaI4B7Mn+8Bq1+pjrHbyJDCcEDaG4MMP\n\tNOo/1MCgKEwo8oxnY98nHD4CZk1zmNehVGhO+GRg=","From":"Daniel Scally <dan.scally@ideasonboard.com>","To":"libcamera-devel@lists.libcamera.org","Cc":"david.plowman@raspberrypi.com, naush@raspberrypi.com,\n\tDaniel Scally <dan.scally@ideasonboard.com>","Subject":"[PATCH 2/2] libcamera: rpi: Draw sensor delays from\n\tCameraSensorProperties","Date":"Wed, 27 Nov 2024 13:32:33 +0000","Message-Id":"<20241127133233.247977-3-dan.scally@ideasonboard.com>","X-Mailer":"git-send-email 2.34.1","In-Reply-To":"<20241127133233.247977-1-dan.scally@ideasonboard.com>","References":"<20241127133233.247977-1-dan.scally@ideasonboard.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":"Now that we have camera sensor control application delay values in\nthe CameraSensorProperties class, remove the duplicated definitions\nin the RPi IPA's CameraSensorHelpers and update the pipeline handler\nto use the values from CameraSensorProperties.\n\nSigned-off-by: Daniel Scally <dan.scally@ideasonboard.com>\n---\n include/libcamera/ipa/raspberrypi.mojom           |  4 ----\n src/ipa/rpi/cam_helper/cam_helper.cpp             | 13 -------------\n src/ipa/rpi/cam_helper/cam_helper.h               |  7 -------\n src/ipa/rpi/cam_helper/cam_helper_imx283.cpp      | 12 ------------\n src/ipa/rpi/cam_helper/cam_helper_imx290.cpp      | 11 -----------\n src/ipa/rpi/cam_helper/cam_helper_imx296.cpp      | 11 -----------\n src/ipa/rpi/cam_helper/cam_helper_imx477.cpp      | 11 -----------\n src/ipa/rpi/cam_helper/cam_helper_imx519.cpp      | 11 -----------\n src/ipa/rpi/cam_helper/cam_helper_imx708.cpp      | 11 -----------\n src/ipa/rpi/cam_helper/cam_helper_ov5647.cpp      | 15 ---------------\n src/ipa/rpi/cam_helper/cam_helper_ov64a40.cpp     | 12 ------------\n src/ipa/rpi/cam_helper/cam_helper_ov7251.cpp      | 12 ------------\n src/ipa/rpi/cam_helper/cam_helper_ov9281.cpp      | 12 ------------\n src/ipa/rpi/common/ipa_base.cpp                   | 14 ++------------\n .../pipeline/rpi/common/pipeline_base.cpp         |  9 +++++----\n 15 files changed, 7 insertions(+), 158 deletions(-)","diff":"diff --git a/include/libcamera/ipa/raspberrypi.mojom b/include/libcamera/ipa/raspberrypi.mojom\nindex 0b92587d..e30c70bd 100644\n--- a/include/libcamera/ipa/raspberrypi.mojom\n+++ b/include/libcamera/ipa/raspberrypi.mojom\n@@ -12,10 +12,6 @@ import \"include/libcamera/ipa/core.mojom\";\n const uint32 MaxLsGridSize = 0x8000;\n \n struct SensorConfig {\n-\tuint32 gainDelay;\n-\tuint32 exposureDelay;\n-\tuint32 vblankDelay;\n-\tuint32 hblankDelay;\n \tuint32 sensorMetadata;\n };\n \ndiff --git a/src/ipa/rpi/cam_helper/cam_helper.cpp b/src/ipa/rpi/cam_helper/cam_helper.cpp\nindex 6493e882..8c720652 100644\n--- a/src/ipa/rpi/cam_helper/cam_helper.cpp\n+++ b/src/ipa/rpi/cam_helper/cam_helper.cpp\n@@ -156,19 +156,6 @@ void CamHelper::setCameraMode(const CameraMode &mode)\n \t}\n }\n \n-void CamHelper::getDelays(int &exposureDelay, int &gainDelay,\n-\t\t\t  int &vblankDelay, int &hblankDelay) const\n-{\n-\t/*\n-\t * These values are correct for many sensors. Other sensors will\n-\t * need to over-ride this function.\n-\t */\n-\texposureDelay = 2;\n-\tgainDelay = 1;\n-\tvblankDelay = 2;\n-\thblankDelay = 2;\n-}\n-\n bool CamHelper::sensorEmbeddedDataPresent() const\n {\n \treturn false;\ndiff --git a/src/ipa/rpi/cam_helper/cam_helper.h b/src/ipa/rpi/cam_helper/cam_helper.h\nindex 4a4ab5e6..29371bdb 100644\n--- a/src/ipa/rpi/cam_helper/cam_helper.h\n+++ b/src/ipa/rpi/cam_helper/cam_helper.h\n@@ -36,11 +36,6 @@ namespace RPiController {\n  * exposure time, and to convert between the sensor's gain codes and actual\n  * gains.\n  *\n- * A function to return the number of frames of delay between updating exposure,\n- * analogue gain and vblanking, and for the changes to take effect. For many\n- * sensors these take the values 2, 1 and 2 respectively, but sensors that are\n- * different will need to over-ride the default function provided.\n- *\n  * A function to query if the sensor outputs embedded data that can be parsed.\n  *\n  * A function to return the sensitivity of a given camera mode.\n@@ -91,8 +86,6 @@ public:\n \tlibcamera::utils::Duration lineLengthPckToDuration(uint32_t lineLengthPck) const;\n \tvirtual uint32_t gainCode(double gain) const = 0;\n \tvirtual double gain(uint32_t gainCode) const = 0;\n-\tvirtual void getDelays(int &exposureDelay, int &gainDelay,\n-\t\t\t       int &vblankDelay, int &hblankDelay) const;\n \tvirtual bool sensorEmbeddedDataPresent() const;\n \tvirtual double getModeSensitivity(const CameraMode &mode) const;\n \tvirtual unsigned int hideFramesStartup() const;\ndiff --git a/src/ipa/rpi/cam_helper/cam_helper_imx283.cpp b/src/ipa/rpi/cam_helper/cam_helper_imx283.cpp\nindex cb0be72a..efc03193 100644\n--- a/src/ipa/rpi/cam_helper/cam_helper_imx283.cpp\n+++ b/src/ipa/rpi/cam_helper/cam_helper_imx283.cpp\n@@ -17,8 +17,6 @@ public:\n \tCamHelperImx283();\n \tuint32_t gainCode(double gain) const override;\n \tdouble gain(uint32_t gainCode) const override;\n-\tvoid getDelays(int &exposureDelay, int &gainDelay,\n-\t\t       int &vblankDelay, int &hblankDelay) const override;\n \tunsigned int hideFramesModeSwitch() const override;\n \n private:\n@@ -49,16 +47,6 @@ double CamHelperImx283::gain(uint32_t gainCode) const\n \treturn static_cast<double>(2048.0 / (2048 - gainCode));\n }\n \n-void CamHelperImx283::getDelays(int &exposureDelay, int &gainDelay,\n-\t\t\t\tint &vblankDelay, int &hblankDelay) const\n-{\n-\t/* The driver appears to behave as follows: */\n-\texposureDelay = 2;\n-\tgainDelay = 2;\n-\tvblankDelay = 2;\n-\thblankDelay = 2;\n-}\n-\n unsigned int CamHelperImx283::hideFramesModeSwitch() const\n {\n \t/* After a mode switch, we seem to get 1 bad frame. */\ndiff --git a/src/ipa/rpi/cam_helper/cam_helper_imx290.cpp b/src/ipa/rpi/cam_helper/cam_helper_imx290.cpp\nindex 3b87751e..c1aa8528 100644\n--- a/src/ipa/rpi/cam_helper/cam_helper_imx290.cpp\n+++ b/src/ipa/rpi/cam_helper/cam_helper_imx290.cpp\n@@ -17,8 +17,6 @@ public:\n \tCamHelperImx290();\n \tuint32_t gainCode(double gain) const override;\n \tdouble gain(uint32_t gainCode) const override;\n-\tvoid getDelays(int &exposureDelay, int &gainDelay,\n-\t\t       int &vblankDelay, int &hblankDelay) const override;\n \tunsigned int hideFramesStartup() const override;\n \tunsigned int hideFramesModeSwitch() const override;\n \n@@ -46,15 +44,6 @@ double CamHelperImx290::gain(uint32_t gainCode) const\n \treturn std::pow(10, 0.015 * gainCode);\n }\n \n-void CamHelperImx290::getDelays(int &exposureDelay, int &gainDelay,\n-\t\t\t\tint &vblankDelay, int &hblankDelay) const\n-{\n-\texposureDelay = 2;\n-\tgainDelay = 2;\n-\tvblankDelay = 2;\n-\thblankDelay = 2;\n-}\n-\n unsigned int CamHelperImx290::hideFramesStartup() const\n {\n \t/* On startup, we seem to get 1 bad frame. */\ndiff --git a/src/ipa/rpi/cam_helper/cam_helper_imx296.cpp b/src/ipa/rpi/cam_helper/cam_helper_imx296.cpp\nindex d4a4fa79..ac7ee2ea 100644\n--- a/src/ipa/rpi/cam_helper/cam_helper_imx296.cpp\n+++ b/src/ipa/rpi/cam_helper/cam_helper_imx296.cpp\n@@ -23,8 +23,6 @@ public:\n \tdouble gain(uint32_t gainCode) const override;\n \tuint32_t exposureLines(const Duration exposure, const Duration lineLength) const override;\n \tDuration exposure(uint32_t exposureLines, const Duration lineLength) const override;\n-\tvoid getDelays(int &exposureDelay, int &gainDelay,\n-\t\t       int &vblankDelay, int &hblankDelay) const override;\n \n private:\n \tstatic constexpr uint32_t minExposureLines = 1;\n@@ -66,15 +64,6 @@ Duration CamHelperImx296::exposure(uint32_t exposureLines,\n \treturn std::max<uint32_t>(minExposureLines, exposureLines) * timePerLine + 14.26us;\n }\n \n-void CamHelperImx296::getDelays(int &exposureDelay, int &gainDelay,\n-\t\t\t\tint &vblankDelay, int &hblankDelay) const\n-{\n-\texposureDelay = 2;\n-\tgainDelay = 2;\n-\tvblankDelay = 2;\n-\thblankDelay = 2;\n-}\n-\n static CamHelper *create()\n {\n \treturn new CamHelperImx296();\ndiff --git a/src/ipa/rpi/cam_helper/cam_helper_imx477.cpp b/src/ipa/rpi/cam_helper/cam_helper_imx477.cpp\nindex a53c40cd..a72ac67d 100644\n--- a/src/ipa/rpi/cam_helper/cam_helper_imx477.cpp\n+++ b/src/ipa/rpi/cam_helper/cam_helper_imx477.cpp\n@@ -51,8 +51,6 @@ public:\n \tvoid prepare(libcamera::Span<const uint8_t> buffer, Metadata &metadata) override;\n \tstd::pair<uint32_t, uint32_t> getBlanking(Duration &exposure, Duration minFrameDuration,\n \t\t\t\t\t\t  Duration maxFrameDuration) const override;\n-\tvoid getDelays(int &exposureDelay, int &gainDelay,\n-\t\t       int &vblankDelay, int &hblankDelay) const override;\n \tbool sensorEmbeddedDataPresent() const override;\n \n private:\n@@ -159,15 +157,6 @@ std::pair<uint32_t, uint32_t> CamHelperImx477::getBlanking(Duration &exposure,\n \treturn { frameLength - mode_.height, hblank };\n }\n \n-void CamHelperImx477::getDelays(int &exposureDelay, int &gainDelay,\n-\t\t\t\tint &vblankDelay, int &hblankDelay) const\n-{\n-\texposureDelay = 2;\n-\tgainDelay = 2;\n-\tvblankDelay = 3;\n-\thblankDelay = 3;\n-}\n-\n bool CamHelperImx477::sensorEmbeddedDataPresent() const\n {\n \treturn true;\ndiff --git a/src/ipa/rpi/cam_helper/cam_helper_imx519.cpp b/src/ipa/rpi/cam_helper/cam_helper_imx519.cpp\nindex 2ff08653..10cbea48 100644\n--- a/src/ipa/rpi/cam_helper/cam_helper_imx519.cpp\n+++ b/src/ipa/rpi/cam_helper/cam_helper_imx519.cpp\n@@ -51,8 +51,6 @@ public:\n \tvoid prepare(libcamera::Span<const uint8_t> buffer, Metadata &metadata) override;\n \tstd::pair<uint32_t, uint32_t> getBlanking(Duration &exposure, Duration minFrameDuration,\n \t\t\t\t\t\t  Duration maxFrameDuration) const override;\n-\tvoid getDelays(int &exposureDelay, int &gainDelay,\n-\t\t       int &vblankDelay, int &hblankDelay) const override;\n \tbool sensorEmbeddedDataPresent() const override;\n \n private:\n@@ -159,15 +157,6 @@ std::pair<uint32_t, uint32_t> CamHelperImx519::getBlanking(Duration &exposure,\n \treturn { frameLength - mode_.height, hblank };\n }\n \n-void CamHelperImx519::getDelays(int &exposureDelay, int &gainDelay,\n-\t\t\t\tint &vblankDelay, int &hblankDelay) const\n-{\n-\texposureDelay = 2;\n-\tgainDelay = 2;\n-\tvblankDelay = 3;\n-\thblankDelay = 3;\n-}\n-\n bool CamHelperImx519::sensorEmbeddedDataPresent() const\n {\n \treturn true;\ndiff --git a/src/ipa/rpi/cam_helper/cam_helper_imx708.cpp b/src/ipa/rpi/cam_helper/cam_helper_imx708.cpp\nindex ec83d9fd..24ffc846 100644\n--- a/src/ipa/rpi/cam_helper/cam_helper_imx708.cpp\n+++ b/src/ipa/rpi/cam_helper/cam_helper_imx708.cpp\n@@ -54,8 +54,6 @@ public:\n \tvoid process(StatisticsPtr &stats, Metadata &metadata) override;\n \tstd::pair<uint32_t, uint32_t> getBlanking(Duration &exposure, Duration minFrameDuration,\n \t\t\t\t\t\t  Duration maxFrameDuration) const override;\n-\tvoid getDelays(int &exposureDelay, int &gainDelay,\n-\t\t       int &vblankDelay, int &hblankDelay) const override;\n \tbool sensorEmbeddedDataPresent() const override;\n \tdouble getModeSensitivity(const CameraMode &mode) const override;\n \tunsigned int hideFramesModeSwitch() const override;\n@@ -208,15 +206,6 @@ std::pair<uint32_t, uint32_t> CamHelperImx708::getBlanking(Duration &exposure,\n \treturn { frameLength - mode_.height, hblank };\n }\n \n-void CamHelperImx708::getDelays(int &exposureDelay, int &gainDelay,\n-\t\t\t\tint &vblankDelay, int &hblankDelay) const\n-{\n-\texposureDelay = 2;\n-\tgainDelay = 2;\n-\tvblankDelay = 3;\n-\thblankDelay = 3;\n-}\n-\n bool CamHelperImx708::sensorEmbeddedDataPresent() const\n {\n \treturn true;\ndiff --git a/src/ipa/rpi/cam_helper/cam_helper_ov5647.cpp b/src/ipa/rpi/cam_helper/cam_helper_ov5647.cpp\nindex c30b017c..40d6b6d7 100644\n--- a/src/ipa/rpi/cam_helper/cam_helper_ov5647.cpp\n+++ b/src/ipa/rpi/cam_helper/cam_helper_ov5647.cpp\n@@ -17,8 +17,6 @@ public:\n \tCamHelperOv5647();\n \tuint32_t gainCode(double gain) const override;\n \tdouble gain(uint32_t gainCode) const override;\n-\tvoid getDelays(int &exposureDelay, int &gainDelay,\n-\t\t       int &vblankDelay, int &hblankDelay) const override;\n \tunsigned int hideFramesStartup() const override;\n \tunsigned int hideFramesModeSwitch() const override;\n \tunsigned int mistrustFramesStartup() const override;\n@@ -52,19 +50,6 @@ double CamHelperOv5647::gain(uint32_t gainCode) const\n \treturn static_cast<double>(gainCode) / 16.0;\n }\n \n-void CamHelperOv5647::getDelays(int &exposureDelay, int &gainDelay,\n-\t\t\t\tint &vblankDelay, int &hblankDelay) const\n-{\n-\t/*\n-\t * We run this sensor in a mode where the gain delay is bumped up to\n-\t * 2. It seems to be the only way to make the delays \"predictable\".\n-\t */\n-\texposureDelay = 2;\n-\tgainDelay = 2;\n-\tvblankDelay = 2;\n-\thblankDelay = 2;\n-}\n-\n unsigned int CamHelperOv5647::hideFramesStartup() const\n {\n \t/*\ndiff --git a/src/ipa/rpi/cam_helper/cam_helper_ov64a40.cpp b/src/ipa/rpi/cam_helper/cam_helper_ov64a40.cpp\nindex a8efd389..980495a8 100644\n--- a/src/ipa/rpi/cam_helper/cam_helper_ov64a40.cpp\n+++ b/src/ipa/rpi/cam_helper/cam_helper_ov64a40.cpp\n@@ -18,8 +18,6 @@ public:\n \tCamHelperOv64a40();\n \tuint32_t gainCode(double gain) const override;\n \tdouble gain(uint32_t gainCode) const override;\n-\tvoid getDelays(int &exposureDelay, int &gainDelay,\n-\t\t       int &vblankDelay, int &hblankDelay) const override;\n \tdouble getModeSensitivity(const CameraMode &mode) const override;\n \n private:\n@@ -45,16 +43,6 @@ double CamHelperOv64a40::gain(uint32_t gainCode) const\n \treturn static_cast<double>(gainCode) / 128.0;\n }\n \n-void CamHelperOv64a40::getDelays(int &exposureDelay, int &gainDelay,\n-\t\t\t\t int &vblankDelay, int &hblankDelay) const\n-{\n-\t/* The driver appears to behave as follows: */\n-\texposureDelay = 2;\n-\tgainDelay = 2;\n-\tvblankDelay = 2;\n-\thblankDelay = 2;\n-}\n-\n double CamHelperOv64a40::getModeSensitivity(const CameraMode &mode) const\n {\n \tif (mode.binX >= 2 && mode.scaleX >= 4) {\ndiff --git a/src/ipa/rpi/cam_helper/cam_helper_ov7251.cpp b/src/ipa/rpi/cam_helper/cam_helper_ov7251.cpp\nindex 7b12c445..fc7b999f 100644\n--- a/src/ipa/rpi/cam_helper/cam_helper_ov7251.cpp\n+++ b/src/ipa/rpi/cam_helper/cam_helper_ov7251.cpp\n@@ -17,8 +17,6 @@ public:\n \tCamHelperOv7251();\n \tuint32_t gainCode(double gain) const override;\n \tdouble gain(uint32_t gainCode) const override;\n-\tvoid getDelays(int &exposureDelay, int &gainDelay,\n-\t\t       int &vblankDelay, int &hblankDelay) const override;\n \n private:\n \t/*\n@@ -48,16 +46,6 @@ double CamHelperOv7251::gain(uint32_t gainCode) const\n \treturn static_cast<double>(gainCode) / 16.0;\n }\n \n-void CamHelperOv7251::getDelays(int &exposureDelay, int &gainDelay,\n-\t\t\t\tint &vblankDelay, int &hblankDelay) const\n-{\n-\t/* The driver appears to behave as follows: */\n-\texposureDelay = 2;\n-\tgainDelay = 2;\n-\tvblankDelay = 2;\n-\thblankDelay = 2;\n-}\n-\n static CamHelper *create()\n {\n \treturn new CamHelperOv7251();\ndiff --git a/src/ipa/rpi/cam_helper/cam_helper_ov9281.cpp b/src/ipa/rpi/cam_helper/cam_helper_ov9281.cpp\nindex a65c8ac0..e56868e4 100644\n--- a/src/ipa/rpi/cam_helper/cam_helper_ov9281.cpp\n+++ b/src/ipa/rpi/cam_helper/cam_helper_ov9281.cpp\n@@ -17,8 +17,6 @@ public:\n \tCamHelperOv9281();\n \tuint32_t gainCode(double gain) const override;\n \tdouble gain(uint32_t gainCode) const override;\n-\tvoid getDelays(int &exposureDelay, int &gainDelay,\n-\t\t       int &vblankDelay, int &hblankDelay) const override;\n \n private:\n \t/*\n@@ -48,16 +46,6 @@ double CamHelperOv9281::gain(uint32_t gainCode) const\n \treturn static_cast<double>(gainCode) / 16.0;\n }\n \n-void CamHelperOv9281::getDelays(int &exposureDelay, int &gainDelay,\n-\t\t\t\tint &vblankDelay, int &hblankDelay) const\n-{\n-\t/* The driver appears to behave as follows: */\n-\texposureDelay = 2;\n-\tgainDelay = 2;\n-\tvblankDelay = 2;\n-\thblankDelay = 2;\n-}\n-\n static CamHelper *create()\n {\n \treturn new CamHelperOv9281();\ndiff --git a/src/ipa/rpi/common/ipa_base.cpp b/src/ipa/rpi/common/ipa_base.cpp\nindex 5fce17e6..45e2a1d7 100644\n--- a/src/ipa/rpi/common/ipa_base.cpp\n+++ b/src/ipa/rpi/common/ipa_base.cpp\n@@ -134,18 +134,8 @@ int32_t IpaBase::init(const IPASettings &settings, const InitParams &params, Ini\n \t\treturn -EINVAL;\n \t}\n \n-\t/*\n-\t * Pass out the sensor config to the pipeline handler in order\n-\t * to setup the staggered writer class.\n-\t */\n-\tint gainDelay, exposureDelay, vblankDelay, hblankDelay, sensorMetadata;\n-\thelper_->getDelays(exposureDelay, gainDelay, vblankDelay, hblankDelay);\n-\tsensorMetadata = helper_->sensorEmbeddedDataPresent();\n-\n-\tresult->sensorConfig.gainDelay = gainDelay;\n-\tresult->sensorConfig.exposureDelay = exposureDelay;\n-\tresult->sensorConfig.vblankDelay = vblankDelay;\n-\tresult->sensorConfig.hblankDelay = hblankDelay;\n+\t/* Pass out the sensor metadata to the pipeline handler */\n+\tint sensorMetadata = helper_->sensorEmbeddedDataPresent();\n \tresult->sensorConfig.sensorMetadata = sensorMetadata;\n \n \t/* Load the tuning file for this sensor. */\ndiff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp\nindex 9e2d9d23..398a0280 100644\n--- a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp\n+++ b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp\n@@ -816,11 +816,12 @@ int PipelineHandlerBase::registerCamera(std::unique_ptr<RPi::CameraData> &camera\n \t * Setup our delayed control writer with the sensor default\n \t * gain and exposure delays. Mark VBLANK for priority write.\n \t */\n+\tconst CameraSensorProperties::SensorDelays &delays = data->sensor_->sensorDelays();\n \tstd::unordered_map<uint32_t, RPi::DelayedControls::ControlParams> params = {\n-\t\t{ V4L2_CID_ANALOGUE_GAIN, { result.sensorConfig.gainDelay, false } },\n-\t\t{ V4L2_CID_EXPOSURE, { result.sensorConfig.exposureDelay, false } },\n-\t\t{ V4L2_CID_HBLANK, { result.sensorConfig.hblankDelay, false } },\n-\t\t{ V4L2_CID_VBLANK, { result.sensorConfig.vblankDelay, true } }\n+\t\t{ V4L2_CID_ANALOGUE_GAIN, { delays.gainDelay, false } },\n+\t\t{ V4L2_CID_EXPOSURE, { delays.exposureDelay, false } },\n+\t\t{ V4L2_CID_HBLANK, { delays.hblankDelay, false } },\n+\t\t{ V4L2_CID_VBLANK, { delays.vblankDelay, true } }\n \t};\n \tdata->delayedCtrls_ = std::make_unique<RPi::DelayedControls>(data->sensor_->device(), params);\n \tdata->sensorMetadata_ = result.sensorConfig.sensorMetadata;\n","prefixes":["2/2"]}