run most camera control setting in background

makes trigger focus, continuous focus, autogain, gain ctrl, auto
exposure, exposure ctrl run in background to not block the UI thread.

The camera updates the image while this is in progress, so you can for
example see the camera live focus as on common other phones.
This commit is contained in:
WebFreak001 2021-07-01 00:06:19 +00:00 committed by Martijn Braam
parent 5ad97d03f6
commit 1282a75db9
No known key found for this signature in database
GPG Key ID: C4280ACB000B060F
3 changed files with 45 additions and 9 deletions

View File

@ -1178,6 +1178,31 @@ control_impl_int32(MPCamera *camera, uint32_t id, int request, int32_t *value)
return true;
}
void
mp_camera_control_set_int32_bg(MPCamera *camera, uint32_t id, int32_t v)
{
struct v4l2_ext_control ctrl = {};
ctrl.id = id;
ctrl.value = v;
struct v4l2_ext_controls ctrls = {
.ctrl_class = 0,
.which = V4L2_CTRL_WHICH_CUR_VAL,
.count = 1,
.controls = &ctrl,
};
int fd = control_fd(camera);
// fork only after all the memory has been read
if (fork() != 0)
return; // discard errors, nothing to do in parent process
// ignore errors
xioctl(fd, VIDIOC_S_EXT_CTRLS, &ctrls);
// exit without calling exit handlers
_exit(0);
}
bool
mp_camera_control_try_int32(MPCamera *camera, uint32_t id, int32_t *v)
{
@ -1221,3 +1246,10 @@ mp_camera_control_get_bool(MPCamera *camera, uint32_t id)
control_impl_int32(camera, id, VIDIOC_G_EXT_CTRLS, &v);
return v;
}
void
mp_camera_control_set_bool_bg(MPCamera *camera, uint32_t id, bool v)
{
int32_t value = v;
return mp_camera_control_set_int32_bg(camera, id, value);
}

View File

@ -111,7 +111,11 @@ bool mp_camera_query_control(MPCamera *camera, uint32_t id, MPControl *control);
bool mp_camera_control_try_int32(MPCamera *camera, uint32_t id, int32_t *v);
bool mp_camera_control_set_int32(MPCamera *camera, uint32_t id, int32_t v);
int32_t mp_camera_control_get_int32(MPCamera *camera, uint32_t id);
// set the value in the background, discards result
void mp_camera_control_set_int32_bg(MPCamera *camera, uint32_t id, int32_t v);
bool mp_camera_control_try_bool(MPCamera *camera, uint32_t id, bool *v);
bool mp_camera_control_set_bool(MPCamera *camera, uint32_t id, bool v);
bool mp_camera_control_get_bool(MPCamera *camera, uint32_t id);
// set the value in the background, discards result
void mp_camera_control_set_bool_bg(MPCamera *camera, uint32_t id, bool v);

View File

@ -199,7 +199,7 @@ setup_camera(MPDeviceList **device_list, const struct mp_camera_config *config)
if (mp_camera_query_control(info->camera, V4L2_CID_FOCUS_AUTO,
NULL)) {
info->has_auto_focus_continuous = true;
mp_camera_control_set_bool(info->camera, V4L2_CID_FOCUS_AUTO,
mp_camera_control_set_bool_bg(info->camera, V4L2_CID_FOCUS_AUTO,
true);
}
if (mp_camera_query_control(info->camera, V4L2_CID_AUTO_FOCUS_START,
@ -362,10 +362,10 @@ update_controls()
if (want_focus) {
if (info->has_auto_focus_continuous) {
mp_camera_control_set_bool(info->camera, V4L2_CID_FOCUS_AUTO,
mp_camera_control_set_bool_bg(info->camera, V4L2_CID_FOCUS_AUTO,
1);
} else if (info->has_auto_focus_start) {
mp_camera_control_set_bool(info->camera,
mp_camera_control_set_bool_bg(info->camera,
V4L2_CID_AUTO_FOCUS_START, 1);
}
@ -373,19 +373,19 @@ update_controls()
}
if (current_controls.gain_is_manual != desired_controls.gain_is_manual) {
mp_camera_control_set_bool(info->camera, V4L2_CID_AUTOGAIN,
mp_camera_control_set_bool_bg(info->camera, V4L2_CID_AUTOGAIN,
!desired_controls.gain_is_manual);
}
if (desired_controls.gain_is_manual &&
current_controls.gain != desired_controls.gain) {
mp_camera_control_set_int32(info->camera, info->gain_ctrl,
mp_camera_control_set_int32_bg(info->camera, info->gain_ctrl,
desired_controls.gain);
}
if (current_controls.exposure_is_manual !=
desired_controls.exposure_is_manual) {
mp_camera_control_set_int32(info->camera, V4L2_CID_EXPOSURE_AUTO,
mp_camera_control_set_int32_bg(info->camera, V4L2_CID_EXPOSURE_AUTO,
desired_controls.exposure_is_manual ?
V4L2_EXPOSURE_MANUAL :
V4L2_EXPOSURE_AUTO);
@ -393,7 +393,7 @@ update_controls()
if (desired_controls.exposure_is_manual &&
current_controls.exposure != desired_controls.exposure) {
mp_camera_control_set_int32(info->camera, V4L2_CID_EXPOSURE,
mp_camera_control_set_int32_bg(info->camera, V4L2_CID_EXPOSURE,
desired_controls.exposure);
}
@ -444,13 +444,13 @@ on_frame(MPBuffer buffer, void * _data)
// Restore the auto exposure and gain if needed
if (!current_controls.exposure_is_manual) {
mp_camera_control_set_int32(info->camera,
mp_camera_control_set_int32_bg(info->camera,
V4L2_CID_EXPOSURE_AUTO,
V4L2_EXPOSURE_AUTO);
}
if (!current_controls.gain_is_manual) {
mp_camera_control_set_bool(info->camera,
mp_camera_control_set_bool_bg(info->camera,
V4L2_CID_AUTOGAIN, true);
}