@@ -253,9 +253,22 @@ int PipelineHandlerUVC::processControls(UVCCameraData *data, Request *request)
controls.set(V4L2_CID_SATURATION, value);
} else if (id == controls::ExposureTime) {
controls.set(V4L2_CID_EXPOSURE_AUTO, static_cast<int32_t>(1));
- controls.set(V4L2_CID_EXPOSURE_ABSOLUTE, value);
+ /*
+ * controls::ExposureTime is in units of 1 us, and UVC
+ * expects V4L2_CID_EXPOSURE_ABSOLUTE in units of 100 us.
+ */
+ controls.set(V4L2_CID_EXPOSURE_ABSOLUTE,
+ value.get<int32_t>() / 100);
} else if (id == controls::AnalogueGain) {
- controls.set(V4L2_CID_GAIN, value);
+ /*
+ * controls::AnalogueGain is specified as an absolute
+ * multiplier for all RGB samples. Map this multiplier
+ * in a linear way such that 1.0 -> default gain
+ * of the V4L2_CID_GAIN control on the uvcvideo device.
+ */
+ const ControlInfo &gainInfo = controls.infoMap()->at(V4L2_CID_GAIN);
+ int32_t gain = lroundf(value.get<float>() * gainInfo.def().get<int32_t>());
+ controls.set(V4L2_CID_GAIN, gain);
}
}
@@ -350,7 +363,7 @@ int UVCCameraData::init(MediaEntity *entity)
ControlInfoMap::Map ctrls;
for (const auto &ctrl : controls) {
- const ControlInfo &info = ctrl.second;
+ ControlInfo info = ctrl.second;
const ControlId *id;
switch (ctrl.first->id()) {
@@ -368,6 +381,15 @@ int UVCCameraData::init(MediaEntity *entity)
break;
case V4L2_CID_GAIN:
id = &controls::AnalogueGain;
+ /*
+ * AnalogueGain is a float control, convert the type of
+ * the range.
+ */
+ info = ControlInfo{
+ { static_cast<float>(info.min().get<int32_t>()) },
+ { static_cast<float>(info.max().get<int32_t>()) },
+ { static_cast<float>(info.def().get<int32_t>()) }
+ };
break;
default:
continue;