diff --git a/src/camera.c b/src/camera.c index d390ca7..e621c34 100644 --- a/src/camera.c +++ b/src/camera.c @@ -27,6 +27,20 @@ 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; @@ -674,11 +688,13 @@ mp_control_list_free(MPControlList *list) bool mp_camera_query_control(libmegapixels_camera *camera, uint32_t id, - MPControl *control) + MPControl *control, + int fd_type) { struct v4l2_query_ext_ctrl ctrl = {}; ctrl.id = id; - if (xioctl(camera->sensor_fd, VIDIOC_QUERY_EXT_CTRL, &ctrl) == -1) { + 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"); } @@ -708,7 +724,8 @@ static bool control_impl_int32(libmegapixels_camera *camera, uint32_t id, int request, - int32_t *value) + int32_t *value, + int fd_type) { struct v4l2_ext_control ctrl = {}; ctrl.id = id; @@ -720,7 +737,8 @@ control_impl_int32(libmegapixels_camera *camera, .count = 1, .controls = &ctrl, }; - if (xioctl(camera->sensor_fd, request, &ctrls) == -1) { + int fd = get_fd_from_type(camera, fd_type); + if (xioctl(fd, request, &ctrls) == -1) { return false; } @@ -729,7 +747,7 @@ control_impl_int32(libmegapixels_camera *camera, } pid_t -mp_camera_control_set_int32_bg(MPCamera *camera, uint32_t id, int32_t v) +mp_camera_control_set_int32_bg(MPCamera *camera, uint32_t id, int32_t v, int fd_type) { struct v4l2_ext_control ctrl = {}; ctrl.id = id; @@ -742,7 +760,7 @@ mp_camera_control_set_int32_bg(MPCamera *camera, uint32_t id, int32_t v) .controls = &ctrl, }; - int fd = camera->camera->sensor_fd; + int fd = get_fd_from_type(camera->camera, fd_type); // fork only after all the memory has been read pid_t pid = fork(); @@ -763,20 +781,20 @@ mp_camera_control_set_int32_bg(MPCamera *camera, uint32_t id, int32_t v) bool mp_camera_control_try_int32(libmegapixels_camera *camera, uint32_t id, int32_t *v) { - return control_impl_int32(camera, id, VIDIOC_TRY_EXT_CTRLS, v); + return control_impl_int32(camera, id, VIDIOC_TRY_EXT_CTRLS, v, FD_TYPE_SENSOR); } bool mp_camera_control_set_int32(libmegapixels_camera *camera, uint32_t id, int32_t v) { - return control_impl_int32(camera, id, VIDIOC_S_EXT_CTRLS, &v); + return control_impl_int32(camera, id, VIDIOC_S_EXT_CTRLS, &v, FD_TYPE_SENSOR); } int32_t -mp_camera_control_get_int32(libmegapixels_camera *camera, uint32_t id) +mp_camera_control_get_int32(libmegapixels_camera *camera, uint32_t id, int fd_type) { int32_t v = 0; - control_impl_int32(camera, id, VIDIOC_G_EXT_CTRLS, &v); + control_impl_int32(camera, id, VIDIOC_G_EXT_CTRLS, &v, fd_type); return v; } @@ -784,7 +802,7 @@ bool mp_camera_control_try_boolean(libmegapixels_camera *camera, uint32_t id, bool *v) { int32_t value = *v; - bool s = control_impl_int32(camera, id, VIDIOC_TRY_EXT_CTRLS, &value); + bool s = control_impl_int32(camera, id, VIDIOC_TRY_EXT_CTRLS, &value, FD_TYPE_SENSOR); *v = value; return s; } @@ -793,14 +811,14 @@ bool mp_camera_control_set_bool(libmegapixels_camera *camera, uint32_t id, bool v) { int32_t value = v; - return control_impl_int32(camera, id, VIDIOC_S_EXT_CTRLS, &value); + return control_impl_int32(camera, id, VIDIOC_S_EXT_CTRLS, &value, FD_TYPE_SENSOR); } bool mp_camera_control_get_bool(libmegapixels_camera *camera, uint32_t id) { int32_t v = false; - control_impl_int32(camera, id, VIDIOC_G_EXT_CTRLS, &v); + control_impl_int32(camera, id, VIDIOC_G_EXT_CTRLS, &v, FD_TYPE_SENSOR); return v; } @@ -808,5 +826,5 @@ pid_t 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); + return mp_camera_control_set_int32_bg(camera, id, value, FD_TYPE_SENSOR); } diff --git a/src/camera.h b/src/camera.h index 0c0333c..f0b9ddc 100644 --- a/src/camera.h +++ b/src/camera.h @@ -9,6 +9,9 @@ #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; @@ -60,13 +63,13 @@ 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); +bool mp_camera_query_control(libmegapixels_camera *camera, uint32_t id, MPControl *control, int fd_type); 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); +int32_t mp_camera_control_get_int32(libmegapixels_camera *camera, uint32_t id, int fd_type); // set the value in the background, discards result -pid_t mp_camera_control_set_int32_bg(MPCamera *camera, uint32_t id, int32_t v); +pid_t mp_camera_control_set_int32_bg(MPCamera *camera, uint32_t id, int32_t v, int fd_type); 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); diff --git a/src/io_pipeline.c b/src/io_pipeline.c index 8f585c4..9a13391 100644 --- a/src/io_pipeline.c +++ b/src/io_pipeline.c @@ -67,21 +67,21 @@ update_process_pipeline() // 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); + state_io.camera, state_io.gain.control, FD_TYPE_SENSOR); } 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); + state_io.camera, state_io.exposure.control, FD_TYPE_SENSOR); } 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); + state_io.red.control, FD_TYPE_SENSOR); int blue = mp_camera_control_get_int32(state_io.camera, - state_io.blue.control); + state_io.blue.control, FD_TYPE_SENSOR); balance_red = (float)red / (float)state_io.red.max; balance_blue = (float)blue / (float)state_io.blue.max; } @@ -165,7 +165,7 @@ capture(MPPipeline *pipeline, const void *data) // 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); + mp_camera_control_get_int32(state_io.camera, V4L2_CID_GAIN, FD_TYPE_SENSOR); 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); @@ -257,7 +257,8 @@ update_controls() 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); + state_io.gain.value_req, + FD_TYPE_SENSOR); state_io.gain.value = state_io.gain.value_req; state_changed = true; } @@ -276,7 +277,8 @@ update_controls() 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); + state_io.exposure.value_req, + FD_TYPE_SENSOR); state_io.exposure.value = state_io.exposure.value_req; state_changed = true; } @@ -387,7 +389,8 @@ on_frame(MPBuffer buffer, void *_data) mp_camera_control_set_int32_bg( mpcamera, V4L2_CID_EXPOSURE_AUTO, - V4L2_EXPOSURE_AUTO); + V4L2_EXPOSURE_AUTO, + FD_TYPE_SENSOR); } if (!state_io.gain.manual) { @@ -419,14 +422,14 @@ static void init_controls() { if (mp_camera_query_control( - state_io.camera, V4L2_CID_FOCUS_ABSOLUTE, NULL)) { + state_io.camera, V4L2_CID_FOCUS_ABSOLUTE, NULL, FD_TYPE_SENSOR)) { // TODO: Set focus state state_io.focus.control = V4L2_CID_FOCUS_ABSOLUTE; } else { state_io.focus.control = 0; } - if (mp_camera_query_control(state_io.camera, V4L2_CID_FOCUS_AUTO, NULL)) { + if (mp_camera_query_control(state_io.camera, V4L2_CID_FOCUS_AUTO, NULL, FD_TYPE_SENSOR)) { mp_camera_control_set_bool_bg( mpcamera, V4L2_CID_FOCUS_AUTO, true); state_io.focus.auto_control = V4L2_CID_FOCUS_AUTO; @@ -435,14 +438,14 @@ init_controls() } state_io.can_af_trigger = mp_camera_query_control( - state_io.camera, V4L2_CID_AUTO_FOCUS_START, NULL); + state_io.camera, V4L2_CID_AUTO_FOCUS_START, NULL, FD_TYPE_SENSOR); MPControl control; - if (mp_camera_query_control(state_io.camera, V4L2_CID_GAIN, &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; } else if (mp_camera_query_control( - state_io.camera, V4L2_CID_ANALOGUE_GAIN, &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; } else { @@ -451,12 +454,12 @@ init_controls() } if (state_io.gain.control) { state_io.gain.value = mp_camera_control_get_int32( - state_io.camera, state_io.gain.control); + state_io.camera, state_io.gain.control, FD_TYPE_SENSOR); } else { state_io.gain.value = 0; } - if (mp_camera_query_control(state_io.camera, V4L2_CID_AUTOGAIN, &control)) { + if (mp_camera_query_control(state_io.camera, V4L2_CID_AUTOGAIN, &control, FD_TYPE_SENSOR)) { state_io.gain.auto_control = V4L2_CID_AUTOGAIN; state_io.gain.manual = mp_camera_control_get_bool(state_io.camera, @@ -465,29 +468,29 @@ init_controls() state_io.gain.auto_control = 0; } - if (mp_camera_query_control(state_io.camera, V4L2_CID_EXPOSURE, &control)) { + 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); + state_io.camera, V4L2_CID_EXPOSURE, FD_TYPE_SENSOR); } else { state_io.exposure.control = 0; } if (mp_camera_query_control( - state_io.camera, V4L2_CID_EXPOSURE_AUTO, &control)) { + state_io.camera, V4L2_CID_EXPOSURE_AUTO, &control, FD_TYPE_SENSOR)) { state_io.exposure.auto_control = V4L2_CID_EXPOSURE_AUTO; state_io.exposure.manual = mp_camera_control_get_int32(state_io.camera, - V4L2_CID_EXPOSURE_AUTO) == + V4L2_CID_EXPOSURE_AUTO, FD_TYPE_SENSOR) == V4L2_EXPOSURE_MANUAL; } else { state_io.exposure.auto_control = 0; } if (mp_camera_query_control( - state_io.camera, V4L2_CID_RED_BALANCE, &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; } else { @@ -495,7 +498,7 @@ init_controls() } if (mp_camera_query_control( - state_io.camera, V4L2_CID_BLUE_BALANCE, &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; } else {