From patchwork Mon Oct 31 11:45:17 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Naushir Patuck X-Patchwork-Id: 17737 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 348B2BDB16 for ; Mon, 31 Oct 2022 11:45:34 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id C5B9763047; Mon, 31 Oct 2022 12:45:33 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1667216733; bh=3OkQGGuHDaXKnQLqJ7ahIMxqVij/7kQdZAl0mQRualY=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=G2/4IS9n3ZQyQEEiak/qTJr/xKAOXIfPH4ZAbSGF4leSj2RWVc3sDVTHaHn3Q49PE zwppSnAOmbt2cI+3J6oktFGl5Ha/0lZe5hWXAs2Llp7fjsVRlzbydVAVgtYPRuy/kY VX07hDWbhDb4iBs7fink7KXTa+fKw/yFyfB9gPmw25vpKtkxQV0in28BFStV6NIbaG 40eNJ+3TZtJQKf6busZnGrh29ocY88TueCzvFT8xqok7Uc028Mkt6dsOvKLKFzi+IY c0Rar9cPcWCmlzt01ghY/S07OWMG82dHQicAOut5r6BSOk0cUw5TPUWWnbVfgeHvwW aafeiFI3vkV1A== Received: from mail-wm1-x333.google.com (mail-wm1-x333.google.com [IPv6:2a00:1450:4864:20::333]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 13EEE6303C for ; Mon, 31 Oct 2022 12:45:30 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="D6pFidVE"; dkim-atps=neutral Received: by mail-wm1-x333.google.com with SMTP id l16-20020a05600c4f1000b003c6c0d2a445so7829417wmq.4 for ; Mon, 31 Oct 2022 04:45:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=19O3ykJgy/boyGdyqfUfUKxSJwPQG6EIUI1ltOgJCc4=; b=D6pFidVEA+b3+qjLrOSnPP/jTE5yVYVqPtKfx3WVmL5dZ6NBKFxkKh4Kh8YFJteVCs RVCCdvOq4vGBiX21SzA8FMd8BjMlnhqaY/KcNCyasswgVgZzX+KKtHcOXAFXsshZ06wN P6fW7j3HedxmjbbVhzqHT7Fl0YiKovPiQ1wC9+ZLRwOv61uxooOxfy//AJiul6EEL8tE 6cPTv7e0JiEOoC1oEW3X/NOtAq+k6cJMzHo0g3PRDHXI3fdpw6a4hYqinHSV6VihN+0S qeudl3FpQbPZTkLUUApVJTkJIncq2X7DwViFrIrlxby6QNG2lcuz1JfcJKnlbtmdKAlM m3kA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=19O3ykJgy/boyGdyqfUfUKxSJwPQG6EIUI1ltOgJCc4=; b=Mth0AMVS+n8Htet6SSlYNcAiYIPeOAR+xNsI/4rrAe2le6Ltk0leM9REZV4pUN1IhF iJjrpy0vTCBeFLNHk54Mmy+hFeKCYf4eSRHICONz3JYFk+IxWKw4bdchtwwmmz5MKhg2 jbh6Rke+ctA7XtDLhCbHolvdDjxgaduhkN24wrDIdfEicHu4YcOB4qpRrKdw27+UFhu4 SvOhn9xuBn62g0aYCJSZSEZlspCIo83l7i6BTkOyTomaQY0EdPoQ37c26LKBknPnyKUy DCH+WaHfGrCV8huzp3r9dfThlEZbL00Kk11+YQB1TwHXjElwcsxATUuRnSOLU8lU73fd w8xw== X-Gm-Message-State: ACrzQf3n6VovA1dgTVDQBfNke0X0gKUjgwyzp3x7QZ22i9SROMQnCKGv U1Rk/sTS9jBxSWj1vCEDr+cJqER5PK7q6Q== X-Google-Smtp-Source: AMsMyM4Go6ZeYV2BLR3MGXOEMynTKcC7jiI3J+h4V+1BJOLyQysHmy6G4yXGF+8DS2Vy7dgzn0+SWQ== X-Received: by 2002:a05:600c:a4b:b0:3b9:859d:7ed6 with SMTP id c11-20020a05600c0a4b00b003b9859d7ed6mr17964247wmq.169.1667216729061; Mon, 31 Oct 2022 04:45:29 -0700 (PDT) Received: from naush-laptop.localdomain ([93.93.133.154]) by smtp.gmail.com with ESMTPSA id h11-20020adff18b000000b0023677e1157fsm6936354wro.56.2022.10.31.04.45.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Oct 2022 04:45:28 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Mon, 31 Oct 2022 11:45:17 +0000 Message-Id: <20221031114522.14215-3-naush@raspberrypi.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221031114522.14215-1-naush@raspberrypi.com> References: <20221031114522.14215-1-naush@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v5 2/7] delayed_controls: Add user cookie to DelayedControls 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: , X-Patchwork-Original-From: Naushir Patuck via libcamera-devel From: Naushir Patuck Reply-To: Naushir Patuck Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Allow the caller to provide a cookie value to DelayedControls::reset and DelayedControls::push. This cookie value is returned from DelayedControls::get for the frame that has the control values applied to it. The cookie value is useful in tracking when a set of controls has been applied to a frame. In a subsequent commit, it will be used by the Raspberry Pi IPA to track the IPA context used when setting the control values. Signed-off-by: Naushir Patuck Reviewed-by: David Plowman Tested-by: David Plowman Reviewed-by: Kieran Bingham --- include/libcamera/internal/delayed_controls.h | 8 ++++--- src/libcamera/delayed_controls.cpp | 22 ++++++++++------- src/libcamera/pipeline/ipu3/ipu3.cpp | 9 +++---- .../pipeline/raspberrypi/raspberrypi.cpp | 6 ++--- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 7 +++--- test/delayed_controls.cpp | 24 +++++++++---------- 6 files changed, 43 insertions(+), 33 deletions(-) diff --git a/include/libcamera/internal/delayed_controls.h b/include/libcamera/internal/delayed_controls.h index de8026e3e4f0..14470f3966ac 100644 --- a/include/libcamera/internal/delayed_controls.h +++ b/include/libcamera/internal/delayed_controls.h @@ -9,6 +9,7 @@ #include #include +#include #include @@ -27,10 +28,10 @@ public: DelayedControls(V4L2Device *device, const std::unordered_map &controlParams); - void reset(); + void reset(unsigned int cookie); - bool push(const ControlList &controls); - ControlList get(uint32_t sequence); + bool push(const ControlList &controls, unsigned int cookie); + std::pair get(uint32_t sequence); void applyControls(uint32_t sequence); @@ -77,6 +78,7 @@ private: uint32_t writeCount_; /* \todo Evaluate if we should index on ControlId * or unsigned int */ std::unordered_map> values_; + RingBuffer cookies_; }; } /* namespace libcamera */ diff --git a/src/libcamera/delayed_controls.cpp b/src/libcamera/delayed_controls.cpp index 777441e8222a..26243dc9e939 100644 --- a/src/libcamera/delayed_controls.cpp +++ b/src/libcamera/delayed_controls.cpp @@ -104,19 +104,21 @@ DelayedControls::DelayedControls(V4L2Device *device, maxDelay_ = std::max(maxDelay_, controlParams_[id].delay); } - reset(); + reset(0); } /** * \brief Reset state machine + * \param[in] cookie User supplied reset cookie value * * Resets the state machine to a starting position based on control values * retrieved from the device. */ -void DelayedControls::reset() +void DelayedControls::reset(unsigned int cookie) { queueCount_ = 1; writeCount_ = 0; + cookies_[0] = cookie; /* Retrieve control as reported by the device. */ std::vector ids; @@ -140,13 +142,15 @@ void DelayedControls::reset() /** * \brief Push a set of controls on the queue * \param[in] controls List of controls to add to the device queue + * \param[in] cookie User supplied cookie value for \a controls * * Push a set of controls to the control queue. This increases the control queue - * depth by one. + * depth by one. The \a cookie value will be subsequently returned from + * \a get() for the frame with all controls applied. * * \returns true if \a controls are accepted, or false otherwise */ -bool DelayedControls::push(const ControlList &controls) +bool DelayedControls::push(const ControlList &controls, const unsigned int cookie) { /* Copy state from previous frame. */ for (auto &ctrl : values_) { @@ -180,6 +184,7 @@ bool DelayedControls::push(const ControlList &controls) << " at index " << queueCount_; } + cookies_[queueCount_] = cookie; queueCount_++; return true; @@ -198,9 +203,10 @@ bool DelayedControls::push(const ControlList &controls) * push(). The max history from the current sequence number that yields valid * values are thus 16 minus number of controls pushed. * - * \return The controls at \a sequence number + * \return The controls at \a sequence number and associated user supplied + * cookie value. */ -ControlList DelayedControls::get(uint32_t sequence) +std::pair DelayedControls::get(uint32_t sequence) { unsigned int index = std::max(0, sequence - maxDelay_); @@ -217,7 +223,7 @@ ControlList DelayedControls::get(uint32_t sequence) << " at index " << index; } - return out; + return { out, cookies_[index] }; } /** @@ -276,7 +282,7 @@ void DelayedControls::applyControls(uint32_t sequence) while (writeCount_ > queueCount_) { LOG(DelayedControls, Debug) << "Queue is empty, auto queue no-op."; - push({}); + push({}, cookies_[queueCount_ - 1]); } device_->setControls(&out); diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp index 3b892d9671c5..8a5de76aa1b8 100644 --- a/src/libcamera/pipeline/ipu3/ipu3.cpp +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp @@ -789,7 +789,7 @@ int PipelineHandlerIPU3::start(Camera *camera, [[maybe_unused]] const ControlLis if (ret) goto error; - data->delayedCtrls_->reset(); + data->delayedCtrls_->reset(0); /* * Start the ImgU video devices, buffers will be queued to the @@ -1265,11 +1265,11 @@ int IPU3CameraData::loadIPA() return 0; } -void IPU3CameraData::setSensorControls([[maybe_unused]] unsigned int id, +void IPU3CameraData::setSensorControls(unsigned int id, const ControlList &sensorControls, const ControlList &lensControls) { - delayedCtrls_->push(sensorControls); + delayedCtrls_->push(sensorControls, id); CameraLens *focusLens = cio2_.sensor()->focusLens(); if (!focusLens) @@ -1389,7 +1389,8 @@ void IPU3CameraData::cio2BufferReady(FrameBuffer *buffer) request->metadata().set(controls::SensorTimestamp, buffer->metadata().timestamp); - info->effectiveSensorControls = delayedCtrls_->get(buffer->metadata().sequence); + auto [controls, cookie] = delayedCtrls_->get(buffer->metadata().sequence); + info->effectiveSensorControls = std::move(controls); if (request->findBuffer(&rawStream_)) pipe()->completeBuffer(request, buffer); diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp index 343f8cb2c7ed..29626c0ef14e 100644 --- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp +++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp @@ -1064,7 +1064,7 @@ int PipelineHandlerRPi::start(Camera *camera, const ControlList *controls) * Reset the delayed controls with the gain and exposure values set by * the IPA. */ - data->delayedCtrls_->reset(); + data->delayedCtrls_->reset(0); data->state_ = RPiCameraData::State::Idle; @@ -1794,7 +1794,7 @@ void RPiCameraData::setIspControls(const ControlList &controls) void RPiCameraData::setDelayedControls(const ControlList &controls) { - if (!delayedCtrls_->push(controls)) + if (!delayedCtrls_->push(controls, 0)) LOG(RPI, Error) << "V4L2 DelayedControl set failed"; handleState(); } @@ -1867,7 +1867,7 @@ void RPiCameraData::unicamBufferDequeue(FrameBuffer *buffer) * Lookup the sensor controls used for this frame sequence from * DelayedControl and queue them along with the frame buffer. */ - ControlList ctrl = delayedCtrls_->get(buffer->metadata().sequence); + auto [ctrl, cookie] = delayedCtrls_->get(buffer->metadata().sequence); /* * Add the frame timestamp to the ControlList for the IPA to use * as it does not receive the FrameBuffer object. diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 455ee2a0a711..6f3c34e764fd 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -376,10 +376,10 @@ void RkISP1CameraData::paramFilled(unsigned int frame) selfPath_->queueBuffer(info->selfPathBuffer); } -void RkISP1CameraData::setSensorControls([[maybe_unused]] unsigned int frame, +void RkISP1CameraData::setSensorControls(unsigned int frame, const ControlList &sensorControls) { - delayedCtrls_->push(sensorControls); + delayedCtrls_->push(sensorControls, frame); } void RkISP1CameraData::metadataReady(unsigned int frame, const ControlList &metadata) @@ -1191,8 +1191,9 @@ void PipelineHandlerRkISP1::statReady(FrameBuffer *buffer) if (data->frame_ <= buffer->metadata().sequence) data->frame_ = buffer->metadata().sequence + 1; + auto [controls, cookie] = data->delayedCtrls_->get(buffer->metadata().sequence); data->ipa_->processStatsBuffer(info->frame, info->statBuffer->cookie(), - data->delayedCtrls_->get(buffer->metadata().sequence)); + controls); } REGISTER_PIPELINE_HANDLER(PipelineHandlerRkISP1) diff --git a/test/delayed_controls.cpp b/test/delayed_controls.cpp index a8ce9828d73d..26037268f245 100644 --- a/test/delayed_controls.cpp +++ b/test/delayed_controls.cpp @@ -82,7 +82,7 @@ protected: /* Reset control to value not used in test. */ ctrls.set(V4L2_CID_BRIGHTNESS, 1); dev_->setControls(&ctrls); - delayed->reset(); + delayed->reset(0); /* Trigger the first frame start event */ delayed->applyControls(0); @@ -92,11 +92,11 @@ protected: int32_t value = 100 + i; ctrls.set(V4L2_CID_BRIGHTNESS, value); - delayed->push(ctrls); + delayed->push(ctrls, i); delayed->applyControls(i); - ControlList result = delayed->get(i); + auto [result, cookie] = delayed->get(i); int32_t brightness = result.get(V4L2_CID_BRIGHTNESS).get(); if (brightness != value) { cerr << "Failed single control without delay" @@ -124,7 +124,7 @@ protected: int32_t expected = 4; ctrls.set(V4L2_CID_BRIGHTNESS, expected); dev_->setControls(&ctrls); - delayed->reset(); + delayed->reset(0); /* Trigger the first frame start event */ delayed->applyControls(0); @@ -134,11 +134,11 @@ protected: int32_t value = 10 + i; ctrls.set(V4L2_CID_BRIGHTNESS, value); - delayed->push(ctrls); + delayed->push(ctrls, i); delayed->applyControls(i); - ControlList result = delayed->get(i); + auto [result, cookie] = delayed->get(i); int32_t brightness = result.get(V4L2_CID_BRIGHTNESS).get(); if (brightness != expected) { cerr << "Failed single control with delay" @@ -172,7 +172,7 @@ protected: ctrls.set(V4L2_CID_BRIGHTNESS, expected); ctrls.set(V4L2_CID_CONTRAST, expected + 1); dev_->setControls(&ctrls); - delayed->reset(); + delayed->reset(0); /* Trigger the first frame start event */ delayed->applyControls(0); @@ -183,11 +183,11 @@ protected: ctrls.set(V4L2_CID_BRIGHTNESS, value); ctrls.set(V4L2_CID_CONTRAST, value + 1); - delayed->push(ctrls); + delayed->push(ctrls, i); delayed->applyControls(i); - ControlList result = delayed->get(i); + auto [result, cookie] = delayed->get(i); int32_t brightness = result.get(V4L2_CID_BRIGHTNESS).get(); int32_t contrast = result.get(V4L2_CID_CONTRAST).get(); if (brightness != expected || contrast != expected + 1) { @@ -223,7 +223,7 @@ protected: ctrls.set(V4L2_CID_BRIGHTNESS, expected); ctrls.set(V4L2_CID_CONTRAST, expected); dev_->setControls(&ctrls); - delayed->reset(); + delayed->reset(0); /* Trigger the first frame start event */ delayed->applyControls(0); @@ -238,7 +238,7 @@ protected: ctrls.set(V4L2_CID_BRIGHTNESS, value); ctrls.set(V4L2_CID_CONTRAST, value); - delayed->push(ctrls); + delayed->push(ctrls, i); } /* Process all queued controls. */ @@ -247,7 +247,7 @@ protected: delayed->applyControls(i); - ControlList result = delayed->get(i); + auto [result, cookie] = delayed->get(i); int32_t brightness = result.get(V4L2_CID_BRIGHTNESS).get(); int32_t contrast = result.get(V4L2_CID_CONTRAST).get();