From patchwork Thu Oct 28 10:03:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hanlin Chen X-Patchwork-Id: 14391 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 3B1E5BF415 for ; Thu, 28 Oct 2021 10:03:57 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id DF1E7600C0; Thu, 28 Oct 2021 12:03:56 +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="CMnRzdNi"; dkim-atps=neutral Received: from mail-pj1-x1043.google.com (mail-pj1-x1043.google.com [IPv6:2607:f8b0:4864:20::1043]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 78BE1600B7 for ; Thu, 28 Oct 2021 12:03:55 +0200 (CEST) Received: by mail-pj1-x1043.google.com with SMTP id gn3so4325947pjb.0 for ; Thu, 28 Oct 2021 03:03:55 -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=1SMrpSDlqic9LD5peqt2PFspq8nG97POBwGqQWYZUr8=; b=CMnRzdNiZiWZJXumxDzWtyflq9nK2sLaMigIIEhOQZ2R52gxi/RLpt2e3Phn3fklUI g4Q13kDkUK1MLLCbwU/dLi/3la9JkdsTgSJuXboiC0KRFEgMaAVpgYlxTM5ABjK2yz65 R6ihLN1SQuDs7LERtU9qc6dDkl0hOH5VHvklE= 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=1SMrpSDlqic9LD5peqt2PFspq8nG97POBwGqQWYZUr8=; b=su9YdP3p0PuTkeTjvu2oWF2ODDqQ8TprqQked7WCAli1GQGcgyKi8AG0IUdgNGwLvp GnUCYILws8opVpK+fDy1BaULBqSjwvurHU/pYv1JkrF4sfr2b8/7uE2z57sLyQvRdQs0 RHlKrMV2fr6MHaxg5O1K8UiIA++dC+Irm+agp3ObIT3u963lGDklMRZhx30mToYEvhyy UUGi71wIofO66tzxVCsNP2QyK2xMIbVa+hY9j53RLdQbHvW602GNsEMOcIym0JPiHULK MJ8PNcrGN5OuQ294FY4kCa20gstWQ6XrBUWHzfEXzB/QdcIQEj7ZVhrOPbotPNjsrMUi n91A== X-Gm-Message-State: AOAM532AuTyTU0WeFs/P3YAxV9wdcgLd1RL1yg20LfFvp67+m3JxOrW0 NDdUKxGTnDlhVjDmOorwA5+h5idLW9XgZiA7 X-Google-Smtp-Source: ABdhPJzJ4VLbeLoMF5Ov70rF1+dbAff8ANCLyAjbu35FEkIf5kroTks/ycPYXfezKt+QaaUvSlWupA== X-Received: by 2002:a17:902:c407:b0:13f:68f:6753 with SMTP id k7-20020a170902c40700b0013f068f6753mr2783522plk.39.1635415433891; Thu, 28 Oct 2021 03:03:53 -0700 (PDT) Received: from localhost ([2401:fa00:1:10:1bc:52e7:6df5:c7cf]) by smtp.gmail.com with UTF8SMTPSA id g4sm674353pfv.195.2021.10.28.03.03.53 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 28 Oct 2021 03:03:53 -0700 (PDT) From: Han-Lin Chen To: libcamera-devel@lists.libcamera.org Date: Thu, 28 Oct 2021 18:03:45 +0800 Message-Id: <20211028100349.1098545-2-hanlinchen@chromium.org> X-Mailer: git-send-email 2.33.1.1089.g2158813163f-goog In-Reply-To: <20211028100349.1098545-1-hanlinchen@chromium.org> References: <20211028100349.1098545-1-hanlinchen@chromium.org> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 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. --- 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 */