summaryrefslogtreecommitdiff
path: root/src/ipa/raspberrypi/controller/rpi/alsc.cpp
diff options
context:
space:
mode:
authorDavid Plowman <david.plowman@raspberrypi.com>2020-08-01 09:01:50 +0100
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2020-08-05 17:48:55 +0300
commit7f6b9121cc51cc5356a4c91957cce1aa6011d47e (patch)
treed23541e7ea62b326b95f287eaa0f45ad7c01b9a2 /src/ipa/raspberrypi/controller/rpi/alsc.cpp
parentdb552b0b925a9ba2c3cc54aa40feed6fb7e66981 (diff)
libcamera: ipa: raspberrypi: ALSC: Resample luminance table
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 <david.plowman@raspberrypi.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Naushir Patuck <naush@raspberrypi.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Diffstat (limited to 'src/ipa/raspberrypi/controller/rpi/alsc.cpp')
-rw-r--r--src/ipa/raspberrypi/controller/rpi/alsc.cpp39
1 files changed, 26 insertions, 13 deletions
diff --git a/src/ipa/raspberrypi/controller/rpi/alsc.cpp b/src/ipa/raspberrypi/controller/rpi/alsc.cpp
index 12359dc5..4df99347 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()
+{
+ if (async_started_) {
+ async_started_ = false;
+ std::unique_lock<std::mutex> lock(mutex_);
+ sync_signal_.wait(lock, [&] {
+ return async_finished_;
+ });
+ 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_started_ = true;
{
std::lock_guard<std::mutex> lock(mutex_);
@@ -672,9 +685,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;
@@ -697,7 +710,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);
}