diff --git a/src/io_pipeline.c b/src/io_pipeline.c index 881fce6..eb4f936 100644 --- a/src/io_pipeline.c +++ b/src/io_pipeline.c @@ -103,6 +103,12 @@ update_process_pipeline() .gain.max = state_io.gain.max, .gain.manual = state_io.gain.manual, + .dgain.control = state_io.dgain.control, + .dgain.auto_control = state_io.dgain.auto_control, + .dgain.value = state_io.dgain.value, + .dgain.max = state_io.dgain.max, + .dgain.manual = state_io.dgain.manual, + .exposure.control = state_io.exposure.control, .exposure.auto_control = state_io.exposure.auto_control, .exposure.value = state_io.exposure.value, @@ -168,6 +174,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.gain.control); + state_io.dgain.value = mp_camera_control_get_int32(&state_io.dgain.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); @@ -509,6 +516,24 @@ init_controls() state_io.gain.auto_control.id = 0; } + MPControl dgain_control; + if (mp_camera_query_control( + state_io.camera->sensor_fd, V4L2_CID_DIGITAL_GAIN, &dgain_control)) { + state_io.dgain.control = dgain_control; + state_io.dgain.max = dgain_control.max; + printf("Have d/gain, max: %d\n", dgain_control.max); + } else { + state_io.dgain.max = 0; + state_io.dgain.control.id = 0; + } + mp_camera_control_set_int32(&state_io.gain.control, 768); + if (state_io.dgain.control.id) { + state_io.dgain.value = + mp_camera_control_get_int32(&state_io.dgain.control); + } else { + state_io.dgain.value = 0; + } + MPControl exposure_control; if (mp_camera_query_control(state_io.camera->sensor_fd, V4L2_CID_EXPOSURE, @@ -648,6 +673,11 @@ update_state(MPPipeline *pipeline, const mp_state_io *new_state) state_io.gain.manual = new_state->gain.manual; state_io.gain.manual_req = new_state->gain.manual_req; + state_io.dgain.value = new_state->dgain.value; + state_io.dgain.value_req = new_state->dgain.value_req; + state_io.dgain.manual = new_state->dgain.manual; + state_io.dgain.manual_req = new_state->dgain.manual_req; + state_io.exposure.value = new_state->exposure.value; state_io.exposure.value_req = new_state->exposure.value_req; state_io.exposure.manual = new_state->exposure.manual; diff --git a/src/main.c b/src/main.c index aa1a8ff..b910db1 100644 --- a/src/main.c +++ b/src/main.c @@ -128,6 +128,14 @@ update_io_pipeline() .gain.manual = state.gain.manual, .gain.manual_req = state.gain.manual_req, + .dgain.control = state.dgain.control, + .dgain.auto_control = state.dgain.auto_control, + .dgain.value = state.dgain.value, + .dgain.value_req = state.dgain.value_req, + .dgain.max = state.dgain.max, + .dgain.manual = state.dgain.manual, + .dgain.manual_req = state.dgain.manual_req, + .exposure.control = state.exposure.control, .exposure.auto_control = state.exposure.auto_control, .exposure.value = state.exposure.value, @@ -186,6 +194,12 @@ update_state(const mp_state_main *new_state) state.gain.max = new_state->gain.max; state.gain.manual = new_state->gain.manual; + state.dgain.control = new_state->dgain.control; + state.dgain.auto_control = new_state->dgain.auto_control; + state.dgain.value = new_state->dgain.value; + state.dgain.max = new_state->dgain.max; + state.dgain.manual = new_state->dgain.manual; + state.exposure.control = new_state->exposure.control; state.exposure.auto_control = new_state->exposure.auto_control; state.exposure.value = new_state->exposure.value; diff --git a/src/main.h b/src/main.h index 1dff644..9b35502 100644 --- a/src/main.h +++ b/src/main.h @@ -14,6 +14,8 @@ struct mp_main_state { bool gain_is_manual; int gain; int gain_max; + int dgain; + int dgain_max; bool exposure_is_manual; int exposure; diff --git a/src/process_pipeline.c b/src/process_pipeline.c index 46d54a2..7249f6a 100644 --- a/src/process_pipeline.c +++ b/src/process_pipeline.c @@ -505,7 +505,6 @@ process_aaa() int step = 0; if (direction > 0) { // Preview is too dark - // Try raising the exposure time first if (state_proc.exposure.value < state_proc.exposure.max) { step = state_proc.exposure.value / 4; @@ -515,19 +514,30 @@ process_aaa() (step * direction); printf("Expose + %d\n", state_proc.exposure.value_req); - } else { + } else if (state_proc.gain.value < state_proc.gain.max) { // Raise sensor gain if exposure limit is hit step = state_proc.gain.value / 4; step = step < 4 ? 4 : step; state_proc.gain.value_req = state_proc.gain.value + (step * direction); printf("Gain + %d\n", state_proc.gain.value_req); - } + } else { + // Raise sensor gain if exposure limit is hit + step = state_proc.dgain.value / 4; + step = step < 4 ? 4 : step; + state_proc.dgain.value_req = + state_proc.dgain.value + (step * direction); + printf("D/Gain + %d\n", state_proc.dgain.value_req); + } } else if (direction < 0) { // Preview is too bright - // Lower the sensor gain first to have less noise - if (state_proc.gain.value > 0) { + if (state_proc.dgain.value > 256 /* state_proc.dgain.min FIXME */) { + step = state_proc.dgain.value / 4; + state_proc.dgain.value_req = + state_proc.dgain.value + (step * direction); + printf("D/Gain - %d\n", state_proc.gain.value_req); + } else if (state_proc.gain.value > 0) { step = state_proc.gain.value / 4; state_proc.gain.value_req = state_proc.gain.value + (step * direction); @@ -544,12 +554,16 @@ process_aaa() } clamp_control(&state_proc.gain); + clamp_control(&state_proc.dgain); clamp_control(&state_proc.exposure); mp_io_pipeline_set_control_int32(&state_proc.gain.control, state_proc.gain.value_req); + mp_io_pipeline_set_control_int32(&state_proc.dgain.control, + state_proc.dgain.value_req); 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.dgain.value = state_proc.dgain.value_req; state_proc.exposure.value = state_proc.exposure.value_req; } @@ -1378,6 +1392,12 @@ update_state(MPPipeline *pipeline, const mp_state_proc *new_state) state_proc.gain.max = new_state->gain.max; state_proc.gain.manual = new_state->gain.manual; + state_proc.dgain.control = new_state->dgain.control; + state_proc.dgain.auto_control = new_state->dgain.auto_control; + state_proc.dgain.value = new_state->dgain.value; + state_proc.dgain.max = new_state->dgain.max; + state_proc.dgain.manual = new_state->dgain.manual; + state_proc.exposure.control = new_state->exposure.control; state_proc.exposure.auto_control = new_state->exposure.auto_control; state_proc.exposure.value = new_state->exposure.value; @@ -1453,6 +1473,13 @@ update_state(MPPipeline *pipeline, const mp_state_proc *new_state) .gain.max = state_proc.gain.max, .gain.manual = state_proc.gain.manual, + .dgain.control = state_proc.dgain.control, + .dgain.auto_control = state_proc.dgain.auto_control, + .dgain.value = state_proc.dgain.value, + .dgain.value_req = state_proc.dgain.value_req, + .dgain.max = state_proc.dgain.max, + .dgain.manual = state_proc.dgain.manual, + .exposure.control = state_proc.exposure.control, .exposure.auto_control = state_proc.exposure.auto_control, .exposure.value = state_proc.exposure.value, diff --git a/src/state.h b/src/state.h index 7823e32..1372aa6 100644 --- a/src/state.h +++ b/src/state.h @@ -34,6 +34,7 @@ typedef struct state_main { // Control state bool flash_enabled; controlstate gain; + controlstate dgain; controlstate exposure; controlstate focus; @@ -55,6 +56,7 @@ typedef struct state_io { // Control state controlstate gain; + controlstate dgain; controlstate exposure; controlstate focus; controlstate red; @@ -97,6 +99,7 @@ typedef struct state_proc { float balance[3]; controlstate gain; + controlstate dgain; controlstate exposure; controlstate focus; @@ -111,4 +114,4 @@ typedef struct state_proc { int mode_focus; bool flash_enabled; -} mp_state_proc; \ No newline at end of file +} mp_state_proc;