|
@@ -66,11 +66,18 @@ 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.id) {
|
|
if (!state_io.gain.manual && state_io.gain.control.id) {
|
|
- state_io.gain.value = mp_camera_control_get_int32(&state_io.gain.control);
|
|
|
|
|
|
+ state_io.gain.value =
|
|
|
|
+ mp_camera_control_get_int32(&state_io.gain.control);
|
|
}
|
|
}
|
|
|
|
|
|
if (!state_io.exposure.manual && state_io.exposure.control.id) {
|
|
if (!state_io.exposure.manual && state_io.exposure.control.id) {
|
|
- state_io.exposure.value = mp_camera_control_get_int32(&state_io.exposure.control);
|
|
|
|
|
|
+ state_io.exposure.value =
|
|
|
|
+ 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_red = 1.0f;
|
|
@@ -153,14 +160,14 @@ capture(MPPipeline *pipeline, const void *data)
|
|
|
|
|
|
// Disable the autogain/exposure while taking the burst
|
|
// Disable the autogain/exposure while taking the burst
|
|
mp_camera_control_set_int32(&state_io.gain.auto_control, 0);
|
|
mp_camera_control_set_int32(&state_io.gain.auto_control, 0);
|
|
- mp_camera_control_set_int32(&state_io.exposure.auto_control, V4L2_EXPOSURE_MANUAL);
|
|
|
|
|
|
+ mp_camera_control_set_int32(&state_io.exposure.auto_control,
|
|
|
|
+ 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 =
|
|
|
|
- mp_camera_control_get_int32(&state_io.gain.control);
|
|
|
|
|
|
+ state_io.gain.value = 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);
|
|
@@ -243,6 +250,28 @@ update_controls()
|
|
start_focus();
|
|
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) {
|
|
if (state_io.gain.manual != state_io.gain.manual_req) {
|
|
mp_camera_control_set_bool_bg(mpcamera,
|
|
mp_camera_control_set_bool_bg(mpcamera,
|
|
&state_io.gain.auto_control,
|
|
&state_io.gain.auto_control,
|
|
@@ -254,9 +283,8 @@ update_controls()
|
|
if ((state_io.gain.manual ||
|
|
if ((state_io.gain.manual ||
|
|
(!state_io.gain.manual && state_io.gain.auto_control.id == 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,
|
|
|
|
- &state_io.gain.control,
|
|
|
|
- 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 = state_io.gain.value_req;
|
|
state_io.gain.value = state_io.gain.value_req;
|
|
state_changed = true;
|
|
state_changed = true;
|
|
}
|
|
}
|
|
@@ -334,8 +362,9 @@ do_aaa()
|
|
static void
|
|
static void
|
|
on_frame(MPBuffer buffer, void *_data)
|
|
on_frame(MPBuffer buffer, void *_data)
|
|
{
|
|
{
|
|
- // Don't process frame when the window is not active, unless we're capturing an image,
|
|
|
|
- // in which case the flash window may be active instead of this window
|
|
|
|
|
|
+ // Don't process frame when the window is not active, unless we're capturing
|
|
|
|
+ // an image, in which case the flash window may be active instead of this
|
|
|
|
+ // window
|
|
if (!check_window_active() && state_io.captures_remaining == 0) {
|
|
if (!check_window_active() && state_io.captures_remaining == 0) {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
@@ -418,17 +447,28 @@ static void
|
|
init_controls()
|
|
init_controls()
|
|
{
|
|
{
|
|
MPControl focus_control;
|
|
MPControl focus_control;
|
|
- if (mp_camera_query_control(
|
|
|
|
- state_io.camera->sensor_fd, V4L2_CID_FOCUS_ABSOLUTE, &focus_control)) {
|
|
|
|
|
|
+ // 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.control = focus_control;
|
|
|
|
+ state_io.focus.max = focus_control.max;
|
|
|
|
+ state_io.focus.value =
|
|
|
|
+ mp_camera_control_get_int32(&state_io.focus.control);
|
|
} else {
|
|
} else {
|
|
state_io.focus.control.id = 0;
|
|
state_io.focus.control.id = 0;
|
|
}
|
|
}
|
|
|
|
|
|
MPControl auto_focus_control;
|
|
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, &auto_focus_control, true);
|
|
|
|
|
|
+ if (mp_camera_query_control(state_io.camera->sensor_fd,
|
|
|
|
+ V4L2_CID_FOCUS_AUTO,
|
|
|
|
+ &auto_focus_control)) {
|
|
|
|
+ mp_camera_control_set_bool_bg(mpcamera, &auto_focus_control, true);
|
|
state_io.focus.auto_control = auto_focus_control;
|
|
state_io.focus.auto_control = auto_focus_control;
|
|
} else {
|
|
} else {
|
|
state_io.focus.auto_control.id = 0;
|
|
state_io.focus.auto_control.id = 0;
|
|
@@ -438,11 +478,13 @@ init_controls()
|
|
state_io.camera->sensor_fd, V4L2_CID_AUTO_FOCUS_START, NULL);
|
|
state_io.camera->sensor_fd, V4L2_CID_AUTO_FOCUS_START, NULL);
|
|
|
|
|
|
MPControl gain_control;
|
|
MPControl gain_control;
|
|
- if (mp_camera_query_control(state_io.camera->sensor_fd, V4L2_CID_GAIN, &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.control = gain_control;
|
|
state_io.gain.max = gain_control.max;
|
|
state_io.gain.max = gain_control.max;
|
|
- } else if (mp_camera_query_control(
|
|
|
|
- state_io.camera->sensor_fd, V4L2_CID_ANALOGUE_GAIN, &gain_control)) {
|
|
|
|
|
|
+ } else if (mp_camera_query_control(state_io.camera->sensor_fd,
|
|
|
|
+ V4L2_CID_ANALOGUE_GAIN,
|
|
|
|
+ &gain_control)) {
|
|
state_io.gain.control = gain_control;
|
|
state_io.gain.control = gain_control;
|
|
state_io.gain.max = gain_control.max;
|
|
state_io.gain.max = gain_control.max;
|
|
} else {
|
|
} else {
|
|
@@ -450,13 +492,16 @@ init_controls()
|
|
state_io.gain.control.id = 0;
|
|
state_io.gain.control.id = 0;
|
|
}
|
|
}
|
|
if (state_io.gain.control.id) {
|
|
if (state_io.gain.control.id) {
|
|
- state_io.gain.value = mp_camera_control_get_int32(&state_io.gain.control);
|
|
|
|
|
|
+ state_io.gain.value =
|
|
|
|
+ mp_camera_control_get_int32(&state_io.gain.control);
|
|
} else {
|
|
} else {
|
|
state_io.gain.value = 0;
|
|
state_io.gain.value = 0;
|
|
}
|
|
}
|
|
|
|
|
|
MPControl auto_gain_control;
|
|
MPControl auto_gain_control;
|
|
- if (mp_camera_query_control(state_io.camera->sensor_fd, V4L2_CID_AUTOGAIN, &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.auto_control = auto_gain_control;
|
|
state_io.gain.manual =
|
|
state_io.gain.manual =
|
|
mp_camera_control_get_bool(&auto_gain_control) == 0;
|
|
mp_camera_control_get_bool(&auto_gain_control) == 0;
|
|
@@ -465,27 +510,33 @@ init_controls()
|
|
}
|
|
}
|
|
|
|
|
|
MPControl exposure_control;
|
|
MPControl exposure_control;
|
|
- if (mp_camera_query_control(state_io.camera->sensor_fd, V4L2_CID_EXPOSURE, &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.control = exposure_control;
|
|
state_io.exposure.max = exposure_control.max;
|
|
state_io.exposure.max = exposure_control.max;
|
|
- state_io.exposure.value = mp_camera_control_get_int32(&exposure_control);
|
|
|
|
|
|
+ state_io.exposure.value =
|
|
|
|
+ mp_camera_control_get_int32(&exposure_control);
|
|
} else {
|
|
} else {
|
|
state_io.exposure.control.id = 0;
|
|
state_io.exposure.control.id = 0;
|
|
}
|
|
}
|
|
|
|
|
|
MPControl auto_exposure_control;
|
|
MPControl auto_exposure_control;
|
|
- if (mp_camera_query_control(
|
|
|
|
- state_io.camera->sensor_fd, V4L2_CID_EXPOSURE_AUTO, &auto_exposure_control)) {
|
|
|
|
|
|
+ if (mp_camera_query_control(state_io.camera->sensor_fd,
|
|
|
|
+ V4L2_CID_EXPOSURE_AUTO,
|
|
|
|
+ &auto_exposure_control)) {
|
|
state_io.exposure.auto_control = auto_exposure_control;
|
|
state_io.exposure.auto_control = auto_exposure_control;
|
|
state_io.exposure.manual =
|
|
state_io.exposure.manual =
|
|
- mp_camera_control_get_int32(&auto_exposure_control) == V4L2_EXPOSURE_MANUAL;
|
|
|
|
|
|
+ mp_camera_control_get_int32(&auto_exposure_control) ==
|
|
|
|
+ V4L2_EXPOSURE_MANUAL;
|
|
} else {
|
|
} else {
|
|
state_io.exposure.auto_control.id = 0;
|
|
state_io.exposure.auto_control.id = 0;
|
|
}
|
|
}
|
|
|
|
|
|
MPControl red_control;
|
|
MPControl red_control;
|
|
- if (mp_camera_query_control(
|
|
|
|
- state_io.camera->sensor_fd, V4L2_CID_RED_BALANCE, &red_control)) {
|
|
|
|
|
|
+ if (mp_camera_query_control(state_io.camera->sensor_fd,
|
|
|
|
+ V4L2_CID_RED_BALANCE,
|
|
|
|
+ &red_control)) {
|
|
state_io.red.control = red_control;
|
|
state_io.red.control = red_control;
|
|
state_io.red.max = red_control.max;
|
|
state_io.red.max = red_control.max;
|
|
} else {
|
|
} else {
|
|
@@ -493,8 +544,9 @@ init_controls()
|
|
}
|
|
}
|
|
|
|
|
|
MPControl blue_control;
|
|
MPControl blue_control;
|
|
- if (mp_camera_query_control(
|
|
|
|
- state_io.camera->sensor_fd, V4L2_CID_BLUE_BALANCE, &blue_control)) {
|
|
|
|
|
|
+ if (mp_camera_query_control(state_io.camera->sensor_fd,
|
|
|
|
+ V4L2_CID_BLUE_BALANCE,
|
|
|
|
+ &blue_control)) {
|
|
state_io.blue.control = blue_control;
|
|
state_io.blue.control = blue_control;
|
|
state_io.blue.max = blue_control.max;
|
|
state_io.blue.max = blue_control.max;
|
|
} else {
|
|
} else {
|
|
@@ -525,7 +577,6 @@ update_state(MPPipeline *pipeline, const mp_state_io *new_state)
|
|
|
|
|
|
state_io.camera = new_state->camera;
|
|
state_io.camera = new_state->camera;
|
|
if (state_io.camera) {
|
|
if (state_io.camera) {
|
|
- libmegapixels_open(state_io.camera);
|
|
|
|
mpcamera = mp_camera_new(state_io.camera);
|
|
mpcamera = mp_camera_new(state_io.camera);
|
|
state_io.mode_preview = NULL;
|
|
state_io.mode_preview = NULL;
|
|
state_io.mode_capture = NULL;
|
|
state_io.mode_capture = NULL;
|
|
@@ -621,10 +672,10 @@ update_state(MPPipeline *pipeline, const mp_state_io *new_state)
|
|
void
|
|
void
|
|
mp_io_pipeline_update_state(const mp_state_io *state)
|
|
mp_io_pipeline_update_state(const mp_state_io *state)
|
|
{
|
|
{
|
|
- if (!pipeline) {
|
|
|
|
- printf("no pipeline\n");
|
|
|
|
- exit(1);
|
|
|
|
- }
|
|
|
|
|
|
+ if (!pipeline) {
|
|
|
|
+ printf("no pipeline\n");
|
|
|
|
+ exit(1);
|
|
|
|
+ }
|
|
mp_pipeline_invoke(pipeline,
|
|
mp_pipeline_invoke(pipeline,
|
|
(MPPipelineCallback)update_state,
|
|
(MPPipelineCallback)update_state,
|
|
state,
|
|
state,
|