|
@@ -39,14 +39,6 @@ libmegapixels_camera *pr_camera;
|
|
|
static int output_buffer_width = -1;
|
|
|
static int output_buffer_height = -1;
|
|
|
|
|
|
-// static bool gain_is_manual;
|
|
|
-static int gain;
|
|
|
-static int gain_max;
|
|
|
-static float balance[3] = { 1.0f, 1.0f, 1.0f };
|
|
|
-
|
|
|
-static bool exposure_is_manual;
|
|
|
-static int exposure;
|
|
|
-
|
|
|
static bool flash_enabled;
|
|
|
|
|
|
static char capture_fname[255];
|
|
@@ -468,6 +460,24 @@ process_image_for_preview(const uint8_t *image)
|
|
|
mp_process_pipeline_buffer_ref(output_buffer);
|
|
|
mp_main_set_preview(output_buffer);
|
|
|
|
|
|
+ if (!state_proc.exposure.manual) {
|
|
|
+ int width = output_buffer_width / 3;
|
|
|
+ int height = output_buffer_height / 3;
|
|
|
+ uint32_t *center = g_malloc_n(width * height * sizeof(uint32_t), 1);
|
|
|
+ glReadPixels(width,
|
|
|
+ height,
|
|
|
+ width,
|
|
|
+ height,
|
|
|
+ GL_RGBA,
|
|
|
+ GL_UNSIGNED_BYTE,
|
|
|
+ center);
|
|
|
+ libmegapixels_aaa_software_statistics(
|
|
|
+ center, width, height, state_proc.stats);
|
|
|
+ printf("STAT: %d %d\n",
|
|
|
+ state_proc.stats->exposure,
|
|
|
+ state_proc.stats->whitebalance);
|
|
|
+ }
|
|
|
+
|
|
|
// Create a thumbnail from the preview for the last capture
|
|
|
GdkTexture *thumb = NULL;
|
|
|
if (state_proc.captures_remaining == 1) {
|
|
@@ -571,7 +581,7 @@ process_image_for_capture(const uint8_t *image, int count)
|
|
|
|
|
|
static const float neutral[] = { 1.0, 1.0, 1.0 };
|
|
|
TIFFSetField(tif, TIFFTAG_ASSHOTNEUTRAL, 3, neutral);
|
|
|
- TIFFSetField(tif, TIFFTAG_ANALOGBALANCE, 3, balance);
|
|
|
+ TIFFSetField(tif, TIFFTAG_ANALOGBALANCE, 3, state_proc.balance);
|
|
|
|
|
|
// Write black thumbnail, only windows uses this
|
|
|
{
|
|
@@ -643,7 +653,7 @@ process_image_for_capture(const uint8_t *image, int count)
|
|
|
// Add an EXIF block to the tiff
|
|
|
TIFFCreateEXIFDirectory(tif);
|
|
|
// 1 = manual, 2 = full auto, 3 = aperture priority, 4 = shutter priority
|
|
|
- if (!exposure_is_manual) {
|
|
|
+ if (!state_proc.exposure.manual) {
|
|
|
TIFFSetField(tif, EXIFTAG_EXPOSUREPROGRAM, 2);
|
|
|
} else {
|
|
|
TIFFSetField(tif, EXIFTAG_EXPOSUREPROGRAM, 1);
|
|
@@ -945,44 +955,51 @@ mod(int a, int b)
|
|
|
}
|
|
|
|
|
|
static void
|
|
|
-update_state(MPPipeline *pipeline, const struct mp_process_pipeline_state *state)
|
|
|
+update_state(MPPipeline *pipeline, const mp_state_proc *new_state)
|
|
|
{
|
|
|
- state_proc.configuration = state->configuration;
|
|
|
- state_proc.camera = state->camera;
|
|
|
+ state_proc.configuration = new_state->configuration;
|
|
|
+ state_proc.camera = new_state->camera;
|
|
|
+
|
|
|
+ state_proc.gain.control = new_state->gain.control;
|
|
|
+ state_proc.gain.value = new_state->gain.value;
|
|
|
+ state_proc.gain.max = new_state->gain.max;
|
|
|
+ state_proc.gain.manual = new_state->gain.manual;
|
|
|
+
|
|
|
+ state_proc.exposure.control = new_state->exposure.control;
|
|
|
+ state_proc.exposure.value = new_state->exposure.value;
|
|
|
+ state_proc.exposure.max = new_state->exposure.max;
|
|
|
+ state_proc.exposure.manual = new_state->exposure.manual;
|
|
|
+
|
|
|
+ state_proc.focus.control = new_state->focus.control;
|
|
|
+ state_proc.focus.value = new_state->focus.value;
|
|
|
+ state_proc.focus.max = new_state->focus.max;
|
|
|
+ state_proc.focus.manual = new_state->focus.manual;
|
|
|
|
|
|
const bool output_changed =
|
|
|
!libmegapixels_mode_equals(state_proc.mode,
|
|
|
- state->camera->current_mode) ||
|
|
|
- state_proc.preview_width != state->preview_width ||
|
|
|
- state_proc.preview_height != state->preview_height ||
|
|
|
- state_proc.device_rotation != state->device_rotation;
|
|
|
+ new_state->camera->current_mode) ||
|
|
|
+ state_proc.preview_width != new_state->preview_width ||
|
|
|
+ state_proc.preview_height != new_state->preview_height ||
|
|
|
+ state_proc.device_rotation != new_state->device_rotation;
|
|
|
|
|
|
bool format_changed = state_proc.mode == NULL;
|
|
|
|
|
|
- if (!format_changed &&
|
|
|
- state_proc.mode->v4l_pixfmt != state->camera->current_mode->v4l_pixfmt) {
|
|
|
+ if (!format_changed && state_proc.mode->v4l_pixfmt !=
|
|
|
+ new_state->camera->current_mode->v4l_pixfmt) {
|
|
|
format_changed = true;
|
|
|
}
|
|
|
- if (state_proc.mode == NULL) {
|
|
|
- state_proc.mode = state->camera->current_mode;
|
|
|
- }
|
|
|
-
|
|
|
- state_proc.mode = state->camera->current_mode;
|
|
|
|
|
|
- state_proc.preview_width = state->preview_width;
|
|
|
- state_proc.preview_height = state->preview_height;
|
|
|
+ state_proc.mode = new_state->camera->current_mode;
|
|
|
|
|
|
- state_proc.device_rotation = state->device_rotation;
|
|
|
- state_proc.burst_length = state->burst_length;
|
|
|
+ state_proc.preview_width = new_state->preview_width;
|
|
|
+ state_proc.preview_height = new_state->preview_height;
|
|
|
|
|
|
- state_proc.gain.manual = state->gain_is_manual;
|
|
|
- state_proc.gain.value = state->gain;
|
|
|
- state_proc.gain.max = state->gain_max;
|
|
|
- state_proc.balance[0] = state->balance_red;
|
|
|
- state_proc.balance[2] = state->balance_blue;
|
|
|
+ state_proc.device_rotation = new_state->device_rotation;
|
|
|
+ state_proc.burst_length = new_state->burst_length;
|
|
|
|
|
|
- exposure_is_manual = state->exposure_is_manual;
|
|
|
- exposure = state->exposure;
|
|
|
+ state_proc.balance[0] = new_state->balance[0];
|
|
|
+ state_proc.balance[1] = new_state->balance[1];
|
|
|
+ state_proc.balance[2] = new_state->balance[2];
|
|
|
|
|
|
if (output_changed) {
|
|
|
state_proc.camera_rotation = mod(
|
|
@@ -991,32 +1008,32 @@ update_state(MPPipeline *pipeline, const struct mp_process_pipeline_state *state
|
|
|
on_output_changed(format_changed);
|
|
|
}
|
|
|
|
|
|
- mp_state_main new_state = {
|
|
|
+ mp_state_main new_main = {
|
|
|
.camera = pr_camera,
|
|
|
- .gain_is_manual = state->gain_is_manual,
|
|
|
- .gain = gain,
|
|
|
- .gain_max = gain_max,
|
|
|
- .exposure_is_manual = exposure_is_manual,
|
|
|
- .exposure = exposure,
|
|
|
- .has_auto_focus_continuous = state->has_auto_focus_continuous,
|
|
|
- .has_auto_focus_start = state->has_auto_focus_start,
|
|
|
+ .gain_is_manual = new_state->gain.manual,
|
|
|
+ .gain = state_proc.gain.value,
|
|
|
+ .gain_max = state_proc.gain.max,
|
|
|
+ .exposure_is_manual = state_proc.exposure.manual,
|
|
|
+ .exposure = state_proc.exposure.value,
|
|
|
+ .has_auto_focus_continuous = false,
|
|
|
+ .has_auto_focus_start = false,
|
|
|
.preview_buffer_width = output_buffer_width,
|
|
|
.preview_buffer_height = output_buffer_height,
|
|
|
- .control_gain = state->control_gain,
|
|
|
- .control_exposure = state->control_exposure,
|
|
|
- .control_focus = state->control_focus,
|
|
|
- .control_flash = state->control_flash,
|
|
|
+ .control_gain = new_state->gain.control != 0,
|
|
|
+ .control_exposure = state_proc.exposure.control != 0,
|
|
|
+ .control_focus = state_proc.focus.control != 0,
|
|
|
+ .control_flash = false,
|
|
|
};
|
|
|
- mp_main_update_state(&new_state);
|
|
|
+ mp_main_update_state(&new_main);
|
|
|
}
|
|
|
|
|
|
void
|
|
|
-mp_process_pipeline_update_state(const struct mp_process_pipeline_state *new_state)
|
|
|
+mp_process_pipeline_update_state(const mp_state_proc *new_state)
|
|
|
{
|
|
|
mp_pipeline_invoke(pipeline,
|
|
|
(MPPipelineCallback)update_state,
|
|
|
new_state,
|
|
|
- sizeof(struct mp_process_pipeline_state));
|
|
|
+ sizeof(mp_state_proc));
|
|
|
}
|
|
|
|
|
|
// GTK4 seems to require this
|