Refactor camera control functions to use MPControl, store fd in MPControl
This commit is contained in:

committed by
Martijn Braam

parent
cd392d85cd
commit
3280c1d113
68
src/camera.c
68
src/camera.c
@@ -27,20 +27,6 @@ xioctl(int fd, int request, void *arg)
|
|||||||
return r;
|
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 {
|
struct video_buffer {
|
||||||
uint32_t length;
|
uint32_t length;
|
||||||
uint8_t *data;
|
uint8_t *data;
|
||||||
@@ -686,14 +672,12 @@ mp_control_list_free(MPControlList *list)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
mp_camera_query_control(libmegapixels_camera *camera,
|
mp_camera_query_control(int fd,
|
||||||
uint32_t id,
|
uint32_t id,
|
||||||
MPControl *control,
|
MPControl *control)
|
||||||
int fd_type)
|
|
||||||
{
|
{
|
||||||
struct v4l2_query_ext_ctrl ctrl = {};
|
struct v4l2_query_ext_ctrl ctrl = {};
|
||||||
ctrl.id = id;
|
ctrl.id = id;
|
||||||
int fd = get_fd_from_type(camera, fd_type);
|
|
||||||
if (xioctl(fd, VIDIOC_QUERY_EXT_CTRL, &ctrl) == -1) {
|
if (xioctl(fd, VIDIOC_QUERY_EXT_CTRL, &ctrl) == -1) {
|
||||||
if (errno != EINVAL) {
|
if (errno != EINVAL) {
|
||||||
errno_printerr("VIDIOC_QUERY_EXT_CTRL");
|
errno_printerr("VIDIOC_QUERY_EXT_CTRL");
|
||||||
@@ -702,6 +686,7 @@ mp_camera_query_control(libmegapixels_camera *camera,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (control) {
|
if (control) {
|
||||||
|
control->fd = fd;
|
||||||
control->id = ctrl.id;
|
control->id = ctrl.id;
|
||||||
control->type = ctrl.type;
|
control->type = ctrl.type;
|
||||||
strcpy(control->name, ctrl.name);
|
strcpy(control->name, ctrl.name);
|
||||||
@@ -721,14 +706,12 @@ mp_camera_query_control(libmegapixels_camera *camera,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
control_impl_int32(libmegapixels_camera *camera,
|
control_impl_int32(MPControl *control,
|
||||||
uint32_t id,
|
|
||||||
int request,
|
int request,
|
||||||
int32_t *value,
|
int32_t *value)
|
||||||
int fd_type)
|
|
||||||
{
|
{
|
||||||
struct v4l2_ext_control ctrl = {};
|
struct v4l2_ext_control ctrl = {};
|
||||||
ctrl.id = id;
|
ctrl.id = control->id;
|
||||||
ctrl.value = *value;
|
ctrl.value = *value;
|
||||||
|
|
||||||
struct v4l2_ext_controls ctrls = {
|
struct v4l2_ext_controls ctrls = {
|
||||||
@@ -737,8 +720,7 @@ control_impl_int32(libmegapixels_camera *camera,
|
|||||||
.count = 1,
|
.count = 1,
|
||||||
.controls = &ctrl,
|
.controls = &ctrl,
|
||||||
};
|
};
|
||||||
int fd = get_fd_from_type(camera, fd_type);
|
if (xioctl(control->fd, request, &ctrls) == -1) {
|
||||||
if (xioctl(fd, request, &ctrls) == -1) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -747,10 +729,10 @@ control_impl_int32(libmegapixels_camera *camera,
|
|||||||
}
|
}
|
||||||
|
|
||||||
pid_t
|
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 = {};
|
struct v4l2_ext_control ctrl = {};
|
||||||
ctrl.id = id;
|
ctrl.id = control->id;
|
||||||
ctrl.value = v;
|
ctrl.value = v;
|
||||||
|
|
||||||
struct v4l2_ext_controls ctrls = {
|
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,
|
.controls = &ctrl,
|
||||||
};
|
};
|
||||||
|
|
||||||
int fd = get_fd_from_type(camera->camera, fd_type);
|
|
||||||
|
|
||||||
// fork only after all the memory has been read
|
// fork only after all the memory has been read
|
||||||
pid_t pid = fork();
|
pid_t pid = fork();
|
||||||
if (pid == -1) {
|
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
|
// ignore errors
|
||||||
xioctl(fd, VIDIOC_S_EXT_CTRLS, &ctrls);
|
xioctl(control->fd, VIDIOC_S_EXT_CTRLS, &ctrls);
|
||||||
// exit without calling exit handlers
|
// exit without calling exit handlers
|
||||||
_exit(0);
|
_exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
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
|
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
|
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;
|
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;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
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;
|
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;
|
*v = value;
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
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;
|
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
|
bool
|
||||||
mp_camera_control_get_bool(libmegapixels_camera *camera, uint32_t id)
|
mp_camera_control_get_bool(MPControl *control)
|
||||||
{
|
{
|
||||||
int32_t v = false;
|
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;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
pid_t
|
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;
|
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);
|
||||||
}
|
}
|
||||||
|
23
src/camera.h
23
src/camera.h
@@ -8,10 +8,6 @@
|
|||||||
|
|
||||||
#define MAX_VIDEO_BUFFERS 20
|
#define MAX_VIDEO_BUFFERS 20
|
||||||
#define MAX_BG_TASKS 8
|
#define MAX_BG_TASKS 8
|
||||||
|
|
||||||
#define FD_TYPE_SENSOR 0
|
|
||||||
#define FD_TYPE_LENS 1
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t index;
|
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);
|
bool mp_camera_release_buffer(MPCamera *camera, uint32_t buffer_index);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
int fd;
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
uint32_t type;
|
uint32_t type;
|
||||||
char name[32];
|
char name[32];
|
||||||
@@ -63,16 +60,16 @@ MPControl *mp_control_list_get(MPControlList *list);
|
|||||||
MPControlList *mp_control_list_next(MPControlList *list);
|
MPControlList *mp_control_list_next(MPControlList *list);
|
||||||
void mp_control_list_free(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_try_int32(MPControl *control, int32_t *v);
|
||||||
bool mp_camera_control_set_int32(libmegapixels_camera *camera, uint32_t id, int32_t v);
|
bool mp_camera_control_set_int32(MPControl *control, int32_t v);
|
||||||
int32_t mp_camera_control_get_int32(libmegapixels_camera *camera, uint32_t id, int fd_type);
|
int32_t mp_camera_control_get_int32(MPControl *control);
|
||||||
// set the value in the background, discards result
|
// 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_try_bool(MPControl *control, bool *v);
|
||||||
bool mp_camera_control_set_bool(libmegapixels_camera *camera, uint32_t id, bool v);
|
bool mp_camera_control_set_bool(MPControl *control, bool v);
|
||||||
bool mp_camera_control_get_bool(libmegapixels_camera *camera, uint32_t id);
|
bool mp_camera_control_get_bool(MPControl *control);
|
||||||
// set the value in the background, discards result
|
// 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);
|
||||||
|
@@ -25,7 +25,7 @@ static GSource *capture_source;
|
|||||||
static bool pipeline_changed = true;
|
static bool pipeline_changed = true;
|
||||||
|
|
||||||
typedef struct invoke_set_control {
|
typedef struct invoke_set_control {
|
||||||
uint32_t control;
|
MPControl *control;
|
||||||
int32_t int_value;
|
int32_t int_value;
|
||||||
bool bool_value;
|
bool bool_value;
|
||||||
} invoke_set_control;
|
} invoke_set_control;
|
||||||
@@ -65,23 +65,19 @@ update_process_pipeline()
|
|||||||
}
|
}
|
||||||
pipeline_changed = false;
|
pipeline_changed = false;
|
||||||
// Grab the latest control values
|
// Grab the latest control values
|
||||||
if (!state_io.gain.manual && state_io.gain.control) {
|
if (!state_io.gain.manual && state_io.gain.control.id) {
|
||||||
state_io.gain.value = mp_camera_control_get_int32(
|
state_io.gain.value = mp_camera_control_get_int32(&state_io.gain.control);
|
||||||
state_io.camera, state_io.gain.control, FD_TYPE_SENSOR);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!state_io.exposure.manual && state_io.exposure.control) {
|
if (!state_io.exposure.manual && state_io.exposure.control.id) {
|
||||||
state_io.exposure.value = mp_camera_control_get_int32(
|
state_io.exposure.value = mp_camera_control_get_int32(&state_io.exposure.control);
|
||||||
state_io.camera, state_io.exposure.control, FD_TYPE_SENSOR);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float balance_red = 1.0f;
|
float balance_red = 1.0f;
|
||||||
float balance_blue = 1.0f;
|
float balance_blue = 1.0f;
|
||||||
if (state_io.red.control && state_io.blue.control) {
|
if (state_io.red.control.id && state_io.blue.control.id) {
|
||||||
int red = mp_camera_control_get_int32(state_io.camera,
|
int red = mp_camera_control_get_int32(&state_io.red.control);
|
||||||
state_io.red.control, FD_TYPE_SENSOR);
|
int blue = mp_camera_control_get_int32(&state_io.blue.control);
|
||||||
int blue = mp_camera_control_get_int32(state_io.camera,
|
|
||||||
state_io.blue.control, FD_TYPE_SENSOR);
|
|
||||||
balance_red = (float)red / (float)state_io.red.max;
|
balance_red = (float)red / (float)state_io.red.max;
|
||||||
balance_blue = (float)blue / (float)state_io.blue.max;
|
balance_blue = (float)blue / (float)state_io.blue.max;
|
||||||
}
|
}
|
||||||
@@ -136,11 +132,11 @@ static void
|
|||||||
set_control_int32(MPPipeline *pipeline, const void *data)
|
set_control_int32(MPPipeline *pipeline, const void *data)
|
||||||
{
|
{
|
||||||
const invoke_set_control *control_data = (const invoke_set_control *)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
|
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 };
|
invoke_set_control data = { 0 };
|
||||||
data.control = control;
|
data.control = control;
|
||||||
@@ -156,16 +152,15 @@ capture(MPPipeline *pipeline, const void *data)
|
|||||||
float gain_norm;
|
float gain_norm;
|
||||||
|
|
||||||
// Disable the autogain/exposure while taking the burst
|
// 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.gain.auto_control, 0);
|
||||||
mp_camera_control_set_int32(
|
mp_camera_control_set_int32(&state_io.exposure.auto_control, V4L2_EXPOSURE_MANUAL);
|
||||||
state_io.camera, V4L2_CID_EXPOSURE_AUTO, V4L2_EXPOSURE_MANUAL);
|
|
||||||
|
|
||||||
// Get current gain to calculate a burst length;
|
// Get current gain to calculate a burst length;
|
||||||
// with low gain there's 3, with the max automatic gain of the ov5640
|
// 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
|
// the value seems to be 248 which creates a 5 frame burst
|
||||||
// for manual gain you can go up to 11 frames
|
// for manual gain you can go up to 11 frames
|
||||||
state_io.gain.value =
|
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;
|
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 = (int)fmax(sqrtf(gain_norm) * 10, 2) + 1;
|
||||||
state_io.burst_length = MAX(1, state_io.burst_length);
|
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))
|
!mp_camera_check_task_complete(mpcamera, focus_continuous_task))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (state_io.focus.control) {
|
if (state_io.focus.control.id) {
|
||||||
focus_continuous_task = mp_camera_control_set_bool_bg(
|
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) {
|
} 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(
|
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) {
|
if (state_io.gain.manual != state_io.gain.manual_req) {
|
||||||
mp_camera_control_set_bool_bg(mpcamera,
|
mp_camera_control_set_bool_bg(mpcamera,
|
||||||
V4L2_CID_AUTOGAIN,
|
&state_io.gain.auto_control,
|
||||||
!state_io.gain.manual_req);
|
!state_io.gain.manual_req);
|
||||||
state_io.gain.manual = state_io.gain.manual_req;
|
state_io.gain.manual = state_io.gain.manual_req;
|
||||||
state_changed = true;
|
state_changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((state_io.gain.manual ||
|
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) {
|
state_io.gain.value != state_io.gain.value_req) {
|
||||||
mp_camera_control_set_int32_bg(mpcamera,
|
mp_camera_control_set_int32_bg(mpcamera,
|
||||||
state_io.gain.control,
|
&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_io.gain.value = state_io.gain.value_req;
|
||||||
state_changed = true;
|
state_changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state_io.exposure.manual != state_io.exposure.manual_req) {
|
if (state_io.exposure.manual != state_io.exposure.manual_req) {
|
||||||
mp_camera_control_set_bool_bg(mpcamera,
|
mp_camera_control_set_bool_bg(mpcamera,
|
||||||
V4L2_CID_EXPOSURE_AUTO,
|
&state_io.exposure.auto_control,
|
||||||
state_io.exposure.manual_req ?
|
state_io.exposure.manual_req ?
|
||||||
V4L2_EXPOSURE_MANUAL :
|
V4L2_EXPOSURE_MANUAL :
|
||||||
V4L2_EXPOSURE_AUTO);
|
V4L2_EXPOSURE_AUTO);
|
||||||
@@ -276,9 +274,8 @@ update_controls()
|
|||||||
if (state_io.exposure.manual &&
|
if (state_io.exposure.manual &&
|
||||||
state_io.exposure.value != state_io.exposure.value_req) {
|
state_io.exposure.value != state_io.exposure.value_req) {
|
||||||
mp_camera_control_set_int32_bg(mpcamera,
|
mp_camera_control_set_int32_bg(mpcamera,
|
||||||
state_io.exposure.control,
|
&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_io.exposure.value = state_io.exposure.value_req;
|
||||||
state_changed = true;
|
state_changed = true;
|
||||||
}
|
}
|
||||||
@@ -293,7 +290,7 @@ static void
|
|||||||
do_aaa()
|
do_aaa()
|
||||||
{
|
{
|
||||||
bool auto_exposure =
|
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) {
|
if (auto_exposure) {
|
||||||
int direction = state_io.stats.exposure;
|
int direction = state_io.stats.exposure;
|
||||||
@@ -388,14 +385,13 @@ on_frame(MPBuffer buffer, void *_data)
|
|||||||
if (!state_io.exposure.manual) {
|
if (!state_io.exposure.manual) {
|
||||||
mp_camera_control_set_int32_bg(
|
mp_camera_control_set_int32_bg(
|
||||||
mpcamera,
|
mpcamera,
|
||||||
V4L2_CID_EXPOSURE_AUTO,
|
&state_io.exposure.auto_control,
|
||||||
V4L2_EXPOSURE_AUTO,
|
V4L2_EXPOSURE_AUTO);
|
||||||
FD_TYPE_SENSOR);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!state_io.gain.manual) {
|
if (!state_io.gain.manual) {
|
||||||
mp_camera_control_set_bool_bg(
|
mp_camera_control_set_bool_bg(
|
||||||
mpcamera, V4L2_CID_AUTOGAIN, true);
|
mpcamera, &state_io.gain.auto_control, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Go back to preview mode
|
// Go back to preview mode
|
||||||
@@ -421,88 +417,88 @@ on_frame(MPBuffer buffer, void *_data)
|
|||||||
static void
|
static void
|
||||||
init_controls()
|
init_controls()
|
||||||
{
|
{
|
||||||
|
MPControl focus_control;
|
||||||
if (mp_camera_query_control(
|
if (mp_camera_query_control(
|
||||||
state_io.camera, V4L2_CID_FOCUS_ABSOLUTE, NULL, FD_TYPE_SENSOR)) {
|
state_io.camera->sensor_fd, V4L2_CID_FOCUS_ABSOLUTE, &focus_control)) {
|
||||||
// TODO: Set focus state
|
state_io.focus.control = focus_control;
|
||||||
state_io.focus.control = V4L2_CID_FOCUS_ABSOLUTE;
|
|
||||||
} else {
|
} 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(
|
mp_camera_control_set_bool_bg(
|
||||||
mpcamera, V4L2_CID_FOCUS_AUTO, true);
|
mpcamera, &auto_focus_control, true);
|
||||||
state_io.focus.auto_control = V4L2_CID_FOCUS_AUTO;
|
state_io.focus.auto_control = auto_focus_control;
|
||||||
} else {
|
} 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.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;
|
MPControl gain_control;
|
||||||
if (mp_camera_query_control(state_io.camera, V4L2_CID_GAIN, &control, FD_TYPE_SENSOR)) {
|
if (mp_camera_query_control(state_io.camera->sensor_fd, V4L2_CID_GAIN, &gain_control)) {
|
||||||
state_io.gain.control = V4L2_CID_GAIN;
|
state_io.gain.control = gain_control;
|
||||||
state_io.gain.max = control.max;
|
state_io.gain.max = gain_control.max;
|
||||||
} else if (mp_camera_query_control(
|
} else if (mp_camera_query_control(
|
||||||
state_io.camera, V4L2_CID_ANALOGUE_GAIN, &control, FD_TYPE_SENSOR)) {
|
state_io.camera->sensor_fd, V4L2_CID_ANALOGUE_GAIN, &gain_control)) {
|
||||||
state_io.gain.control = V4L2_CID_ANALOGUE_GAIN;
|
state_io.gain.control = gain_control;
|
||||||
state_io.gain.max = control.max;
|
state_io.gain.max = gain_control.max;
|
||||||
} else {
|
} else {
|
||||||
state_io.gain.max = 0;
|
state_io.gain.max = 0;
|
||||||
state_io.gain.control = 0;
|
state_io.gain.control.id = 0;
|
||||||
}
|
}
|
||||||
if (state_io.gain.control) {
|
if (state_io.gain.control.id) {
|
||||||
state_io.gain.value = mp_camera_control_get_int32(
|
state_io.gain.value = mp_camera_control_get_int32(&state_io.gain.control);
|
||||||
state_io.camera, state_io.gain.control, FD_TYPE_SENSOR);
|
|
||||||
} else {
|
} else {
|
||||||
state_io.gain.value = 0;
|
state_io.gain.value = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mp_camera_query_control(state_io.camera, V4L2_CID_AUTOGAIN, &control, FD_TYPE_SENSOR)) {
|
MPControl auto_gain_control;
|
||||||
state_io.gain.auto_control = V4L2_CID_AUTOGAIN;
|
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 =
|
state_io.gain.manual =
|
||||||
mp_camera_control_get_bool(state_io.camera,
|
mp_camera_control_get_bool(&auto_gain_control) == 0;
|
||||||
V4L2_CID_AUTOGAIN) == 0;
|
|
||||||
} else {
|
} 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)) {
|
MPControl exposure_control;
|
||||||
state_io.exposure.control = V4L2_CID_EXPOSURE;
|
if (mp_camera_query_control(state_io.camera->sensor_fd, V4L2_CID_EXPOSURE, &exposure_control)) {
|
||||||
state_io.exposure.max = control.max;
|
state_io.exposure.control = exposure_control;
|
||||||
state_io.exposure.value = mp_camera_control_get_int32(
|
state_io.exposure.max = exposure_control.max;
|
||||||
state_io.camera, V4L2_CID_EXPOSURE, FD_TYPE_SENSOR);
|
state_io.exposure.value = mp_camera_control_get_int32(&exposure_control);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
state_io.exposure.control = 0;
|
state_io.exposure.control.id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MPControl auto_exposure_control;
|
||||||
if (mp_camera_query_control(
|
if (mp_camera_query_control(
|
||||||
state_io.camera, V4L2_CID_EXPOSURE_AUTO, &control, FD_TYPE_SENSOR)) {
|
state_io.camera->sensor_fd, V4L2_CID_EXPOSURE_AUTO, &auto_exposure_control)) {
|
||||||
state_io.exposure.auto_control = V4L2_CID_EXPOSURE_AUTO;
|
state_io.exposure.auto_control = auto_exposure_control;
|
||||||
state_io.exposure.manual =
|
state_io.exposure.manual =
|
||||||
mp_camera_control_get_int32(state_io.camera,
|
mp_camera_control_get_int32(&auto_exposure_control) == V4L2_EXPOSURE_MANUAL;
|
||||||
V4L2_CID_EXPOSURE_AUTO, FD_TYPE_SENSOR) ==
|
|
||||||
V4L2_EXPOSURE_MANUAL;
|
|
||||||
} else {
|
} else {
|
||||||
state_io.exposure.auto_control = 0;
|
state_io.exposure.auto_control.id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MPControl red_control;
|
||||||
if (mp_camera_query_control(
|
if (mp_camera_query_control(
|
||||||
state_io.camera, V4L2_CID_RED_BALANCE, &control, FD_TYPE_SENSOR)) {
|
state_io.camera->sensor_fd, V4L2_CID_RED_BALANCE, &red_control)) {
|
||||||
state_io.red.control = V4L2_CID_RED_BALANCE;
|
state_io.red.control = red_control;
|
||||||
state_io.red.max = control.max;
|
state_io.red.max = red_control.max;
|
||||||
} else {
|
} else {
|
||||||
state_io.red.control = 0;
|
state_io.red.control.id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MPControl blue_control;
|
||||||
if (mp_camera_query_control(
|
if (mp_camera_query_control(
|
||||||
state_io.camera, V4L2_CID_BLUE_BALANCE, &control, FD_TYPE_SENSOR)) {
|
state_io.camera->sensor_fd, V4L2_CID_BLUE_BALANCE, &blue_control)) {
|
||||||
state_io.blue.control = V4L2_CID_BLUE_BALANCE;
|
state_io.blue.control = blue_control;
|
||||||
state_io.blue.max = control.max;
|
state_io.blue.max = blue_control.max;
|
||||||
} else {
|
} else {
|
||||||
state_io.blue.control = 0;
|
state_io.blue.control.id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pipeline_changed = true;
|
pipeline_changed = true;
|
||||||
|
@@ -10,7 +10,7 @@ void mp_io_pipeline_stop();
|
|||||||
|
|
||||||
void mp_io_pipeline_focus();
|
void mp_io_pipeline_focus();
|
||||||
void mp_io_pipeline_capture();
|
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);
|
void mp_io_pipeline_release_buffer(uint32_t buffer_index);
|
||||||
|
|
||||||
|
@@ -199,10 +199,10 @@ update_state(const mp_state_main *new_state)
|
|||||||
state.stats.focus = new_state->stats.focus;
|
state.stats.focus = new_state->stats.focus;
|
||||||
|
|
||||||
// Make the right settings available for the camera
|
// 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
|
// 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(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;
|
return false;
|
||||||
}
|
}
|
||||||
|
@@ -378,9 +378,9 @@ static void
|
|||||||
process_aaa()
|
process_aaa()
|
||||||
{
|
{
|
||||||
bool auto_exposure =
|
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 =
|
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;
|
bool auto_balance = TRUE;
|
||||||
if (!auto_exposure && !auto_focus && !auto_balance) {
|
if (!auto_exposure && !auto_focus && !auto_balance) {
|
||||||
return;
|
return;
|
||||||
@@ -445,9 +445,9 @@ process_aaa()
|
|||||||
|
|
||||||
clamp_control(&state_proc.gain);
|
clamp_control(&state_proc.gain);
|
||||||
clamp_control(&state_proc.exposure);
|
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);
|
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.exposure.value_req);
|
||||||
state_proc.gain.value = state_proc.gain.value_req;
|
state_proc.gain.value = state_proc.gain.value_req;
|
||||||
state_proc.exposure.value = state_proc.exposure.value_req;
|
state_proc.exposure.value = state_proc.exposure.value_req;
|
||||||
|
@@ -1,16 +1,17 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "camera.h"
|
||||||
#include "dcp.h"
|
#include "dcp.h"
|
||||||
#include <libmegapixels.h>
|
#include <libmegapixels.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
typedef struct cstate {
|
typedef struct cstate {
|
||||||
uint32_t control;
|
MPControl control;
|
||||||
int32_t value;
|
int32_t value;
|
||||||
int32_t value_req;
|
int32_t value_req;
|
||||||
int32_t max;
|
int32_t max;
|
||||||
bool manual;
|
bool manual;
|
||||||
bool manual_req;
|
bool manual_req;
|
||||||
uint32_t auto_control;
|
MPControl auto_control;
|
||||||
} controlstate;
|
} controlstate;
|
||||||
|
|
||||||
typedef struct state_main {
|
typedef struct state_main {
|
||||||
|
Reference in New Issue
Block a user