瀏覽代碼

Process pipeline refactoring

Martijn Braam 1 年之前
父節點
當前提交
6e8293116b
共有 6 個文件被更改,包括 129 次插入182 次删除
  1. 2 1
      src/io_pipeline.c
  2. 1 0
      src/io_pipeline.h
  3. 1 0
      src/main.c
  4. 99 180
      src/process_pipeline.c
  5. 1 0
      src/process_pipeline.h
  6. 25 1
      src/state.h

+ 2 - 1
src/io_pipeline.c

@@ -75,6 +75,7 @@ update_process_pipeline()
 
         struct mp_process_pipeline_state pipeline_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,
@@ -454,7 +455,7 @@ update_state(MPPipeline *pipeline, const struct mp_io_pipeline_state *state)
                         init_controls();
                 }
         }
-
+        state_io.configuration = state->configuration;
         state_io.burst_length = state->burst_length;
         state_io.preview_width = state->preview_width;
         state_io.preview_height = state->preview_height;

+ 1 - 0
src/io_pipeline.h

@@ -6,6 +6,7 @@
 
 struct mp_io_pipeline_state {
         libmegapixels_camera *camera;
+        libmegapixels_devconfig *configuration;
 
         int burst_length;
 

+ 1 - 0
src/main.c

@@ -95,6 +95,7 @@ update_io_pipeline()
 {
         struct mp_io_pipeline_state io_state = {
                 .camera = state.camera,
+                .configuration = state.configuration,
                 .burst_length = state.burst_length,
                 .preview_width = state.preview_width,
                 .preview_height = state.preview_height,

+ 99 - 180
src/process_pipeline.c

@@ -4,6 +4,7 @@
 #include "io_pipeline.h"
 #include "main.h"
 #include "pipeline.h"
+#include "state.h"
 #include "zbar_pipeline.h"
 #include <assert.h>
 #include <gtk/gtk.h>
@@ -25,6 +26,7 @@ static const float colormatrix_srgb[] = { 3.2409f,  -1.5373f, -0.4986f,
                                           0.0556f,  -0.2039f, 1.0569f };
 
 static MPPipeline *pipeline;
+mp_state_proc state_proc;
 
 static char burst_dir[23];
 
@@ -33,17 +35,6 @@ static volatile int frames_processed = 0;
 static volatile int frames_received = 0;
 
 libmegapixels_camera *pr_camera;
-libmegapixels_mode *mode;
-
-static int camera_rotation;
-
-static int burst_length;
-static int captures_remaining = 0;
-
-static int preview_width;
-static int preview_height;
-
-static int device_rotation;
 
 static int output_buffer_width = -1;
 static int output_buffer_height = -1;
@@ -237,9 +228,7 @@ void
 mp_process_pipeline_start()
 {
         pipeline = mp_pipeline_new();
-
         mp_pipeline_invoke(pipeline, setup, NULL, 0);
-
         mp_zbar_pipeline_start();
 }
 
@@ -247,7 +236,6 @@ void
 mp_process_pipeline_stop()
 {
         mp_pipeline_free(pipeline);
-
         mp_zbar_pipeline_stop();
 }
 
@@ -442,17 +430,19 @@ process_image_for_preview(const uint8_t *image)
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-        glTexImage2D(GL_TEXTURE_2D,
-                     0,
-                     GL_LUMINANCE,
-                     libmegapixels_mode_width_to_bytes(mode->format, mode->width) +
-                             libmegapixels_mode_width_to_padding(mode->format,
-                                                                 mode->width),
-                     mode->height,
-                     0,
-                     GL_LUMINANCE,
-                     GL_UNSIGNED_BYTE,
-                     image);
+        glTexImage2D(
+                GL_TEXTURE_2D,
+                0,
+                GL_LUMINANCE,
+                libmegapixels_mode_width_to_bytes(state_proc.mode->format,
+                                                  state_proc.mode->width) +
+                        libmegapixels_mode_width_to_padding(state_proc.mode->format,
+                                                            state_proc.mode->width),
+                state_proc.mode->height,
+                0,
+                GL_LUMINANCE,
+                GL_UNSIGNED_BYTE,
+                image);
         check_gl();
 
         gles2_debayer_process(
@@ -480,7 +470,7 @@ process_image_for_preview(const uint8_t *image)
 
         // Create a thumbnail from the preview for the last capture
         GdkTexture *thumb = NULL;
-        if (captures_remaining == 1) {
+        if (state_proc.captures_remaining == 1) {
                 printf("Making thumbnail\n");
 
                 size_t size = output_buffer_width * output_buffer_height *
@@ -541,26 +531,27 @@ process_image_for_capture(const uint8_t *image, int count)
 
         // Define TIFF thumbnail
         TIFFSetField(tif, TIFFTAG_SUBFILETYPE, 1);
-        TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, mode->width >> 4);
-        TIFFSetField(tif, TIFFTAG_IMAGELENGTH, mode->height >> 4);
+        TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, state_proc.mode->width >> 4);
+        TIFFSetField(tif, TIFFTAG_IMAGELENGTH, state_proc.mode->height >> 4);
         TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
         TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
         TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
-        TIFFSetField(tif, TIFFTAG_MAKE, "MAKE"); // TODO: fix
-        TIFFSetField(tif, TIFFTAG_MODEL, "MODEL");
+        TIFFSetField(tif, TIFFTAG_MAKE, state_proc.configuration->make);
+        TIFFSetField(tif, TIFFTAG_MODEL, state_proc.configuration->model);
+
         uint16_t orientation;
-        if (camera_rotation == 0) {
-                orientation =
-                        mode->mirrored ? ORIENTATION_TOPRIGHT : ORIENTATION_TOPLEFT;
-        } else if (camera_rotation == 90) {
-                orientation =
-                        mode->mirrored ? ORIENTATION_RIGHTBOT : ORIENTATION_LEFTBOT;
-        } else if (camera_rotation == 180) {
-                orientation =
-                        mode->mirrored ? ORIENTATION_BOTLEFT : ORIENTATION_BOTRIGHT;
+        if (state_proc.device_rotation == 0) {
+                orientation = state_proc.mode->mirrored ? ORIENTATION_TOPRIGHT :
+                                                          ORIENTATION_TOPLEFT;
+        } else if (state_proc.device_rotation == 90) {
+                orientation = state_proc.mode->mirrored ? ORIENTATION_RIGHTBOT :
+                                                          ORIENTATION_LEFTBOT;
+        } else if (state_proc.device_rotation == 180) {
+                orientation = state_proc.mode->mirrored ? ORIENTATION_BOTLEFT :
+                                                          ORIENTATION_BOTRIGHT;
         } else {
-                orientation =
-                        mode->mirrored ? ORIENTATION_LEFTTOP : ORIENTATION_RIGHTTOP;
+                orientation = state_proc.mode->mirrored ? ORIENTATION_LEFTTOP :
+                                                          ORIENTATION_RIGHTTOP;
         }
         TIFFSetField(tif, TIFFTAG_ORIENTATION, orientation);
         TIFFSetField(tif, TIFFTAG_DATETIME, datetime);
@@ -574,98 +565,19 @@ process_image_for_capture(const uint8_t *image, int count)
         char uniquecameramodel[255];
         sprintf(uniquecameramodel,
                 "%s %s",
-                "MAKE", // TODO: fix
-                "MODEL");
+                state_proc.configuration->make,
+                state_proc.configuration->model);
         TIFFSetField(tif, TIFFTAG_UNIQUECAMERAMODEL, uniquecameramodel);
 
-        // Color matrices
-        /*
-        if (pr_camera->calibration.color_matrix_1[0]) {
-                TIFFSetField(tif,
-                             TIFFTAG_COLORMATRIX1,
-                             9,
-                             pr_camera->calibration.color_matrix_1);
-        } else if (pr_camera->colormatrix[0]) {
-                TIFFSetField(tif, TIFFTAG_COLORMATRIX1, 9, pr_camera->colormatrix);
-        } else {
-                TIFFSetField(tif, TIFFTAG_COLORMATRIX1, 9, colormatrix_srgb);
-        }
-        if (pr_camera->calibration.color_matrix_2[0]) {
-                TIFFSetField(tif,
-                             TIFFTAG_COLORMATRIX2,
-                             9,
-                             pr_camera->calibration.color_matrix_2);
-        }
-
-        if (pr_camera->calibration.forward_matrix_1[0]) {
-                TIFFSetField(tif,
-                             TIFFTAG_FORWARDMATRIX1,
-                             9,
-                             pr_camera->calibration.forward_matrix_1);
-        } else if (pr_camera->forwardmatrix[0]) {
-                TIFFSetField(tif, TIFFTAG_FORWARDMATRIX1, 9,
-        pr_camera->forwardmatrix);
-        }
-
-        if (pr_camera->calibration.forward_matrix_2[0]) {
-                TIFFSetField(tif,
-                             TIFFTAG_FORWARDMATRIX2,
-                             9,
-                             pr_camera->calibration.forward_matrix_2);
-        }
-
         static const float neutral[] = { 1.0, 1.0, 1.0 };
         TIFFSetField(tif, TIFFTAG_ASSHOTNEUTRAL, 3, neutral);
-        if (pr_camera->calibration.illuminant_1) {
-                TIFFSetField(tif,
-                             TIFFTAG_CALIBRATIONILLUMINANT1,
-                             pr_camera->calibration.illuminant_1);
-        } else {
-                TIFFSetField(tif, TIFFTAG_CALIBRATIONILLUMINANT1, 21);
-        }
-
-        if (pr_camera->calibration.illuminant_2) {
-                TIFFSetField(tif,
-                             TIFFTAG_CALIBRATIONILLUMINANT2,
-                             pr_camera->calibration.illuminant_2);
-        }
-
-        if (pr_camera->calibration.tone_curve_length) {
-                TIFFSetField(tif,
-                             DCPTAG_PROFILE_TONE_CURVE,
-                             pr_camera->calibration.tone_curve_length,
-                             pr_camera->calibration.tone_curve);
-        }
-
-        if (pr_camera->calibration.hue_sat_map_dims[0]) {
-                TIFFSetField(tif,
-                             DCPTAG_PROFILE_HUE_SAT_MAP_DIMS,
-                             3,
-                             pr_camera->calibration.hue_sat_map_dims);
-                TIFFSetField(tif,
-                             DCPTAG_PROFILE_HUE_SAT_MAP_DATA_1,
-                             pr_camera->calibration.hue_sat_map_dims[0] *
-                                     pr_camera->calibration.hue_sat_map_dims[1] *
-                                     pr_camera->calibration.hue_sat_map_dims[2] * 3,
-                             pr_camera->calibration.hue_sat_map_data_1);
-                if (pr_camera->calibration.hue_sat_map_data_2 != NULL) {
-                        TIFFSetField(
-                                tif,
-                                DCPTAG_PROFILE_HUE_SAT_MAP_DATA_2,
-                                pr_camera->calibration.hue_sat_map_dims[0] *
-                                        pr_camera->calibration.hue_sat_map_dims[1] *
-                                        pr_camera->calibration.hue_sat_map_dims[2] *
-        3, pr_camera->calibration.hue_sat_map_data_2);
-                }
-        }
-       */
         TIFFSetField(tif, TIFFTAG_ANALOGBALANCE, 3, balance);
 
         // Write black thumbnail, only windows uses this
         {
-                unsigned char *buf =
-                        (unsigned char *)calloc(1, (mode->width >> 4) * 3);
-                for (int row = 0; row < (mode->height >> 4); row++) {
+                unsigned char *buf = (unsigned char *)calloc(
+                        1, (state_proc.mode->width >> 4) * 3);
+                for (int row = 0; row < (state_proc.mode->height >> 4); row++) {
                         TIFFWriteScanline(tif, buf, row, 0);
                 }
                 free(buf);
@@ -674,11 +586,11 @@ process_image_for_capture(const uint8_t *image, int count)
 
         // Define main photo
         TIFFSetField(tif, TIFFTAG_SUBFILETYPE, 0);
-        TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, mode->width);
-        TIFFSetField(tif, TIFFTAG_IMAGELENGTH, mode->height);
+        TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, state_proc.mode->width);
+        TIFFSetField(tif, TIFFTAG_IMAGELENGTH, state_proc.mode->height);
         TIFFSetField(tif,
                      TIFFTAG_BITSPERSAMPLE,
-                     libmegapixels_format_bits_per_pixel(mode->format));
+                     libmegapixels_format_bits_per_pixel(state_proc.mode->format));
         TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_CFA);
         TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1);
         TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
@@ -692,11 +604,12 @@ process_image_for_capture(const uint8_t *image, int count)
         TIFFSetField(tif,
                      TIFFTAG_CFAPATTERN,
                      4,
-                     libmegapixels_format_cfa_pattern(mode->format));
+                     libmegapixels_format_cfa_pattern(state_proc.mode->format));
 #endif
         printf("TIFF version %d\n", TIFFLIB_VERSION);
         int whitelevel =
-                (1 << libmegapixels_format_bits_per_pixel(mode->format)) - 1;
+                (1 << libmegapixels_format_bits_per_pixel(state_proc.mode->format)) -
+                1;
         TIFFSetField(tif, TIFFTAG_WHITELEVEL, 1, &whitelevel);
         TIFFCheckpointDirectory(tif);
         printf("Writing frame to %s\n", fname);
@@ -704,19 +617,21 @@ process_image_for_capture(const uint8_t *image, int count)
         uint8_t *output_image = (uint8_t *)image;
 
         // Repack 10-bit image from sensor format into a sequencial format
-        if (libmegapixels_format_bits_per_pixel(mode->format) == 10) {
-                output_image = malloc(libmegapixels_mode_width_to_bytes(
-                                              mode->format, mode->width) *
-                                      mode->height);
+        if (libmegapixels_format_bits_per_pixel(state_proc.mode->format) == 10) {
+                output_image = malloc(
+                        libmegapixels_mode_width_to_bytes(state_proc.mode->format,
+                                                          state_proc.mode->width) *
+                        state_proc.mode->height);
 
-                repack_image_sequencial(image, output_image, mode);
+                repack_image_sequencial(image, output_image, state_proc.mode);
         }
 
-        for (int row = 0; row < mode->height; row++) {
+        for (int row = 0; row < state_proc.mode->height; row++) {
                 TIFFWriteScanline(tif,
                                   (void *)output_image +
                                           (row * libmegapixels_mode_width_to_bytes(
-                                                         mode->format, mode->width)),
+                                                         state_proc.mode->format,
+                                                         state_proc.mode->width)),
                                   row,
                                   0);
         }
@@ -876,20 +791,21 @@ process_image(MPPipeline *pipeline, const MPBuffer *buffer)
         clock_t t1 = clock();
 #endif
 
-        size_t size =
-                (libmegapixels_mode_width_to_bytes(mode->format, mode->width) +
-                 libmegapixels_mode_width_to_padding(mode->format, mode->width)) *
-                mode->height;
+        size_t size = (libmegapixels_mode_width_to_bytes(state_proc.mode->format,
+                                                         state_proc.mode->width) +
+                       libmegapixels_mode_width_to_padding(state_proc.mode->format,
+                                                           state_proc.mode->width)) *
+                      state_proc.mode->height;
         uint8_t *image = malloc(size);
         memcpy(image, buffer->data, size);
         mp_io_pipeline_release_buffer(buffer->index);
 
         MPZBarImage *zbar_image = mp_zbar_image_new(image,
-                                                    mode->format,
-                                                    mode->width,
-                                                    mode->height,
-                                                    camera_rotation,
-                                                    mode->mirrored);
+                                                    state_proc.mode->format,
+                                                    state_proc.mode->width,
+                                                    state_proc.mode->height,
+                                                    state_proc.device_rotation,
+                                                    state_proc.mode->mirrored);
         mp_zbar_pipeline_process_image(mp_zbar_image_ref(zbar_image));
 
 #ifdef PROFILE_PROCESS
@@ -898,13 +814,13 @@ process_image(MPPipeline *pipeline, const MPBuffer *buffer)
 
         GdkTexture *thumb = process_image_for_preview(image);
 
-        if (captures_remaining > 0) {
-                int count = burst_length - captures_remaining;
-                --captures_remaining;
+        if (state_proc.captures_remaining > 0) {
+                int count = state_proc.burst_length - state_proc.captures_remaining;
+                --state_proc.captures_remaining;
 
                 process_image_for_capture(image, count);
 
-                if (captures_remaining == 0) {
+                if (state_proc.captures_remaining == 0) {
                         assert(thumb);
                         process_capture_burst(thumb);
                 } else {
@@ -917,7 +833,7 @@ process_image(MPPipeline *pipeline, const MPBuffer *buffer)
         mp_zbar_image_unref(zbar_image);
 
         ++frames_processed;
-        if (captures_remaining == 0) {
+        if (state_proc.captures_remaining == 0) {
                 is_capturing = false;
         }
 
@@ -961,7 +877,7 @@ capture()
 
         strcpy(burst_dir, tempdir);
 
-        captures_remaining = burst_length;
+        state_proc.captures_remaining = state_proc.burst_length;
 }
 
 void
@@ -975,10 +891,10 @@ mp_process_pipeline_capture()
 static void
 on_output_changed(bool format_changed)
 {
-        output_buffer_width = mode->width / 2;
-        output_buffer_height = mode->height / 2;
+        output_buffer_width = state_proc.mode->width / 2;
+        output_buffer_height = state_proc.mode->height / 2;
 
-        if (mode->rotation != 0 && mode->rotation != 180) {
+        if (state_proc.mode->rotation != 0 && state_proc.mode->rotation != 180) {
                 int tmp = output_buffer_width;
                 output_buffer_width = output_buffer_height;
                 output_buffer_height = tmp;
@@ -1004,7 +920,7 @@ on_output_changed(bool format_changed)
                 if (gles2_debayer)
                         gles2_debayer_free(gles2_debayer);
 
-                gles2_debayer = gles2_debayer_new(mode->format);
+                gles2_debayer = gles2_debayer_new(state_proc.mode->format);
                 check_gl();
 
                 gles2_debayer_use(gles2_debayer);
@@ -1013,9 +929,9 @@ on_output_changed(bool format_changed)
         gles2_debayer_configure(gles2_debayer,
                                 output_buffer_width,
                                 output_buffer_height,
-                                mode->width,
-                                mode->height,
-                                mode->rotation,
+                                state_proc.mode->width,
+                                state_proc.mode->height,
+                                state_proc.mode->rotation,
                                 0,
                                 NULL,
                                 0);
@@ -1031,43 +947,46 @@ mod(int a, int b)
 static void
 update_state(MPPipeline *pipeline, const struct mp_process_pipeline_state *state)
 {
+        state_proc.configuration = state->configuration;
+        state_proc.camera = state->camera;
+
         const bool output_changed =
-                !libmegapixels_mode_equals(mode, state->camera->current_mode) ||
-                preview_width != state->preview_width ||
-                preview_height != state->preview_height ||
-                device_rotation != state->device_rotation;
+                !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;
 
-        bool format_changed = mode == NULL;
+        bool format_changed = state_proc.mode == NULL;
 
         if (!format_changed &&
-            mode->v4l_pixfmt != state->camera->current_mode->v4l_pixfmt) {
+            state_proc.mode->v4l_pixfmt != state->camera->current_mode->v4l_pixfmt) {
                 format_changed = true;
         }
-        if (mode == NULL) {
-                mode = state->camera->current_mode;
+        if (state_proc.mode == NULL) {
+                state_proc.mode = state->camera->current_mode;
         }
 
-        pr_camera = state->camera;
-        mode = state->camera->current_mode;
-
-        preview_width = state->preview_width;
-        preview_height = state->preview_height;
+        state_proc.mode = state->camera->current_mode;
 
-        device_rotation = state->device_rotation;
+        state_proc.preview_width = state->preview_width;
+        state_proc.preview_height = state->preview_height;
 
-        burst_length = state->burst_length;
+        state_proc.device_rotation = state->device_rotation;
+        state_proc.burst_length = state->burst_length;
 
-        // gain_is_manual = state->gain_is_manual;
-        gain = state->gain;
-        gain_max = state->gain_max;
-        balance[0] = state->balance_red;
-        balance[2] = state->balance_blue;
+        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;
 
         exposure_is_manual = state->exposure_is_manual;
         exposure = state->exposure;
 
         if (output_changed) {
-                camera_rotation = mod(mode->rotation - device_rotation, 360);
+                state_proc.camera_rotation = mod(
+                        state_proc.mode->rotation - state_proc.device_rotation, 360);
 
                 on_output_changed(format_changed);
         }

+ 1 - 0
src/process_pipeline.h

@@ -7,6 +7,7 @@ typedef struct _GdkSurface GdkSurface;
 
 struct mp_process_pipeline_state {
         libmegapixels_camera *camera;
+        libmegapixels_devconfig *configuration;
 
         int burst_length;
 

+ 25 - 1
src/state.h

@@ -47,6 +47,7 @@ typedef struct cstate {
 } controlstate;
 
 typedef struct state_io {
+        libmegapixels_devconfig *configuration;
         libmegapixels_camera *camera;
         libmegapixels_mode *mode_capture;
         libmegapixels_mode *mode_preview;
@@ -70,4 +71,27 @@ typedef struct state_io {
         int preview_width;
         int preview_height;
         int device_rotation;
-} mp_state_io;
+} mp_state_io;
+
+typedef struct state_proc {
+        libmegapixels_devconfig *configuration;
+        libmegapixels_camera *camera;
+        libmegapixels_mode *mode;
+
+        int burst_length;
+        int captures_remaining;
+        int preview_width;
+        int preview_height;
+
+        // Device orientation in degrees
+        int device_rotation;
+        // Camera orientation as number
+        int camera_rotation;
+
+        bool is_capturing;
+
+        float balance[3];
+        controlstate gain;
+        controlstate exposure;
+        controlstate focus;
+} mp_state_proc;