This commit is contained in:
Martijn Braam
2023-07-21 12:08:12 +02:00
parent e97ce527b0
commit e90f16dcfa
4 changed files with 108 additions and 55 deletions

View File

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

View File

@@ -39,14 +39,6 @@ libmegapixels_camera *pr_camera;
static int output_buffer_width = -1; static int output_buffer_width = -1;
static int output_buffer_height = -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 bool flash_enabled;
static char capture_fname[255]; 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_process_pipeline_buffer_ref(output_buffer);
mp_main_set_preview(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 // Create a thumbnail from the preview for the last capture
GdkTexture *thumb = NULL; GdkTexture *thumb = NULL;
if (state_proc.captures_remaining == 1) { 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 }; static const float neutral[] = { 1.0, 1.0, 1.0 };
TIFFSetField(tif, TIFFTAG_ASSHOTNEUTRAL, 3, neutral); 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 // 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 // Add an EXIF block to the tiff
TIFFCreateEXIFDirectory(tif); TIFFCreateEXIFDirectory(tif);
// 1 = manual, 2 = full auto, 3 = aperture priority, 4 = shutter priority // 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); TIFFSetField(tif, EXIFTAG_EXPOSUREPROGRAM, 2);
} else { } else {
TIFFSetField(tif, EXIFTAG_EXPOSUREPROGRAM, 1); TIFFSetField(tif, EXIFTAG_EXPOSUREPROGRAM, 1);
@@ -945,44 +955,51 @@ mod(int a, int b)
} }
static void 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.configuration = new_state->configuration;
state_proc.camera = state->camera; 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 = const bool output_changed =
!libmegapixels_mode_equals(state_proc.mode, !libmegapixels_mode_equals(state_proc.mode,
state->camera->current_mode) || new_state->camera->current_mode) ||
state_proc.preview_width != state->preview_width || state_proc.preview_width != new_state->preview_width ||
state_proc.preview_height != state->preview_height || state_proc.preview_height != new_state->preview_height ||
state_proc.device_rotation != state->device_rotation; state_proc.device_rotation != new_state->device_rotation;
bool format_changed = state_proc.mode == NULL; bool format_changed = state_proc.mode == NULL;
if (!format_changed && if (!format_changed && state_proc.mode->v4l_pixfmt !=
state_proc.mode->v4l_pixfmt != state->camera->current_mode->v4l_pixfmt) { new_state->camera->current_mode->v4l_pixfmt) {
format_changed = true; format_changed = true;
} }
if (state_proc.mode == NULL) {
state_proc.mode = state->camera->current_mode;
}
state_proc.mode = state->camera->current_mode; state_proc.mode = new_state->camera->current_mode;
state_proc.preview_width = state->preview_width; state_proc.preview_width = new_state->preview_width;
state_proc.preview_height = state->preview_height; state_proc.preview_height = new_state->preview_height;
state_proc.device_rotation = state->device_rotation; state_proc.device_rotation = new_state->device_rotation;
state_proc.burst_length = state->burst_length; state_proc.burst_length = new_state->burst_length;
state_proc.gain.manual = state->gain_is_manual; state_proc.balance[0] = new_state->balance[0];
state_proc.gain.value = state->gain; state_proc.balance[1] = new_state->balance[1];
state_proc.gain.max = state->gain_max; state_proc.balance[2] = new_state->balance[2];
state_proc.balance[0] = state->balance_red;
state_proc.balance[2] = state->balance_blue;
exposure_is_manual = state->exposure_is_manual;
exposure = state->exposure;
if (output_changed) { if (output_changed) {
state_proc.camera_rotation = mod( 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); on_output_changed(format_changed);
} }
mp_state_main new_state = { mp_state_main new_main = {
.camera = pr_camera, .camera = pr_camera,
.gain_is_manual = state->gain_is_manual, .gain_is_manual = new_state->gain.manual,
.gain = gain, .gain = state_proc.gain.value,
.gain_max = gain_max, .gain_max = state_proc.gain.max,
.exposure_is_manual = exposure_is_manual, .exposure_is_manual = state_proc.exposure.manual,
.exposure = exposure, .exposure = state_proc.exposure.value,
.has_auto_focus_continuous = state->has_auto_focus_continuous, .has_auto_focus_continuous = false,
.has_auto_focus_start = state->has_auto_focus_start, .has_auto_focus_start = false,
.preview_buffer_width = output_buffer_width, .preview_buffer_width = output_buffer_width,
.preview_buffer_height = output_buffer_height, .preview_buffer_height = output_buffer_height,
.control_gain = state->control_gain, .control_gain = new_state->gain.control != 0,
.control_exposure = state->control_exposure, .control_exposure = state_proc.exposure.control != 0,
.control_focus = state->control_focus, .control_focus = state_proc.focus.control != 0,
.control_flash = state->control_flash, .control_flash = false,
}; };
mp_main_update_state(&new_state); mp_main_update_state(&new_main);
} }
void 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, mp_pipeline_invoke(pipeline,
(MPPipelineCallback)update_state, (MPPipelineCallback)update_state,
new_state, new_state,
sizeof(struct mp_process_pipeline_state)); sizeof(mp_state_proc));
} }
// GTK4 seems to require this // GTK4 seems to require this

View File

@@ -1,6 +1,7 @@
#pragma once #pragma once
#include "camera.h" #include "camera.h"
#include "state.h"
#include <gtk/gtk.h> #include <gtk/gtk.h>
typedef struct _GdkSurface GdkSurface; 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_process_image(MPBuffer buffer);
void mp_process_pipeline_capture(); 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; typedef struct _MPProcessPipelineBuffer MPProcessPipelineBuffer;

View File

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