Selaa lähdekoodia

Refactor camera control functions to use MPControl, store fd in MPControl

Kristian Vos 4 kuukautta sitten
vanhempi
commit
a2f57c02ac
7 muutettua tiedostoa jossa 121 lisäystä ja 147 poistoa
  1. 24 44
      src/camera.c
  2. 10 13
      src/camera.h
  3. 77 81
      src/io_pipeline.c
  4. 1 1
      src/io_pipeline.h
  5. 2 2
      src/main.c
  6. 4 4
      src/process_pipeline.c
  7. 3 2
      src/state.h

+ 24 - 44
src/camera.c

@@ -27,20 +27,6 @@ xioctl(int fd, int request, void *arg)
         return r;
 }
 
-int
-get_fd_from_type(libmegapixels_camera *camera, int fd_type)
-{
-        switch (fd_type) {
-                case FD_TYPE_SENSOR:
-                        return camera->sensor_fd;
-                case FD_TYPE_LENS:
-                        return camera->lens_fd;
-                default:
-                        fprintf(stderr, "Unknown fd type %d\n", fd_type);
-                        return -1;
-        }
-}
-
 struct video_buffer {
         uint32_t length;
         uint8_t *data;
@@ -686,14 +672,12 @@ mp_control_list_free(MPControlList *list)
 }
 
 bool
-mp_camera_query_control(libmegapixels_camera *camera,
+mp_camera_query_control(int fd,
                         uint32_t id,
-                        MPControl *control,
-                        int fd_type)
+                        MPControl *control)
 {
         struct v4l2_query_ext_ctrl ctrl = {};
         ctrl.id = id;
-        int fd = get_fd_from_type(camera, fd_type);
         if (xioctl(fd, VIDIOC_QUERY_EXT_CTRL, &ctrl) == -1) {
                 if (errno != EINVAL) {
                         errno_printerr("VIDIOC_QUERY_EXT_CTRL");
@@ -702,6 +686,7 @@ mp_camera_query_control(libmegapixels_camera *camera,
         }
 
         if (control) {
+                control->fd = fd;
                 control->id = ctrl.id;
                 control->type = ctrl.type;
                 strcpy(control->name, ctrl.name);
@@ -721,14 +706,12 @@ mp_camera_query_control(libmegapixels_camera *camera,
 }
 
 static bool
-control_impl_int32(libmegapixels_camera *camera,
-                   uint32_t id,
+control_impl_int32(MPControl *control,
                    int request,
-                   int32_t *value,
-                   int fd_type)
+                   int32_t *value)
 {
         struct v4l2_ext_control ctrl = {};
-        ctrl.id = id;
+        ctrl.id = control->id;
         ctrl.value = *value;
 
         struct v4l2_ext_controls ctrls = {
@@ -737,8 +720,7 @@ control_impl_int32(libmegapixels_camera *camera,
                 .count = 1,
                 .controls = &ctrl,
         };
-        int fd = get_fd_from_type(camera, fd_type);
-        if (xioctl(fd, request, &ctrls) == -1) {
+        if (xioctl(control->fd, request, &ctrls) == -1) {
                 return false;
         }
 
@@ -747,10 +729,10 @@ control_impl_int32(libmegapixels_camera *camera,
 }
 
 pid_t
-mp_camera_control_set_int32_bg(MPCamera *camera, uint32_t id, int32_t v, int fd_type)
+mp_camera_control_set_int32_bg(MPCamera *camera, MPControl *control, int32_t v)
 {
         struct v4l2_ext_control ctrl = {};
-        ctrl.id = id;
+        ctrl.id = control->id;
         ctrl.value = v;
 
         struct v4l2_ext_controls ctrls = {
@@ -760,8 +742,6 @@ mp_camera_control_set_int32_bg(MPCamera *camera, uint32_t id, int32_t v, int fd_
                 .controls = &ctrl,
         };
 
-        int fd = get_fd_from_type(camera->camera, fd_type);
-
         // fork only after all the memory has been read
         pid_t pid = fork();
         if (pid == -1) {
@@ -773,58 +753,58 @@ mp_camera_control_set_int32_bg(MPCamera *camera, uint32_t id, int32_t v, int fd_
         }
 
         // ignore errors
-        xioctl(fd, VIDIOC_S_EXT_CTRLS, &ctrls);
+        xioctl(control->fd, VIDIOC_S_EXT_CTRLS, &ctrls);
         // exit without calling exit handlers
         _exit(0);
 }
 
 bool
-mp_camera_control_try_int32(libmegapixels_camera *camera, uint32_t id, int32_t *v)
+mp_camera_control_try_int32(MPControl *control, int32_t *v)
 {
-        return control_impl_int32(camera, id, VIDIOC_TRY_EXT_CTRLS, v, FD_TYPE_SENSOR);
+        return control_impl_int32(control, VIDIOC_TRY_EXT_CTRLS, v);
 }
 
 bool
-mp_camera_control_set_int32(libmegapixels_camera *camera, uint32_t id, int32_t v)
+mp_camera_control_set_int32(MPControl *control, int32_t v)
 {
-        return control_impl_int32(camera, id, VIDIOC_S_EXT_CTRLS, &v, FD_TYPE_SENSOR);
+        return control_impl_int32(control, VIDIOC_S_EXT_CTRLS, &v);
 }
 
 int32_t
-mp_camera_control_get_int32(libmegapixels_camera *camera, uint32_t id, int fd_type)
+mp_camera_control_get_int32(MPControl *control)
 {
         int32_t v = 0;
-        control_impl_int32(camera, id, VIDIOC_G_EXT_CTRLS, &v, fd_type);
+        control_impl_int32(control, VIDIOC_G_EXT_CTRLS, &v);
         return v;
 }
 
 bool
-mp_camera_control_try_boolean(libmegapixels_camera *camera, uint32_t id, bool *v)
+mp_camera_control_try_boolean(MPControl *control, bool *v)
 {
         int32_t value = *v;
-        bool s = control_impl_int32(camera, id, VIDIOC_TRY_EXT_CTRLS, &value, FD_TYPE_SENSOR);
+        bool s = control_impl_int32(control, VIDIOC_TRY_EXT_CTRLS, &value);
         *v = value;
         return s;
 }
 
 bool
-mp_camera_control_set_bool(libmegapixels_camera *camera, uint32_t id, bool v)
+mp_camera_control_set_bool(MPControl *control, bool v)
 {
         int32_t value = v;
-        return control_impl_int32(camera, id, VIDIOC_S_EXT_CTRLS, &value, FD_TYPE_SENSOR);
+        return control_impl_int32(control, VIDIOC_S_EXT_CTRLS, &value);
 }
 
 bool
-mp_camera_control_get_bool(libmegapixels_camera *camera, uint32_t id)
+mp_camera_control_get_bool(MPControl *control)
 {
         int32_t v = false;
-        control_impl_int32(camera, id, VIDIOC_G_EXT_CTRLS, &v, FD_TYPE_SENSOR);
+        control_impl_int32(control, VIDIOC_G_EXT_CTRLS, &v);
         return v;
 }
 
 pid_t
-mp_camera_control_set_bool_bg(MPCamera *camera, uint32_t id, bool v)
+mp_camera_control_set_bool_bg(MPCamera *camera, MPControl *control, bool v)
 {
         int32_t value = v;
-        return mp_camera_control_set_int32_bg(camera, id, value, FD_TYPE_SENSOR);
+        return mp_camera_control_set_int32_bg(camera, control, value);
 }

+ 10 - 13
src/camera.h

@@ -8,10 +8,6 @@
 
 #define MAX_VIDEO_BUFFERS 20
 #define MAX_BG_TASKS 8
-
-#define FD_TYPE_SENSOR 0
-#define FD_TYPE_LENS 1
-
 typedef struct {
         uint32_t index;
 
@@ -36,6 +32,7 @@ bool mp_camera_capture_buffer(MPCamera *camera, MPBuffer *buffer);
 bool mp_camera_release_buffer(MPCamera *camera, uint32_t buffer_index);
 
 typedef struct {
+        int fd;
         uint32_t id;
         uint32_t type;
         char name[32];
@@ -63,16 +60,16 @@ MPControl *mp_control_list_get(MPControlList *list);
 MPControlList *mp_control_list_next(MPControlList *list);
 void mp_control_list_free(MPControlList *list);
 
-bool mp_camera_query_control(libmegapixels_camera *camera, uint32_t id, MPControl *control, int fd_type);
+bool mp_camera_query_control(int fd, uint32_t id, MPControl *control);
 
-bool mp_camera_control_try_int32(libmegapixels_camera *camera, uint32_t id, int32_t *v);
-bool mp_camera_control_set_int32(libmegapixels_camera *camera, uint32_t id, int32_t v);
-int32_t mp_camera_control_get_int32(libmegapixels_camera *camera, uint32_t id, int fd_type);
+bool mp_camera_control_try_int32(MPControl *control, int32_t *v);
+bool mp_camera_control_set_int32(MPControl *control, int32_t v);
+int32_t mp_camera_control_get_int32(MPControl *control);
 // set the value in the background, discards result
-pid_t mp_camera_control_set_int32_bg(MPCamera *camera, uint32_t id, int32_t v, int fd_type);
+pid_t mp_camera_control_set_int32_bg(MPCamera *camera, MPControl *control, int32_t v);
 
-bool mp_camera_control_try_bool(libmegapixels_camera *camera, uint32_t id, bool *v);
-bool mp_camera_control_set_bool(libmegapixels_camera *camera, uint32_t id, bool v);
-bool mp_camera_control_get_bool(libmegapixels_camera *camera, uint32_t id);
+bool mp_camera_control_try_bool(MPControl *control, bool *v);
+bool mp_camera_control_set_bool(MPControl *control, bool v);
+bool mp_camera_control_get_bool(MPControl *control);
 // set the value in the background, discards result
-pid_t mp_camera_control_set_bool_bg(MPCamera *camera, uint32_t id, bool v);
+pid_t mp_camera_control_set_bool_bg(MPCamera *camera, MPControl *control, bool v);

+ 77 - 81
src/io_pipeline.c

@@ -25,7 +25,7 @@ static GSource *capture_source;
 static bool pipeline_changed = true;
 
 typedef struct invoke_set_control {
-        uint32_t control;
+        MPControl *control;
         int32_t int_value;
         bool bool_value;
 } invoke_set_control;
@@ -65,23 +65,19 @@ update_process_pipeline()
         }
         pipeline_changed = false;
         // Grab the latest control values
-        if (!state_io.gain.manual && state_io.gain.control) {
-                state_io.gain.value = mp_camera_control_get_int32(
-                        state_io.camera, state_io.gain.control, FD_TYPE_SENSOR);
+        if (!state_io.gain.manual && state_io.gain.control.id) {
+                state_io.gain.value = mp_camera_control_get_int32(&state_io.gain.control);
         }
 
-        if (!state_io.exposure.manual && state_io.exposure.control) {
-                state_io.exposure.value = mp_camera_control_get_int32(
-                        state_io.camera, state_io.exposure.control, FD_TYPE_SENSOR);
+        if (!state_io.exposure.manual && state_io.exposure.control.id) {
+                state_io.exposure.value = mp_camera_control_get_int32(&state_io.exposure.control);
         }
 
         float balance_red = 1.0f;
         float balance_blue = 1.0f;
-        if (state_io.red.control && state_io.blue.control) {
-                int red = mp_camera_control_get_int32(state_io.camera,
-                                                      state_io.red.control, FD_TYPE_SENSOR);
-                int blue = mp_camera_control_get_int32(state_io.camera,
-                                                       state_io.blue.control, FD_TYPE_SENSOR);
+        if (state_io.red.control.id && state_io.blue.control.id) {
+                int red = mp_camera_control_get_int32(&state_io.red.control);
+                int blue = mp_camera_control_get_int32(&state_io.blue.control);
                 balance_red = (float)red / (float)state_io.red.max;
                 balance_blue = (float)blue / (float)state_io.blue.max;
         }
@@ -136,11 +132,11 @@ static void
 set_control_int32(MPPipeline *pipeline, const void *data)
 {
         const invoke_set_control *control_data = (const invoke_set_control *)data;
-        mp_camera_control_set_int32(state_io.camera, control_data->control, control_data->int_value);
+        mp_camera_control_set_int32(control_data->control, control_data->int_value);
 }
 
 void
-mp_io_pipeline_set_control_int32(uint32_t control, uint32_t value)
+mp_io_pipeline_set_control_int32(MPControl *control, uint32_t value)
 {
         invoke_set_control data = { 0 };
         data.control = control;
@@ -156,16 +152,15 @@ capture(MPPipeline *pipeline, const void *data)
         float gain_norm;
 
         // Disable the autogain/exposure while taking the burst
-        mp_camera_control_set_int32(state_io.camera, V4L2_CID_AUTOGAIN, 0);
-        mp_camera_control_set_int32(
-                state_io.camera, V4L2_CID_EXPOSURE_AUTO, V4L2_EXPOSURE_MANUAL);
+        mp_camera_control_set_int32(&state_io.gain.auto_control, 0);
+        mp_camera_control_set_int32(&state_io.exposure.auto_control, V4L2_EXPOSURE_MANUAL);
 
         // Get current gain to calculate a burst length;
         // with low gain there's 3, with the max automatic gain of the ov5640
         // the value seems to be 248 which creates a 5 frame burst
         // for manual gain you can go up to 11 frames
         state_io.gain.value =
-                mp_camera_control_get_int32(state_io.camera, V4L2_CID_GAIN, FD_TYPE_SENSOR);
+                mp_camera_control_get_int32(&state_io.gain.control);
         gain_norm = (float)state_io.gain.value / (float)state_io.gain.max;
         state_io.burst_length = (int)fmax(sqrtf(gain_norm) * 10, 2) + 1;
         state_io.burst_length = MAX(1, state_io.burst_length);
@@ -221,12 +216,16 @@ start_focus()
             !mp_camera_check_task_complete(mpcamera, focus_continuous_task))
                 return;
 
-        if (state_io.focus.control) {
+        if (state_io.focus.control.id) {
                 focus_continuous_task = mp_camera_control_set_bool_bg(
-                        mpcamera, state_io.focus.control, 1);
+                        mpcamera, &state_io.focus.control, 1);
         } else if (state_io.can_af_trigger) {
+                // TODO improve
+                MPControl auto_focus_start_control;
+                auto_focus_start_control.id = V4L2_CID_AUTO_FOCUS_START;
+                auto_focus_start_control.fd = state_io.camera->sensor_fd;
                 start_focus_task = mp_camera_control_set_bool_bg(
-                        mpcamera, V4L2_CID_AUTO_FOCUS_START, 1);
+                        mpcamera, &auto_focus_start_control, 1);
         }
 }
 
@@ -246,26 +245,25 @@ update_controls()
 
         if (state_io.gain.manual != state_io.gain.manual_req) {
                 mp_camera_control_set_bool_bg(mpcamera,
-                                              V4L2_CID_AUTOGAIN,
+                                              &state_io.gain.auto_control,
                                               !state_io.gain.manual_req);
                 state_io.gain.manual = state_io.gain.manual_req;
                 state_changed = true;
         }
 
         if ((state_io.gain.manual ||
-             (!state_io.gain.manual && state_io.gain.auto_control == 0)) &&
+             (!state_io.gain.manual && state_io.gain.auto_control.id == 0)) &&
             state_io.gain.value != state_io.gain.value_req) {
                 mp_camera_control_set_int32_bg(mpcamera,
-                                               state_io.gain.control,
-                                               state_io.gain.value_req,
-                                               FD_TYPE_SENSOR);
+                                               &state_io.gain.control,
+                                               state_io.gain.value_req);
                 state_io.gain.value = state_io.gain.value_req;
                 state_changed = true;
         }
 
         if (state_io.exposure.manual != state_io.exposure.manual_req) {
                 mp_camera_control_set_bool_bg(mpcamera,
-                                              V4L2_CID_EXPOSURE_AUTO,
+                                              &state_io.exposure.auto_control,
                                               state_io.exposure.manual_req ?
                                                       V4L2_EXPOSURE_MANUAL :
                                                       V4L2_EXPOSURE_AUTO);
@@ -276,9 +274,8 @@ update_controls()
         if (state_io.exposure.manual &&
             state_io.exposure.value != state_io.exposure.value_req) {
                 mp_camera_control_set_int32_bg(mpcamera,
-                                               state_io.exposure.control,
-                                               state_io.exposure.value_req,
-                                               FD_TYPE_SENSOR);
+                                               &state_io.exposure.control,
+                                               state_io.exposure.value_req);
                 state_io.exposure.value = state_io.exposure.value_req;
                 state_changed = true;
         }
@@ -293,7 +290,7 @@ static void
 do_aaa()
 {
         bool auto_exposure =
-                !state_io.exposure.manual && state_io.exposure.auto_control == 0;
+                !state_io.exposure.manual && state_io.exposure.auto_control.id == 0;
 
         if (auto_exposure) {
                 int direction = state_io.stats.exposure;
@@ -388,14 +385,13 @@ on_frame(MPBuffer buffer, void *_data)
                         if (!state_io.exposure.manual) {
                                 mp_camera_control_set_int32_bg(
                                         mpcamera,
-                                        V4L2_CID_EXPOSURE_AUTO,
-                                        V4L2_EXPOSURE_AUTO,
-                                        FD_TYPE_SENSOR);
+                                        &state_io.exposure.auto_control,
+                                        V4L2_EXPOSURE_AUTO);
                         }
 
                         if (!state_io.gain.manual) {
                                 mp_camera_control_set_bool_bg(
-                                        mpcamera, V4L2_CID_AUTOGAIN, true);
+                                        mpcamera, &state_io.gain.auto_control, true);
                         }
 
                         // Go back to preview mode
@@ -421,88 +417,88 @@ on_frame(MPBuffer buffer, void *_data)
 static void
 init_controls()
 {
+        MPControl focus_control;
         if (mp_camera_query_control(
-                    state_io.camera, V4L2_CID_FOCUS_ABSOLUTE, NULL, FD_TYPE_SENSOR)) {
-                // TODO: Set focus state
-                state_io.focus.control = V4L2_CID_FOCUS_ABSOLUTE;
+                state_io.camera->sensor_fd, V4L2_CID_FOCUS_ABSOLUTE, &focus_control)) {
+                state_io.focus.control = focus_control;
         } else {
-                state_io.focus.control = 0;
+                state_io.focus.control.id = 0;
         }
 
-        if (mp_camera_query_control(state_io.camera, V4L2_CID_FOCUS_AUTO, NULL, FD_TYPE_SENSOR)) {
+        MPControl auto_focus_control;
+        if (mp_camera_query_control(state_io.camera->sensor_fd, V4L2_CID_FOCUS_AUTO, &auto_focus_control)) {
                 mp_camera_control_set_bool_bg(
-                        mpcamera, V4L2_CID_FOCUS_AUTO, true);
-                state_io.focus.auto_control = V4L2_CID_FOCUS_AUTO;
+                        mpcamera, &auto_focus_control, true);
+                state_io.focus.auto_control = auto_focus_control;
         } else {
-                state_io.focus.auto_control = 0;
+                state_io.focus.auto_control.id = 0;
         }
 
         state_io.can_af_trigger = mp_camera_query_control(
-                state_io.camera, V4L2_CID_AUTO_FOCUS_START, NULL, FD_TYPE_SENSOR);
+                state_io.camera->sensor_fd, V4L2_CID_AUTO_FOCUS_START, NULL);
 
-        MPControl control;
-        if (mp_camera_query_control(state_io.camera, V4L2_CID_GAIN, &control, FD_TYPE_SENSOR)) {
-                state_io.gain.control = V4L2_CID_GAIN;
-                state_io.gain.max = control.max;
+        MPControl gain_control;
+        if (mp_camera_query_control(state_io.camera->sensor_fd, V4L2_CID_GAIN, &gain_control)) {
+                state_io.gain.control = gain_control;
+                state_io.gain.max = gain_control.max;
         } else if (mp_camera_query_control(
-                           state_io.camera, V4L2_CID_ANALOGUE_GAIN, &control, FD_TYPE_SENSOR)) {
-                state_io.gain.control = V4L2_CID_ANALOGUE_GAIN;
-                state_io.gain.max = control.max;
+                           state_io.camera->sensor_fd, V4L2_CID_ANALOGUE_GAIN, &gain_control)) {
+                state_io.gain.control = gain_control;
+                state_io.gain.max = gain_control.max;
         } else {
                 state_io.gain.max = 0;
-                state_io.gain.control = 0;
+                state_io.gain.control.id = 0;
         }
-        if (state_io.gain.control) {
-                state_io.gain.value = mp_camera_control_get_int32(
-                        state_io.camera, state_io.gain.control, FD_TYPE_SENSOR);
+        if (state_io.gain.control.id) {
+                state_io.gain.value = mp_camera_control_get_int32(&state_io.gain.control);
         } else {
                 state_io.gain.value = 0;
         }
 
-        if (mp_camera_query_control(state_io.camera, V4L2_CID_AUTOGAIN, &control, FD_TYPE_SENSOR)) {
-                state_io.gain.auto_control = V4L2_CID_AUTOGAIN;
+        MPControl auto_gain_control;
+        if (mp_camera_query_control(state_io.camera->sensor_fd, V4L2_CID_AUTOGAIN, &auto_gain_control)) {
+                state_io.gain.auto_control = auto_gain_control;
                 state_io.gain.manual =
-                        mp_camera_control_get_bool(state_io.camera,
-                                                   V4L2_CID_AUTOGAIN) == 0;
+                        mp_camera_control_get_bool(&auto_gain_control) == 0;
         } else {
-                state_io.gain.auto_control = 0;
+                state_io.gain.auto_control.id = 0;
         }
 
-        if (mp_camera_query_control(state_io.camera, V4L2_CID_EXPOSURE, &control, FD_TYPE_SENSOR)) {
-                state_io.exposure.control = V4L2_CID_EXPOSURE;
-                state_io.exposure.max = control.max;
-                state_io.exposure.value = mp_camera_control_get_int32(
-                        state_io.camera, V4L2_CID_EXPOSURE, FD_TYPE_SENSOR);
-
+        MPControl exposure_control;
+        if (mp_camera_query_control(state_io.camera->sensor_fd, V4L2_CID_EXPOSURE, &exposure_control)) {
+                state_io.exposure.control = exposure_control;
+                state_io.exposure.max = exposure_control.max;
+                state_io.exposure.value = mp_camera_control_get_int32(&exposure_control);
         } else {
-                state_io.exposure.control = 0;
+                state_io.exposure.control.id = 0;
         }
 
+        MPControl auto_exposure_control;
         if (mp_camera_query_control(
-                    state_io.camera, V4L2_CID_EXPOSURE_AUTO, &control, FD_TYPE_SENSOR)) {
-                state_io.exposure.auto_control = V4L2_CID_EXPOSURE_AUTO;
+                    state_io.camera->sensor_fd, V4L2_CID_EXPOSURE_AUTO, &auto_exposure_control)) {
+                state_io.exposure.auto_control = auto_exposure_control;
                 state_io.exposure.manual =
-                        mp_camera_control_get_int32(state_io.camera,
-                                                    V4L2_CID_EXPOSURE_AUTO, FD_TYPE_SENSOR) ==
-                        V4L2_EXPOSURE_MANUAL;
+                        mp_camera_control_get_int32(&auto_exposure_control) == V4L2_EXPOSURE_MANUAL;
         } else {
-                state_io.exposure.auto_control = 0;
+                state_io.exposure.auto_control.id = 0;
         }
 
+        MPControl red_control;
         if (mp_camera_query_control(
-                    state_io.camera, V4L2_CID_RED_BALANCE, &control, FD_TYPE_SENSOR)) {
-                state_io.red.control = V4L2_CID_RED_BALANCE;
-                state_io.red.max = control.max;
+                    state_io.camera->sensor_fd, V4L2_CID_RED_BALANCE, &red_control)) {
+                state_io.red.control = red_control;
+                state_io.red.max = red_control.max;
         } else {
-                state_io.red.control = 0;
+                state_io.red.control.id = 0;
         }
 
+        MPControl blue_control;
         if (mp_camera_query_control(
-                    state_io.camera, V4L2_CID_BLUE_BALANCE, &control, FD_TYPE_SENSOR)) {
-                state_io.blue.control = V4L2_CID_BLUE_BALANCE;
-                state_io.blue.max = control.max;
+                    state_io.camera->sensor_fd, V4L2_CID_BLUE_BALANCE, &blue_control)) {
+                state_io.blue.control = blue_control;
+                state_io.blue.max = blue_control.max;
         } else {
-                state_io.blue.control = 0;
+                state_io.blue.control.id = 0;
         }
 
         pipeline_changed = true;

+ 1 - 1
src/io_pipeline.h

@@ -10,7 +10,7 @@ void mp_io_pipeline_stop();
 
 void mp_io_pipeline_focus();
 void mp_io_pipeline_capture();
-void mp_io_pipeline_set_control_int32(uint32_t control, uint32_t value);
+void mp_io_pipeline_set_control_int32(MPControl *control, uint32_t value);
 
 void mp_io_pipeline_release_buffer(uint32_t buffer_index);
 

+ 2 - 2
src/main.c

@@ -199,10 +199,10 @@ update_state(const mp_state_main *new_state)
         state.stats.focus = new_state->stats.focus;
 
         // 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);
         // 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);
-        gtk_widget_set_visible(iso_button, state.gain.control != 0);
-        gtk_widget_set_visible(shutter_button, state.exposure.control != 0);
 
         return false;
 }

+ 4 - 4
src/process_pipeline.c

@@ -377,9 +377,9 @@ static void
 process_aaa()
 {
         bool auto_exposure =
-                !state_proc.exposure.manual && state_proc.exposure.auto_control == 0;
+                !state_proc.exposure.manual && state_proc.exposure.auto_control.id == 0;
         bool auto_focus =
-                !state_proc.focus.manual && state_proc.focus.auto_control == 0;
+                !state_proc.focus.manual && state_proc.focus.auto_control.id == 0;
         bool auto_balance = TRUE;
         if (!auto_exposure && !auto_focus && !auto_balance) {
                 return;
@@ -444,9 +444,9 @@ process_aaa()
 
                 clamp_control(&state_proc.gain);
                 clamp_control(&state_proc.exposure);
-                mp_io_pipeline_set_control_int32(state_proc.gain.control,
+                mp_io_pipeline_set_control_int32(&state_proc.gain.control,
                                                  state_proc.gain.value_req);
-                mp_io_pipeline_set_control_int32(state_proc.exposure.control,
+                mp_io_pipeline_set_control_int32(&state_proc.exposure.control,
                                                  state_proc.exposure.value_req);
                 state_proc.gain.value = state_proc.gain.value_req;
                 state_proc.exposure.value = state_proc.exposure.value_req;

+ 3 - 2
src/state.h

@@ -1,16 +1,17 @@
 #pragma once
+#include "camera.h"
 #include "dcp.h"
 #include <libmegapixels.h>
 #include <stdbool.h>
 
 typedef struct cstate {
-        uint32_t control;
+        MPControl control;
         int32_t value;
         int32_t value_req;
         int32_t max;
         bool manual;
         bool manual_req;
-        uint32_t auto_control;
+        MPControl auto_control;
 } controlstate;
 
 typedef struct state_main {