From 1282a75db97ff71051053d47cffb80321978d083 Mon Sep 17 00:00:00 2001 From: WebFreak001 Date: Thu, 1 Jul 2021 00:06:19 +0000 Subject: [PATCH] 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. --- src/camera.c | 32 ++++++++++++++++++++++++++++++++ src/camera.h | 4 ++++ src/io_pipeline.c | 18 +++++++++--------- 3 files changed, 45 insertions(+), 9 deletions(-) diff --git a/src/camera.c b/src/camera.c index 6bc3e36..918e4f4 100644 --- a/src/camera.c +++ b/src/camera.c @@ -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); +} diff --git a/src/camera.h b/src/camera.h index 323ac63..6177226 100644 --- a/src/camera.h +++ b/src/camera.h @@ -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); diff --git a/src/io_pipeline.c b/src/io_pipeline.c index f9bb1dc..e28b886 100644 --- a/src/io_pipeline.c +++ b/src/io_pipeline.c @@ -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); }