From patchwork Thu Jul 30 11:11:32 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Plowman X-Patchwork-Id: 9079 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 6C1C8BD878 for ; Thu, 30 Jul 2020 11:11:44 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 365FC61DC3; Thu, 30 Jul 2020 13:11:44 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="corUk9et"; dkim-atps=neutral Received: from mail-wr1-x443.google.com (mail-wr1-x443.google.com [IPv6:2a00:1450:4864:20::443]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id DA1B2605B2 for ; Thu, 30 Jul 2020 13:11:40 +0200 (CEST) Received: by mail-wr1-x443.google.com with SMTP id a14so24519753wra.5 for ; Thu, 30 Jul 2020 04:11:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=/vU50YwdRbjN/X7IPem/bDcMy210W4lUqKwV06EiTB8=; b=corUk9et8Ftl991qFarTB8UCL8wd6vVoPy3DvxYzB30top7FUqpjYD2+S0/V8ErqZK 1w8Kf9GQKhAcxXyilqjOZ8evNIhWZYUy2327/aZDuuhX1YLuiUtwTRaHNS1vAguAYJoc s+KSMv0fIgRqKhvsDGs1smv1jzsrMEaoSgINdruAIp+PRtnqvqXOTZwVeDcSQkmyXTHL 0Y+Ahd0VF6UTAqTfktbJNzu2EqYTzr7TLNAyRW1dxCK9PwEyTlei4JM5+C/eZXi/VFeI mnnR4xHG3djM4/YbgqvHtJmnkvTUHzpZnpXbSV5Kw1VkVe3Tygqll97fOVGWYH3RPckC Fm9Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=/vU50YwdRbjN/X7IPem/bDcMy210W4lUqKwV06EiTB8=; b=BgFFsOT0J0pgDgFanpKrCIcGppnZW8VXf2IbRC1hLsjTbq0xCMoBeNLl/CRXl5tVe6 bJe65R9caKRZIr2L/vcB2KwM+E5IMMCzLbs3wjRsrR34urxqLtQhfyZY0QuzNM15hgWS 2+ZVTJypcOcgj/xPBopCdzQx9PKAdfnVwn/Isl8z4PbLEHKadj4MzL17o+lETXfQez4N d+QYGVesBiG5BPgttUU57etVYyTAkeAMbZwJEBIkdtax6W2hlCCSYU9TACCayIiaZDsY lX8NdGFfVXy9bUYCLHe6RHGwEBX001RW9Vj8eSkK/bh95/CO82Y0Hp73qmhx/Jpm6FN8 zD6w== X-Gm-Message-State: AOAM531JS6Kaj/E3BXk8skDCppYJKNrsNBGP9HW7joWFGfX3uy/D3hZt c8pm2gAkAoR3vxVRltj3vG3zO9bH2pX0vg== X-Google-Smtp-Source: ABdhPJx07B9bgznzQly7gpWk2iQZjQhHQezpqRSzL2FxVZvxRgdvMhP3eBTWpIj9D9J4v+v3BmwADw== X-Received: by 2002:adf:ee51:: with SMTP id w17mr35193322wro.239.1596107500350; Thu, 30 Jul 2020 04:11:40 -0700 (PDT) Received: from pi4-davidp.lan (plowpeople3.plus.com. [80.229.223.72]) by smtp.gmail.com with ESMTPSA id l10sm9526651wru.3.2020.07.30.04.11.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 30 Jul 2020 04:11:39 -0700 (PDT) From: David Plowman To: libcamera-devel@lists.libcamera.org Date: Thu, 30 Jul 2020 12:11:32 +0100 Message-Id: <20200730111134.641-2-david.plowman@raspberrypi.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200730111134.641-1-david.plowman@raspberrypi.com> References: <20200730111134.641-1-david.plowman@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 1/3] libcamera: ipa: raspberrypi: ALSC: Camera mode does not need to be atomic 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" In the libcamera framework, SwitchMode (which overwrites the camera_mode) cannot run concurrently with Prepare (which uses it). Signed-off-by: David Plowman Reviewed-by: Laurent Pinchart --- src/ipa/raspberrypi/controller/rpi/alsc.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ipa/raspberrypi/controller/rpi/alsc.hpp b/src/ipa/raspberrypi/controller/rpi/alsc.hpp index 3806257..e895913 100644 --- a/src/ipa/raspberrypi/controller/rpi/alsc.hpp +++ b/src/ipa/raspberrypi/controller/rpi/alsc.hpp @@ -59,7 +59,7 @@ private: // configuration is read-only, and available to both threads AlscConfig config_; bool first_time_; - std::atomic camera_mode_; + CameraMode camera_mode_; std::thread async_thread_; void asyncFunc(); // asynchronous thread function std::mutex mutex_; From patchwork Thu Jul 30 11:11:33 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Plowman X-Patchwork-Id: 9080 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 72B87BD878 for ; Thu, 30 Jul 2020 11:11:45 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 8DC6661DD4; Thu, 30 Jul 2020 13:11:44 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="N5w07dVN"; dkim-atps=neutral Received: from mail-wr1-x430.google.com (mail-wr1-x430.google.com [IPv6:2a00:1450:4864:20::430]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 1BEA06197D for ; Thu, 30 Jul 2020 13:11:42 +0200 (CEST) Received: by mail-wr1-x430.google.com with SMTP id f1so23945875wro.2 for ; Thu, 30 Jul 2020 04:11:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=1uGr9lvmfxr/iPVARwLmF+18vHN/Vn7giWfJqlP5pFE=; b=N5w07dVNbog1/cKlTidZR8G2I+vhPP9oIUsL2lIamvop7e96RcqEVtk9ucGl/9Ls/O w1gDI6OicxFUoONmhpvKZZBcumP2yNr+plsyn3t+jcuR/+9CfWrtyR+KetgGVC6hw63C cm772ofxx8qNRRm8Rsebm9zgO1d72pZKmCdklPlMNMYe2yNmTxXZETJYxov0hAfKi15a SFSjCXozlNmwbyVhTKQHwFBxZrSHTZTQayROwchrKNlmEj9KIPoWQ7F7gTZtEbeKq/OS ZY3GLjQ+scb4EGpmkPMM+yOl9gwGhxdMQJ9rdCQjMkr/yYy2nH7NQi80uoUZsa/Hoac/ 4+Cg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=1uGr9lvmfxr/iPVARwLmF+18vHN/Vn7giWfJqlP5pFE=; b=cEusnl9nw8HaioLztkl1B0oGd6VnA5B+IYs8vvbxgQv3PXBYPPphMDhnVBTtiXHqyg 9+nlzYgB7O2GQU69lqZ2n6KyL16TsPW2OCO/vo568I7pdR5QnT3B3UPeQxKOxlYc72ag gcpTZPD0QcORStcy3np+eYWJj5Yc6/J76KkGiCiUEGL9J92yBZzoaeb6GUniEBahzHvq aF7M/YkJiG860Bi9k3Tcf6tddh28CzGZcleB+Y/WwSz3uraGhUgxqsWH79aNd15q4F+k F2n6X2SlODb+qoKQedJoX8unNgfyg7wmYez9+WwXKhHzLMqlT8U2AAHln6+GrFjGKsXN nJ3g== X-Gm-Message-State: AOAM5331+NeC5hWZ6pfYl0DysKCPjVxJbFHqX2qahUfXv7u82tu6n2a0 RqNl1eZ5/qlm4JKPq9zw+STmtWLXNyOpiA== X-Google-Smtp-Source: ABdhPJwoq0EfK7oWUuyQhfZP+BVyiX7syJVESrTYOMaNgDfyGFeiPqvjK43wCDEDwocBoDTtR1D9Jg== X-Received: by 2002:adf:fe50:: with SMTP id m16mr2464264wrs.27.1596107501187; Thu, 30 Jul 2020 04:11:41 -0700 (PDT) Received: from pi4-davidp.lan (plowpeople3.plus.com. [80.229.223.72]) by smtp.gmail.com with ESMTPSA id l10sm9526651wru.3.2020.07.30.04.11.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 30 Jul 2020 04:11:40 -0700 (PDT) From: David Plowman To: libcamera-devel@lists.libcamera.org Date: Thu, 30 Jul 2020 12:11:33 +0100 Message-Id: <20200730111134.641-3-david.plowman@raspberrypi.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200730111134.641-1-david.plowman@raspberrypi.com> References: <20200730111134.641-1-david.plowman@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 2/3] libcamera: ipa: raspberrypi: ALSC: Resample luminance table 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" This fixes a bug where the luminance correction table was not being resampled according to the camera mode, in the same way as the colour tables. This could be noticeable if any camera modes crop aggressively. This resampling can be done "up front" in the SwitchMode, as we have only a single fixed luminance table. In order to protect the recalculation of the table from the asynchronous thread (which reads it) I've elected to wait for that thread to go idle (though I doubt it would have mattered much). As a by-product of stopping the thread, it no longer needs its own copy of the camera mode (async_camera_mode_). Signed-off-by: David Plowman Reviewed-by: Laurent Pinchart --- src/ipa/raspberrypi/controller/rpi/alsc.cpp | 39 ++++++++++++++------- src/ipa/raspberrypi/controller/rpi/alsc.hpp | 3 +- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/ipa/raspberrypi/controller/rpi/alsc.cpp b/src/ipa/raspberrypi/controller/rpi/alsc.cpp index 76e2f04..8f7720b 100644 --- a/src/ipa/raspberrypi/controller/rpi/alsc.cpp +++ b/src/ipa/raspberrypi/controller/rpi/alsc.cpp @@ -173,19 +173,34 @@ void Alsc::Initialise() lambda_r_[i] = lambda_b_[i] = 1.0; } +void Alsc::waitForAysncThread() +{ + std::unique_lock lock(mutex_); + if (async_started_) { + sync_signal_.wait(lock, [&] { + return async_finished_; + }); + async_started_ = false; + async_finished_ = false; + } +} + void Alsc::SwitchMode(CameraMode const &camera_mode, Metadata *metadata) { (void)metadata; + // Ensure the other thread isn't running while we do this. + waitForAysncThread(); + // There's a bit of a question what we should do if the "crop" of the - // camera mode has changed. Any calculation currently in flight would - // not be useful to the new mode, so arguably we should abort it, and - // generate a new table (like the "first_time" code already here). When - // the crop doesn't change, we can presumably just leave things - // alone. For now, I think we'll just wait and see. When the crop does - // change, any effects should be transient, and if they're not transient - // enough, we'll revisit the question then. + // camera mode has changed. Should we effectively reset the algorithm + // and start over? camera_mode_ = camera_mode; + + // We must resample the luminance table like we do the others, but it's + // fixed so we can simply do it up front here. + resample_cal_table(config_.luminance_lut, camera_mode_, luminance_table_); + if (first_time_) { // On the first time, arrange for something sensible in the // initial tables. Construct the tables for some default colour @@ -201,7 +216,7 @@ void Alsc::SwitchMode(CameraMode const &camera_mode, Metadata *metadata) compensate_lambdas_for_cal(cal_table_b, lambda_b_, async_lambda_b_); add_luminance_to_tables(sync_results_, async_lambda_r_, 1.0, - async_lambda_b_, config_.luminance_lut, + async_lambda_b_, luminance_table_, config_.luminance_strength); memcpy(prev_sync_results_, sync_results_, sizeof(prev_sync_results_)); @@ -266,8 +281,6 @@ void Alsc::restartAsync(StatisticsPtr &stats, Metadata *image_metadata) } copy_stats(statistics_, stats, alsc_status); frame_phase_ = 0; - // copy the camera mode so it won't change during the calculations - async_camera_mode_ = camera_mode_; async_start_ = true; async_started_ = true; async_signal_.notify_one(); @@ -670,9 +683,9 @@ void Alsc::doAlsc() // Fetch the new calibrations (if any) for this CT. Resample them in // case the camera mode is not full-frame. get_cal_table(ct_, config_.calibrations_Cr, cal_table_tmp); - resample_cal_table(cal_table_tmp, async_camera_mode_, cal_table_r); + resample_cal_table(cal_table_tmp, camera_mode_, cal_table_r); get_cal_table(ct_, config_.calibrations_Cb, cal_table_tmp); - resample_cal_table(cal_table_tmp, async_camera_mode_, cal_table_b); + resample_cal_table(cal_table_tmp, camera_mode_, cal_table_b); // You could print out the cal tables for this image here, if you're // tuning the algorithm... (void)print_cal_table; @@ -695,7 +708,7 @@ void Alsc::doAlsc() compensate_lambdas_for_cal(cal_table_b, lambda_b_, async_lambda_b_); // Fold in the luminance table at the appropriate strength. add_luminance_to_tables(async_results_, async_lambda_r_, 1.0, - async_lambda_b_, config_.luminance_lut, + async_lambda_b_, luminance_table_, config_.luminance_strength); } diff --git a/src/ipa/raspberrypi/controller/rpi/alsc.hpp b/src/ipa/raspberrypi/controller/rpi/alsc.hpp index e895913..95572af 100644 --- a/src/ipa/raspberrypi/controller/rpi/alsc.hpp +++ b/src/ipa/raspberrypi/controller/rpi/alsc.hpp @@ -60,10 +60,10 @@ private: AlscConfig config_; bool first_time_; CameraMode camera_mode_; + double luminance_table_[ALSC_CELLS_X * ALSC_CELLS_Y]; std::thread async_thread_; void asyncFunc(); // asynchronous thread function std::mutex mutex_; - CameraMode async_camera_mode_; // condvar for async thread to wait on std::condition_variable async_signal_; // condvar for synchronous thread to wait on @@ -86,6 +86,7 @@ private: int frame_count2_; double sync_results_[3][ALSC_CELLS_Y][ALSC_CELLS_X]; double prev_sync_results_[3][ALSC_CELLS_Y][ALSC_CELLS_X]; + void waitForAysncThread(); // The following are for the asynchronous thread to use, though the main // thread can set/reset them if the async thread is known to be idle: void restartAsync(StatisticsPtr &stats, Metadata *image_metadata); From patchwork Thu Jul 30 11:11:34 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Plowman X-Patchwork-Id: 9081 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 1E408BD878 for ; Thu, 30 Jul 2020 11:11:46 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 4C98361DE1; Thu, 30 Jul 2020 13:11:45 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=raspberrypi.com header.i=@raspberrypi.com header.b="jUw9+ptD"; dkim-atps=neutral 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 BA6FC605B2 for ; Thu, 30 Jul 2020 13:11:42 +0200 (CEST) Received: by mail-wm1-x333.google.com with SMTP id q76so4616718wme.4 for ; Thu, 30 Jul 2020 04:11:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=raspberrypi.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=xrloTKAOEE0Y2mtELiuLyOshxZTe6/71mKidKz4OVnM=; b=jUw9+ptD5hKOWSMde1jghRW0G8P7L3H+bdk/qb+NQ45EHjKr9+yresa29Ytr+yEoJE sb4HLsuaKhNsmIyXx358PvhRjemb0ofWIF7xuaJDGcJh4fir0c0jYwNb+WttEyPNo6He OO46OJHM3N9VwCrf0dPyCX8pKwFUMZ0tW8ov6OlJ8I3N8ewfT4uohFupi+rZoB8TZ2sz oIVN6HOmKtye62olgNRXqzboSfmYGo+mCvBBvc7G1mFveqt9ZZUyKqBbt/0qHtXO4KcM W+nDNSLdwJX1GbG3wSnVXfGqc+WBjbnez1AzoCBv27I0uylmrcW6VEHLInnWBX+At74E Eb3Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=xrloTKAOEE0Y2mtELiuLyOshxZTe6/71mKidKz4OVnM=; b=Nyq+PAXaBRddnCX555nvf1evKO7adNmCIPDrZdYV91f0/dDgkqhhaGoeVeO7gvOhGs iohFelNV8oGkZwv8d3b6SshUroovNSp+XwrC7dgNSbGJOoGPWIKcBDZiRVbqlPUcnh/z rJlZCGxua0k2XLHgEw0FHd0E5qu2+jHjmG/tmcYu5PXQwmWRlpnDJtgwWh4HLmnzP2bA BtTv6SWBRx8mz5xqgWMH1N3/9HJGljh/AphvYpx2Z3NURKbuMhi7EB5sT8obdam4ttFO 0r52lLjybaCsaBOabzinpVxuU/9DU8CTHQI3uHY9QVunwnwqtW8UjpHbi34VAO6WNBx6 N/YQ== X-Gm-Message-State: AOAM530U2RnYNatJrOpx8iWscGj4kLtos9vLGuxJDMhodUne+6x7+JM7 8UTP4RwMHowKqadTLsmYYja38MDLRovWYw== X-Google-Smtp-Source: ABdhPJzRD1vokgg9ViuCCfqdzgcw7x6+4y/sOU1e4gx6GOaJfBLQNqJ2f+RNKts6DF7mVpXPWdzYWQ== X-Received: by 2002:a1c:2dc6:: with SMTP id t189mr13638060wmt.26.1596107502085; Thu, 30 Jul 2020 04:11:42 -0700 (PDT) Received: from pi4-davidp.lan (plowpeople3.plus.com. [80.229.223.72]) by smtp.gmail.com with ESMTPSA id l10sm9526651wru.3.2020.07.30.04.11.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 30 Jul 2020 04:11:41 -0700 (PDT) From: David Plowman To: libcamera-devel@lists.libcamera.org Date: Thu, 30 Jul 2020 12:11:34 +0100 Message-Id: <20200730111134.641-4-david.plowman@raspberrypi.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200730111134.641-1-david.plowman@raspberrypi.com> References: <20200730111134.641-1-david.plowman@raspberrypi.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 3/3] libcamera: ipa: raspberrypi: ALSC: Improve behaviour when camera mode changes 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" Now that we stop the asynchronous thread on a SwitchMode, we would do better to regenerate all the tables if the new camera mode crops in a significantly different way to the old one. A few minor tweaks make sense along with this: * Reset the lambda values when we reset everything. It wouldn't make sense to re-start with the old mode's values. * Use the last recorded colour temperature to generate new tables rather than any default value. * Set the frame "phase" counter to ensure the adaptive procedure will run asap. Signed-off-by: David Plowman Reviewed-by: Laurent Pinchart --- src/ipa/raspberrypi/controller/rpi/alsc.cpp | 54 ++++++++++++++------- 1 file changed, 37 insertions(+), 17 deletions(-) diff --git a/src/ipa/raspberrypi/controller/rpi/alsc.cpp b/src/ipa/raspberrypi/controller/rpi/alsc.cpp index 8f7720b..1e70637 100644 --- a/src/ipa/raspberrypi/controller/rpi/alsc.cpp +++ b/src/ipa/raspberrypi/controller/rpi/alsc.cpp @@ -166,11 +166,8 @@ void Alsc::Initialise() RPI_LOG("Alsc"); frame_count2_ = frame_count_ = frame_phase_ = 0; first_time_ = true; - // Initialise the lambdas. Each call to Process then restarts from the - // previous results. Also initialise the previous frame tables to the - // same harmless values. - for (int i = 0; i < XY; i++) - lambda_r_[i] = lambda_b_[i] = 1.0; + ct_ = config_.default_ct; + // The lambdas are initialised in the SwitchMode. } void Alsc::waitForAysncThread() @@ -185,31 +182,53 @@ void Alsc::waitForAysncThread() } } +static bool compare_modes(CameraMode const &cm0, CameraMode const &cm1) +{ + // Return true if the modes crop from the sensor significantly differently. + int left_diff = std::abs(cm0.crop_x - cm1.crop_x); + int top_diff = std::abs(cm0.crop_y - cm1.crop_y); + int right_diff = std::abs(cm0.crop_x + cm0.scale_x * cm0.width - + cm1.crop_x - cm1.scale_x * cm1.width); + int bottom_diff = std::abs(cm0.crop_y + cm0.scale_y * cm0.height - + cm1.crop_y - cm1.scale_y * cm1.height); + // These thresholds are a rather arbitrary amount chosen to trigger + // when carrying on with the previously calculated tables might be + // worse than regenerating them (but without the adaptive algorithm). + int threshold_x = cm0.sensor_width >> 4; + int threshold_y = cm0.sensor_height >> 4; + return left_diff > threshold_x || right_diff > threshold_x || + top_diff > threshold_y || bottom_diff > threshold_y; +} + void Alsc::SwitchMode(CameraMode const &camera_mode, Metadata *metadata) { (void)metadata; + // We're going to start over with the tables if there's any "significant" + // change. + bool reset_tables = first_time_ || compare_modes(camera_mode_, camera_mode); + // Ensure the other thread isn't running while we do this. waitForAysncThread(); - // There's a bit of a question what we should do if the "crop" of the - // camera mode has changed. Should we effectively reset the algorithm - // and start over? camera_mode_ = camera_mode; // We must resample the luminance table like we do the others, but it's // fixed so we can simply do it up front here. resample_cal_table(config_.luminance_lut, camera_mode_, luminance_table_); - if (first_time_) { - // On the first time, arrange for something sensible in the - // initial tables. Construct the tables for some default colour - // temperature. This echoes the code in doAlsc, without the - // adaptive algorithm. + if (reset_tables) { + // Upon every "table reset", arrange for something sensible to be + // generated. Construct the tables for the previous recorded colour + // temperature. In order to start over from scratch we initialise + // the lambdas, but the rest of this code then echoes the code in + // doAlsc, without the adaptive algorithm. + for (int i = 0; i < XY; i++) + lambda_r_[i] = lambda_b_[i] = 1.0; double cal_table_r[XY], cal_table_b[XY], cal_table_tmp[XY]; - get_cal_table(4000, config_.calibrations_Cr, cal_table_tmp); + get_cal_table(ct_, config_.calibrations_Cr, cal_table_tmp); resample_cal_table(cal_table_tmp, camera_mode_, cal_table_r); - get_cal_table(4000, config_.calibrations_Cb, cal_table_tmp); + get_cal_table(ct_, config_.calibrations_Cb, cal_table_tmp); resample_cal_table(cal_table_tmp, camera_mode_, cal_table_b); compensate_lambdas_for_cal(cal_table_r, lambda_r_, async_lambda_r_); @@ -220,6 +239,7 @@ void Alsc::SwitchMode(CameraMode const &camera_mode, Metadata *metadata) config_.luminance_strength); memcpy(prev_sync_results_, sync_results_, sizeof(prev_sync_results_)); + frame_phase_ = config_.frame_period; // run the algo again asap first_time_ = false; } } @@ -265,8 +285,8 @@ void Alsc::restartAsync(StatisticsPtr &stats, Metadata *image_metadata) { RPI_LOG("Starting ALSC thread"); // Get the current colour temperature. It's all we need from the - // metadata. - ct_ = get_ct(image_metadata, config_.default_ct); + // metadata. Default to the last CT value (which could be the default). + ct_ = get_ct(image_metadata, ct_); // We have to copy the statistics here, dividing out our best guess of // the LSC table that the pipeline applied to them. AlscStatus alsc_status;