libcamera: pipeline: uvcvideo: Fix ExposureTimeMode control setting

The mapping in `UVCCameraData::processControl()` is not entirely correct
because the control value is retrieved as a `bool` instead of `int32_t`.
Additionally, the available modes are not taken into account.

Retrieve the control value with the right type, `int32_t`, check if the
requested mode is available, and if so, set the appropriate V4L2 control
value selected by `addControl()` earlier.

Fixes: bad8d591f8 ("libcamera: uvcvideo: Register ExposureTimeMode control")
Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
This commit is contained in:
Barnabás Pőcze 2025-02-14 18:08:03 +01:00
parent 799982b646
commit 8b2533d0ac

View file

@ -98,8 +98,8 @@ public:
bool match(DeviceEnumerator *enumerator) override; bool match(DeviceEnumerator *enumerator) override;
private: private:
int processControl(ControlList *controls, unsigned int id, int processControl(const UVCCameraData *data, ControlList *controls,
const ControlValue &value); unsigned int id, const ControlValue &value);
int processControls(UVCCameraData *data, Request *request); int processControls(UVCCameraData *data, Request *request);
bool acquireDevice(Camera *camera) override; bool acquireDevice(Camera *camera) override;
@ -312,8 +312,8 @@ void PipelineHandlerUVC::stopDevice(Camera *camera)
data->video_->releaseBuffers(); data->video_->releaseBuffers();
} }
int PipelineHandlerUVC::processControl(ControlList *controls, unsigned int id, int PipelineHandlerUVC::processControl(const UVCCameraData *data, ControlList *controls,
const ControlValue &value) unsigned int id, const ControlValue &value)
{ {
uint32_t cid; uint32_t cid;
@ -357,10 +357,21 @@ int PipelineHandlerUVC::processControl(ControlList *controls, unsigned int id,
} }
case V4L2_CID_EXPOSURE_AUTO: { case V4L2_CID_EXPOSURE_AUTO: {
int32_t ivalue = value.get<bool>() std::optional<v4l2_exposure_auto_type> mode;
? V4L2_EXPOSURE_APERTURE_PRIORITY
: V4L2_EXPOSURE_MANUAL; switch (value.get<int32_t>()) {
controls->set(V4L2_CID_EXPOSURE_AUTO, ivalue); case controls::ExposureTimeModeAuto:
mode = data->autoExposureMode_;
break;
case controls::ExposureTimeModeManual:
mode = data->manualExposureMode_;
break;
}
if (!mode)
return -EINVAL;
controls->set(V4L2_CID_EXPOSURE_AUTO, static_cast<int32_t>(*mode));
break; break;
} }
@ -398,7 +409,7 @@ int PipelineHandlerUVC::processControls(UVCCameraData *data, Request *request)
ControlList controls(data->video_->controls()); ControlList controls(data->video_->controls());
for (const auto &[id, value] : request->controls()) for (const auto &[id, value] : request->controls())
processControl(&controls, id, value); processControl(data, &controls, id, value);
for (const auto &ctrl : controls) for (const auto &ctrl : controls)
LOG(UVC, Debug) LOG(UVC, Debug)