Martijn Braam 1 anno fa
parent
commit
e90f16dcfa
4 ha cambiato i file con 108 aggiunte e 55 eliminazioni
  1. 38 4
      src/io_pipeline.c
  2. 67 50
      src/process_pipeline.c
  3. 2 1
      src/process_pipeline.h
  4. 1 0
      src/state.h

+ 38 - 4
src/io_pipeline.c

@@ -74,6 +74,32 @@ update_process_pipeline()
                 balance_blue = (float)blue / (float)state_io.blue.max;
         }
 
+        mp_state_proc new_state = {
+                .camera = state_io.camera,
+                .configuration = state_io.configuration,
+                .burst_length = state_io.burst_length,
+                .preview_width = state_io.preview_width,
+                .preview_height = state_io.preview_height,
+                .device_rotation = state_io.device_rotation,
+
+                .gain.control = state_io.gain.control,
+                .gain.value = state_io.gain.value,
+                .gain.max = state_io.gain.max,
+                .gain.manual = state_io.gain.manual,
+
+                .exposure.control = state_io.exposure.control,
+                .exposure.value = state_io.exposure.value,
+                .exposure.max = state_io.exposure.max,
+                .exposure.manual = state_io.exposure.manual,
+
+                .focus.control = state_io.focus.control,
+                .focus.value = state_io.focus.value,
+                .focus.max = state_io.focus.max,
+                .focus.manual = state_io.focus.manual,
+
+                .balance = {balance_red, 1.0f, balance_blue},
+        };
+
         struct mp_process_pipeline_state pipeline_state = {
                 .camera = state_io.camera,
                 .configuration = state_io.configuration,
@@ -96,7 +122,7 @@ update_process_pipeline()
                 .control_focus = state_io.focus.control != 0,
                 .control_flash = true,
         };
-        mp_process_pipeline_update_state(&pipeline_state);
+        mp_process_pipeline_update_state(&new_state);
 }
 
 static void
@@ -245,7 +271,7 @@ on_frame(MPBuffer buffer, void *_data)
         if (!check_window_active()) {
                 return;
         }
-        
+
         // Only update controls right after a frame was captured
         update_controls();
 
@@ -360,8 +386,16 @@ init_controls()
         state_io.gain.manual =
                 mp_camera_control_get_bool(state_io.camera, V4L2_CID_AUTOGAIN) == 0;
 
-        state_io.exposure.value =
-                mp_camera_control_get_int32(state_io.camera, V4L2_CID_EXPOSURE);
+        if (mp_camera_query_control(state_io.camera, V4L2_CID_EXPOSURE, &control)) {
+                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);
+
+        } else {
+                state_io.exposure.control = 0;
+        }
+
         state_io.exposure.manual =
                 mp_camera_control_get_int32(state_io.camera,
                                             V4L2_CID_EXPOSURE_AUTO) ==

+ 67 - 50
src/process_pipeline.c

@@ -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

+ 2 - 1
src/process_pipeline.h

@@ -1,6 +1,7 @@
 #pragma once
 
 #include "camera.h"
+#include "state.h"
 #include <gtk/gtk.h>
 
 typedef struct _GdkSurface GdkSurface;
@@ -48,7 +49,7 @@ void mp_process_pipeline_init_gl(GdkSurface *window);
 
 void mp_process_pipeline_process_image(MPBuffer buffer);
 void mp_process_pipeline_capture();
-void mp_process_pipeline_update_state(const struct mp_process_pipeline_state *state);
+void mp_process_pipeline_update_state(const mp_state_proc *new_state);
 
 typedef struct _MPProcessPipelineBuffer MPProcessPipelineBuffer;
 

+ 1 - 0
src/state.h

@@ -77,6 +77,7 @@ typedef struct state_proc {
         libmegapixels_devconfig *configuration;
         libmegapixels_camera *camera;
         libmegapixels_mode *mode;
+        libmegapixels_aaa_stats *stats;
 
         int burst_length;
         int captures_remaining;