summaryrefslogtreecommitdiff
path: root/src/libcamera/pipeline/uvcvideo
diff options
context:
space:
mode:
authorNaushir Patuck <naush@raspberrypi.com>2020-04-24 11:46:58 +0100
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2020-04-27 20:18:12 +0300
commiteff4b1aa01c1a9fa96df5a25d2ae7c540f5d5e84 (patch)
tree876a1efe624f252dbaa1a1224438df7882f32f53 /src/libcamera/pipeline/uvcvideo
parentfa77a02c0a099ad02ed55935bdbe8cd441a8d893 (diff)
libcamera: controls: Reorder and update description of existing controls
Group AE, AWB, etc. controls together for accessibility. Update descriptions for Contrast, Brightness, and Saturation controls. Update the uvcvideo and vimc pipeline handlers to use the new brightness, contrast and saturation units. UVC has no explicit units for those controls, so map them with a best effort heuristic. For VIMC, hardcode the control range based on knowledge of the driver implementation for simplicity. Signed-off-by: Naushir Patuck <naush@raspberrypi.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Diffstat (limited to 'src/libcamera/pipeline/uvcvideo')
-rw-r--r--src/libcamera/pipeline/uvcvideo/uvcvideo.cpp67
1 files changed, 57 insertions, 10 deletions
diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
index 08462542..030ac686 100644
--- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
+++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
@@ -263,12 +263,29 @@ int PipelineHandlerUVC::processControl(ControlList *controls, unsigned int id,
return -EINVAL;
const ControlInfo &v4l2Info = controls->infoMap()->at(cid);
+ int32_t min = v4l2Info.min().get<int32_t>();
+ int32_t def = v4l2Info.def().get<int32_t>();
+ int32_t max = v4l2Info.max().get<int32_t>();
/*
* See UVCCameraData::addControl() for explanations of the different
* value mappings.
*/
switch (cid) {
+ case V4L2_CID_BRIGHTNESS: {
+ float scale = std::max(max - def, def - min);
+ float fvalue = value.get<float>() * scale + def;
+ controls->set(cid, static_cast<int32_t>(lroundf(fvalue)));
+ break;
+ }
+
+ case V4L2_CID_SATURATION: {
+ float scale = def - min;
+ float fvalue = value.get<float>() * scale + min;
+ controls->set(cid, static_cast<int32_t>(lroundf(fvalue)));
+ break;
+ }
+
case V4L2_CID_EXPOSURE_AUTO: {
int32_t ivalue = value.get<bool>()
? V4L2_EXPOSURE_APERTURE_PRIORITY
@@ -281,11 +298,8 @@ int PipelineHandlerUVC::processControl(ControlList *controls, unsigned int id,
controls->set(cid, value.get<int32_t>() / 100);
break;
+ case V4L2_CID_CONTRAST:
case V4L2_CID_GAIN: {
- int32_t min = v4l2Info.min().get<int32_t>();
- int32_t max = v4l2Info.max().get<int32_t>();
- int32_t def = v4l2Info.def().get<int32_t>();
-
float m = (4.0f - 1.0f) / (max - def);
float p = 1.0f - m * def;
@@ -457,6 +471,38 @@ void UVCCameraData::addControl(uint32_t cid, const ControlInfo &v4l2Info,
int32_t def = v4l2Info.def().get<int32_t>();
switch (cid) {
+ case V4L2_CID_BRIGHTNESS: {
+ /*
+ * The Brightness control is a float, with 0.0 mapped to the
+ * default value. The control range is [-1.0, 1.0], but the V4L2
+ * default may not be in the middle of the V4L2 range.
+ * Accommodate this by restricting the range of the libcamera
+ * control, but always within the maximum limits.
+ */
+ float scale = std::max(max - def, def - min);
+
+ info = ControlInfo{
+ { static_cast<float>(min - def) / scale },
+ { static_cast<float>(max - def) / scale },
+ { 0.0f }
+ };
+ break;
+ }
+
+ case V4L2_CID_SATURATION:
+ /*
+ * The Saturation control is a float, with 0.0 mapped to the
+ * minimum value (corresponding to a fully desaturated image)
+ * and 1.0 mapped to the default value. Calculate the maximum
+ * value accordingly.
+ */
+ info = ControlInfo{
+ { 0.0f },
+ { static_cast<float>(max - min) / (def - min) },
+ { 1.0f }
+ };
+ break;
+
case V4L2_CID_EXPOSURE_AUTO:
info = ControlInfo{ false, true, true };
break;
@@ -473,14 +519,15 @@ void UVCCameraData::addControl(uint32_t cid, const ControlInfo &v4l2Info,
};
break;
+ case V4L2_CID_CONTRAST:
case V4L2_CID_GAIN: {
/*
- * The AnalogueGain control is a float, with 1.0 mapped to the
- * default value. UVC doesn't specify units, and cameras have
- * been seen to expose very different ranges for the gain
- * control. Arbitrarily assume that the minimum and maximum
- * values are respectively no lower than 0.5 and no higher than
- * 4.0.
+ * The Contrast and AnalogueGain controls are floats, with 1.0
+ * mapped to the default value. UVC doesn't specify units, and
+ * cameras have been seen to expose very different ranges for
+ * the controls. Arbitrarily assume that the minimum and
+ * maximum values are respectively no lower than 0.5 and no
+ * higher than 4.0.
*/
float m = (4.0f - 1.0f) / (max - def);
float p = 1.0f - m * def;