diff --git a/main.c b/main.c index 4f71623..8eb0b28 100644 --- a/main.c +++ b/main.c @@ -18,7 +18,7 @@ #include #include "config.h" #include "ini.h" -#include "quickdebayer.h" +#include "quickpreview.h" #define NUM_CAMERAS 5 @@ -609,16 +609,48 @@ process_image(const int *p, int size) static const float neutral[] = {1.0, 1.0, 1.0}; static uint16_t isospeed[] = {0}; + /* + int sizing = -1; + + switch(current.fmt) { + case V4L2_PIX_FMT_SBGGR8: + case V4L2_PIX_FMT_SGBRG8: + case V4L2_PIX_FMT_SGRBG8: + case V4L2_PIX_FMT_SRGGB8: + sizing = 1; + break; + case V4L2_PIX_FMT_UYVY: + sizing = 2; + break; + } + */ + // Only process preview frames when not capturing if (capture == 0) { - if(current.width > 1280) { + if(current.width > 1920) { skip = 3; } + if(current.width > 1281) { + skip = 2; + } pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, current.width / (skip*2), current.height / (skip*2)); pixels = gdk_pixbuf_get_pixels(pixbuf); - quick_debayer((const uint8_t *)p, pixels, current.fmt, - current.width, current.height, skip, - current.blacklevel); + + switch(current.fmt) { + case V4L2_PIX_FMT_SBGGR8: + case V4L2_PIX_FMT_SGBRG8: + case V4L2_PIX_FMT_SGRBG8: + case V4L2_PIX_FMT_SRGGB8: + quick_debayer((const uint8_t *)p, pixels, current.fmt, + current.width, current.height, skip, + current.blacklevel); + break; + case V4L2_PIX_FMT_UYVY: + case V4L2_PIX_FMT_YUYV: + quick_yuv2rgb((const uint8_t *)p, pixels, current.fmt, + current.width, current.height, skip); + break; + } if (current.rotate == 0) { pixbufrot = pixbuf; @@ -905,8 +937,8 @@ get_frame() } errno_exit("select"); } else if (r == 0) { - fprintf(stderr, "select timeout\\n"); - exit(EXIT_FAILURE); + g_printerr("get_frame: select timeout\n"); + return TRUE; } if (read_frame(current.video_fd)) { @@ -991,6 +1023,9 @@ config_ini_handler(void *user, const char *section, const char *name, } else if (strcmp(value, "GBRG8") == 0) { cc->fmt = V4L2_PIX_FMT_SGBRG8; cc->mbus = MEDIA_BUS_FMT_SGBRG8_1X8; + } else if (strcmp(value, "UYVY") == 0) { + cc->fmt = V4L2_PIX_FMT_UYVY; + cc->mbus = MEDIA_BUS_FMT_UYVY8_2X8; } else { g_printerr("Unsupported pixelformat %s\n", value); exit(1); diff --git a/meson.build b/meson.build index ce4bc1b..3cc25ca 100644 --- a/meson.build +++ b/meson.build @@ -15,7 +15,7 @@ configure_file( output: 'config.h', configuration: conf ) -executable('megapixels', 'main.c', 'ini.c', 'quickdebayer.c', resources, dependencies : [gtkdep, libm, tiff], install : true) +executable('megapixels', 'main.c', 'ini.c', 'quickpreview.c', resources, dependencies : [gtkdep, libm, tiff], install : true) install_data(['data/org.postmarketos.Megapixels.desktop'], install_dir : get_option('datadir') / 'applications') diff --git a/quickdebayer.c b/quickpreview.c similarity index 72% rename from quickdebayer.c rename to quickpreview.c index 7b4f8c7..dad02fc 100644 --- a/quickdebayer.c +++ b/quickpreview.c @@ -4,7 +4,7 @@ */ #include -#include "quickdebayer.h" +#include "quickpreview.h" /* Linear -> sRGB lookup table */ static const int srgb[] = { @@ -82,3 +82,48 @@ void quick_debayer(const uint8_t *source, uint8_t *destination, } } while (i < input_size); } + + +// YUV format to RGB, currently only extracts the Y channel for a grayscale preview +void quick_yuv2rgb(const uint8_t *source, uint8_t *destination, + uint32_t pix_fmt, int width, int height, int skip) +{ + int stride = width * 2; + int pixelsize = 4; + int input_size = width * 2 * height; + int i = 0, j = 0; + int row_left = stride; + uint8_t Y1, Y2, U, V; + do { + switch (pix_fmt) { + case V4L2_PIX_FMT_UYVY: + Y1 = source[i+1]; + Y2 = source[i+3]; + U = source[i]; + V = source[i+2]; + break; + case V4L2_PIX_FMT_YUYV: + Y1 = source[i]; + Y2 = source[i+2]; + U = source[i+1]; + V = source[i+3]; + break; + } + destination[j] = Y1; + destination[j+1] = Y1; + destination[j+2] = Y1; + j += 3; + destination[j] = Y2; + destination[j+1] = Y2; + destination[j+2] = Y2; + j += 3; + + i += pixelsize * skip * 2; + row_left -= (pixelsize * skip * 2); + if(row_left < (pixelsize * skip * 2)){ + i = i + row_left; + row_left = width; + i = i + (stride * skip); + } + } while (i < input_size); +} diff --git a/quickdebayer.h b/quickpreview.h similarity index 57% rename from quickdebayer.h rename to quickpreview.h index b5a0aac..7ee7877 100644 --- a/quickdebayer.h +++ b/quickpreview.h @@ -3,3 +3,6 @@ void quick_debayer(const uint8_t *source, uint8_t *destination, uint32_t pix_fmt, int width, int height, int skip, int blacklevel); + +void quick_yuv2rgb(const uint8_t *source, uint8_t *destination, + uint32_t pix_fmt, int width, int height, int skip);