summaryrefslogtreecommitdiff
path: root/src/ipa/libipa/camera_sensor_helper.h
blob: 3ea1806cb1fd7445d79017323bead19a819a7e4e (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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
 * Copyright (C) 2021, Google Inc.
 *
 * camera_sensor_helper.h - Helper class that performs sensor-specific parameter computations
 */

#pragma once

#include <stdint.h>

#include <memory>
#include <string>
#include <vector>

#include <libcamera/base/class.h>

namespace libcamera {

namespace ipa {

class CameraSensorHelper
{
public:
	CameraSensorHelper() = default;
	virtual ~CameraSensorHelper() = default;

	virtual uint32_t gainCode(double gain) const;
	virtual double gain(uint32_t gainCode) const;

protected:
	enum AnalogueGainType {
		AnalogueGainLinear,
		AnalogueGainExponential,
	};

	struct AnalogueGainLinearConstants {
		int16_t m0;
		int16_t c0;
		int16_t m1;
		int16_t c1;
	};

	struct AnalogueGainExpConstants {
		double a;
		double m;
	};

	union AnalogueGainConstants {
		AnalogueGainLinearConstants linear;
		AnalogueGainExpConstants exp;
	};

	AnalogueGainType gainType_;
	AnalogueGainConstants gainConstants_;

private:
	LIBCAMERA_DISABLE_COPY_AND_MOVE(CameraSensorHelper)
};

class CameraSensorHelperFactoryBase
{
public:
	CameraSensorHelperFactoryBase(const std::string name);
	virtual ~CameraSensorHelperFactoryBase() = default;

	static std::unique_ptr<CameraSensorHelper> create(const std::string &name);

	static std::vector<CameraSensorHelperFactoryBase *> &factories();

private:
	LIBCAMERA_DISABLE_COPY_AND_MOVE(CameraSensorHelperFactoryBase)

	static void registerType(CameraSensorHelperFactoryBase *factory);

	virtual std::unique_ptr<CameraSensorHelper> createInstance() const = 0;

	std::string name_;
};

template<typename _Helper>
class CameraSensorHelperFactory final : public CameraSensorHelperFactoryBase
{
public:
	CameraSensorHelperFactory(const char *name)
		: CameraSensorHelperFactoryBase(name)
	{
	}

private:
	std::unique_ptr<CameraSensorHelper> createInstance() const
	{
		return std::make_unique<_Helper>();
	}
};

#define REGISTER_CAMERA_SENSOR_HELPER(name, helper) \
static CameraSensorHelperFactory<helper> global_##helper##Factory(name);

} /* namespace ipa */

} /* namespace libcamera */
he media graph"; return TestFail; } /* * Test if link can be consistently retrieved through the * different methods the media device offers. */ string linkName("'Debayer A':[1] -> 'Scaler':[0]'"); MediaLink *link = media_->link("Debayer A", 1, "Scaler", 0); if (!link) { cerr << "Unable to find link: " << linkName << " using lookup by name" << endl; return TestFail; } MediaEntity *source = media_->getEntityByName("Debayer A"); if (!source) { cerr << "Unable to find entity: 'Debayer A'" << endl; return TestFail; } MediaEntity *sink = media_->getEntityByName("Scaler"); if (!sink) { cerr << "Unable to find entity: 'Scaler'" << endl; return TestFail; } MediaLink *link2 = media_->link(source, 1, sink, 0); if (!link2) { cerr << "Unable to find link: " << linkName << " using lookup by entity" << endl; return TestFail; } if (link != link2) { cerr << "Link lookup by name and by entity don't match" << endl; return TestFail; } link2 = media_->link(source->getPadByIndex(1), sink->getPadByIndex(0)); if (!link2) { cerr << "Unable to find link: " << linkName << " using lookup by pad" << endl; return TestFail; } if (link != link2) { cerr << "Link lookup by name and by pad don't match" << endl; return TestFail; } /* After reset the link shall not be enabled. */ if (link->flags() & MEDIA_LNK_FL_ENABLED) { cerr << "Link " << linkName << " should not be enabled after a device reset" << endl; return TestFail; } /* Enable the link and test if enabling was successful. */ if (link->setEnabled(true)) { cerr << "Failed to enable link: " << linkName << endl; return TestFail; } if (!(link->flags() & MEDIA_LNK_FL_ENABLED)) { cerr << "Link " << linkName << " was enabled but it is reported as disabled" << endl; return TestFail; } /* Disable the link and test if disabling was successful. */ if (link->setEnabled(false)) { cerr << "Failed to disable link: " << linkName << endl; return TestFail; } if (link->flags() & MEDIA_LNK_FL_ENABLED) { cerr << "Link " << linkName << " was disabled but it is reported as enabled" << endl; return TestFail; } /* Try to get a non existing link. */ linkName = "'Sensor A':[1] -> 'Scaler':[0]"; link = media_->link("Sensor A", 1, "Scaler", 0); if (link) { cerr << "Link lookup for " << linkName << " succeeded but link does not exist" << endl; return TestFail; } /* Now get an immutable link and try to disable it. */ linkName = "'Sensor A':[0] -> 'Raw Capture 0':[0]"; link = media_->link("Sensor A", 0, "Raw Capture 0", 0); if (!link) { cerr << "Unable to find link: " << linkName << " using lookup by name" << endl; return TestFail; } if (!(link->flags() & MEDIA_LNK_FL_IMMUTABLE)) { cerr << "Link " << linkName << " should be 'IMMUTABLE'" << endl; return TestFail; } /* Disabling an immutable link shall fail. */ if (!link->setEnabled(false)) { cerr << "Disabling immutable link " << linkName << " succeeded but should have failed" << endl; return TestFail; } /* * Enable an disabled link, and verify it is disabled again * after disabling all links in the media graph. */ linkName = "'Debayer B':[1] -> 'Scaler':[0]'"; link = media_->link("Debayer B", 1, "Scaler", 0); if (!link) { cerr << "Unable to find link: " << linkName << " using lookup by name" << endl; return TestFail; } if (link->setEnabled(true)) { cerr << "Failed to enable link: " << linkName << endl; return TestFail; } if (!(link->flags() & MEDIA_LNK_FL_ENABLED)) { cerr << "Link " << linkName << " was enabled but it is reported as disabled" << endl; return TestFail; } if (media_->disableLinks()) { cerr << "Failed to disable all links in the media graph"; return TestFail; } if (link->flags() & MEDIA_LNK_FL_ENABLED) { cerr << "All links in the media graph have been disabled" << " but link " << linkName << " is still reported as enabled" << endl; return TestFail; } return 0; } void cleanup() { media_->release(); } }; TEST_REGISTER(MediaDeviceLinkTest)