Add debayering support for all bayer CFAs
This commit is contained in:
parent
c16dbf6810
commit
212e75ed3c
|
@ -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
|
||||
|
||||
|
|
|
@ -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
src/camera.c
32
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)
|
||||
{
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 };
|
||||
|
|
|
@ -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 = {
|
||||
|
|
Loading…
Reference in New Issue