[libcamera-devel] [RFC PATCH 2/5] libcamera: V4L2Subdevice: Add getter/setter function for test pattern mode
Jacopo Mondi
jacopo at jmondi.org
Fri Apr 9 10:55:37 CEST 2021
Hi Hiro,
On Fri, Apr 09, 2021 at 01:32:05PM +0900, Hirokazu Honda wrote:
> 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"
I'm afraid this is not correct. We don't want any android specific
definition in libcamera core. libcamera run on non-android systems,
and we don't want generic application to depend on anything Andoroid.
> /**
> * \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);
I'm not sure if you have considered the following and found any
blocker, but:
- Controls are enumerated in V4L2Device::listControls() with
VIDIOC_QUERY_EXT_CTRL
- Menu controls are accepted but not really handled there yet. I think
you should modify listControls() to handle menu controls properly
and store them as ControlInfo. ControlInfo currently support being
constructed with a Span<> of values but as far as I can tell
V4l2ControlInfo does not.
- Once you have valid ControlInfo for the menu control, it should
contain the V4L2 identifers for the menu entries
- The pipeline handler should then populate the libcamera controls in
Camera::controls_ by inspecting the V4L2 controls returned by the
v4l2 subdevice as we do today in IPU3::listControls(). You should
use the libcamera controls identifiers that you have defined in
patch #1, not the android defined values
- The camera HAL inspects the Camera::controls() to translate from
libcamera defined controls to Android defined metadata
Does this make sense to you ?
Thanks
j
> + 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
>
> _______________________________________________
> libcamera-devel mailing list
> libcamera-devel at lists.libcamera.org
> https://lists.libcamera.org/listinfo/libcamera-devel
More information about the libcamera-devel
mailing list