{"id":9127,"url":"https://patchwork.libcamera.org/api/1.1/patches/9127/?format=json","web_url":"https://patchwork.libcamera.org/patch/9127/","project":{"id":1,"url":"https://patchwork.libcamera.org/api/1.1/projects/1/?format=json","name":"libcamera","link_name":"libcamera","list_id":"libcamera_core","list_email":"libcamera-devel@lists.libcamera.org","web_url":"","scm_url":"","webscm_url":""},"msgid":"<20200801080151.4282-4-david.plowman@raspberrypi.com>","date":"2020-08-01T08:01:50","name":"[libcamera-devel,v3,3/4] libcamera: ipa: raspberrypi: ALSC: Resample luminance table","commit_ref":null,"pull_url":null,"state":"accepted","archived":false,"hash":"0804762f3ffee78afa3fb19f116cb7c14fa3f481","submitter":{"id":42,"url":"https://patchwork.libcamera.org/api/1.1/people/42/?format=json","name":"David Plowman","email":"david.plowman@raspberrypi.com"},"delegate":null,"mbox":"https://patchwork.libcamera.org/patch/9127/mbox/","series":[{"id":1174,"url":"https://patchwork.libcamera.org/api/1.1/series/1174/?format=json","web_url":"https://patchwork.libcamera.org/project/libcamera/list/?series=1174","date":"2020-08-01T08:01:47","name":"Raspberry Pi ALSC improvements","version":3,"mbox":"https://patchwork.libcamera.org/series/1174/mbox/"}],"comments":"https://patchwork.libcamera.org/api/patches/9127/comments/","check":"pending","checks":"https://patchwork.libcamera.org/api/patches/9127/checks/","tags":{},"headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 06A23BD879\n\tfor <parsemail@patchwork.libcamera.org>;\n\tSat,  1 Aug 2020 08:02:01 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id B0CF661F5D;\n\tSat,  1 Aug 2020 10:02:00 +0200 (CEST)","from mail-wm1-x32e.google.com (mail-wm1-x32e.google.com\n\t[IPv6:2a00:1450:4864:20::32e])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 3AE2561F4C\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSat,  1 Aug 2020 10:01:59 +0200 (CEST)","by mail-wm1-x32e.google.com with SMTP id 184so11136223wmb.0\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSat, 01 Aug 2020 01:01:59 -0700 (PDT)","from pi4-davidp.lan (plowpeople3.plus.com. [80.229.223.72])\n\tby smtp.gmail.com with ESMTPSA id\n\tl67sm17385253wml.13.2020.08.01.01.01.57\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tSat, 01 Aug 2020 01:01:57 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=raspberrypi.com header.i=@raspberrypi.com\n\theader.b=\"bivLCrY2\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=raspberrypi.com; s=google;\n\th=from:to:cc:subject:date:message-id:in-reply-to:references\n\t:mime-version:content-transfer-encoding;\n\tbh=BkhnOjtcYZUZR4IAtisTMj71R1n33rN9aiwswXHSvXE=;\n\tb=bivLCrY2IP9kfcnBB6Vgk8rOMrxSqcRhlMHbMwbZiouoD7xdQGn3qO0zjD/qbsBRMQ\n\t3CigZhgzB18UNrGf23ZVHB8cKcxWiLPu8sXsnq9d3ln0ZIIL6ps2ccs6gyS7CrDgTRH7\n\tQJZ/CfIbeosVOz7BxMj7WOaHqt8JCpvQqc9MKhXEvpxfKFgC2An7iCDwchD2g83ws5Ej\n\tv8Ttkw9sVOc8hREkaz8sIidbCqO5XwG2ME1v6DPRrkEyjYl6v1CAsUniJZ5KAibdn8sN\n\tiJbX/g8AdRonIOJ+q1E7zYmjwaf/FDONgm+jM4CDbSXw8VG+4KQvcsmQl6aOsmDS5vA6\n\tPaXQ==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to\n\t:references:mime-version:content-transfer-encoding;\n\tbh=BkhnOjtcYZUZR4IAtisTMj71R1n33rN9aiwswXHSvXE=;\n\tb=L/9K1uPpFFlZnCwX4PsrT/PLO7l93neL8e1vSd7MC2bfDNe7Hk+Os2F03UpdBOSO0e\n\t/dqAmOXRHCD944KImjOWIYUwlhEe8WaPgkEfgfH8tMU/CWn17l3pQbIBAGFg7nFgGa47\n\tnruNVNy19hVZWzyERC/khlFgM0luPWAEFdjmguhSqMUy52pspFGvnyHq3w7fjyyFX+99\n\tHLr0f1ulZzHr499GnVl+pICv8H2GHi22XSW+FrULVhVRQc9JNWJ/5EoLDA+zXuvmJ/vT\n\to3C4St0nJr19/LSH1k7JgW7w1slE2Bk6hM4/zmdmWuMKGGfQkKyeNiN2Luxiz6Ok+k7i\n\tu/nA==","X-Gm-Message-State":"AOAM532zshcnhraLOlk3HJ3IrHkQDt0/OR9DA07Vrla6IehxgKYMHWzd\n\tXuqEIWMQ9Ypmvv24oNUzN8PYJ1svS6Vdgg==","X-Google-Smtp-Source":"ABdhPJxQ/DfCwrABv2F7Xce1dQ1YUmiHS/z+/q1AMdFIBuTkIKN+rueIaPIIyDhPhXzM4jpjisZuBA==","X-Received":"by 2002:a1c:7918:: with SMTP id\n\tl24mr7009530wme.158.1596268918432; \n\tSat, 01 Aug 2020 01:01:58 -0700 (PDT)","From":"David Plowman <david.plowman@raspberrypi.com>","To":"libcamera-devel@lists.libcamera.org","Date":"Sat,  1 Aug 2020 09:01:50 +0100","Message-Id":"<20200801080151.4282-4-david.plowman@raspberrypi.com>","X-Mailer":"git-send-email 2.20.1","In-Reply-To":"<20200801080151.4282-1-david.plowman@raspberrypi.com>","References":"<20200801080151.4282-1-david.plowman@raspberrypi.com>","MIME-Version":"1.0","Subject":"[libcamera-devel] [PATCH v3 3/4] libcamera: ipa: raspberrypi: ALSC:\n\tResample luminance table","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Content-Type":"text/plain; charset=\"us-ascii\"","Content-Transfer-Encoding":"7bit","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"},"content":"This fixes a bug where the luminance correction table was not being\nresampled according to the camera mode, in the same way as the colour\ntables. This could be noticeable if any camera modes crop\naggressively.\n\nThis resampling can be done \"up front\" in the SwitchMode, as we have\nonly a single fixed luminance table. In order to protect the\nrecalculation of the table from the asynchronous thread (which reads\nit) I've elected to wait for that thread to go idle (though I doubt it\nwould have mattered much). As a by-product of stopping the thread, it\nno longer needs its own copy of the camera mode (async_camera_mode_).\n\nSigned-off-by: David Plowman <david.plowman@raspberrypi.com>\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n---\n src/ipa/raspberrypi/controller/rpi/alsc.cpp | 39 ++++++++++++++-------\n src/ipa/raspberrypi/controller/rpi/alsc.hpp |  3 +-\n 2 files changed, 28 insertions(+), 14 deletions(-)","diff":"diff --git a/src/ipa/raspberrypi/controller/rpi/alsc.cpp b/src/ipa/raspberrypi/controller/rpi/alsc.cpp\nindex 12359dc..4df9934 100644\n--- a/src/ipa/raspberrypi/controller/rpi/alsc.cpp\n+++ b/src/ipa/raspberrypi/controller/rpi/alsc.cpp\n@@ -173,19 +173,34 @@ void Alsc::Initialise()\n \t\tlambda_r_[i] = lambda_b_[i] = 1.0;\n }\n \n+void Alsc::waitForAysncThread()\n+{\n+\tif (async_started_) {\n+\t\tasync_started_ = false;\n+\t\tstd::unique_lock<std::mutex> lock(mutex_);\n+\t\tsync_signal_.wait(lock, [&] {\n+\t\t\treturn async_finished_;\n+\t\t});\n+\t\tasync_finished_ = false;\n+\t}\n+}\n+\n void Alsc::SwitchMode(CameraMode const &camera_mode, Metadata *metadata)\n {\n \t(void)metadata;\n \n+\t// Ensure the other thread isn't running while we do this.\n+\twaitForAysncThread();\n+\n \t// There's a bit of a question what we should do if the \"crop\" of the\n-\t// camera mode has changed.  Any calculation currently in flight would\n-\t// not be useful to the new mode, so arguably we should abort it, and\n-\t// generate a new table (like the \"first_time\" code already here).  When\n-\t// the crop doesn't change, we can presumably just leave things\n-\t// alone. For now, I think we'll just wait and see. When the crop does\n-\t// change, any effects should be transient, and if they're not transient\n-\t// enough, we'll revisit the question then.\n+\t// camera mode has changed. Should we effectively reset the algorithm\n+\t// and start over?\n \tcamera_mode_ = camera_mode;\n+\n+\t// We must resample the luminance table like we do the others, but it's\n+\t// fixed so we can simply do it up front here.\n+\tresample_cal_table(config_.luminance_lut, camera_mode_, luminance_table_);\n+\n \tif (first_time_) {\n \t\t// On the first time, arrange for something sensible in the\n \t\t// initial tables. Construct the tables for some default colour\n@@ -201,7 +216,7 @@ void Alsc::SwitchMode(CameraMode const &camera_mode, Metadata *metadata)\n \t\tcompensate_lambdas_for_cal(cal_table_b, lambda_b_,\n \t\t\t\t\t   async_lambda_b_);\n \t\tadd_luminance_to_tables(sync_results_, async_lambda_r_, 1.0,\n-\t\t\t\t\tasync_lambda_b_, config_.luminance_lut,\n+\t\t\t\t\tasync_lambda_b_, luminance_table_,\n \t\t\t\t\tconfig_.luminance_strength);\n \t\tmemcpy(prev_sync_results_, sync_results_,\n \t\t       sizeof(prev_sync_results_));\n@@ -266,8 +281,6 @@ void Alsc::restartAsync(StatisticsPtr &stats, Metadata *image_metadata)\n \t}\n \tcopy_stats(statistics_, stats, alsc_status);\n \tframe_phase_ = 0;\n-\t// copy the camera mode so it won't change during the calculations\n-\tasync_camera_mode_ = camera_mode_;\n \tasync_started_ = true;\n \t{\n \t\tstd::lock_guard<std::mutex> lock(mutex_);\n@@ -672,9 +685,9 @@ void Alsc::doAlsc()\n \t// Fetch the new calibrations (if any) for this CT. Resample them in\n \t// case the camera mode is not full-frame.\n \tget_cal_table(ct_, config_.calibrations_Cr, cal_table_tmp);\n-\tresample_cal_table(cal_table_tmp, async_camera_mode_, cal_table_r);\n+\tresample_cal_table(cal_table_tmp, camera_mode_, cal_table_r);\n \tget_cal_table(ct_, config_.calibrations_Cb, cal_table_tmp);\n-\tresample_cal_table(cal_table_tmp, async_camera_mode_, cal_table_b);\n+\tresample_cal_table(cal_table_tmp, camera_mode_, cal_table_b);\n \t// You could print out the cal tables for this image here, if you're\n \t// tuning the algorithm...\n \t(void)print_cal_table;\n@@ -697,7 +710,7 @@ void Alsc::doAlsc()\n \tcompensate_lambdas_for_cal(cal_table_b, lambda_b_, async_lambda_b_);\n \t// Fold in the luminance table at the appropriate strength.\n \tadd_luminance_to_tables(async_results_, async_lambda_r_, 1.0,\n-\t\t\t\tasync_lambda_b_, config_.luminance_lut,\n+\t\t\t\tasync_lambda_b_, luminance_table_,\n \t\t\t\tconfig_.luminance_strength);\n }\n \ndiff --git a/src/ipa/raspberrypi/controller/rpi/alsc.hpp b/src/ipa/raspberrypi/controller/rpi/alsc.hpp\nindex e895913..95572af 100644\n--- a/src/ipa/raspberrypi/controller/rpi/alsc.hpp\n+++ b/src/ipa/raspberrypi/controller/rpi/alsc.hpp\n@@ -60,10 +60,10 @@ private:\n \tAlscConfig config_;\n \tbool first_time_;\n \tCameraMode camera_mode_;\n+\tdouble luminance_table_[ALSC_CELLS_X * ALSC_CELLS_Y];\n \tstd::thread async_thread_;\n \tvoid asyncFunc(); // asynchronous thread function\n \tstd::mutex mutex_;\n-\tCameraMode async_camera_mode_;\n \t// condvar for async thread to wait on\n \tstd::condition_variable async_signal_;\n \t// condvar for synchronous thread to wait on\n@@ -86,6 +86,7 @@ private:\n \tint frame_count2_;\n \tdouble sync_results_[3][ALSC_CELLS_Y][ALSC_CELLS_X];\n \tdouble prev_sync_results_[3][ALSC_CELLS_Y][ALSC_CELLS_X];\n+\tvoid waitForAysncThread();\n \t// The following are for the asynchronous thread to use, though the main\n \t// thread can set/reset them if the async thread is known to be idle:\n \tvoid restartAsync(StatisticsPtr &stats, Metadata *image_metadata);\n","prefixes":["libcamera-devel","v3","3/4"]}