From patchwork Fri Oct 24 08:50:49 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Klug X-Patchwork-Id: 24791 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 6AA02BE080 for ; Fri, 24 Oct 2025 08:52:55 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 23A3F60931; Fri, 24 Oct 2025 10:52:55 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="f7j2R2YW"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 54CFE608F7 for ; Fri, 24 Oct 2025 10:52:53 +0200 (CEST) Received: from ideasonboard.com (unknown [IPv6:2a00:6020:448c:6c00:7edc:62f4:c118:1549]) by perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id C4EA64AEB; Fri, 24 Oct 2025 10:51:07 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1761295867; bh=w0Hxg2XU1TUu/+ZvDaC8neBCy+QwzFpeQN0WFkwbwlQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=f7j2R2YW+AEoOtwfTf54jZaT9Zz4bVm3puzXCDftzEorZ/5GJtgSUN30ZYIHhq3d5 OyScJA9cdXJfsJ9mO/KJdo1jsNVOOjQcZZwspmClwyFet9Cd46fEI/U2jVBO01OOA6 OtdJFEXCsIPQNp0oA7Uk5zWoV2I6MeKGY/rt3Cxc= From: Stefan Klug To: libcamera-devel@lists.libcamera.org Cc: Stefan Klug Subject: [PATCH v1 25/35] pipeline: rkisp1: Add SequenceSyncHelper class Date: Fri, 24 Oct 2025 10:50:49 +0200 Message-ID: <20251024085130.995967-26-stefan.klug@ideasonboard.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20251024085130.995967-1-stefan.klug@ideasonboard.com> References: <20251024085130.995967-1-stefan.klug@ideasonboard.com> MIME-Version: 1.0 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 a V4L2 buffer the assigned sequence is not known until the buffer is dequeued. But for per frame controls we have to prepare other data like sensor controls and ISP params in advance. So we try to anticipate the sequence number a given buffer will be. In a perfect world this works well as long as the initial sequence is assigned correctly. But it breaks as soon as things like running out of buffers or incomplete images happen. To make things even more complicated, in most cases more than one buffer is queued to the kernel at a time. So as soon as a sequence number doesn't match the expected one after dequeuing, most likely all the already queued buffers will be dequeued with the same error. It is not sufficient to simply add the correction after dequeuing because the error on all queued frames would accumulate and the whole system starts to oscillate. To work around that add a SequenceSyncHelper class that tracks the expected error and allows to easily query the necessary correction when queuing new buffers. Signed-off-by: Stefan Klug --- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 2 + .../pipeline/rkisp1/sequence_sync_helper.h | 69 +++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 src/libcamera/pipeline/rkisp1/sequence_sync_helper.h diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 7a4957d7e535..d83f7d787892 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -51,10 +51,12 @@ #include "libcamera/internal/yaml_parser.h" #include "rkisp1_path.h" +#include "sequence_sync_helper.h" namespace libcamera { LOG_DEFINE_CATEGORY(RkISP1) +LOG_DEFINE_CATEGORY(RkISP1Schedule) class PipelineHandlerRkISP1; class RkISP1CameraData; diff --git a/src/libcamera/pipeline/rkisp1/sequence_sync_helper.h b/src/libcamera/pipeline/rkisp1/sequence_sync_helper.h new file mode 100644 index 000000000000..c3f91dbed45f --- /dev/null +++ b/src/libcamera/pipeline/rkisp1/sequence_sync_helper.h @@ -0,0 +1,69 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2025, Ideas on Board + * + * Sequence sync helper + */ + +#pragma once + +#include + +#include + +namespace libcamera { + +LOG_DECLARE_CATEGORY(RkISP1Schedule) + +class SequenceSyncHelper +{ +public: + int gotFrame(size_t expectedSequence, size_t actualSequence) + { + ASSERT(!corrections_.empty()); + int diff = actualSequence - expectedSequence; + int corr = corrections_.front(); + corrections_.pop(); + expectedOffset_ -= corr; + int necessaryCorrection = diff - expectedOffset_; + correctionToApply_ += necessaryCorrection; + + LOG(RkISP1Schedule, Debug) << "Sync frame " + << "expected: " << expectedSequence + << " actual: " << actualSequence + << " correction: " << corr + << " expectedOffset: " << expectedOffset_ + << " correctionToApply " << correctionToApply_; + + expectedOffset_ += necessaryCorrection; + return necessaryCorrection; + } + + /* Value to be added to the source sequence */ + int correction() + { + return correctionToApply_; + } + + void pushCorrection(int correction) + { + corrections_.push(correction); + correctionToApply_ -= correction; + LOG(RkISP1Schedule, Debug) + << "Push correction " << correction + << " correctionToApply " << correctionToApply_; + } + + void reset() + { + corrections_ = {}; + correctionToApply_ = 0; + expectedOffset_ = 0; + } + + std::queue corrections_; + int correctionToApply_ = 0; + int expectedOffset_ = 0; +}; + +} /* namespace libcamera */