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

Add debayering support for all bayer CFAs

Yassine Oudjana 3 éve
szülő
commit
212e75ed3c
6 módosított fájl, 65 hozzáadás és 14 törlés
  1. 1 1
      README.md
  2. 8 2
      data/debayer.frag
  3. 32 0
      src/camera.c
  4. 1 0
      src/camera.h
  5. 8 4
      src/gles2_debayer.c
  6. 15 7
      src/process_pipeline.c

+ 1 - 1
README.md

@@ -60,7 +60,7 @@ when previewing.
 
 * `width=640` and `height=480` the resolution to use for the sensor
 * `rate=15` the refresh rate in fps to use for the sensor
-* `fmt=BGGR8` sets the pixel and bus formats used when capturing from the sensor, only BGGR8 is fully supported
+* `fmt=BGGR8` sets the pixel and bus formats used when capturing from the sensor.
 
 # Post processing
 

+ 8 - 2
data/debayer.frag

@@ -44,9 +44,15 @@ main()
                             texture2D(texture, bottom_right_uv).r);
 #endif
 
-        // Assume BGGR for now. Currently this just takes 3 of the four samples
-        // for each pixel, there's room here to do some better debayering.
+#if defined(CFA_BGGR)
         vec3 color = vec3(samples.w, (samples.y + samples.z) / 2.0, samples.x);
+#elif defined(CFA_GBRG)
+        vec3 color = vec3(samples.z, (samples.x + samples.w) / 2.0, samples.y);
+#elif defined(CFA_GRBG)
+        vec3 color = vec3(samples.y, (samples.x + samples.w) / 2.0, samples.z);
+#else
+        vec3 color = vec3(samples.x, (samples.y + samples.z) / 2.0, samples.w);
+#endif
 
         // Some crude blacklevel correction to make the preview a bit nicer, this
         // should be an uniform

+ 32 - 0
src/camera.c

@@ -144,6 +144,38 @@ mp_pixel_format_pixel_depth(MPPixelFormat pixel_format)
         }
 }
 
+const char *
+mp_pixel_format_cfa(MPPixelFormat pixel_format)
+{
+        g_return_val_if_fail(pixel_format < MP_PIXEL_FMT_MAX, 0);
+        switch (pixel_format) {
+        case MP_PIXEL_FMT_BGGR8:
+        case MP_PIXEL_FMT_BGGR10P:
+                return "BGGR";
+                break;
+        case MP_PIXEL_FMT_GBRG8:
+        case MP_PIXEL_FMT_GBRG10P:
+                return "GBRG";
+                break;
+        case MP_PIXEL_FMT_GRBG8:
+        case MP_PIXEL_FMT_GRBG10P:
+                return "GRBG";
+                break;
+        case MP_PIXEL_FMT_RGGB8:
+        case MP_PIXEL_FMT_RGGB10P:
+                return "RGGB";
+                break;
+        case MP_PIXEL_FMT_UYVY:
+                return "UYUV";
+                break;
+        case MP_PIXEL_FMT_YUYV:
+                return "YUYV";
+                break;
+        default:
+                return "unsupported";
+        }
+}
+
 uint32_t
 mp_pixel_format_width_to_bytes(MPPixelFormat pixel_format, uint32_t width)
 {

+ 1 - 0
src/camera.h

@@ -31,6 +31,7 @@ uint32_t mp_pixel_format_to_v4l_bus_code(MPPixelFormat pixel_format);
 
 uint32_t mp_pixel_format_bits_per_pixel(MPPixelFormat pixel_format);
 uint32_t mp_pixel_format_pixel_depth(MPPixelFormat pixel_format);
+const char *mp_pixel_format_cfa(MPPixelFormat pixel_format);
 uint32_t mp_pixel_format_width_to_bytes(MPPixelFormat pixel_format, uint32_t width);
 uint32_t mp_pixel_format_width_to_colors(MPPixelFormat pixel_format, uint32_t width);
 uint32_t mp_pixel_format_height_to_colors(MPPixelFormat pixel_format,

+ 8 - 4
src/gles2_debayer.c

@@ -24,7 +24,10 @@ struct _GLES2Debayer {
 GLES2Debayer *
 gles2_debayer_new(MPPixelFormat format)
 {
-        if (format != MP_PIXEL_FMT_BGGR8 && format != MP_PIXEL_FMT_BGGR10P) {
+        if (format != MP_PIXEL_FMT_BGGR8 && format != MP_PIXEL_FMT_GBRG8 &&
+            format != MP_PIXEL_FMT_GRBG8 && format != MP_PIXEL_FMT_RGGB8 &&
+            format != MP_PIXEL_FMT_BGGR10P && format != MP_PIXEL_FMT_GBRG10P &&
+            format != MP_PIXEL_FMT_GRBG10P && format != MP_PIXEL_FMT_RGGB10P) {
                 return NULL;
         }
 
@@ -32,10 +35,11 @@ gles2_debayer_new(MPPixelFormat format)
         glGenFramebuffers(1, &frame_buffer);
         check_gl();
 
-        char format_def[32];
+        char format_def[64];
         snprintf(format_def,
-                 32,
-                 "#define BITS_%d\n",
+                 64,
+                 "#define CFA_%s\n#define BITS_%d\n",
+                 mp_pixel_format_cfa(format),
                  mp_pixel_format_bits_per_pixel(format));
 
         const GLchar *def[1] = { format_def };

+ 15 - 7
src/process_pipeline.c

@@ -224,14 +224,9 @@ init_gl(MPPipeline *pipeline, GdkSurface **surface)
                 check_gl();
         }
 
-        gles2_debayer = gles2_debayer_new(MP_PIXEL_FMT_BGGR8);
-        check_gl();
-
         glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
         check_gl();
 
-        gles2_debayer_use(gles2_debayer);
-
         for (size_t i = 0; i < NUM_BUFFERS; ++i) {
                 glGenTextures(1, &output_buffers[i].texture_id);
                 glBindTexture(GL_TEXTURE_2D, output_buffers[i].texture_id);
@@ -718,7 +713,7 @@ mp_process_pipeline_capture()
 }
 
 static void
-on_output_changed()
+on_output_changed(bool format_changed)
 {
         output_buffer_width = mode.width / 2;
         output_buffer_height = mode.height / 2;
@@ -744,6 +739,17 @@ on_output_changed()
 
         glBindTexture(GL_TEXTURE_2D, 0);
 
+        // Create new gles2_debayer on format change
+        if (format_changed) {
+                if (gles2_debayer)
+                        gles2_debayer_free(gles2_debayer);
+
+                gles2_debayer = gles2_debayer_new(mode.pixel_format);
+                check_gl();
+
+                gles2_debayer_use(gles2_debayer);
+        }
+
         gles2_debayer_configure(
                 gles2_debayer,
                 output_buffer_width,
@@ -772,6 +778,8 @@ update_state(MPPipeline *pipeline, const struct mp_process_pipeline_state *state
                 preview_height != state->preview_height ||
                 device_rotation != state->device_rotation;
 
+        const bool format_changed = mode.pixel_format != state->mode.pixel_format;
+
         camera = state->camera;
         mode = state->mode;
 
@@ -793,7 +801,7 @@ update_state(MPPipeline *pipeline, const struct mp_process_pipeline_state *state
         if (output_changed) {
                 camera_rotation = mod(camera->rotate - device_rotation, 360);
 
-                on_output_changed();
+                on_output_changed(format_changed);
         }
 
         struct mp_main_state main_state = {