[libcamera-devel] [RFC PATCH 2/5] libcamera: V4L2Subdevice: Add getter/setter function for test pattern mode
Hirokazu Honda
hiroh at chromium.org
Fri Apr 9 06:32:05 CEST 2021
The supported test pattern modes can be obtained by calling
VIDIOC_QUERYMENU to a camera sensor device. This implements the
getter and setter functions for the test pattern mode in
V4L2SubDevice.
Signed-off-by: Hirokazu Honda <hiroh at chromium.org>
---
include/libcamera/internal/v4l2_subdevice.h | 5 +
src/libcamera/v4l2_subdevice.cpp | 104 ++++++++++++++++++++
2 files changed, 109 insertions(+)
diff --git a/include/libcamera/internal/v4l2_subdevice.h b/include/libcamera/internal/v4l2_subdevice.h
index d2b9ca55..f2f5d3f6 100644
--- a/include/libcamera/internal/v4l2_subdevice.h
+++ b/include/libcamera/internal/v4l2_subdevice.h
@@ -60,6 +60,9 @@ public:
int setFormat(unsigned int pad, V4L2SubdeviceFormat *format,
Whence whence = ActiveFormat);
+ std::vector<int32_t> getAvailableTestPatternModes();
+ int setTestPatternMode(int32_t testPatternMode);
+
static std::unique_ptr<V4L2Subdevice>
fromEntityName(const MediaDevice *media, const std::string &entity);
@@ -74,6 +77,8 @@ private:
unsigned int code);
const MediaEntity *entity_;
+
+ std::map<int32_t, uint32_t> testPatternModeMap_;
};
} /* namespace libcamera */
diff --git a/src/libcamera/v4l2_subdevice.cpp b/src/libcamera/v4l2_subdevice.cpp
index 721ff5a9..130e9c4d 100644
--- a/src/libcamera/v4l2_subdevice.cpp
+++ b/src/libcamera/v4l2_subdevice.cpp
@@ -24,6 +24,7 @@
#include "libcamera/internal/media_object.h"
#include "libcamera/internal/utils.h"
+#include "android/metadata/system/camera_metadata_tags.h"
/**
* \file v4l2_subdevice.h
* \brief V4L2 Subdevice API
@@ -523,4 +524,107 @@ std::vector<SizeRange> V4L2Subdevice::enumPadSizes(unsigned int pad,
return sizes;
}
+/**
+ * \var V4L2Subdevice::testPatternModeMap_
+ * \brief The map from controls::SensorTestPatternMode to an index value to be
+ * used for V4L2_CID_TEST_PATTERN.
+ *
+ * The map is constructed in getAvailableTestPatternModes() and referred in
+ * setTestPatternMode() to find a value associated with the requested test
+ * pattern mode.
+ */
+/**
+ * \fn V4L2Subdevice::getAvailableTestPatternModes()
+ * \brief Retrieve the available test pattern modes.
+ *
+ * \return The available control::SensorTestPatternMode values.
+ */
+std::vector<int32_t> V4L2Subdevice::getAvailableTestPatternModes()
+{
+ std::vector<int32_t> patternModes;
+ if (!testPatternModeMap_.empty()) {
+ for (const auto &mode : testPatternModeMap_)
+ patternModes.push_back(mode.first);
+ return patternModes;
+ }
+
+ v4l2_queryctrl ctrl;
+ memset(&ctrl, 0, sizeof(ctrl));
+ ctrl.id = V4L2_CID_TEST_PATTERN;
+ int ret = ioctl(VIDIOC_QUERYCTRL, &ctrl);
+ if (ret < 0) {
+ LOG(V4L2, Error) << "Unable to get test pattern mode :"
+ << strerror(-ret);
+ return {};
+ }
+
+ v4l2_querymenu menu;
+ memset(&menu, 0, sizeof(menu));
+ menu.id = ctrl.id;
+ for (menu.index = ctrl.minimum;
+ static_cast<int>(menu.index) <= ctrl.maximum; menu.index++) {
+ if (ioctl(VIDIOC_QUERYMENU, &menu) != 0) {
+ continue;
+ }
+
+ const std::string modeName(reinterpret_cast<char *>(menu.name));
+ std::optional<int32_t> androidTestPatternMode;
+ /*
+ * ov13858 and ov5670.
+ * No corresponding value for "Vertical Color Bar Type 3" and
+ * "Vertical Color Bar Type 4".
+ */
+ if (modeName == "Disabled") {
+ androidTestPatternMode =
+ ANDROID_SENSOR_TEST_PATTERN_MODE_OFF;
+ } else if (modeName == "Vertical Color Bar Type 1") {
+ androidTestPatternMode =
+ ANDROID_SENSOR_TEST_PATTERN_MODE_COLOR_BARS;
+ } else if (modeName == "Vertical Color Bar Type 2") {
+ androidTestPatternMode =
+ ANDROID_SENSOR_TEST_PATTERN_MODE_COLOR_BARS_FADE_TO_GRAY;
+ }
+
+ if (androidTestPatternMode) {
+ testPatternModeMap_[*androidTestPatternMode] = menu.index;
+ patternModes.push_back(*androidTestPatternMode);
+ } else {
+ LOG(V4L2, Debug) << "Skip test pattern mode: "
+ << modeName;
+ }
+ }
+
+ return patternModes;
+}
+
+/**
+ * \fn V4L2Subdevice::getAvailableTestPatternModes()
+ * \brief Set the test pattern mode.
+ *
+ * \return 0 on success or a negative error code otherwise.
+ */
+int V4L2Subdevice::setTestPatternMode(int32_t testPatternMode)
+{
+ auto it = testPatternModeMap_.find(testPatternMode);
+ if (it != testPatternModeMap_.end()) {
+ LOG(V4L2, Error) << "Unsupported test pattern mode: "
+ << testPatternMode;
+
+ return -EINVAL;
+ }
+
+ v4l2_control ctrl;
+ memset(&ctrl, 0, sizeof(ctrl));
+ ctrl.id = V4L2_CID_TEST_PATTERN;
+ ctrl.value = it->second;
+ int ret = ioctl(VIDIOC_S_CTRL, &ctrl);
+ if (ret < 0) {
+ LOG(V4L2, Error) << "Unable to set test pattern mode: "
+ << strerror(-ret);
+
+ return -EINVAL;
+ }
+
+ return 0;
+}
} /* namespace libcamera */
--
2.31.1.295.g9ea45b61b8-goog
More information about the libcamera-devel
mailing list