Implement YUV preview

This commit is contained in:
Martijn Braam 2020-11-09 15:44:18 +01:00
parent f36b17f5f6
commit cd7cd8b177
4 changed files with 92 additions and 9 deletions

43
main.c
View File

@ -18,7 +18,7 @@
#include <locale.h>
#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);
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);

View File

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

View File

@ -4,7 +4,7 @@
*/
#include <linux/videodev2.h>
#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);
}

View File

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