Forráskód Böngészése

Add a switch between SRGB and linear colors in the debayer shader

Martijn Braam 1 éve
szülő
commit
128a3696c4
6 módosított fájl, 20 hozzáadás és 13 törlés
  1. 4 6
      data/debayer.frag
  2. 7 5
      src/gles2_debayer.c
  3. 1 1
      src/gles2_debayer.h
  4. 4 0
      src/io_pipeline.c
  5. 2 1
      src/process_pipeline.c
  6. 2 0
      src/state.h

+ 4 - 6
data/debayer.frag

@@ -62,15 +62,13 @@ main()
         // should be an uniform
         vec3 corrected = color - 0.02;
 
-        // Apply the color matrices
-        // vec3 corrected = color_matrix * color2;
-
+#ifdef COLORSPACE_RAW
         // Fast SRGB estimate. See https://mimosa-pudica.net/fast-gamma/
         vec3 srgb_color =
                 (vec3(1.138) * inversesqrt(corrected) - vec3(0.138)) * corrected;
 
-        // Slow SRGB estimate
-        // vec3 srgb_color = pow(color, vec3(1.0 / 2.2));
-
         gl_FragColor = vec4(srgb_color, 1);
+#elif COLORSPACE_SRGB
+        gl_FragColor = vec4(color, 1);
+#endif
 }

+ 7 - 5
src/gles2_debayer.c

@@ -23,7 +23,7 @@ struct _GLES2Debayer {
 };
 
 GLES2Debayer *
-gles2_debayer_new(int format)
+gles2_debayer_new(int format, uint32_t colorspace)
 {
         uint32_t pixfmt = libmegapixels_format_to_v4l_pixfmt(format);
         if (pixfmt != V4L2_PIX_FMT_SBGGR8 && pixfmt != V4L2_PIX_FMT_SGBRG8 &&
@@ -37,12 +37,14 @@ gles2_debayer_new(int format)
         glGenFramebuffers(1, &frame_buffer);
         check_gl();
 
-        char format_def[64];
+        char format_def[96];
+        bool is_srgb = colorspace == V4L2_COLORSPACE_SRGB;
         snprintf(format_def,
-                 64,
-                 "#define CFA_%s\n#define BITS_%d\n",
+                 96,
+                 "#define CFA_%s\n#define BITS_%d\n#define COLORSPACE_%s\n",
                  libmegapixels_format_cfa(format),
-                 libmegapixels_format_bits_per_pixel(format));
+                 libmegapixels_format_bits_per_pixel(format),
+                 is_srgb ? "SRGB" : "RAW");
 
         const GLchar *def[1] = { format_def };
 

+ 1 - 1
src/gles2_debayer.h

@@ -5,7 +5,7 @@
 
 typedef struct _GLES2Debayer GLES2Debayer;
 
-GLES2Debayer *gles2_debayer_new(int format);
+GLES2Debayer *gles2_debayer_new(int format, uint32_t colorspace);
 void gles2_debayer_free(GLES2Debayer *self);
 
 void gles2_debayer_use(GLES2Debayer *self);

+ 4 - 0
src/io_pipeline.c

@@ -81,6 +81,7 @@ update_process_pipeline()
                 .preview_width = state_io.preview_width,
                 .preview_height = state_io.preview_height,
                 .device_rotation = state_io.device_rotation,
+                .colorspace = state_io.colorspace,
 
                 .gain.control = state_io.gain.control,
                 .gain.auto_control = state_io.gain.auto_control,
@@ -144,6 +145,7 @@ capture(MPPipeline *pipeline, const void *data)
         mp_camera_stop_capture(mpcamera);
         struct v4l2_format format = { 0 };
         libmegapixels_select_mode(state_io.camera, state_io.mode_capture, &format);
+        state_io.colorspace = format.fmt.pix.colorspace;
         state_io.flush_pipeline = true;
 
         mp_camera_start_capture(mpcamera);
@@ -326,6 +328,7 @@ on_frame(MPBuffer buffer, void *_data)
                         struct v4l2_format format = { 0 };
                         libmegapixels_select_mode(
                                 state_io.camera, state_io.mode_preview, &format);
+                        state_io.colorspace = format.fmt.pix.colorspace;
                         state_io.flush_pipeline = true;
 
                         mp_camera_start_capture(mpcamera);
@@ -498,6 +501,7 @@ update_state(MPPipeline *pipeline, const mp_state_io *new_state)
                                 libmegapixels_select_mode(state_io.camera,
                                                           state_io.mode_preview,
                                                           &format);
+                                state_io.colorspace = format.fmt.pix.colorspace;
                         }
 
                         mp_camera_start_capture(mpcamera);

+ 2 - 1
src/process_pipeline.c

@@ -927,7 +927,7 @@ on_output_changed(bool format_changed)
                 if (gles2_debayer)
                         gles2_debayer_free(gles2_debayer);
 
-                gles2_debayer = gles2_debayer_new(state_proc.mode->format);
+                gles2_debayer = gles2_debayer_new(state_proc.mode->format, state_proc.colorspace);
                 check_gl();
 
                 gles2_debayer_use(gles2_debayer);
@@ -990,6 +990,7 @@ update_state(MPPipeline *pipeline, const mp_state_proc *new_state)
         }
 
         state_proc.mode = new_state->camera->current_mode;
+        state_proc.colorspace = new_state->colorspace;
 
         state_proc.preview_width = new_state->preview_width;
         state_proc.preview_height = new_state->preview_height;

+ 2 - 0
src/state.h

@@ -51,6 +51,7 @@ typedef struct state_io {
         int captures_remaining;
         bool flush_pipeline;
         int blank_frame_count;
+        uint32_t colorspace;
 
         // Control state
         controlstate gain;
@@ -79,6 +80,7 @@ typedef struct state_proc {
         int counter;
         int preview_width;
         int preview_height;
+        uint32_t colorspace;
 
         // Device orientation in degrees
         int device_rotation;