@@ -41,12 +41,29 @@ int BlackLevel::read(const libcamera::ValueNode ¶ms)
<< " Read black levels red " << blackLevelR_
<< " green " << blackLevelG_
<< " blue " << blackLevelB_;
+
+ /* Allow "black_level_func" as a shorthand for all 3 colours. */
+ libcamera::ipa::Pwl blackLevelFunc;
+ blackLevelFunc = params["black_level_func"].get<ipa::Pwl>(ipa::Pwl{});
+ blackLevelFuncR_ = params["black_level_func_r"].get<ipa::Pwl>(blackLevelFunc);
+ blackLevelFuncG_ = params["black_level_func_g"].get<ipa::Pwl>(blackLevelFunc);
+ blackLevelFuncB_ = params["black_level_func_b"].get<ipa::Pwl>(blackLevelFunc);
+
return 0;
}
void BlackLevel::initialValues(uint16_t &blackLevelR, uint16_t &blackLevelG,
uint16_t &blackLevelB)
{
+ if (!blackLevelFuncR_.empty())
+ blackLevelR_ = blackLevelFuncR_.eval(1.0);
+
+ if (!blackLevelFuncG_.empty())
+ blackLevelG_ = blackLevelFuncG_.eval(1.0);
+
+ if (!blackLevelFuncB_.empty())
+ blackLevelB_ = blackLevelFuncB_.eval(1.0);
+
blackLevelR = blackLevelR_;
blackLevelG = blackLevelG_;
blackLevelB = blackLevelB_;
@@ -54,10 +71,18 @@ void BlackLevel::initialValues(uint16_t &blackLevelR, uint16_t &blackLevelG,
void BlackLevel::prepare(Metadata *imageMetadata)
{
- /*
- * Possibly we should think about doing this in a switchMode or
- * something?
- */
+ DeviceStatus deviceStatus;
+ if (!imageMetadata->get("device.status", deviceStatus)) {
+ if (!blackLevelFuncR_.empty())
+ blackLevelR_ = blackLevelFuncR_.eval(deviceStatus.analogueGain);
+
+ if (!blackLevelFuncG_.empty())
+ blackLevelG_ = blackLevelFuncG_.eval(deviceStatus.analogueGain);
+
+ if (!blackLevelFuncB_.empty())
+ blackLevelB_ = blackLevelFuncB_.eval(deviceStatus.analogueGain);
+ }
+
struct BlackLevelStatus status;
status.blackLevelR = blackLevelR_;
status.blackLevelG = blackLevelG_;
@@ -6,6 +6,8 @@
*/
#pragma once
+#include <libipa/pwl.h>
+
#include "../black_level_algorithm.h"
#include "../black_level_status.h"
@@ -27,6 +29,11 @@ private:
double blackLevelR_;
double blackLevelG_;
double blackLevelB_;
+
+ /* Black levels can vary with analogue gain instead of being constant. */
+ libcamera::ipa::Pwl blackLevelFuncR_;
+ libcamera::ipa::Pwl blackLevelFuncG_;
+ libcamera::ipa::Pwl blackLevelFuncB_;
};
} /* namespace RPiController */
Optionally, a PWL (piecewise linear) function can be specified as the black level instead of a constant value. This PWL is evaluated at the current analogue gain for each frame. Tuning files will also accept "black_level_func" as a shorthand for all three channels. Signed-off-by: David Plowman <david.plowman@raspberrypi.com> --- src/ipa/rpi/controller/rpi/black_level.cpp | 33 +++++++++++++++++++--- src/ipa/rpi/controller/rpi/black_level.h | 7 +++++ 2 files changed, 36 insertions(+), 4 deletions(-)