/* SPDX-License-Identifier: BSD-2-Clause */ /* * Copyright (C) 2019, Raspberry Pi (Trading) Limited * * lux.cpp - Lux control algorithm */ #include #include #include #include "../device_status.h" #include "lux.hpp" using namespace RPiController; using namespace libcamera; using namespace std::literals::chrono_literals; LOG_DEFINE_CATEGORY(RPiLux) #define NAME "rpi.lux" Lux::Lux(Controller *controller) : Algorithm(controller) { // Put in some defaults as there will be no meaningful values until // Process has run. status_.aperture = 1.0; status_.lux = 400; } char const *Lux::Name() const { return NAME; } void Lux::Read(boost::property_tree::ptree const ¶ms) { reference_shutter_speed_ = params.get("reference_shutter_speed") * 1.0us; reference_gain_ = params.get("reference_gain"); reference_aperture_ = params.get("reference_aperture", 1.0); reference_Y_ = params.get("reference_Y"); reference_lux_ = params.get("reference_lux"); current_aperture_ = reference_aperture_; } void Lux::SetCurrentAperture(double aperture) { current_aperture_ = aperture; } void Lux::Prepare(Metadata *image_metadata) { std::unique_lock lock(mutex_); image_metadata->Set("lux.status", status_); } void Lux::Process(StatisticsPtr &stats, Metadata *image_metadata) { DeviceStatus device_status; if (image_metadata->Get("device.status", device_status) == 0) { double current_gain = device_status.analogue_gain; double current_aperture = device_status.aperture; if (current_aperture == 0) current_aperture = current_aperture_; uint64_t sum = 0; uint32_t num = 0; uint32_t *bin = stats->hist[0].g_hist; const int num_bins = sizeof(stats->hist[0].g_hist) / sizeof(stats->hist[0].g_hist[0]); for (int i = 0; i < num_bins; i++) sum += bin[i] * (uint64_t)i, num += bin[i]; // add .5 to reflect the mid-points of bins double current_Y = sum / (double)num + .5; double gain_ratio = reference_gain_ / current_gain; double shutter_speed_ratio = reference_shutter_speed_ / device_status.shutter_speed; double aperture_ratio = reference_aperture_ / current_aperture; double Y_ratio = current_Y * (65536 / num_bins) / reference_Y_; double estimated_lux = shutter_speed_ratio * gain_ratio * aperture_ratio * aperture_ratio * Y_ratio * reference_lux_; LuxStatus status; status.lux = estimated_lux; status.aperture = current_aperture; LOG(RPiLux, Debug) << ": estimated lux " << estimated_lux; { std::unique_lock lock(mutex_); status_ = status; } // Overwrite the metadata here as well, so that downstream // algorithms get the latest value. image_metadata->Set("lux.status", status); } else LOG(RPiLux, Warning) << ": no device metadata"; } // Register algorithm with the system. static Algorithm *Create(Controller *controller) { return (Algorithm *)new Lux(controller); } static RegisterAlgorithm reg(NAME, &Create); 35bb2e84b9ba9daec5a4b844b92ead897'>refslogtreecommitdiff
blob: db95945a15809107d1394a54f8e82f7c8c82a67a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 * Copyright (C) 2019, Google Inc.
 *
 * control_info.cpp - ControlInfoMap tests
 */

#include <iostream>

#include <libcamera/camera.h>
#include <libcamera/camera_manager.h>
#include <libcamera/control_ids.h>
#include <libcamera/controls.h>

#include "libcamera/internal/camera_controls.h"

#include "camera_test.h"
#include "test.h"

using namespace std;
using namespace libcamera;

class ControlInfoMapTest : public CameraTest, public Test
{
public:
	ControlInfoMapTest()
		: CameraTest("platform/vimc.0 Sensor B")
	{
	}

protected:
	int init() override
	{
		return status_;
	}

	int run() override
	{
		const ControlInfoMap &infoMap = camera_->controls();

		/* Test looking up a valid control by ControlId. */
		if (infoMap.count(&controls::Brightness) != 1) {
			cerr << "count() on valid control failed" << endl;
			return TestFail;
		}

		if (infoMap.find(&controls::Brightness) == infoMap.end()) {
			cerr << "find() on valid control failed" << endl;
			return TestFail;
		}

		infoMap.at(&controls::Brightness);

		/* Test looking up a valid control by numerical ID. */
		if (infoMap.count(controls::Brightness.id()) != 1) {
			cerr << "count() on valid ID failed" << endl;
			return TestFail;
		}

		if (infoMap.find(controls::Brightness.id()) == infoMap.end()) {
			cerr << "find() on valid ID failed" << endl;
			return TestFail;
		}