~martijnbraam/megapixels

1282a75db97ff71051053d47cffb80321978d083 — WebFreak001 1 year, 1 month ago 5ad97d0
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.
3 files changed, 45 insertions(+), 9 deletions(-)

M src/camera.c
M src/camera.h
M src/io_pipeline.c
M src/camera.c => src/camera.c +32 -0
@@ 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);
}

M src/camera.h => src/camera.h +4 -0
@@ 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);

M src/io_pipeline.c => src/io_pipeline.c +9 -9
@@ 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);
			}