Browse Source

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.
WebFreak001 3 years ago
parent
commit
1282a75db9
3 changed files with 45 additions and 9 deletions
  1. 32 0
      src/camera.c
  2. 4 0
      src/camera.h
  3. 9 9
      src/io_pipeline.c

+ 32 - 0
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);
+}

+ 4 - 0
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);

+ 9 - 9
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);
 			}