aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab+huawei@kernel.org>2021-11-08 12:16:37 +0000
committerMauro Carvalho Chehab <mchehab+huawei@kernel.org>2021-11-09 09:12:09 +0000
commit9d74b9a088e31b89313ae55d14b5a23cefaf29cf (patch)
treeacee5dfc7023687cc2666cf0da7f511e6f1c374b
parent1af867ab0889b5262a5bbffcb983dd8a9f5ac6f4 (diff)
downloadv4l-utils-9d74b9a088e31b89313ae55d14b5a23cefaf29cf.tar.gz
v4l2grab: use an array for format properties
Instead of hardcoding depth and other per-format properties, place them into an array, in order to make easier to parse. Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
-rw-r--r--contrib/test/v4l2grab.c124
1 files changed, 68 insertions, 56 deletions
diff --git a/contrib/test/v4l2grab.c b/contrib/test/v4l2grab.c
index 899cfc85..b63fadcc 100644
--- a/contrib/test/v4l2grab.c
+++ b/contrib/test/v4l2grab.c
@@ -30,6 +30,8 @@
#define CLEAR_P(x,s) memset((x), 0, s)
#define CLEAR(x) CLEAR_P(&(x), sizeof(x))
+#define ARRAY_SIZE(a) (sizeof(a)/sizeof(*a))
+
static int libv4l = 1;
static int ppm_output = 1;
@@ -63,6 +65,55 @@ static void xioctl(int fh, unsigned long int request, void *arg)
}
}
+struct video_formats {
+ unsigned int pixformat;
+ unsigned int depth;
+ unsigned int y_decimation;
+ unsigned int x_decimation;
+
+ unsigned int is_rgb:1;
+};
+
+static const struct video_formats supported_formats[] = {
+ { V4L2_PIX_FMT_BGR32, 32, 0, 0, 1},
+ { V4L2_PIX_FMT_ABGR32, 32, 0, 0, 1},
+ { V4L2_PIX_FMT_XBGR32, 32, 0, 0, 1},
+ { V4L2_PIX_FMT_RGB32, 32, 0, 0, 1},
+ { V4L2_PIX_FMT_ARGB32, 32, 0, 0, 1},
+ { V4L2_PIX_FMT_XRGB32, 32, 0, 0, 1},
+ { V4L2_PIX_FMT_BGR24, 24, 0, 0, 1},
+ { V4L2_PIX_FMT_RGB24, 24, 0, 0, 1},
+ { V4L2_PIX_FMT_RGB565, 16, 0, 0, 1},
+ { V4L2_PIX_FMT_RGB565X, 16, 0, 0, 1},
+ { V4L2_PIX_FMT_YUYV, 16, 0, 0, 0},
+ { V4L2_PIX_FMT_UYVY, 16, 0, 0, 0},
+ { V4L2_PIX_FMT_YVYU, 16, 0, 0, 0},
+ { V4L2_PIX_FMT_VYUY, 16, 0, 0, 0},
+ { V4L2_PIX_FMT_NV12, 8, 1, 0, 0},
+ { V4L2_PIX_FMT_NV21, 8, 1, 0, 0},
+ { V4L2_PIX_FMT_YUV420, 8, 1, 1, 0},
+ { V4L2_PIX_FMT_YVU420, 8, 1, 1, 0},
+};
+
+static const struct video_formats *video_fmt_props(unsigned int pixformat)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(supported_formats); i++)
+ if (supported_formats[i].pixformat == pixformat)
+ return &supported_formats[i];
+
+ return NULL;
+}
+
+static int is_format_supported(unsigned int pixformat)
+{
+ if (video_fmt_props(pixformat))
+ return 1;
+ return 0;
+
+}
+
/*
* Querycap implementation
*/
@@ -352,6 +403,7 @@ static unsigned int convert_to_rgb24(struct v4l2_format *fmt,
uint32_t width = fmt->fmt.pix.width;
uint32_t height = fmt->fmt.pix.height;
uint32_t bytesperline = fmt->fmt.pix.bytesperline;
+ const struct video_formats *video_fmt;
unsigned char *plane0_start = plane0;
unsigned char *plane1_start = NULL;
unsigned char *plane2_start = NULL;
@@ -370,41 +422,20 @@ static unsigned int convert_to_rgb24(struct v4l2_format *fmt,
else
enc = fmt->fmt.pix.ycbcr_enc;
- switch (fmt->fmt.pix.pixelformat) {
- case V4L2_PIX_FMT_BGR24:
- depth = 24;
- break;
- case V4L2_PIX_FMT_RGB32:
- case V4L2_PIX_FMT_ARGB32:
- case V4L2_PIX_FMT_XRGB32:
- case V4L2_PIX_FMT_BGR32:
- case V4L2_PIX_FMT_ABGR32:
- case V4L2_PIX_FMT_XBGR32:
- depth = 32;
- break;
- case V4L2_PIX_FMT_NV12:
- case V4L2_PIX_FMT_NV21:
- num_planes = 2;
- depth = 8; /* Depth of plane 0 */
- h_dec = 1;
- break;
- case V4L2_PIX_FMT_YUV420:
- case V4L2_PIX_FMT_YVU420:
- num_planes = 3;
- depth = 8; /* Depth of plane 0 */
- h_dec = 1;
- w_dec = 1;
- break;
- case V4L2_PIX_FMT_RGB565:
- case V4L2_PIX_FMT_RGB565X:
- case V4L2_PIX_FMT_YUYV:
- case V4L2_PIX_FMT_UYVY:
- case V4L2_PIX_FMT_YVYU:
- case V4L2_PIX_FMT_VYUY:
- default:
- depth = 16;
- break;
- }
+
+ video_fmt = video_fmt_props(fmt->fmt.pix.pixelformat);
+ if (!video_fmt)
+ return 0;
+
+ depth = video_fmt->depth;
+ h_dec = video_fmt->y_decimation;
+ w_dec = video_fmt->x_decimation;
+
+ if (h_dec)
+ num_planes++;
+
+ if (w_dec)
+ num_planes++;
p_start = p_out;
@@ -1083,32 +1114,13 @@ int main(int argc, char **argv)
libv4l = 0;
ppm_output = 0;
} else {
- switch (fmt.fmt.pix.pixelformat) {
- case V4L2_PIX_FMT_RGB565:
- case V4L2_PIX_FMT_RGB565X:
- case V4L2_PIX_FMT_RGB24:
- case V4L2_PIX_FMT_RGB32:
- case V4L2_PIX_FMT_ARGB32:
- case V4L2_PIX_FMT_XRGB32:
- case V4L2_PIX_FMT_BGR32:
- case V4L2_PIX_FMT_ABGR32:
- case V4L2_PIX_FMT_XBGR32:
- case V4L2_PIX_FMT_YUYV:
- case V4L2_PIX_FMT_UYVY:
- case V4L2_PIX_FMT_YVYU:
- case V4L2_PIX_FMT_VYUY:
- case V4L2_PIX_FMT_NV12:
- case V4L2_PIX_FMT_NV21:
- case V4L2_PIX_FMT_YUV420:
- case V4L2_PIX_FMT_YVU420:
+ if (is_format_supported(fmt.fmt.pix.pixelformat)) {
out_buf = malloc(3 * x_res * y_res);
if (!out_buf) {
perror("Cannot allocate memory");
exit(EXIT_FAILURE);
}
-
- break;
- default:
+ } else {
/* Unknown formats */
if (libv4l) {
char *p = (void *)&fmt.fmt.pix.pixelformat;