From patchwork Thu Oct 28 10:03:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hanlin Chen X-Patchwork-Id: 14392 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 C57E6BF415 for ; Thu, 28 Oct 2021 10:03:58 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 79BED600C4; Thu, 28 Oct 2021 12:03:58 +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="T0CPjW0N"; dkim-atps=neutral Received: from mail-pg1-x541.google.com (mail-pg1-x541.google.com [IPv6:2607:f8b0:4864:20::541]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 85099600B5 for ; Thu, 28 Oct 2021 12:03:57 +0200 (CEST) Received: by mail-pg1-x541.google.com with SMTP id h193so5930243pgc.1 for ; Thu, 28 Oct 2021 03:03:57 -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=lTSTK7FwG3T04+revACHrdm6IhgZuUILZhymSQGcEl8=; b=T0CPjW0Nfww4D7MpTbYCCUf5LVUnhIdCUJJFPHProfRHlAZ6+B7o1M6JR9HWBeeTTO LqXyVZLWq9SjeVjqD9VLsd1HMO1XC6ZYlwLHaxu6HRHoCgh5uY6GOZSWJHYitQ9W7X9d gNYfY3RczquvNOglgx8U3PQU/TllFGqJbtmFQ= 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=lTSTK7FwG3T04+revACHrdm6IhgZuUILZhymSQGcEl8=; b=bsl/cR9nznqcq3e/yDdfPjfbQ5qCwTDRA2mkfsJBX/nUHvL/Mwd4hat7/bYkThb9C8 Ou+m326bBpmrmfJr4E0uRXllN9GMyUrfejuTyQUBxg3dNP8yNUdGw1x8kvVth+sb+85T twSxKvi2Quj12XdImQR1HC9+J39iACm+/ZhlQLOhWNHJ0FMxX90ke+kCnjCRa+brN9f9 DNl40IAKUU8kegpaidP7QTjSP3x+3mGcazZhm8ipbLXTLTq9KTEbPfUUYRvXu9u2RUm6 P8Re5RANW+ZpzMCjMiGf2N9nhhylhjXm6okArqzUTWMCQ/7qJ4bqru3JaAlwi/a+cLWb wNOQ== X-Gm-Message-State: AOAM533K9u7UWsOg9mbt3B3uqjWgAz82mRzIm+y7b4y91doZkb6F9Qw9 +OXkoaz/y/Wzzm13n3LEK4hCHUxOXrOdquCu X-Google-Smtp-Source: ABdhPJwQ+T0RBy2+0iiwhcUCz7MxW53C4qiYj8pKgE7nGKQ8HVmUtpxBXNt7tVK4CDfyK251RCgLGQ== X-Received: by 2002:a63:8f5a:: with SMTP id r26mr2487035pgn.50.1635415435956; Thu, 28 Oct 2021 03:03:55 -0700 (PDT) Received: from localhost ([2401:fa00:1:10:1bc:52e7:6df5:c7cf]) by smtp.gmail.com with UTF8SMTPSA id b10sm2780427pfi.122.2021.10.28.03.03.55 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 28 Oct 2021 03:03:55 -0700 (PDT) From: Han-Lin Chen To: libcamera-devel@lists.libcamera.org Date: Thu, 28 Oct 2021 18:03:46 +0800 Message-Id: <20211028100349.1098545-3-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 3/6] ipu3: Set statistics with the effective AE AiqResults 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: , Cc: Han-Lin Chen Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Set the statistics with the latest AE AiqResults which has the same exposure time and analog gain. The patch reduces the AE haunting during the converging process. Signed-off-by: Han-Lin Chen --- aiq/aiq_input_parameters.cpp | 4 +-- ipu3.cpp | 66 ++++++++++++++++++++++++++++++------ 2 files changed, 57 insertions(+), 13 deletions(-) diff --git a/aiq/aiq_input_parameters.cpp b/aiq/aiq_input_parameters.cpp index bc87b31..5dd2f6c 100644 --- a/aiq/aiq_input_parameters.cpp +++ b/aiq/aiq_input_parameters.cpp @@ -130,7 +130,7 @@ AiqInputParameters &AiqInputParameters::operator=(const AiqInputParameters &othe void AiqInputParameters::setAeAwbAfDefaults() { - /*Ae Params */ + /* Ae Params */ aeInputParams.num_exposures = NUM_EXPOSURES; aeInputParams.frame_use = ia_aiq_frame_use_preview; aeInputParams.flash_mode = ia_aiq_flash_mode_off; @@ -166,7 +166,7 @@ void AiqInputParameters::setAeAwbAfDefaults() ia_aiq_af_range_normal, ia_aiq_af_metering_mode_auto, ia_aiq_flash_mode_off, - NULL, NULL, false + &focusRect, &manualFocusParams, false }; /* GBCE Params */ diff --git a/ipu3.cpp b/ipu3.cpp index 8126e9d..b7de901 100644 --- a/ipu3.cpp +++ b/ipu3.cpp @@ -59,7 +59,8 @@ private: void fillParams(unsigned int frame, ipu3_uapi_params *params); void parseStatistics(unsigned int frame, int64_t frameTimestamp, - const ipu3_uapi_stats_3a *stats); + const ipu3_uapi_stats_3a *stats, + const ControlList& sensorCtrls); void setControls(unsigned int frame); @@ -84,6 +85,7 @@ private: /* Temporary storage until we have a FrameContext object / struct */ aiq::AiqInputParameters aiqInputParams_; aiq::AiqResults results_; + aiq::AiqResultsRingBuffer resultsHistory_; BinaryData aiqb_; BinaryData nvm_; @@ -282,6 +284,8 @@ int IPAIPU3::configure(const IPAConfigInfo &configInfo, /* Upate the camera controls using the new sensor settings. */ updateControls(sensorInfo_, ctrls_, ipaControls); + resultsHistory_.Reset(); + return 0; } @@ -327,7 +331,10 @@ void IPAIPU3::processEvent(const IPU3Event &event) const ipu3_uapi_stats_3a *stats = reinterpret_cast(mem.data()); - parseStatistics(event.frame, event.frameTimestamp, stats); + parseStatistics(event.frame, + event.frameTimestamp, + stats, + event.sensorControls); break; } case EventFillParams: { @@ -374,14 +381,16 @@ void IPAIPU3::fillParams(unsigned int frame, ipu3_uapi_params *params) */ /* Run algorithms into/using this context structure */ - if (frame % 10 == 0) - aiq_.run2a(frame, aiqInputParams_, results_); + aiq_.run2a(frame, aiqInputParams_, results_); aic_.updateRuntimeParams(results_); aic_.run(params); exposure_ = results_.ae()->exposures[0].sensor_exposure->coarse_integration_time; gain_ = results_.ae()->exposures[0].sensor_exposure->analog_gain_code_global; + + resultsHistory_.Push(results_); + setControls(frame); IPU3Action op; @@ -392,7 +401,8 @@ void IPAIPU3::fillParams(unsigned int frame, ipu3_uapi_params *params) void IPAIPU3::parseStatistics(unsigned int frame, int64_t frameTimestamp, - const ipu3_uapi_stats_3a *stats) + const ipu3_uapi_stats_3a *stats, + const ControlList& sensorCtrls) { ControlList ctrls(controls::controls); @@ -403,10 +413,43 @@ void IPAIPU3::parseStatistics(unsigned int frame, */ ASSERT (frameTimestamp > 0); - aiq_.setStatistics(frame, frameTimestamp, results_, stats); + + /* Ae algorithm expects the statistics to be set with it's corresponding Ae + * result, i.e., the Ae result should match the exposure time/analog gain + * with the the effective sensor controls of the statistics. + * Search the required Ae result in the result history and combine it with + * the latest result as the input to AIQ::setStatistics(). + */ + + int32_t effectiveExpo = 0; + int32_t effectiveGain = 0; + ControlValue ctrlValue; + + ctrlValue = sensorCtrls.get(V4L2_CID_EXPOSURE); + if (!ctrlValue.isNone()) + effectiveExpo = ctrlValue.get(); + + ctrlValue = sensorCtrls.get(V4L2_CID_ANALOGUE_GAIN); + if (!ctrlValue.isNone()) + effectiveGain = ctrlValue.get(); + + auto pred = [effectiveExpo, effectiveGain] (aiq::AiqResults& result) { + ia_aiq_exposure_sensor_parameters* sensorExposure = + result.ae()->exposures[0].sensor_exposure; + + return (effectiveExpo == sensorExposure->coarse_integration_time || + effectiveGain == sensorExposure->analog_gain_code_global); + }; + aiq::AiqResults& aeMatchedResults = resultsHistory_.searchBackward(pred, results_); + + aiq::AiqResults combinedResults = results_; + combinedResults.setAe(aeMatchedResults.ae()); + + /* Aiq library expects timestamp in microseconds */ + aiq_.setStatistics(frame, (frameTimestamp / 1000), combinedResults, stats); /* Set frame durations from exposure results */ - ia_aiq_exposure_sensor_parameters *sensorExposure = results_.ae()->exposures->sensor_exposure; + ia_aiq_exposure_sensor_parameters *sensorExposure = combinedResults.ae()->exposures->sensor_exposure; int64_t frameDuration = (sensorExposure->line_length_pixels * sensorExposure->frame_length_lines) / (sensorInfo_.pixelRate / 1e6); ctrls.set(controls::FrameDuration, frameDuration); @@ -423,10 +466,11 @@ void IPAIPU3::setControls(unsigned int frame) IPU3Action op; op.op = ActionSetSensorControls; - ControlList ctrls(ctrls_); - ctrls.set(V4L2_CID_EXPOSURE, static_cast(exposure_)); - ctrls.set(V4L2_CID_ANALOGUE_GAIN, static_cast(gain_)); - op.controls = ctrls; + ControlList sensorCtrls(ctrls_); + sensorCtrls.set(V4L2_CID_EXPOSURE, static_cast(exposure_)); + sensorCtrls.set(V4L2_CID_ANALOGUE_GAIN, static_cast(gain_)); + + op.sensorControls = sensorCtrls; queueFrameAction.emit(frame, op); }