Add debayering support for all bayer CFAs

This commit is contained in:
Yassine Oudjana 2022-01-17 17:05:51 +04:00
parent c16dbf6810
commit 212e75ed3c
6 changed files with 65 additions and 14 deletions

View File

@ -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

View File

@ -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

View File

@ -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)
{

View File

@ -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,

View File

@ -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 };

View File

@ -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 = {