Jelajahi Sumber

Add support for BGGR10P debayering

Yassine Oudjana 3 tahun lalu
induk
melakukan
c16dbf6810
3 mengubah file dengan 50 tambahan dan 5 penghapusan
  1. 24 1
      data/debayer.frag
  2. 25 3
      src/gles2_debayer.c
  3. 1 1
      src/process_pipeline.c

+ 24 - 1
data/debayer.frag

@@ -1,25 +1,48 @@
 #ifdef GL_ES
-precision mediump float;
+precision highp float;
 #endif
 
 uniform sampler2D texture;
 uniform mat3 color_matrix;
+#ifdef BITS_10
+uniform float row_length;
+#endif
 
 varying vec2 top_left_uv;
 varying vec2 top_right_uv;
 varying vec2 bottom_left_uv;
 varying vec2 bottom_right_uv;
 
+#ifdef BITS_10
+vec2
+skip_5th_pixel(vec2 uv)
+{
+        vec2 new_uv = uv;
+
+        new_uv.x *= 0.8;
+        new_uv.x += floor(uv.x * row_length / 5.0) / row_length;
+
+        return new_uv;
+}
+#endif
+
 void
 main()
 {
         // Note the coordinates for texture samples need to be a varying, as the
         // Mali-400 has this as a fast path allowing 32-bit floats. Otherwise
         // they end up as 16-bit floats and that's not accurate enough.
+#ifdef BITS_10
+        vec4 samples = vec4(texture2D(texture, skip_5th_pixel(top_left_uv)).r,
+                            texture2D(texture, skip_5th_pixel(top_right_uv)).r,
+                            texture2D(texture, skip_5th_pixel(bottom_left_uv)).r,
+                            texture2D(texture, skip_5th_pixel(bottom_right_uv)).r);
+#else
         vec4 samples = vec4(texture2D(texture, top_left_uv).r,
                             texture2D(texture, top_right_uv).r,
                             texture2D(texture, bottom_left_uv).r,
                             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.

+ 25 - 3
src/gles2_debayer.c

@@ -8,12 +8,15 @@
 #define TEX_COORD_ATTRIBUTE 1
 
 struct _GLES2Debayer {
+        MPPixelFormat format;
+
         GLuint frame_buffer;
         GLuint program;
         GLuint uniform_transform;
         GLuint uniform_pixel_size;
         GLuint uniform_texture;
         GLuint uniform_color_matrix;
+        GLuint uniform_row_length;
 
         GLuint quad;
 };
@@ -21,7 +24,7 @@ struct _GLES2Debayer {
 GLES2Debayer *
 gles2_debayer_new(MPPixelFormat format)
 {
-        if (format != MP_PIXEL_FMT_BGGR8) {
+        if (format != MP_PIXEL_FMT_BGGR8 && format != MP_PIXEL_FMT_BGGR10P) {
                 return NULL;
         }
 
@@ -29,6 +32,14 @@ gles2_debayer_new(MPPixelFormat format)
         glGenFramebuffers(1, &frame_buffer);
         check_gl();
 
+        char format_def[32];
+        snprintf(format_def,
+                 32,
+                 "#define BITS_%d\n",
+                 mp_pixel_format_bits_per_pixel(format));
+
+        const GLchar *def[1] = { format_def };
+
         GLuint shaders[] = {
                 gl_util_load_shader("/org/postmarketos/Megapixels/debayer.vert",
                                     GL_VERTEX_SHADER,
@@ -36,8 +47,8 @@ gles2_debayer_new(MPPixelFormat format)
                                     0),
                 gl_util_load_shader("/org/postmarketos/Megapixels/debayer.frag",
                                     GL_FRAGMENT_SHADER,
-                                    NULL,
-                                    0),
+                                    def,
+                                    1),
         };
 
         GLuint program = gl_util_link_program(shaders, 2);
@@ -46,6 +57,8 @@ gles2_debayer_new(MPPixelFormat format)
         check_gl();
 
         GLES2Debayer *self = malloc(sizeof(GLES2Debayer));
+        self->format = format;
+
         self->frame_buffer = frame_buffer;
         self->program = program;
 
@@ -54,6 +67,9 @@ gles2_debayer_new(MPPixelFormat format)
         self->uniform_texture = glGetUniformLocation(self->program, "texture");
         self->uniform_color_matrix =
                 glGetUniformLocation(self->program, "color_matrix");
+        if (mp_pixel_format_bits_per_pixel(self->format) == 10)
+                self->uniform_row_length =
+                        glGetUniformLocation(self->program, "row_length");
         check_gl();
 
         self->quad = gl_util_new_quad();
@@ -135,6 +151,12 @@ gles2_debayer_configure(GLES2Debayer *self,
                         self->uniform_color_matrix, 1, GL_FALSE, identity);
         }
         check_gl();
+
+        if (mp_pixel_format_bits_per_pixel(self->format) == 10) {
+                assert(src_width % 4 == 0);
+                glUniform1f(self->uniform_row_length, src_width + src_width / 4);
+                check_gl();
+        }
 }
 
 void

+ 1 - 1
src/process_pipeline.c

@@ -297,7 +297,7 @@ process_image_for_preview(const uint8_t *image)
         glTexImage2D(GL_TEXTURE_2D,
                      0,
                      GL_LUMINANCE,
-                     mode.width,
+                     mp_pixel_format_width_to_bytes(mode.pixel_format, mode.width),
                      mode.height,
                      0,
                      GL_LUMINANCE,