[libcamera-devel] [PATCH v4 2/3] libcamera: camera_sensor: Enable to set a test pattern mode
Hirokazu Honda
hiroh at chromium.org
Thu Nov 4 07:42:51 CET 2021
This adds a function to set a camera sensor driver a test pattern
mode.
Signed-off-by: Hirokazu Honda <hiroh at chromium.org>
Reviewed-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
include/libcamera/internal/camera_sensor.h | 8 ++
src/libcamera/camera_sensor.cpp | 95 ++++++++++++++++++++--
src/libcamera/control_ids.yaml | 5 ++
3 files changed, 100 insertions(+), 8 deletions(-)
diff --git a/include/libcamera/internal/camera_sensor.h b/include/libcamera/internal/camera_sensor.h
index edef2220..40db792a 100644
--- a/include/libcamera/internal/camera_sensor.h
+++ b/include/libcamera/internal/camera_sensor.h
@@ -27,6 +27,9 @@ namespace libcamera {
class BayerFormat;
class MediaEntity;
+class Request;
+
+struct CameraSensorProperties;
class CameraSensor : protected Loggable
{
@@ -47,6 +50,7 @@ public:
{
return testPatternModes_;
}
+ int setTestPatternMode(controls::draft::TestPatternModeEnum testPatternMode);
V4L2SubdeviceFormat getFormat(const std::vector<unsigned int> &mbusCodes,
const Size &size) const;
@@ -55,6 +59,7 @@ public:
const ControlInfoMap &controls() const;
ControlList getControls(const std::vector<uint32_t> &ids);
int setControls(ControlList *ctrls);
+ int applyRequestControls(Request *request);
V4L2Subdevice *device() { return subdev_.get(); }
@@ -82,6 +87,8 @@ private:
std::unique_ptr<V4L2Subdevice> subdev_;
unsigned int pad_;
+ const CameraSensorProperties *staticProps_;
+
std::string model_;
std::string id_;
@@ -89,6 +96,7 @@ private:
std::vector<unsigned int> mbusCodes_;
std::vector<Size> sizes_;
std::vector<controls::draft::TestPatternModeEnum> testPatternModes_;
+ controls::draft::TestPatternModeEnum testPatternMode_;
Size pixelArraySize_;
Rectangle activeArea_;
diff --git a/src/libcamera/camera_sensor.cpp b/src/libcamera/camera_sensor.cpp
index f0aa9f24..bb429b3e 100644
--- a/src/libcamera/camera_sensor.cpp
+++ b/src/libcamera/camera_sensor.cpp
@@ -17,6 +17,7 @@
#include <string.h>
#include <libcamera/property_ids.h>
+#include <libcamera/request.h>
#include <libcamera/base/utils.h>
@@ -54,8 +55,9 @@ LOG_DEFINE_CATEGORY(CameraSensor)
* Once constructed the instance must be initialized with init().
*/
CameraSensor::CameraSensor(const MediaEntity *entity)
- : entity_(entity), pad_(UINT_MAX), bayerFormat_(nullptr),
- properties_(properties::properties)
+ : entity_(entity), pad_(UINT_MAX), staticProps_(nullptr),
+ testPatternMode_(controls::draft::TestPatternModeUnset),
+ bayerFormat_(nullptr), properties_(properties::properties)
{
}
@@ -300,25 +302,30 @@ void CameraSensor::initVimcDefaultProperties()
void CameraSensor::initStaticProperties()
{
- const CameraSensorProperties *props = CameraSensorProperties::get(model_);
- if (!props)
+ staticProps_ = CameraSensorProperties::get(model_);
+ if (!staticProps_)
return;
/* Register the properties retrieved from the sensor database. */
- properties_.set(properties::UnitCellSize, props->unitCellSize);
+ properties_.set(properties::UnitCellSize, staticProps_->unitCellSize);
- initTestPatternModes(props->testPatternModes);
+ initTestPatternModes(staticProps_->testPatternModes);
}
void CameraSensor::initTestPatternModes(
const std::map<controls::draft::TestPatternModeEnum, int32_t> &testPatternModes)
{
- const auto &v4l2TestPattern = controls().find(V4L2_CID_TEST_PATTERN);
- if (v4l2TestPattern == controls().end()) {
+ if (testPatternModes.empty()) {
LOG(CameraSensor, Debug) << "No static test pattern map for \'"
<< model() << "\'";
return;
}
+ const auto &v4l2TestPattern = controls().find(V4L2_CID_TEST_PATTERN);
+ if (v4l2TestPattern == controls().end()) {
+ LOG(CameraSensor, Debug)
+ << "V4L2_CID_TEST_PATTERN is not supported";
+ return;
+ }
/*
* Create a map that associates the V4L2 control index to the test
@@ -531,6 +538,44 @@ Size CameraSensor::resolution() const
* \return The list of test pattern modes
*/
+/**
+ * \brief Set the test pattern mode for the camera sensor
+ * \param[in] testPatternMode Test pattern mode control value to set the camera
+ * sensor
+ *
+ * \return 0 on success or a negative error code otherwise
+ */
+int CameraSensor::setTestPatternMode(
+ controls::draft::TestPatternModeEnum testPatternMode)
+{
+ if (testPatternMode_ == testPatternMode)
+ return 0;
+
+ if (!staticProps_) {
+ return 0;
+ }
+
+ auto it = std::find(testPatternModes_.begin(), testPatternModes_.end(),
+ testPatternMode);
+ if (it != testPatternModes_.end()) {
+ LOG(CameraSensor, Error) << "Unsupported test pattern mode "
+ << testPatternMode;
+ return -EINVAL;
+ }
+
+ int32_t index = staticProps_->testPatternModes.at(testPatternMode);
+ ControlList ctrls{ controls() };
+ ctrls.set(V4L2_CID_TEST_PATTERN, index);
+
+ int ret = setControls(&ctrls);
+ if (ret)
+ return ret;
+
+ testPatternMode_ = testPatternMode;
+
+ return 0;
+}
+
/**
* \brief Retrieve the best sensor format for a desired output
* \param[in] mbusCodes The list of acceptable media bus codes
@@ -705,6 +750,40 @@ int CameraSensor::setControls(ControlList *ctrls)
return subdev_->setControls(ctrls);
}
+/**
+ * \brief Apply controls associated with Request
+ * \param[in] request Request that may contain contorls to be applied
+ *
+ * Some controls have to be applied for a capture associated with Request.
+ * This picks up such controls and set the driver them.
+ *
+ * \return 0 on success or an error code otherwise
+ */
+int32_t CameraSensor::applyRequestControls(Request *request)
+{
+ /* Assumes applying the test pattern mode affects immediately. */
+ if (request->controls().contains(controls::draft::TestPatternMode)) {
+ const int32_t testPatternMode = request->controls().get(
+ controls::draft::TestPatternMode);
+
+ LOG(CameraSensor, Debug) << "Apply test pattern mode: "
+ << testPatternMode;
+
+ int ret = setTestPatternMode(
+ static_cast<controls::draft::TestPatternModeEnum>(testPatternMode));
+ if (ret) {
+ LOG(CameraSensor, Error)
+ << "Failed to set test pattern mode: " << ret;
+ return ret;
+ }
+
+ request->metadata().set(controls::draft::TestPatternMode,
+ testPatternMode);
+ }
+
+ return 0;
+}
+
/**
* \fn CameraSensor::device()
* \brief Retrieve the camera sensor device
diff --git a/src/libcamera/control_ids.yaml b/src/libcamera/control_ids.yaml
index 9d4638ae..083bac7b 100644
--- a/src/libcamera/control_ids.yaml
+++ b/src/libcamera/control_ids.yaml
@@ -639,6 +639,11 @@ controls:
Control to select the test pattern mode. Currently identical to
ANDROID_SENSOR_TEST_PATTERN_MODE.
enum:
+ - name: TestPatternModeUnset
+ value: -1
+ description: |
+ No test pattern is set. Returned frames by the camera device are
+ undefined.
- name: TestPatternModeOff
value: 0
description: |
--
2.33.1.1089.g2158813163f-goog
More information about the libcamera-devel
mailing list