From patchwork Fri Oct 29 11:59:57 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hanlin Chen X-Patchwork-Id: 14419 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 71DDBC324E for ; Fri, 29 Oct 2021 12:00:11 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 0DCC9600BC; Fri, 29 Oct 2021 14:00:11 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.b="WD/YeaBq"; dkim-atps=neutral Received: from mail-pf1-x442.google.com (mail-pf1-x442.google.com [IPv6:2607:f8b0:4864:20::442]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id CCBBB600B8 for ; Fri, 29 Oct 2021 14:00:09 +0200 (CEST) Received: by mail-pf1-x442.google.com with SMTP id m14so9010430pfc.9 for ; Fri, 29 Oct 2021 05:00:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=9JZPwUj7sK91HcP0MWC8uO8gM6PfU3AIrpnW7+5lbN0=; b=WD/YeaBqq8W1MN86NegkqHkgFhayZ5BcjfNZMeL9UuQASLBFBXa3SIIl79PaMfTipk 1OtKr8NpZSlAQdcUOKDe7llthva/6+Hx8ElZ7r4y2zhfMzB7W4laBQDzUBTL4pi/m1jY FuZv/eNISkQR75VELBdhXjdiylCK02deATHd8= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=9JZPwUj7sK91HcP0MWC8uO8gM6PfU3AIrpnW7+5lbN0=; b=DZ1UMlFgkMgKm3EAB7zWlRD/ELtalv/Y+9wDRg8BzWZ91v8bTFzg1iWUgDjCkAc6d0 Oxxu9sT6f6NDESKUKO9z5D5YVqM1shtSXLqIPA+jSuCAteuCYjvc1ZymqkY4Ha/OVERr URKJm6XWLKPvDmjYl5sVRc/mDZQ+ZmMOw+RR1icz2OJrWDoL53kFROFMmIcyk4MOGKYq n3Pibmd5Ee5ZlrLvptifYUIJ5tsvITBQqwC8afKbz2Kq3JMEUWK6P/FJez2c2R7g5KzL n8VpIpDk5pqvZh3wzYsm/rD34V0kmv/vjqPcCTEOvYKMSAx0OkpUShp3WcsKirUkcpAN RGAA== X-Gm-Message-State: AOAM532D5YoJPqGi9idQxKojjQTO8Mn5yMuQIewEMwO7fykFP9Oap7xK 6/6lDguxHs9KYxtjApm1YhA/PRG82805S5BT X-Google-Smtp-Source: ABdhPJy6Q6BUQxSlOwXjB1dfQ85vbH16ATrBS59weJ7QgnqSpSRBNNWMMUKHxy80WRXPkyiAYdaXdA== X-Received: by 2002:a05:6a00:1906:b0:44c:b35d:71a8 with SMTP id y6-20020a056a00190600b0044cb35d71a8mr10586116pfi.51.1635508807145; Fri, 29 Oct 2021 05:00:07 -0700 (PDT) Received: from localhost ([2401:fa00:1:10:35fe:d53b:684:b538]) by smtp.gmail.com with UTF8SMTPSA id l14sm10590902pjq.13.2021.10.29.05.00.06 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 29 Oct 2021 05:00:06 -0700 (PDT) From: Han-Lin Chen To: libcamera-devel@lists.libcamera.org Date: Fri, 29 Oct 2021 19:59:57 +0800 Message-Id: <20211029120001.2469018-2-hanlinchen@chromium.org> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog In-Reply-To: <20211029120001.2469018-1-hanlinchen@chromium.org> References: <20211029120001.2469018-1-hanlinchen@chromium.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2 2/6] ipu3: Add a class AiqResultsRingBuffer to reserve AiqResults history 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 AIQ algorithm expects the statstistics comes with the effective AiqResults applied on the sensor, which may not always be the latest AiqResults, since pipeline handler may delay setting the controls based on SOF. Add a class to reserve the history of the AiqResults generated for previous frames, so IPA can have a chance to look for the suitable one backwards. Signed-off-by: Han-Lin Chen --- aiq/aiq_results.cpp | 85 ++++++++++++++++++++++++++++++++++++++++----- aiq/aiq_results.h | 38 +++++++++++++++----- 2 files changed, 107 insertions(+), 16 deletions(-) diff --git a/aiq/aiq_results.cpp b/aiq/aiq_results.cpp index f727f36..deda4be 100644 --- a/aiq/aiq_results.cpp +++ b/aiq/aiq_results.cpp @@ -63,7 +63,34 @@ AiqResults::AiqResults() sa_.channel_b = channelB_.data(); } -void AiqResults::setAe(ia_aiq_ae_results *ae) +AiqResults::AiqResults(const AiqResults &other) + :AiqResults() +{ + setAe(&other.ae_); + setAf(&other.af_); + setAfBracket(&other.afBracket_); + setAwb(&other.awb_); + setGbce(&other.gbce_); + setDetectedSceneMode(other.detectedSceneMode_); + setPa(&other.pa_); + setSa(&other.sa_); +} + +AiqResults& AiqResults::operator=(const AiqResults &other) +{ + setAe(&other.ae_); + setAf(&other.af_); + setAfBracket(&other.afBracket_); + setAwb(&other.awb_); + setGbce(&other.gbce_); + setDetectedSceneMode(other.detectedSceneMode_); + setPa(&other.pa_); + setSa(&other.sa_); + + return *this; +} + +void AiqResults::setAe(const ia_aiq_ae_results *ae) { /* Todo: Potentially Requires copying * ia_aiq_aperture_control *aperture_control; @@ -121,7 +148,7 @@ void AiqResults::setAe(ia_aiq_ae_results *ae) } } -void AiqResults::setAf(ia_aiq_af_results *af) +void AiqResults::setAf(const ia_aiq_af_results *af) { ASSERT(af); @@ -133,7 +160,7 @@ void AiqResults::setAf(ia_aiq_af_results *af) af_.final_lens_position_reached = af->final_lens_position_reached; } -void AiqResults::setAfBracket(ia_aiq_af_bracket_results *afBracket) +void AiqResults::setAfBracket(const ia_aiq_af_bracket_results *afBracket) { ASSERT(afBracket); @@ -145,7 +172,7 @@ void AiqResults::setAfBracket(ia_aiq_af_bracket_results *afBracket) afBracket_.lens_positions_bracketing = afBracket->lens_positions_bracketing; } -void AiqResults::setAwb(ia_aiq_awb_results *awb) +void AiqResults::setAwb(const ia_aiq_awb_results *awb) { ASSERT(awb); @@ -157,7 +184,7 @@ void AiqResults::setAwb(ia_aiq_awb_results *awb) awb_.distance_from_convergence = awb->distance_from_convergence; } -void AiqResults::setGbce(ia_aiq_gbce_results *gbce) +void AiqResults::setGbce(const ia_aiq_gbce_results *gbce) { ASSERT(gbce); @@ -181,12 +208,12 @@ void AiqResults::setGbce(ia_aiq_gbce_results *gbce) } } -void AiqResults::setDetectedSceneMode(ia_aiq_scene_mode dsm) +void AiqResults::setDetectedSceneMode(const ia_aiq_scene_mode dsm) { detectedSceneMode_ = dsm; } -void AiqResults::setPa(ia_aiq_pa_results *pa) +void AiqResults::setPa(const ia_aiq_pa_results *pa) { ASSERT(pa); @@ -234,7 +261,7 @@ void AiqResults::setPa(ia_aiq_pa_results *pa) pa_.brightness_level = pa->brightness_level; } -void AiqResults::setSa(ia_aiq_sa_results *sa) +void AiqResults::setSa(const ia_aiq_sa_results *sa) { ASSERT(sa && sa->channel_r && sa->channel_gr && sa->channel_gb && sa->channel_b); @@ -275,6 +302,48 @@ void AiqResults::setSa(ia_aiq_sa_results *sa) sa_.frame_params = sa->frame_params; } +AiqResults& AiqResultsRingBuffer::operator[](unsigned int index) +{ + return std::array::operator[](index % bufferSize); +} + +const AiqResults& AiqResultsRingBuffer::operator[](unsigned int index) const +{ + return std::array::operator[](index % bufferSize); +} + +void AiqResultsRingBuffer::Reset() +{ + start_ = end_ = size_ = 0; +} + +void AiqResultsRingBuffer::Push(const AiqResults& result) +{ + operator[](end_) = result; + end_ = (end_ + 1) % bufferSize; + size_ = std::min(size_ + 1, bufferSize); + if (size_ == bufferSize) { + start_ = end_; + } +} + +AiqResults& AiqResultsRingBuffer::searchBackward( + const std::function pred, AiqResults& def) +{ + if (size_ == 0) + return def; + + unsigned int i = (end_ - 1) % bufferSize; + while (i != start_) { + if (pred(operator[](i))) { + return operator[](i); + } + i = --i % bufferSize; + } + + return def; +} + } /* namespace ipa::ipu3::aiq */ } /* namespace libcamera */ diff --git a/aiq/aiq_results.h b/aiq/aiq_results.h index ae19a6c..7005a47 100644 --- a/aiq/aiq_results.h +++ b/aiq/aiq_results.h @@ -8,6 +8,8 @@ * of the aiq result structures. */ +#include +#include #include #include @@ -37,6 +39,8 @@ class AiqResults { public: AiqResults(); + AiqResults(const AiqResults &other); + AiqResults &operator=(const AiqResults &other); const ia_aiq_ae_results *ae() { return &ae_; } ia_aiq_af_results *af() { return &af_; } @@ -46,14 +50,14 @@ public: const ia_aiq_pa_results *pa() { return &pa_; } const ia_aiq_sa_results *sa() { return &sa_; } - void setAe(ia_aiq_ae_results *ae); - void setAf(ia_aiq_af_results *af); - void setAfBracket(ia_aiq_af_bracket_results *afBracket); - void setAwb(ia_aiq_awb_results *awb); - void setGbce(ia_aiq_gbce_results *gbce); - void setDetectedSceneMode(ia_aiq_scene_mode dsm); - void setPa(ia_aiq_pa_results *pa); - void setSa(ia_aiq_sa_results *sa); + void setAe(const ia_aiq_ae_results *ae); + void setAf(const ia_aiq_af_results *af); + void setAfBracket(const ia_aiq_af_bracket_results *afBracket); + void setAwb(const ia_aiq_awb_results *awb); + void setGbce(const ia_aiq_gbce_results *gbce); + void setDetectedSceneMode(const ia_aiq_scene_mode dsm); + void setPa(const ia_aiq_pa_results *pa); + void setSa(const ia_aiq_sa_results *sa); private: ia_aiq_ae_results ae_; @@ -109,6 +113,24 @@ private: std::vector channelGb_; }; +static constexpr unsigned int bufferSize = 16; +class AiqResultsRingBuffer: public std::array +{ +public: + AiqResults &operator[](unsigned int index); + const AiqResults &operator[](unsigned int index) const; + void Reset(); + void Push(const AiqResults& result); + unsigned int size() { return size_; } + AiqResults& searchBackward(const std::function pred, + AiqResults& def); + +private: + unsigned int start_ = 0; + unsigned int end_ = 0; + unsigned int size_ = 0; +}; + } /* namespace libcamera::ipa::ipu3::aiq */ #endif /* IPA_IPU3_AIQ_RESULTS_H */