From 8f37625309f4d8b0196b473c243aa2bf670bf387 Mon Sep 17 00:00:00 2001 From: Kristian Vos Date: Sun, 4 Aug 2024 10:51:27 +0200 Subject: [PATCH] Allow manually changing the focus using controls --- data/camera.ui | 10 +++++ data/focus-auto-symbolic.svg | 40 ++++++++++++++++++++ data/focus-man-symbolic.svg | 41 ++++++++++++++++++++ data/me.gapixels.Megapixels.gresource.xml | 2 + src/io_pipeline.c | 38 ++++++++++++++++++- src/main.c | 46 ++++++++++++++++++++++- 6 files changed, 175 insertions(+), 2 deletions(-) create mode 100644 data/focus-auto-symbolic.svg create mode 100644 data/focus-man-symbolic.svg diff --git a/data/camera.ui b/data/camera.ui index d529fba..96aa53a 100644 --- a/data/camera.ui +++ b/data/camera.ui @@ -67,6 +67,16 @@ + + + start + focus-auto-symbolic + + + start diff --git a/data/focus-auto-symbolic.svg b/data/focus-auto-symbolic.svg new file mode 100644 index 0000000..bb3faac --- /dev/null +++ b/data/focus-auto-symbolic.svg @@ -0,0 +1,40 @@ + + + + + + diff --git a/data/focus-man-symbolic.svg b/data/focus-man-symbolic.svg new file mode 100644 index 0000000..f9cfc8c --- /dev/null +++ b/data/focus-man-symbolic.svg @@ -0,0 +1,41 @@ + + + + + + diff --git a/data/me.gapixels.Megapixels.gresource.xml b/data/me.gapixels.Megapixels.gresource.xml index f244c2c..967657e 100644 --- a/data/me.gapixels.Megapixels.gresource.xml +++ b/data/me.gapixels.Megapixels.gresource.xml @@ -28,5 +28,7 @@ iso-auto-symbolic.svg shutter-man-symbolic.svg shutter-auto-symbolic.svg + focus-man-symbolic.svg + focus-auto-symbolic.svg diff --git a/src/io_pipeline.c b/src/io_pipeline.c index 6f9bcae..0582029 100644 --- a/src/io_pipeline.c +++ b/src/io_pipeline.c @@ -75,6 +75,11 @@ update_process_pipeline() mp_camera_control_get_int32(&state_io.exposure.control); } + if (!state_io.focus.manual && state_io.focus.control.id) { + state_io.focus.value = + mp_camera_control_get_int32(&state_io.focus.control); + } + float balance_red = 1.0f; float balance_blue = 1.0f; if (state_io.red.control.id && state_io.blue.control.id) { @@ -245,6 +250,28 @@ update_controls() start_focus(); } + // Change focus manual/auto if it got changed by the user + if (state_io.focus.manual != state_io.focus.manual_req) { + state_io.focus.manual = state_io.focus.manual_req; + if (state_io.focus.auto_control.id > 0) { + mp_camera_control_set_bool_bg(mpcamera, + &state_io.focus.auto_control, + !state_io.gain.manual_req); + } + state_changed = true; + } + + // If focus is manual, OR auto but no auto control, and the value got + // updated by the program/user, update the manual control + if ((state_io.focus.manual || + (!state_io.focus.manual && state_io.focus.auto_control.id == 0)) && + state_io.focus.value != state_io.focus.value_req) { + mp_camera_control_set_int32_bg( + mpcamera, &state_io.focus.control, state_io.focus.value_req); + state_io.focus.value = state_io.focus.value_req; + state_changed = true; + } + if (state_io.gain.manual != state_io.gain.manual_req) { mp_camera_control_set_bool_bg(mpcamera, &state_io.gain.auto_control, @@ -420,10 +447,19 @@ static void init_controls() { MPControl focus_control; - if (mp_camera_query_control(state_io.camera->sensor_fd, + // V4L2_CID_FOCUS_ABSOLUTE exists on the sensor for PP, but on the lens for + // PPP. Check both, if applicable. + if ((state_io.camera->lens_fd > 0 && + mp_camera_query_control(state_io.camera->lens_fd, + V4L2_CID_FOCUS_ABSOLUTE, + &focus_control)) || + mp_camera_query_control(state_io.camera->sensor_fd, V4L2_CID_FOCUS_ABSOLUTE, &focus_control)) { state_io.focus.control = focus_control; + state_io.focus.max = focus_control.max; + state_io.focus.value = + mp_camera_control_get_int32(&state_io.focus.control); } else { state_io.focus.control.id = 0; } diff --git a/src/main.c b/src/main.c index 4a1fb18..aa1a8ff 100644 --- a/src/main.c +++ b/src/main.c @@ -68,9 +68,10 @@ GtkWidget *preview_bottom_box; GtkWidget *message_box; GtkWidget *message_label; -GtkWidget *flash_button; GtkWidget *iso_button; GtkWidget *shutter_button; +GtkWidget *focus_button; +GtkWidget *flash_button; LfbEvent *capture_event; static GtkWidget *movie; @@ -172,6 +173,13 @@ update_state(const mp_state_main *new_state) gtk_button_set_icon_name(GTK_BUTTON(iso_button), icon_name); } + if (state.focus.manual != new_state->focus.manual) { + const char *icon_name = new_state->focus.manual ? + "focus-man-symbolic" : + "focus-auto-symbolic"; + gtk_button_set_icon_name(GTK_BUTTON(focus_button), icon_name); + } + state.gain.control = new_state->gain.control; state.gain.auto_control = new_state->gain.auto_control; state.gain.value = new_state->gain.value; @@ -204,6 +212,7 @@ update_state(const mp_state_main *new_state) // Make the right settings available for the camera gtk_widget_set_visible(iso_button, state.gain.control.id != 0); gtk_widget_set_visible(shutter_button, state.exposure.control.id != 0); + gtk_widget_set_visible(focus_button, state.focus.control.id != 0); // Even if there's no flash led/v4l, it'll just default to using the screen // as flash, so always enable this button gtk_widget_set_visible(flash_button, true); @@ -915,6 +924,24 @@ set_shutter_auto(bool is_auto) } } +static void +set_focus(double value) +{ + if (state.focus.value != (int)value) { + state.focus.value_req = (int)value; + update_io_pipeline(); + } +} + +static void +set_focus_auto(bool is_auto) +{ + if (state.focus.manual != !is_auto) { + state.focus.manual_req = !is_auto; + update_io_pipeline(); + } +} + static void open_shutter_controls(GtkWidget *button, gpointer user_data) { @@ -930,6 +957,19 @@ open_shutter_controls(GtkWidget *button, gpointer user_data) set_shutter_auto); } +static void +open_focus_controls(GtkWidget *button, gpointer user_data) +{ + open_controls(button, + "Focus", + 0, + state.focus.max, + state.focus.value, + !state.focus.manual, + set_focus, + set_focus_auto); +} + static void flash_button_clicked(GtkWidget *button, gpointer user_data) { @@ -1254,6 +1294,8 @@ activate(GtkApplication *app, gpointer data) GTK_WIDGET(gtk_builder_get_object(builder, "iso-controls-button")); shutter_button = GTK_WIDGET( gtk_builder_get_object(builder, "shutter-controls-button")); + focus_button = + GTK_WIDGET(gtk_builder_get_object(builder, "focus-controls-button")); flash_button = GTK_WIDGET(gtk_builder_get_object(builder, "flash-controls-button")); GtkWidget *setting_dng_button = @@ -1290,6 +1332,8 @@ activate(GtkApplication *app, gpointer data) g_signal_connect(iso_button, "clicked", G_CALLBACK(open_iso_controls), NULL); g_signal_connect( shutter_button, "clicked", G_CALLBACK(open_shutter_controls), NULL); + g_signal_connect( + focus_button, "clicked", G_CALLBACK(open_focus_controls), NULL); g_signal_connect( flash_button, "clicked", G_CALLBACK(flash_button_clicked), NULL);