From patchwork Thu Mar 4 08:17:22 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 11487 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 96E53BD80E for ; Thu, 4 Mar 2021 08:17:39 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 7DAEB68A9C; Thu, 4 Mar 2021 09:17:38 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="XvayiDeW"; dkim-atps=neutral Received: from mail-wr1-x42a.google.com (mail-wr1-x42a.google.com [IPv6:2a00:1450:4864:20::42a]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 0E958602EC for ; Thu, 4 Mar 2021 09:17:37 +0100 (CET) Received: by mail-wr1-x42a.google.com with SMTP id u16so8587593wrt.1 for ; Thu, 04 Mar 2021 00:17:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=nQyawJzd3tRJ8JoKcC5tO+9/7UXwcSecMyb9bdIf+D4=; b=XvayiDeWgh1f1lhdOFWRaqZS5LVddPPM4WJW+inaGii3EbhoK0C7zkRwpqawmCXsze tuDP9afrg8qqLk6wAzzdb3uDhg9zhlyfF2rWvyG2kZRH5BFu7MWKmNpYoVCHvj+myI2n JXXDDeZOmywl4NM10wNs0DAG4IA8DhqIgw/LQY3+2PDubCrCVZtggDAG/nS0aPqwIsT7 vhd1ebpmLIFcbFWtmHWoah2LyPrzktfJ0irxIB3PEPkYOgMQ4WF7x3pUVCzP6PaLjQKH CkX0EOPafJstXdvufZjwK7ac1MYSMQXoKCy2bgu8jzDrdoxzS/eLqohbPWRZmLAnuzdg i1lg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=nQyawJzd3tRJ8JoKcC5tO+9/7UXwcSecMyb9bdIf+D4=; b=cdZ+rVoAnKpFthuwCQOSQDw0oS0ti4oO28SRsChP/8xvhzxzn2O9f0+Cy78Dvepzdq Yh0x6SNehJOCGShoemwArYkZCXQZQRGN+WbDT/NVUhT4irSoJew/NSfB58k65xH5jMGz 46JyVeNUjOHX8J77X+33DHJtM4Sbif0bSTaizOmfTbBjcuKSucHN6XKPmbpqzJENhdHa oM5/7symHl3JYlzbSlwbt9ymTHWXt8pZ0gp2VgXeqMk2NUgELlcGXHRVlFIxfIO+CHdo dnupYoX1+LNUvp8X6mOF+E55K2zV891nzHqv6mRNTv21jwPIqFVBgaGuv9gzjMewGNVQ /qhg== X-Gm-Message-State: AOAM5322qxhVmhm9eu0hASsf2il7doNL6U9ahBntWgOJmjLMN69LTv5S Mx6CILCiBXviK/ypaTt49EJYVxJfBytc5ge+ X-Google-Smtp-Source: ABdhPJwAVHNl9v672/OG1grqY13vv7KYvmQg52vizWr+iVLjDusp24LFv2a1P/AR+wvd/FJF8pQYng== X-Received: by 2002:adf:b60f:: with SMTP id f15mr2677846wre.83.1614845856375; Thu, 04 Mar 2021 00:17:36 -0800 (PST) Received: from naush-laptop.patuck.local ([88.97.76.4]) by smtp.gmail.com with ESMTPSA id b186sm6997926wmc.44.2021.03.04.00.17.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Mar 2021 00:17:36 -0800 (PST) From: Naushir Patuck To: libcamera-devel@lists.libcamera.org Date: Thu, 4 Mar 2021 08:17:22 +0000 Message-Id: <20210304081728.1058394-2-naush@raspberrypi.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210304081728.1058394-1-naush@raspberrypi.com> References: <20210304081728.1058394-1-naush@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 1/7] libcamera: delayed_controls: Add notion of priority write X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" If an exposure time change adjusts the vblanking limits, and we set both VBLANK and EXPOSURE controls through the VIDIOC_S_EXT_CTRLS ioctl, the latter may fail if the value is outside of the limits calculated by the old VBLANK value. This is a limitation in V4L2 and cannot be fixed by setting VBLANK before EXPOSURE in a single VIDIOC_S_EXT_CTRLS ioctl. The workaround here is to have the DelayedControls object mark the VBLANK control as "priority write", which then write VBLANK separately from (and ahead of) any other controls. This way, the sensor driver will update the EXPOSURE control with new limits before the new values is presented, and will thus be seen as valid. To support this, a new struct DelayedControls::ControlParams is used in the constructor to provide the control delay value as well as the priority write flag. Signed-off-by: Naushir Patuck Tested-by: David Plowman Reviewed-by: Paul Elder Tested-by: Jean-Michel Hautbois Reviewed-by: Kieran Bingham --- include/libcamera/internal/delayed_controls.h | 9 +++- src/libcamera/delayed_controls.cpp | 54 +++++++++++++------ src/libcamera/pipeline/ipu3/ipu3.cpp | 8 +-- .../pipeline/raspberrypi/raspberrypi.cpp | 13 +++-- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 8 +-- test/delayed_contols.cpp | 20 +++---- 6 files changed, 68 insertions(+), 44 deletions(-) diff --git a/include/libcamera/internal/delayed_controls.h b/include/libcamera/internal/delayed_controls.h index dc447a882514..564d9f2e2440 100644 --- a/include/libcamera/internal/delayed_controls.h +++ b/include/libcamera/internal/delayed_controls.h @@ -19,8 +19,13 @@ class V4L2Device; class DelayedControls { public: + struct ControlParams { + unsigned int delay; + bool priorityWrite; + }; + DelayedControls(V4L2Device *device, - const std::unordered_map &delays); + const std::unordered_map &controlParams); void reset(); @@ -64,7 +69,7 @@ private: V4L2Device *device_; /* \todo Evaluate if we should index on ControlId * or unsigned int */ - std::unordered_map delays_; + std::unordered_map controlParams_; unsigned int maxDelay_; bool running_; diff --git a/src/libcamera/delayed_controls.cpp b/src/libcamera/delayed_controls.cpp index ab1d40057c5f..3ed1dfebd035 100644 --- a/src/libcamera/delayed_controls.cpp +++ b/src/libcamera/delayed_controls.cpp @@ -40,15 +40,19 @@ LOG_DEFINE_CATEGORY(DelayedControls) /** * \brief Construct a DelayedControls instance * \param[in] device The V4L2 device the controls have to be applied to - * \param[in] delays Map of the numerical V4L2 control ids to their associated - * delays (in frames) + * \param[in] controlParams Map of the numerical V4L2 control ids to their + * associated control parameters. * - * Only controls specified in \a delays are handled. If it's desired to mix - * delayed controls and controls that take effect immediately the immediate - * controls must be listed in the \a delays map with a delay value of 0. + * The control parameters comprise of delays (in frames) and a priority write + * flag. If this flag is set, the relevant control is written separately from, + * ahead of the reset of the batched controls. + * + * Only controls specified in \a controlParams are handled. If it's desired to + * mix delayed controls and controls that take effect immediately the immediate + * controls must be listed in the \a controlParams map with a delay value of 0. */ DelayedControls::DelayedControls(V4L2Device *device, - const std::unordered_map &delays) + const std::unordered_map &controlParams) : device_(device), maxDelay_(0) { const ControlInfoMap &controls = device_->controls(); @@ -57,12 +61,12 @@ DelayedControls::DelayedControls(V4L2Device *device, * Create a map of control ids to delays for controls exposed by the * device. */ - for (auto const &delay : delays) { - auto it = controls.find(delay.first); + for (auto const ¶m : controlParams) { + auto it = controls.find(param.first); if (it == controls.end()) { LOG(DelayedControls, Error) << "Delay request for control id " - << utils::hex(delay.first) + << utils::hex(param.first) << " but control is not exposed by device " << device_->deviceNode(); continue; @@ -70,13 +74,14 @@ DelayedControls::DelayedControls(V4L2Device *device, const ControlId *id = it->first; - delays_[id] = delay.second; + controlParams_[id] = param.second; LOG(DelayedControls, Debug) - << "Set a delay of " << delays_[id] + << "Set a delay of " << controlParams_[id].delay + << " and priority write flag " << controlParams_[id].priorityWrite << " for " << id->name(); - maxDelay_ = std::max(maxDelay_, delays_[id]); + maxDelay_ = std::max(maxDelay_, controlParams_[id].delay); } reset(); @@ -97,8 +102,8 @@ void DelayedControls::reset() /* Retrieve control as reported by the device. */ std::vector ids; - for (auto const &delay : delays_) - ids.push_back(delay.first->id()); + for (auto const ¶m : controlParams_) + ids.push_back(param.first->id()); ControlList controls = device_->getControls(ids); @@ -140,7 +145,7 @@ bool DelayedControls::push(const ControlList &controls) const ControlId *id = it->second; - if (delays_.find(id) == delays_.end()) + if (controlParams_.find(id) == controlParams_.end()) return false; Info &info = values_[id][queueCount_]; @@ -220,12 +225,27 @@ void DelayedControls::applyControls(uint32_t sequence) ControlList out(device_->controls()); for (const auto &ctrl : values_) { const ControlId *id = ctrl.first; - unsigned int delayDiff = maxDelay_ - delays_[id]; + unsigned int delayDiff = maxDelay_ - controlParams_[id].delay; unsigned int index = std::max(0, writeCount_ - delayDiff); const Info &info = ctrl.second[index]; if (info.updated) { - out.set(id->id(), info); + if (controlParams_[id].priorityWrite) { + /* + * This control must be written now, it could + * affect validity of the other controls. + */ + ControlList priority(device_->controls()); + priority.set(id->id(), info); + device_->setControls(&priority); + } else { + /* + * Batch up the list of controls and write them + * at the end of the function. + */ + out.set(id->id(), info); + } + LOG(DelayedControls, Debug) << "Setting " << id->name() << " to " << info.toString() diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 3e6b88af4188..ac92f066a07e 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -963,14 +963,14 @@ int PipelineHandlerIPU3::registerCameras() * a sensor database. For now use generic values taken from * the Raspberry Pi and listed as 'generic values'. */ - std::unordered_map delays = { - { V4L2_CID_ANALOGUE_GAIN, 1 }, - { V4L2_CID_EXPOSURE, 2 }, + std::unordered_map params = { + { V4L2_CID_ANALOGUE_GAIN, { 1, false } }, + { V4L2_CID_EXPOSURE, { 2, false } }, }; data->delayedCtrls_ = std::make_unique(cio2->sensor()->device(), - delays); + params); data->cio2_.frameStart().connect(data->delayedCtrls_.get(), &DelayedControls::applyControls); diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp index a60415d93705..ba74ace183db 100644 --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp @@ -1244,16 +1244,15 @@ int RPiCameraData::configureIPA(const CameraConfiguration *config) if (result.params & ipa::RPi::ConfigSensorParams) { /* * Setup our delayed control writer with the sensor default - * gain and exposure delays. + * gain and exposure delays. Mark VBLANK for priority write. */ - std::unordered_map delays = { - { V4L2_CID_ANALOGUE_GAIN, result.sensorConfig.gainDelay }, - { V4L2_CID_EXPOSURE, result.sensorConfig.exposureDelay }, - { V4L2_CID_VBLANK, result.sensorConfig.vblank } + std::unordered_map params = { + { V4L2_CID_ANALOGUE_GAIN, { result.sensorConfig.gainDelay, false } }, + { V4L2_CID_EXPOSURE, { result.sensorConfig.exposureDelay, false } }, + { V4L2_CID_VBLANK, { result.sensorConfig.vblank, true } } }; - delayedCtrls_ = std::make_unique(unicam_[Unicam::Image].dev(), delays); - + delayedCtrls_ = std::make_unique(unicam_[Unicam::Image].dev(), params); sensorMetadata_ = result.sensorConfig.sensorMetadata; } diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index a794501a9c8d..17c0f9751cd3 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -938,14 +938,14 @@ int PipelineHandlerRkISP1::createCamera(MediaEntity *sensor) * a sensor database. For now use generic values taken from * the Raspberry Pi and listed as generic values. */ - std::unordered_map delays = { - { V4L2_CID_ANALOGUE_GAIN, 1 }, - { V4L2_CID_EXPOSURE, 2 }, + std::unordered_map params = { + { V4L2_CID_ANALOGUE_GAIN, { 1, false } }, + { V4L2_CID_EXPOSURE, { 2, false } }, }; data->delayedCtrls_ = std::make_unique(data->sensor_->device(), - delays); + params); isp_->frameStart.connect(data->delayedCtrls_.get(), &DelayedControls::applyControls); diff --git a/test/delayed_contols.cpp b/test/delayed_contols.cpp index 50169b12e566..3855eb18ecd4 100644 --- a/test/delayed_contols.cpp +++ b/test/delayed_contols.cpp @@ -72,8 +72,8 @@ protected: int singleControlNoDelay() { - std::unordered_map delays = { - { V4L2_CID_BRIGHTNESS, 0 }, + std::unordered_map delays = { + { V4L2_CID_BRIGHTNESS, { 0, false } }, }; std::unique_ptr delayed = std::make_unique(dev_.get(), delays); @@ -109,8 +109,8 @@ protected: int singleControlWithDelay() { - std::unordered_map delays = { - { V4L2_CID_BRIGHTNESS, 1 }, + std::unordered_map delays = { + { V4L2_CID_BRIGHTNESS, { 1, false } }, }; std::unique_ptr delayed = std::make_unique(dev_.get(), delays); @@ -150,9 +150,9 @@ protected: int dualControlsWithDelay(uint32_t startOffset) { - std::unordered_map delays = { - { V4L2_CID_BRIGHTNESS, 1 }, - { V4L2_CID_CONTRAST, 2 }, + std::unordered_map delays = { + { V4L2_CID_BRIGHTNESS, { 1, false } }, + { V4L2_CID_CONTRAST, { 2, false } }, }; std::unique_ptr delayed = std::make_unique(dev_.get(), delays); @@ -197,9 +197,9 @@ protected: int dualControlsMultiQueue() { - std::unordered_map delays = { - { V4L2_CID_BRIGHTNESS, 1 }, - { V4L2_CID_CONTRAST, 2 }, + std::unordered_map delays = { + { V4L2_CID_BRIGHTNESS, { 1, false } }, + { V4L2_CID_CONTRAST, { 2, false } } }; std::unique_ptr delayed = std::make_unique(dev_.get(), delays); From patchwork Thu Mar 4 08:17:23 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 11488 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 56A72BD1F1 for ; Thu, 4 Mar 2021 08:17:40 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D0D7368AA3; Thu, 4 Mar 2021 09:17:39 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="eFBvkeiW"; dkim-atps=neutral Received: from mail-wm1-x330.google.com (mail-wm1-x330.google.com [IPv6:2a00:1450:4864:20::330]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 0D9A9602EC for ; Thu, 4 Mar 2021 09:17:38 +0100 (CET) Received: by mail-wm1-x330.google.com with SMTP id n4so8703873wmq.3 for ; Thu, 04 Mar 2021 00:17:38 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=a67QPnmZ/7naEtWkLMtX0KKvq0VldgvuT1P9Ujvt2t0=; b=eFBvkeiWdVMHgzcJnngnWKqfeHLCXZAUYFmLaW3LODw/aKTO06lwyP51RfI7L4atNy Ag62Uh42Hgr6kVdr7o22a8Rxf0t59FECJYDp4X7R2Vsv25K/jnn0u69E3QiX7AsEbmVl hrbeU1oj+Vu39suI29pybszZ/v/7OuzikkAdMvD3hHdge3t/1leTMBbfnnbuXuucyA/w i0i5xQYWIkBYJSZTMt4Ng2MXkYnXLETwzxS/eldIeQF9/lGgyWrRfkWUHU7/4gNqlovZ dg+oOb5/D6+M4XlaARmOpn1FhjATYD7Uy9hQxamleLJwR0w2XfBwRO6HWEbZTR1tDzdB M9IQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=a67QPnmZ/7naEtWkLMtX0KKvq0VldgvuT1P9Ujvt2t0=; b=SA0PfGmsLPe5Pov2Rehl+VnCS3tSVjY9qUezB/R4ulXyUUpYrY2+1ttMJWQIIMvO0f 1X+clWl1ubr0BpHradiZMYhuXk+1v2RVV1udD7tRQXv59u7SXOgUL4djLhE4E+BPOool nbjmLXA8a1GFzG+kjUiaBv/kWXNLjC5c/QpaTwiw9Rl7q3A5M9f+O7ubZ/XWoUF39ACQ IkaDjdRZafbzHYbO9uXAIBg8C3zeMfeyJzz8h6IY8352cFMFCs2+8i47D9tWIHYZ//JN Lt5YNi6+Sd9OwJYkoowJ9mvk4v+iaaedHS6Be+Rz+niRYM+4S1fzBt5NUFAqRbjwbojV 21sA== X-Gm-Message-State: AOAM532uaA7PjTVgwOjZLff5VS0gXyUBHiDZFQ1ENMJwO9/zbrPv7F+K +S2lyWeRqgXTOCCz8Ti1IoxafHS+eZ3ZxtVk X-Google-Smtp-Source: ABdhPJzxkCSxIX7VUtI7dUcLCrhglVY7LS0d1eBniMGHxyLh6/Pq5oY8bBbYaN/zeGp2ANU/jBcEqA== X-Received: by 2002:a7b:cc90:: with SMTP id p16mr2727943wma.45.1614845857406; Thu, 04 Mar 2021 00:17:37 -0800 (PST) Received: from naush-laptop.patuck.local ([88.97.76.4]) by smtp.gmail.com with ESMTPSA id b186sm6997926wmc.44.2021.03.04.00.17.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Mar 2021 00:17:37 -0800 (PST) From: Naushir Patuck To: libcamera-devel@lists.libcamera.org Date: Thu, 4 Mar 2021 08:17:23 +0000 Message-Id: <20210304081728.1058394-3-naush@raspberrypi.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210304081728.1058394-1-naush@raspberrypi.com> References: <20210304081728.1058394-1-naush@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 2/7] utils: raspberrypi: Add a DelayedControls log parser X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" This script will parse log output from the DelayedControls helper, when enabled with: LIBCAMERA_LOG_LEVELS=DelayedControls:0 It tabulates all control queuing/writing/getting per frame and warns about potential issues related to frame delays not being account for, or writes that are lagging behind or missed. Run with the following command: python3 ./delayedctrls_parse.py Signed-off-by: Naushir Patuck Tested-by: David Plowman Acked-by: Paul Elder Tested-by: Jean-Michel Hautbois Reviewed-by: Kieran Bingham --- utils/raspberrypi/delayedctrls_parse.py | 111 ++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 utils/raspberrypi/delayedctrls_parse.py diff --git a/utils/raspberrypi/delayedctrls_parse.py b/utils/raspberrypi/delayedctrls_parse.py new file mode 100644 index 000000000000..3965b86daaaf --- /dev/null +++ b/utils/raspberrypi/delayedctrls_parse.py @@ -0,0 +1,111 @@ +import re +import sys +import os + +if len(sys.argv) != 2: + print("Usage: {} ".format(sys.argv[0])) + sys.exit() + +infile = sys.argv[1] +insplit = os.path.splitext(infile) +outfile = insplit[0] + '_parsed' + insplit[1] + +frame_re = re.compile('frame (\d+) started') + +delays = { + 'Analogue Gain': 1, + 'Exposure': 2, + 'Vertical Blanking': 2 +} + +ctrl_action = { + 'Write': {}, + 'Get': {}, + 'Queue': {}, + 'No-op': {} +} + +ctrl_re = { + 'Write': re.compile('Setting (.*?) to (\d+) at index (\d+)'), + 'No-op': re.compile('Queue is empty, (.*?) (.*?) (.*?)'), + 'Get': re.compile('Reading (.*?) to (\d+) at index (\d+)'), + 'Queue': re.compile('Queuing (.*?) to (\d+) at index (\d+)') +} + +frame_num = -1 + +max_delay = 0 +for k, d in delays.items(): + if max_delay < d: + max_delay = d + +with open(infile) as f: + lines = f.readlines() + +for line in lines: + r = frame_re.search(line) + if r: + frame_num = int(r.group(1)) + + for (key, re) in ctrl_re.items(): + r = re.search(line) + if r: + ctrl_action[key][(frame_num, r.group(1))] = (r.group(2), r.group(3)) + +with open(outfile, 'wt') as f: + queueIndex = 1 + f.write('{:<10}{:<15}{:<12}{:<18}{}\n'.format('Frame', 'Action', 'Gain', 'Exposure', 'Vblank')) + for frame in range(0, frame_num + 1): + for (k, a) in ctrl_action.items(): + str = '{:<10}{:<10}'.format(frame, k) + + for c in delays.keys(): + # Tabulate all results + str += '{:>5} {:<10}'.format(a[(frame, c)][0] if (frame, c) in a.keys() else '---', + '[' + (a[(frame, c)][1] if (frame, c) in a.keys() else '-') + ']') + + f.write(str.strip() + '\n') + +# Test the write -> get matches the set delay. +for (frame, c) in ctrl_action['Write'].keys(): + set_value = ctrl_action['Write'][(frame, c)][0] + delay_frame = frame + delays[c] + if (delay_frame <= frame_num): + if (delay_frame, c) in ctrl_action['Get']: + get_value = ctrl_action['Get'][(delay_frame, c)][0] + if get_value != set_value: + print('Error: {} written at frame {} to value {} != {} at frame {}' + .format(c, frame, set_value, get_value, delay_frame)) + else: + print('Warning: {} written at frame {} to value {} did not get logged on frame {} - dropped frame?' + .format(c, frame, set_value, delay_frame)) + +# Test the queue -> write matches the set delay. +for (frame, c) in ctrl_action['Queue'].keys(): + set_value = ctrl_action['Queue'][(frame, c)][0] + delay_frame = frame + max_delay - delays[c] + 1 + if (delay_frame <= frame_num): + if (delay_frame, c) in ctrl_action['Write']: + write_value = ctrl_action['Write'][(delay_frame, c)][0] + if write_value != set_value: + print('Info: {} queued at frame {} to value {} != {} written at frame {}' + ' - lagging behind or double queue on a single frame!' + .format(c, frame, set_value, write_value, delay_frame)) + else: + print('Warning: {} queued at frame {} to value {} did not get logged on frame {} - dropped frame?' + .format(c, frame, set_value, delay_frame)) + +# Test the get -> write matches the set delay going backwards. +for (frame, c) in ctrl_action['Get'].keys(): + get_value = ctrl_action['Get'][(frame, c)][0] + delay_frame = frame - delays[c] + if (delay_frame >= 6): + if (delay_frame, c) in ctrl_action['Write']: + write_value = ctrl_action['Write'][(delay_frame, c)][0] + if get_value != write_value: + print('Info: {} got at frame {} to value {} != {} written at frame {}' + ' - lagging behind or double queue on a single frame!' + .format(c, frame, get_value, write_value, delay_frame)) + else: + print('Warning: {} got at frame {} to value {} did not get written on frame {}' + .format(c, frame, get_value, delay_frame)) From patchwork Thu Mar 4 08:17:24 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 11489 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 00A37BD1F1 for ; Thu, 4 Mar 2021 08:17:43 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 979DD68A92; Thu, 4 Mar 2021 09:17:42 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="k/V98RtV"; dkim-atps=neutral Received: from mail-wm1-x32e.google.com (mail-wm1-x32e.google.com [IPv6:2a00:1450:4864:20::32e]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3B4E0602EC for ; Thu, 4 Mar 2021 09:17:39 +0100 (CET) Received: by mail-wm1-x32e.google.com with SMTP id l22so7217524wme.1 for ; Thu, 04 Mar 2021 00:17:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=CW26mmwvmqIlsGYx03OeK2ZIP1RApVX0DdJdSra6nT4=; b=k/V98RtVfG2FbdtNxrUhzMl0pC2GmzQ0ouj2hpi0GL+Aw6UMwnx/Zif/SD3z2zX16Z R9Z/OsF9qgO7zZdr4P8hCDrwIrdSYY8ksWxNQ7gVIx9i/E0agxu8naeIjQPWeEaQLUxi lo+cdnLhO0M8JqfoPz6gP8F6VQa77/SP3sGNhQ7BbqhvF394hZ7228RD2Y30X7urIPmu lw6gUh/G8XZ6MdR80vuDszTCuXe30Gg3FpoSeL7UP6+BvrhtLGO0eIjHyRFzYmYVGnfG WQNZP6Bwiiyzge0tWrvx9M8nwov4/gF+tp6cYhWVaoiwoFTAatRGq5evn1Ur8nEvQqdd HvQg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=CW26mmwvmqIlsGYx03OeK2ZIP1RApVX0DdJdSra6nT4=; b=CCtmpUfsS6lELkhtWuW3N95C4QcXO3PsDwkXnTJcVOu80InAFp2DtX8drly1chGEwB c8PchAD3tfSJXZ5y8QeavNa9wpDei6egKXQlJUouJcO3rxB0f2JBd6wFy36a5UWV7j22 8V3K1JbkzCnF8qiiP0UzMaZdAFzHp3sAceDuy7MkhPr/C98ZxYuF/yJcKZGXWHHZzeF9 jH6c4J/zK8Y7tkLAEMIjQOazwgARk2dfsAAQaJvW2BpwlArnMi65j+pSqARhusGRjG3X h+N+j45lTBewePYAjBI6/5jyvHWzegK/z2HIkUm5bCgtC22gaQUlPWtNyusqUu4Yh7ay hMTQ== X-Gm-Message-State: AOAM533pNhsDy8xhnl6t/DBBSs7NrzFvTCGYD6rLNO4wLD36nkMpoCte B0SYl918faEPqGwG6DZylmWX53A+ZjERMAfF X-Google-Smtp-Source: ABdhPJwF2QuEycY4RrJYWO+lU0CmaaD8OTchlaHn87jyJ98fHs3Pjq3WWHcl3W6oXV/lzO+lCIqJXg== X-Received: by 2002:a1c:9849:: with SMTP id a70mr2797713wme.48.1614845858776; Thu, 04 Mar 2021 00:17:38 -0800 (PST) Received: from naush-laptop.patuck.local ([88.97.76.4]) by smtp.gmail.com with ESMTPSA id b186sm6997926wmc.44.2021.03.04.00.17.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Mar 2021 00:17:38 -0800 (PST) From: Naushir Patuck To: libcamera-devel@lists.libcamera.org Date: Thu, 4 Mar 2021 08:17:24 +0000 Message-Id: <20210304081728.1058394-4-naush@raspberrypi.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210304081728.1058394-1-naush@raspberrypi.com> References: <20210304081728.1058394-1-naush@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 3/7] libcamera: delayed_controls: Remove unneeded write when starting up X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" On DelayedControls::reset(), the values retrieved from the sensor device were added to the queues with the updated flag set to true. This would cause the helper to write out the value to the device again on the first DelayedControls::applyControls() call. This is unnecessary, as the controls written are identical to what is stored in the device driver. Fix this by explicitly setting the update flag to false in DelayedControls::reset() when adding the controls to the queue. Additionally, use the Info() constructor when adding items to the queue for consistency. Signed-off-by: Naushir Patuck Fixes: 3d4b7b005911 ("libcamera: delayed_controls: Add helper for controls that apply with a delay") Tested-by: David Plowman Reviewed-by: Paul Elder Tested-by: Jean-Michel Hautbois Reviewed-by: Kieran Bingham --- include/libcamera/internal/delayed_controls.h | 4 ++-- src/libcamera/delayed_controls.cpp | 9 ++++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/include/libcamera/internal/delayed_controls.h b/include/libcamera/internal/delayed_controls.h index 564d9f2e2440..2a6a912bde10 100644 --- a/include/libcamera/internal/delayed_controls.h +++ b/include/libcamera/internal/delayed_controls.h @@ -43,8 +43,8 @@ private: { } - Info(const ControlValue &v) - : ControlValue(v), updated(true) + Info(const ControlValue &v, bool updated_ = true) + : ControlValue(v), updated(updated_) { } diff --git a/src/libcamera/delayed_controls.cpp b/src/libcamera/delayed_controls.cpp index 3ed1dfebd035..f6d761d1cc41 100644 --- a/src/libcamera/delayed_controls.cpp +++ b/src/libcamera/delayed_controls.cpp @@ -111,7 +111,11 @@ void DelayedControls::reset() values_.clear(); for (const auto &ctrl : controls) { const ControlId *id = device_->controls().idmap().at(ctrl.first); - values_[id][0] = Info(ctrl.second); + /* + * Do not mark this control value as updated, it does not need + * to be written to to device on startup. + */ + values_[id][0] = Info(ctrl.second, false); } } @@ -150,8 +154,7 @@ bool DelayedControls::push(const ControlList &controls) Info &info = values_[id][queueCount_]; - info = control.second; - info.updated = true; + info = Info(control.second); LOG(DelayedControls, Debug) << "Queuing " << id->name() From patchwork Thu Mar 4 08:17:25 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 11490 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 61FA7BD1F1 for ; Thu, 4 Mar 2021 08:17:43 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 12CE868AA9; Thu, 4 Mar 2021 09:17:43 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="gICNlRk7"; dkim-atps=neutral Received: from mail-wr1-x433.google.com (mail-wr1-x433.google.com [IPv6:2a00:1450:4864:20::433]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 5B0AA68AA1 for ; Thu, 4 Mar 2021 09:17:40 +0100 (CET) Received: by mail-wr1-x433.google.com with SMTP id j2so13737988wrx.9 for ; Thu, 04 Mar 2021 00:17:40 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=JVxr9wPhqpMPUC/muNAswAu0GDAhUwE5M/mXi2ElBc4=; b=gICNlRk7Gq2vLTaRJzcIifYAxrBbWKHG2bDhKOmf25b+tuqgETzHpZxXE6kaTltzkB USagNj8M+ErfBP9gQG+ttU4uFtOtZy3oEmGGNNMwWBQGU4ZQXdTeBZj+YwemN+YStQ5r QtxjrmE3sYlBbu2jX6wFZ43pPJeNwE/k4xY1Tj9SiUucBneoLp7EIfuW5hm0t3r+mGOF XkppOW1C7X2AOp9n6QjkP6/hggaLMr7E2NODmoD5wXs17xjmTvSLNEIY93uxx83eM0Ju 9mMf8ISntqRikZ3s4pjYrUga+B93WOCglWQCk+oUEYUcRT+q0KunfvKLM5CiBpIRx3K/ 2ZIA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=JVxr9wPhqpMPUC/muNAswAu0GDAhUwE5M/mXi2ElBc4=; b=Hpc9o0cVwUuXHWQhwqdpoF91L98GuqH29W2YO7qmqW4yxtmnAU9Y2u0cJrWQXpVPbU 62Ii28x1iLJAI4APFjYzJnctn4PMZgJOq9tTrnHphlhqNHcwWSPYUE6Bbdn+nLeIsdUj 7qHmLknT9IARxBeDBpiB8WSljbVJ/3R38PKbpBWlOqQfzlRcbz/TTTTJ6kkZfYWvYBeK DNbdXpXO+z0Wn7B3apbRNNI+DRQ7rF/3NM52zMPGRFBgiN77nQwqMIvHeLtnMEfD1UvZ I8LcCMcvnt32svyaCZSTsSwKQFPmqULvJ7rcyFk9hMRPmOMfiHMzf8BCzNqaqUiQWbH3 IQOg== X-Gm-Message-State: AOAM533qLPFaUxFRxHFuVh2lRL3ZrlCpheuvxw5/GOzLSI61KiaOgiYL B9Zd4yalZBUU/UeoKu5SdkkWwMzANRnv/VDk X-Google-Smtp-Source: ABdhPJykL6rMb79yFZbObpGv6EltQtOhu5+3NFOsIfkCMS3lhKJzba+r97uKj19qkXVNVpz2cN1i9A== X-Received: by 2002:adf:b611:: with SMTP id f17mr2677206wre.8.1614845859868; Thu, 04 Mar 2021 00:17:39 -0800 (PST) Received: from naush-laptop.patuck.local ([88.97.76.4]) by smtp.gmail.com with ESMTPSA id b186sm6997926wmc.44.2021.03.04.00.17.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Mar 2021 00:17:39 -0800 (PST) From: Naushir Patuck To: libcamera-devel@lists.libcamera.org Date: Thu, 4 Mar 2021 08:17:25 +0000 Message-Id: <20210304081728.1058394-5-naush@raspberrypi.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210304081728.1058394-1-naush@raspberrypi.com> References: <20210304081728.1058394-1-naush@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 4/7] libcamera: delayed_controls: Remove spurious no-op queued controls X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" In DelayedControls::applyControls(), the controls queue would be extended via a no-op control push to fill the intermittent slots with unchanged control values. This is needed so that we read back unchanged control values correctly on every frame. However, there was one additional no-op performed on every frame that is not required, meaning that any controls queued by the pipeline handler would have their write delayed by one further frame. The original StaggeredCtrl did not do this, as it only had one index to manage, whereas DelayedControls uses two. Remove this last no-op push so that the pipeline_handler provided controls would be written on the very next frame if possible. As a consequence, we must mark the control update as completed within the DelayedControls::applyControls() loop, otherwise it might get reused when cycling through the ring buffer. Signed-off-by: Naushir Patuck Reported-by: David Plowman Fixes: 3d4b7b005911 ("libcamera: delayed_controls: Add helper for controls that apply with a delay") Tested-by: David Plowman Reviewed-by: Paul Elder Tested-by: Jean-Michel Hautbois Reviewed-by: Kieran Bingham --- src/libcamera/delayed_controls.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/libcamera/delayed_controls.cpp b/src/libcamera/delayed_controls.cpp index f6d761d1cc41..5a05741c0285 100644 --- a/src/libcamera/delayed_controls.cpp +++ b/src/libcamera/delayed_controls.cpp @@ -226,11 +226,11 @@ void DelayedControls::applyControls(uint32_t sequence) * values are set in time to satisfy the sensor delay. */ ControlList out(device_->controls()); - for (const auto &ctrl : values_) { + for (auto &ctrl : values_) { const ControlId *id = ctrl.first; unsigned int delayDiff = maxDelay_ - controlParams_[id].delay; unsigned int index = std::max(0, writeCount_ - delayDiff); - const Info &info = ctrl.second[index]; + Info &info = ctrl.second[index]; if (info.updated) { if (controlParams_[id].priorityWrite) { @@ -253,12 +253,15 @@ void DelayedControls::applyControls(uint32_t sequence) << "Setting " << id->name() << " to " << info.toString() << " at index " << index; + + /* Done with this update, so mark as completed. */ + info.updated = false; } } writeCount_++; - while (writeCount_ >= queueCount_) { + while (writeCount_ > queueCount_) { LOG(DelayedControls, Debug) << "Queue is empty, auto queue no-op."; push({}); From patchwork Thu Mar 4 08:17:26 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 11491 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id AE309BD1F1 for ; Thu, 4 Mar 2021 08:17:45 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 69C9E60522; Thu, 4 Mar 2021 09:17:45 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="ReJBY6TU"; dkim-atps=neutral Received: from mail-wm1-x332.google.com (mail-wm1-x332.google.com [IPv6:2a00:1450:4864:20::332]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 4372468A98 for ; Thu, 4 Mar 2021 09:17:41 +0100 (CET) Received: by mail-wm1-x332.google.com with SMTP id o2so8200304wme.5 for ; Thu, 04 Mar 2021 00:17:41 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Dphl3ZTsb6BZ6uAfpHD339RxAaUTr2aTC087IdEwZ2k=; b=ReJBY6TU+83bOKNy+De0vStD/SSEQ31E0EnarAMkyW3hhjnCIr28shDH49vQno1cER 8JgCbtVC1Gwr+C3uPgjvU99uPK51ZNxLe22xbM7mgU9U1bkHX5MqAL541nIf5IatlEox ef4NEsjX/69ZAXKchMOC5FBLk8ocQweAstDQ0JFLy89F91RmFj1sRm2bEDLugRPi6bBA QL6zoS9r6NXsqmGe+/69pd88dOKWRaPnVQ0ehyf4s1s2JZKInkfe/iOK55HtZoSwv9UH /K7zJhLda0wGcJbk2rxt3B2DoslB6BtHoSFSgLkHD6p/inJZewZlzBswBIpMVH8oVRqn Cb/w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Dphl3ZTsb6BZ6uAfpHD339RxAaUTr2aTC087IdEwZ2k=; b=PiFWgkBwV0MneyqnirsMUWnSgB2mzrBP3/61e2/q8X80eKjclkfb+SQOobryNnDJAl 7UTFSjyKqcdYlIlxduMzup5zY86LSoJvSxKDYoEVzm+NEdQ7VPtiHtPC99E9ijo6193Z n8SwUzRhT4thtRkpBT/VxjupYWMHVnEr+Na79uAbBQubFYqSiHNjIQQFa9/wIUI8yiV5 j0lpuVeNPXbvym62Zsg+aGCx5+kCMlTWqvxIWYYi61Wupp7YcPsnu1aTXZsNs/2Dv8oM XMNbW95u5ByVUdqHGiAEWVLSQSoEMFwfhmHvwSw1SMhIRvRchCtcruy1ihZ+OTXAidye kuyQ== X-Gm-Message-State: AOAM532pIcsgEPSqInSpxrl7sclkpYZhq6iY4Y+x7Syup6QHEed1GloZ e4+TCnFPjYAqWmRfR/FG5sbxQGaV4xGHqF15 X-Google-Smtp-Source: ABdhPJwjd9c6bEBspbWYbvFTHhISJsK+BkQbY1TvlHSKfoqa+LjG9JHB95pDOwkva+Li9De3aIcRiQ== X-Received: by 2002:a1c:730a:: with SMTP id d10mr2609391wmb.53.1614845860814; Thu, 04 Mar 2021 00:17:40 -0800 (PST) Received: from naush-laptop.patuck.local ([88.97.76.4]) by smtp.gmail.com with ESMTPSA id b186sm6997926wmc.44.2021.03.04.00.17.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Mar 2021 00:17:40 -0800 (PST) From: Naushir Patuck To: libcamera-devel@lists.libcamera.org Date: Thu, 4 Mar 2021 08:17:26 +0000 Message-Id: <20210304081728.1058394-6-naush@raspberrypi.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210304081728.1058394-1-naush@raspberrypi.com> References: <20210304081728.1058394-1-naush@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 5/7] libcamera: delayed_controls: Fix off-by-one error in get() X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" There was an off-by-one error in DelayedControls::get() when picking controls from the queue to return back to the pipeline handler. This is only noticeable as small oscillations in brightness when closely viewing frame while AGC is running. The old StaggeredCtrl did not show this error as the startup queuing mechanism has changed in DelayedControls. Fix this by indexing to the correct position in the queue. Signed-off-by: Naushir Patuck Reported-by: David Plowman Fixes: 3d4b7b005911 ("libcamera: delayed_controls: Add helper for controls that apply with a delay") Tested-by: David Plowman Reviewed-by: Paul Elder Tested-by: Jean-Michel Hautbois Reviewed-by: Kieran Bingham --- src/libcamera/delayed_controls.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcamera/delayed_controls.cpp b/src/libcamera/delayed_controls.cpp index 5a05741c0285..138761c9852e 100644 --- a/src/libcamera/delayed_controls.cpp +++ b/src/libcamera/delayed_controls.cpp @@ -184,7 +184,7 @@ bool DelayedControls::push(const ControlList &controls) */ ControlList DelayedControls::get(uint32_t sequence) { - uint32_t adjustedSeq = sequence - firstSequence_ + 1; + uint32_t adjustedSeq = sequence - firstSequence_; unsigned int index = std::max(0, adjustedSeq - maxDelay_); ControlList out(device_->controls()); From patchwork Thu Mar 4 08:17:27 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 11492 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 14CAFBD80E for ; Thu, 4 Mar 2021 08:17:46 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id C50C368AB0; Thu, 4 Mar 2021 09:17:45 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="fXEkafgf"; dkim-atps=neutral Received: from mail-wm1-x335.google.com (mail-wm1-x335.google.com [IPv6:2a00:1450:4864:20::335]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 2D40968A98 for ; Thu, 4 Mar 2021 09:17:42 +0100 (CET) Received: by mail-wm1-x335.google.com with SMTP id o7-20020a05600c4fc7b029010a0247d5f0so4061193wmq.1 for ; Thu, 04 Mar 2021 00:17:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=/2nAUCPXEZmL+MFvY43byb0UcTthYl9RlzZxWH65CNw=; b=fXEkafgf/sApgd4P6bQA+PGQSV7kmIh93LbsoArrtvXFPduweAs4qfoKsUdfw1XW34 v6DF5bf7brB/LJRYgXiTmwonozwrGygMCATyC1VQwt4TT0qEb43xBAcKWDb2LO+FRTQ9 jGtXMz9FuJXjThWQ3ETLpDC6RZnJJngOdknmrpU0T5ET91eT+ZG77MB+a9KLN1/Qe9Hh mR4TFCP9Mebw67WZfLKotCRudfUAF+6mV3edMde2B+wgxaxyml1F47YzjnYlIdREYN0w lDNH1bYXJuVFhgDs8GwyE5lgtVid5dI6/b/zqLnNcXWYI3fcib7sMCDDK2zuOK3tx6KU QXYQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=/2nAUCPXEZmL+MFvY43byb0UcTthYl9RlzZxWH65CNw=; b=G9IQZT13VCcaen9W4XxQ6NnOh+jMS0EagKS32vMT81LrpDPX9cj5J9VvFEnjYEWfME BIhi9NOe5XHu4tnOGfqiZsGbyL7qd7g66/6zvLu2zvVeMJFz+nl1M1uR2rHw12FwnSrk O0+JKYEYaV/xf8dJs6ersg0WuZCl3zsemHjO4DZ9u/viAA+NMBge5svUVP8iCWXGlimR W6KZYbFAYPpWxro+BNp+EkGltIWLuNPOHEw6aEfqc8M0wt2/ib1ckvxOHdOmeJ4rKlPc 8LhVjwUJ3VU8z+vHXla3q34ucORH/oZVeIu9pyAudFUeFxJaGLNhQHp0QaA9JIsd4q2A TrQw== X-Gm-Message-State: AOAM533i1Um4AmDhaCa4HJalmjE8INQpixUSjE27a/3MhrEbOIXwI01a rw2DsytbMfmE0pL4Kr2ImoWV4vpIaL4j+tQB X-Google-Smtp-Source: ABdhPJzHOM9x7QaLGh5J8vM0/S8GrB41VafjORgnpHRBUVoolhwTSuInwPC9KiifpBwoHqNXWiDuYg== X-Received: by 2002:a7b:ce16:: with SMTP id m22mr2676697wmc.65.1614845861571; Thu, 04 Mar 2021 00:17:41 -0800 (PST) Received: from naush-laptop.patuck.local ([88.97.76.4]) by smtp.gmail.com with ESMTPSA id b186sm6997926wmc.44.2021.03.04.00.17.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 04 Mar 2021 00:17:41 -0800 (PST) From: Naushir Patuck To: libcamera-devel@lists.libcamera.org Date: Thu, 4 Mar 2021 08:17:27 +0000 Message-Id: <20210304081728.1058394-7-naush@raspberrypi.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210304081728.1058394-1-naush@raspberrypi.com> References: <20210304081728.1058394-1-naush@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v4 6/7] test: delayed_controls: Fixup tests after recent DelayedControls changes X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The recent fixes applied to DelayedControls change the behavior of the library. As such, the tests ended up failing as they relied on the old behavior of the helper. Update the tests to account for the new behavior and get the tests passing again. Specifically, the following changes have been made for each test: singleControlNoDelay(): - Add a call to reset() to initialise internal DelayedControls state only after setting the control on the device. - Trigger a first frame start by calling applyControls() as a pipeline handler would. - Test frames from 1 onwards, as we will never have a queue item at frame 0, since the reset() handles that. singleControlWithDelay(): - Trigger a first frame start by calling applyControls() as a pipeline handler would. - Test frames from 1 onwards, as we will never have a queue item at frame 0, since the reset() handles that. dualControlsWithDelay() and dualControlsMultiQueue(): - Trigger a first frame start by calling applyControls() as a pipeline handler would. - Test frames from (startOffset + 1) onwards, as we will never have a queue item at frame startOffset. - Use the max delay (2 in this case) to determine the expected result value. Signed-off-by: Naushir Patuck Reviewed-by: Kieran Bingham --- test/delayed_contols.cpp | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/test/delayed_contols.cpp b/test/delayed_contols.cpp index 3855eb18ecd4..c6f195b7bc7f 100644 --- a/test/delayed_contols.cpp +++ b/test/delayed_contols.cpp @@ -82,9 +82,13 @@ protected: /* Reset control to value not used in test. */ ctrls.set(V4L2_CID_BRIGHTNESS, 1); dev_->setControls(&ctrls); + delayed->reset(); + + /* Trigger the first frame start event */ + delayed->applyControls(0); /* Test control without delay are set at once. */ - for (unsigned int i = 0; i < 100; i++) { + for (unsigned int i = 1; i < 100; i++) { int32_t value = 100 + i; ctrls.set(V4L2_CID_BRIGHTNESS, value); @@ -122,8 +126,11 @@ protected: dev_->setControls(&ctrls); delayed->reset(); + /* Trigger the first frame start event */ + delayed->applyControls(0); + /* Test single control with delay. */ - for (unsigned int i = 0; i < 100; i++) { + for (unsigned int i = 1; i < 100; i++) { int32_t value = 10 + i; ctrls.set(V4L2_CID_BRIGHTNESS, value); @@ -150,9 +157,11 @@ protected: int dualControlsWithDelay(uint32_t startOffset) { + static const unsigned int maxDelay = 2; + std::unordered_map delays = { { V4L2_CID_BRIGHTNESS, { 1, false } }, - { V4L2_CID_CONTRAST, { 2, false } }, + { V4L2_CID_CONTRAST, { maxDelay, false } }, }; std::unique_ptr delayed = std::make_unique(dev_.get(), delays); @@ -165,8 +174,11 @@ protected: dev_->setControls(&ctrls); delayed->reset(); + /* Trigger the first frame start event */ + delayed->applyControls(startOffset); + /* Test dual control with delay. */ - for (unsigned int i = 0; i < 100; i++) { + for (unsigned int i = 1; i < 100; i++) { uint32_t frame = startOffset + i; int32_t value = 10 + i; @@ -189,7 +201,7 @@ protected: return TestFail; } - expected = i < 1 ? expected : value - 1; + expected = i < maxDelay ? expected : value - 1; } return TestPass; @@ -197,9 +209,11 @@ protected: int dualControlsMultiQueue() { + static const unsigned int maxDelay = 2; + std::unordered_map delays = { { V4L2_CID_BRIGHTNESS, { 1, false } }, - { V4L2_CID_CONTRAST, { 2, false } } + { V4L2_CID_CONTRAST, { maxDelay, false } } }; std::unique_ptr delayed = std::make_unique(dev_.get(), delays); @@ -212,6 +226,9 @@ protected: dev_->setControls(&ctrls); delayed->reset(); + /* Trigger the first frame start event */ + delayed->applyControls(0); + /* * Queue all controls before any fake frame start. Note we * can't queue up more then the delayed controls history size @@ -226,8 +243,8 @@ protected: } /* Process all queued controls. */ - for (unsigned int i = 0; i < 16; i++) { - int32_t value = 10 + i; + for (unsigned int i = 1; i < 16; i++) { + int32_t value = 10 + i - 1; delayed->applyControls(i); @@ -245,7 +262,7 @@ protected: return TestFail; } - expected = i < 1 ? expected : value - 1; + expected = i < maxDelay ? expected : value - 1; } return TestPass;