From 09e112ad08c3776d6f19082842b95ee8c9785559 Mon Sep 17 00:00:00 2001 From: You-Sheng Yang Date: Wed, 24 Mar 2021 17:31:52 +0800 Subject: [PATCH 1/5] vidioc: skip format name/flags filling on kernel >= 4.2 Since all known formats are defined, also removed ifdef-endif preprocessor directives from formats array. Signed-off-by: You-Sheng Yang --- v4l2loopback.c | 20 +- v4l2loopback_formats.h | 1012 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 933 insertions(+), 99 deletions(-) diff --git a/v4l2loopback.c b/v4l2loopback.c index f45c4a56..4faa0421 100644 --- a/v4l2loopback.c +++ b/v4l2loopback.c @@ -795,17 +795,13 @@ static int vidioc_enum_fmt_cap(struct file *file, void *fh, if (f->index) return -EINVAL; if (dev->ready_for_capture) { - const __u32 format = dev->pix_format.pixelformat; - - snprintf(f->description, sizeof(f->description), "[%c%c%c%c]", - (format >> 0) & 0xFF, (format >> 8) & 0xFF, - (format >> 16) & 0xFF, (format >> 24) & 0xFF); - f->pixelformat = dev->pix_format.pixelformat; } else { return -EINVAL; } - f->flags = 0; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0) + v4l_fill_fmtdesc(f); +#endif MARK(); return 0; } @@ -894,10 +890,6 @@ static int vidioc_enum_fmt_out(struct file *file, void *fh, if (NULL == fmt) return -EINVAL; - /* f->flags = ??; */ - snprintf(f->description, sizeof(f->description), "%s", - fmt->name); - f->pixelformat = dev->pix_format.pixelformat; } else { /* fill in a dummy format */ @@ -908,10 +900,10 @@ static int vidioc_enum_fmt_out(struct file *file, void *fh, fmt = &formats[f->index]; f->pixelformat = fmt->fourcc; - snprintf(f->description, sizeof(f->description), "%s", - fmt->name); } - f->flags = 0; +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0) + v4l_fill_fmtdesc(f); +#endif return 0; } diff --git a/v4l2loopback_formats.h b/v4l2loopback_formats.h index 5a29b260..6b5e9b0f 100644 --- a/v4l2loopback_formats.h +++ b/v4l2loopback_formats.h @@ -1,11 +1,671 @@ -static const struct v4l2l_format formats[] = { +#include +#include +#if defined(__KERNEL__) +#include +#endif + +/* Fix build error: initializer element is not constant + * + * See kernel commit ff3c65cb8115 ("media: videodev2.h: Fix shifting signed + * 32-bit value by 31 bits problem"). + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 3, 0) +#undef v4l2_fourcc_be +#define v4l2_fourcc_be(a, b, c, d) (v4l2_fourcc(a, b, c, d) | (1U << 31)) + +/* undefine previously defined symbols so that they will be defined again using + * the correct version of v4l2_fourcc_be. + */ +#if defined(V4L2_PIX_FMT_ARGB555X) +#undef V4L2_PIX_FMT_ARGB555X +#endif +#if defined(V4L2_PIX_FMT_XRGB555X) +#undef V4L2_PIX_FMT_XRGB555X +#endif +#if defined(V4L2_PIX_FMT_Y16_BE) +#undef V4L2_PIX_FMT_Y16_BE +#endif +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 3, 0) */ + +// Generated by: +// $ cd kernel_tree +// $ cat $(grep -l -r -E '#define\s+V4L2_\S+_FMT_.*v4l2_fourcc' include/ drivers/media | sort) +// | sed -n -E '/define V4L2_\S+_FMT_.*v4l2_fourcc/{s/^.*(V4L2_\S+_FMT_\S+)\s+(v4l2_fourcc[^\)]+\)).*$/#ifndef \1\n#define \1 \2\n#endif/;p}' +#ifndef V4L2_PIX_FMT_HEVC_SLICE +#define V4L2_PIX_FMT_HEVC_SLICE v4l2_fourcc('S', '2', '6', '5') +#endif +#ifndef V4L2_PIX_FMT_VP8_FRAME +#define V4L2_PIX_FMT_VP8_FRAME v4l2_fourcc('V', 'P', '8', 'F') +#endif +#ifndef V4L2_PIX_FMT_RGB332 +#define V4L2_PIX_FMT_RGB332 v4l2_fourcc('R', 'G', 'B', '1') +#endif +#ifndef V4L2_PIX_FMT_RGB444 +#define V4L2_PIX_FMT_RGB444 v4l2_fourcc('R', '4', '4', '4') +#endif +#ifndef V4L2_PIX_FMT_ARGB444 +#define V4L2_PIX_FMT_ARGB444 v4l2_fourcc('A', 'R', '1', '2') +#endif +#ifndef V4L2_PIX_FMT_XRGB444 +#define V4L2_PIX_FMT_XRGB444 v4l2_fourcc('X', 'R', '1', '2') +#endif +#ifndef V4L2_PIX_FMT_RGBA444 +#define V4L2_PIX_FMT_RGBA444 v4l2_fourcc('R', 'A', '1', '2') +#endif +#ifndef V4L2_PIX_FMT_RGBX444 +#define V4L2_PIX_FMT_RGBX444 v4l2_fourcc('R', 'X', '1', '2') +#endif +#ifndef V4L2_PIX_FMT_ABGR444 +#define V4L2_PIX_FMT_ABGR444 v4l2_fourcc('A', 'B', '1', '2') +#endif +#ifndef V4L2_PIX_FMT_XBGR444 +#define V4L2_PIX_FMT_XBGR444 v4l2_fourcc('X', 'B', '1', '2') +#endif +#ifndef V4L2_PIX_FMT_BGRA444 +#define V4L2_PIX_FMT_BGRA444 v4l2_fourcc('G', 'A', '1', '2') +#endif +#ifndef V4L2_PIX_FMT_BGRX444 +#define V4L2_PIX_FMT_BGRX444 v4l2_fourcc('B', 'X', '1', '2') +#endif +#ifndef V4L2_PIX_FMT_RGB555 +#define V4L2_PIX_FMT_RGB555 v4l2_fourcc('R', 'G', 'B', 'O') +#endif +#ifndef V4L2_PIX_FMT_ARGB555 +#define V4L2_PIX_FMT_ARGB555 v4l2_fourcc('A', 'R', '1', '5') +#endif +#ifndef V4L2_PIX_FMT_XRGB555 +#define V4L2_PIX_FMT_XRGB555 v4l2_fourcc('X', 'R', '1', '5') +#endif +#ifndef V4L2_PIX_FMT_RGBA555 +#define V4L2_PIX_FMT_RGBA555 v4l2_fourcc('R', 'A', '1', '5') +#endif +#ifndef V4L2_PIX_FMT_RGBX555 +#define V4L2_PIX_FMT_RGBX555 v4l2_fourcc('R', 'X', '1', '5') +#endif +#ifndef V4L2_PIX_FMT_ABGR555 +#define V4L2_PIX_FMT_ABGR555 v4l2_fourcc('A', 'B', '1', '5') +#endif +#ifndef V4L2_PIX_FMT_XBGR555 +#define V4L2_PIX_FMT_XBGR555 v4l2_fourcc('X', 'B', '1', '5') +#endif +#ifndef V4L2_PIX_FMT_BGRA555 +#define V4L2_PIX_FMT_BGRA555 v4l2_fourcc('B', 'A', '1', '5') +#endif +#ifndef V4L2_PIX_FMT_BGRX555 +#define V4L2_PIX_FMT_BGRX555 v4l2_fourcc('B', 'X', '1', '5') +#endif +#ifndef V4L2_PIX_FMT_RGB565 +#define V4L2_PIX_FMT_RGB565 v4l2_fourcc('R', 'G', 'B', 'P') +#endif +#ifndef V4L2_PIX_FMT_RGB555X +#define V4L2_PIX_FMT_RGB555X v4l2_fourcc('R', 'G', 'B', 'Q') +#endif +#ifndef V4L2_PIX_FMT_ARGB555X +#define V4L2_PIX_FMT_ARGB555X v4l2_fourcc_be('A', 'R', '1', '5') +#endif +#ifndef V4L2_PIX_FMT_XRGB555X +#define V4L2_PIX_FMT_XRGB555X v4l2_fourcc_be('X', 'R', '1', '5') +#endif +#ifndef V4L2_PIX_FMT_RGB565X +#define V4L2_PIX_FMT_RGB565X v4l2_fourcc('R', 'G', 'B', 'R') +#endif +#ifndef V4L2_PIX_FMT_BGR666 +#define V4L2_PIX_FMT_BGR666 v4l2_fourcc('B', 'G', 'R', 'H') +#endif +#ifndef V4L2_PIX_FMT_BGR24 +#define V4L2_PIX_FMT_BGR24 v4l2_fourcc('B', 'G', 'R', '3') +#endif +#ifndef V4L2_PIX_FMT_RGB24 +#define V4L2_PIX_FMT_RGB24 v4l2_fourcc('R', 'G', 'B', '3') +#endif +#ifndef V4L2_PIX_FMT_BGR32 +#define V4L2_PIX_FMT_BGR32 v4l2_fourcc('B', 'G', 'R', '4') +#endif +#ifndef V4L2_PIX_FMT_ABGR32 +#define V4L2_PIX_FMT_ABGR32 v4l2_fourcc('A', 'R', '2', '4') +#endif +#ifndef V4L2_PIX_FMT_XBGR32 +#define V4L2_PIX_FMT_XBGR32 v4l2_fourcc('X', 'R', '2', '4') +#endif +#ifndef V4L2_PIX_FMT_BGRA32 +#define V4L2_PIX_FMT_BGRA32 v4l2_fourcc('R', 'A', '2', '4') +#endif +#ifndef V4L2_PIX_FMT_BGRX32 +#define V4L2_PIX_FMT_BGRX32 v4l2_fourcc('R', 'X', '2', '4') +#endif +#ifndef V4L2_PIX_FMT_RGB32 +#define V4L2_PIX_FMT_RGB32 v4l2_fourcc('R', 'G', 'B', '4') +#endif +#ifndef V4L2_PIX_FMT_RGBA32 +#define V4L2_PIX_FMT_RGBA32 v4l2_fourcc('A', 'B', '2', '4') +#endif +#ifndef V4L2_PIX_FMT_RGBX32 +#define V4L2_PIX_FMT_RGBX32 v4l2_fourcc('X', 'B', '2', '4') +#endif +#ifndef V4L2_PIX_FMT_ARGB32 +#define V4L2_PIX_FMT_ARGB32 v4l2_fourcc('B', 'A', '2', '4') +#endif +#ifndef V4L2_PIX_FMT_XRGB32 +#define V4L2_PIX_FMT_XRGB32 v4l2_fourcc('B', 'X', '2', '4') +#endif +#ifndef V4L2_PIX_FMT_GREY +#define V4L2_PIX_FMT_GREY v4l2_fourcc('G', 'R', 'E', 'Y') +#endif +#ifndef V4L2_PIX_FMT_Y4 +#define V4L2_PIX_FMT_Y4 v4l2_fourcc('Y', '0', '4', ' ') +#endif +#ifndef V4L2_PIX_FMT_Y6 +#define V4L2_PIX_FMT_Y6 v4l2_fourcc('Y', '0', '6', ' ') +#endif +#ifndef V4L2_PIX_FMT_Y10 +#define V4L2_PIX_FMT_Y10 v4l2_fourcc('Y', '1', '0', ' ') +#endif +#ifndef V4L2_PIX_FMT_Y12 +#define V4L2_PIX_FMT_Y12 v4l2_fourcc('Y', '1', '2', ' ') +#endif +#ifndef V4L2_PIX_FMT_Y14 +#define V4L2_PIX_FMT_Y14 v4l2_fourcc('Y', '1', '4', ' ') +#endif +#ifndef V4L2_PIX_FMT_Y16 +#define V4L2_PIX_FMT_Y16 v4l2_fourcc('Y', '1', '6', ' ') +#endif +#ifndef V4L2_PIX_FMT_Y16_BE +#define V4L2_PIX_FMT_Y16_BE v4l2_fourcc_be('Y', '1', '6', ' ') +#endif +#ifndef V4L2_PIX_FMT_Y10BPACK +#define V4L2_PIX_FMT_Y10BPACK v4l2_fourcc('Y', '1', '0', 'B') +#endif +#ifndef V4L2_PIX_FMT_Y10P +#define V4L2_PIX_FMT_Y10P v4l2_fourcc('Y', '1', '0', 'P') +#endif +#ifndef V4L2_PIX_FMT_PAL8 +#define V4L2_PIX_FMT_PAL8 v4l2_fourcc('P', 'A', 'L', '8') +#endif +#ifndef V4L2_PIX_FMT_UV8 +#define V4L2_PIX_FMT_UV8 v4l2_fourcc('U', 'V', '8', ' ') +#endif +#ifndef V4L2_PIX_FMT_YUYV +#define V4L2_PIX_FMT_YUYV v4l2_fourcc('Y', 'U', 'Y', 'V') +#endif +#ifndef V4L2_PIX_FMT_YYUV +#define V4L2_PIX_FMT_YYUV v4l2_fourcc('Y', 'Y', 'U', 'V') +#endif +#ifndef V4L2_PIX_FMT_YVYU +#define V4L2_PIX_FMT_YVYU v4l2_fourcc('Y', 'V', 'Y', 'U') +#endif +#ifndef V4L2_PIX_FMT_UYVY +#define V4L2_PIX_FMT_UYVY v4l2_fourcc('U', 'Y', 'V', 'Y') +#endif +#ifndef V4L2_PIX_FMT_VYUY +#define V4L2_PIX_FMT_VYUY v4l2_fourcc('V', 'Y', 'U', 'Y') +#endif +#ifndef V4L2_PIX_FMT_Y41P +#define V4L2_PIX_FMT_Y41P v4l2_fourcc('Y', '4', '1', 'P') +#endif +#ifndef V4L2_PIX_FMT_YUV444 +#define V4L2_PIX_FMT_YUV444 v4l2_fourcc('Y', '4', '4', '4') +#endif +#ifndef V4L2_PIX_FMT_YUV555 +#define V4L2_PIX_FMT_YUV555 v4l2_fourcc('Y', 'U', 'V', 'O') +#endif +#ifndef V4L2_PIX_FMT_YUV565 +#define V4L2_PIX_FMT_YUV565 v4l2_fourcc('Y', 'U', 'V', 'P') +#endif +#ifndef V4L2_PIX_FMT_YUV32 +#define V4L2_PIX_FMT_YUV32 v4l2_fourcc('Y', 'U', 'V', '4') +#endif +#ifndef V4L2_PIX_FMT_AYUV32 +#define V4L2_PIX_FMT_AYUV32 v4l2_fourcc('A', 'Y', 'U', 'V') +#endif +#ifndef V4L2_PIX_FMT_XYUV32 +#define V4L2_PIX_FMT_XYUV32 v4l2_fourcc('X', 'Y', 'U', 'V') +#endif +#ifndef V4L2_PIX_FMT_VUYA32 +#define V4L2_PIX_FMT_VUYA32 v4l2_fourcc('V', 'U', 'Y', 'A') +#endif +#ifndef V4L2_PIX_FMT_VUYX32 +#define V4L2_PIX_FMT_VUYX32 v4l2_fourcc('V', 'U', 'Y', 'X') +#endif +#ifndef V4L2_PIX_FMT_M420 +#define V4L2_PIX_FMT_M420 v4l2_fourcc('M', '4', '2', '0') +#endif +#ifndef V4L2_PIX_FMT_NV12 +#define V4L2_PIX_FMT_NV12 v4l2_fourcc('N', 'V', '1', '2') +#endif +#ifndef V4L2_PIX_FMT_NV21 +#define V4L2_PIX_FMT_NV21 v4l2_fourcc('N', 'V', '2', '1') +#endif +#ifndef V4L2_PIX_FMT_NV16 +#define V4L2_PIX_FMT_NV16 v4l2_fourcc('N', 'V', '1', '6') +#endif +#ifndef V4L2_PIX_FMT_NV61 +#define V4L2_PIX_FMT_NV61 v4l2_fourcc('N', 'V', '6', '1') +#endif +#ifndef V4L2_PIX_FMT_NV24 +#define V4L2_PIX_FMT_NV24 v4l2_fourcc('N', 'V', '2', '4') +#endif +#ifndef V4L2_PIX_FMT_NV42 +#define V4L2_PIX_FMT_NV42 v4l2_fourcc('N', 'V', '4', '2') +#endif +#ifndef V4L2_PIX_FMT_HM12 +#define V4L2_PIX_FMT_HM12 v4l2_fourcc('H', 'M', '1', '2') +#endif +#ifndef V4L2_PIX_FMT_NV12M +#define V4L2_PIX_FMT_NV12M v4l2_fourcc('N', 'M', '1', '2') +#endif +#ifndef V4L2_PIX_FMT_NV21M +#define V4L2_PIX_FMT_NV21M v4l2_fourcc('N', 'M', '2', '1') +#endif +#ifndef V4L2_PIX_FMT_NV16M +#define V4L2_PIX_FMT_NV16M v4l2_fourcc('N', 'M', '1', '6') +#endif +#ifndef V4L2_PIX_FMT_NV61M +#define V4L2_PIX_FMT_NV61M v4l2_fourcc('N', 'M', '6', '1') +#endif +#ifndef V4L2_PIX_FMT_NV12MT +#define V4L2_PIX_FMT_NV12MT v4l2_fourcc('T', 'M', '1', '2') +#endif +#ifndef V4L2_PIX_FMT_NV12MT_16X16 +#define V4L2_PIX_FMT_NV12MT_16X16 v4l2_fourcc('V', 'M', '1', '2') +#endif +#ifndef V4L2_PIX_FMT_YUV410 +#define V4L2_PIX_FMT_YUV410 v4l2_fourcc('Y', 'U', 'V', '9') +#endif +#ifndef V4L2_PIX_FMT_YVU410 +#define V4L2_PIX_FMT_YVU410 v4l2_fourcc('Y', 'V', 'U', '9') +#endif +#ifndef V4L2_PIX_FMT_YUV411P +#define V4L2_PIX_FMT_YUV411P v4l2_fourcc('4', '1', '1', 'P') +#endif +#ifndef V4L2_PIX_FMT_YUV420 +#define V4L2_PIX_FMT_YUV420 v4l2_fourcc('Y', 'U', '1', '2') +#endif +#ifndef V4L2_PIX_FMT_YVU420 +#define V4L2_PIX_FMT_YVU420 v4l2_fourcc('Y', 'V', '1', '2') +#endif +#ifndef V4L2_PIX_FMT_YUV422P +#define V4L2_PIX_FMT_YUV422P v4l2_fourcc('4', '2', '2', 'P') +#endif +#ifndef V4L2_PIX_FMT_YUV420M +#define V4L2_PIX_FMT_YUV420M v4l2_fourcc('Y', 'M', '1', '2') +#endif +#ifndef V4L2_PIX_FMT_YVU420M +#define V4L2_PIX_FMT_YVU420M v4l2_fourcc('Y', 'M', '2', '1') +#endif +#ifndef V4L2_PIX_FMT_YUV422M +#define V4L2_PIX_FMT_YUV422M v4l2_fourcc('Y', 'M', '1', '6') +#endif +#ifndef V4L2_PIX_FMT_YVU422M +#define V4L2_PIX_FMT_YVU422M v4l2_fourcc('Y', 'M', '6', '1') +#endif +#ifndef V4L2_PIX_FMT_YUV444M +#define V4L2_PIX_FMT_YUV444M v4l2_fourcc('Y', 'M', '2', '4') +#endif +#ifndef V4L2_PIX_FMT_YVU444M +#define V4L2_PIX_FMT_YVU444M v4l2_fourcc('Y', 'M', '4', '2') +#endif +#ifndef V4L2_PIX_FMT_SBGGR8 +#define V4L2_PIX_FMT_SBGGR8 v4l2_fourcc('B', 'A', '8', '1') +#endif +#ifndef V4L2_PIX_FMT_SGBRG8 +#define V4L2_PIX_FMT_SGBRG8 v4l2_fourcc('G', 'B', 'R', 'G') +#endif +#ifndef V4L2_PIX_FMT_SGRBG8 +#define V4L2_PIX_FMT_SGRBG8 v4l2_fourcc('G', 'R', 'B', 'G') +#endif +#ifndef V4L2_PIX_FMT_SRGGB8 +#define V4L2_PIX_FMT_SRGGB8 v4l2_fourcc('R', 'G', 'G', 'B') +#endif +#ifndef V4L2_PIX_FMT_SBGGR10 +#define V4L2_PIX_FMT_SBGGR10 v4l2_fourcc('B', 'G', '1', '0') +#endif +#ifndef V4L2_PIX_FMT_SGBRG10 +#define V4L2_PIX_FMT_SGBRG10 v4l2_fourcc('G', 'B', '1', '0') +#endif +#ifndef V4L2_PIX_FMT_SGRBG10 +#define V4L2_PIX_FMT_SGRBG10 v4l2_fourcc('B', 'A', '1', '0') +#endif +#ifndef V4L2_PIX_FMT_SRGGB10 +#define V4L2_PIX_FMT_SRGGB10 v4l2_fourcc('R', 'G', '1', '0') +#endif +#ifndef V4L2_PIX_FMT_SBGGR10P +#define V4L2_PIX_FMT_SBGGR10P v4l2_fourcc('p', 'B', 'A', 'A') +#endif +#ifndef V4L2_PIX_FMT_SGBRG10P +#define V4L2_PIX_FMT_SGBRG10P v4l2_fourcc('p', 'G', 'A', 'A') +#endif +#ifndef V4L2_PIX_FMT_SGRBG10P +#define V4L2_PIX_FMT_SGRBG10P v4l2_fourcc('p', 'g', 'A', 'A') +#endif +#ifndef V4L2_PIX_FMT_SRGGB10P +#define V4L2_PIX_FMT_SRGGB10P v4l2_fourcc('p', 'R', 'A', 'A') +#endif +#ifndef V4L2_PIX_FMT_SBGGR10ALAW8 +#define V4L2_PIX_FMT_SBGGR10ALAW8 v4l2_fourcc('a', 'B', 'A', '8') +#endif +#ifndef V4L2_PIX_FMT_SGBRG10ALAW8 +#define V4L2_PIX_FMT_SGBRG10ALAW8 v4l2_fourcc('a', 'G', 'A', '8') +#endif +#ifndef V4L2_PIX_FMT_SGRBG10ALAW8 +#define V4L2_PIX_FMT_SGRBG10ALAW8 v4l2_fourcc('a', 'g', 'A', '8') +#endif +#ifndef V4L2_PIX_FMT_SRGGB10ALAW8 +#define V4L2_PIX_FMT_SRGGB10ALAW8 v4l2_fourcc('a', 'R', 'A', '8') +#endif +#ifndef V4L2_PIX_FMT_SBGGR10DPCM8 +#define V4L2_PIX_FMT_SBGGR10DPCM8 v4l2_fourcc('b', 'B', 'A', '8') +#endif +#ifndef V4L2_PIX_FMT_SGBRG10DPCM8 +#define V4L2_PIX_FMT_SGBRG10DPCM8 v4l2_fourcc('b', 'G', 'A', '8') +#endif +#ifndef V4L2_PIX_FMT_SGRBG10DPCM8 +#define V4L2_PIX_FMT_SGRBG10DPCM8 v4l2_fourcc('B', 'D', '1', '0') +#endif +#ifndef V4L2_PIX_FMT_SRGGB10DPCM8 +#define V4L2_PIX_FMT_SRGGB10DPCM8 v4l2_fourcc('b', 'R', 'A', '8') +#endif +#ifndef V4L2_PIX_FMT_SBGGR12 +#define V4L2_PIX_FMT_SBGGR12 v4l2_fourcc('B', 'G', '1', '2') +#endif +#ifndef V4L2_PIX_FMT_SGBRG12 +#define V4L2_PIX_FMT_SGBRG12 v4l2_fourcc('G', 'B', '1', '2') +#endif +#ifndef V4L2_PIX_FMT_SGRBG12 +#define V4L2_PIX_FMT_SGRBG12 v4l2_fourcc('B', 'A', '1', '2') +#endif +#ifndef V4L2_PIX_FMT_SRGGB12 +#define V4L2_PIX_FMT_SRGGB12 v4l2_fourcc('R', 'G', '1', '2') +#endif +#ifndef V4L2_PIX_FMT_SBGGR12P +#define V4L2_PIX_FMT_SBGGR12P v4l2_fourcc('p', 'B', 'C', 'C') +#endif +#ifndef V4L2_PIX_FMT_SGBRG12P +#define V4L2_PIX_FMT_SGBRG12P v4l2_fourcc('p', 'G', 'C', 'C') +#endif +#ifndef V4L2_PIX_FMT_SGRBG12P +#define V4L2_PIX_FMT_SGRBG12P v4l2_fourcc('p', 'g', 'C', 'C') +#endif +#ifndef V4L2_PIX_FMT_SRGGB12P +#define V4L2_PIX_FMT_SRGGB12P v4l2_fourcc('p', 'R', 'C', 'C') +#endif +#ifndef V4L2_PIX_FMT_SBGGR14 +#define V4L2_PIX_FMT_SBGGR14 v4l2_fourcc('B', 'G', '1', '4') +#endif +#ifndef V4L2_PIX_FMT_SGBRG14 +#define V4L2_PIX_FMT_SGBRG14 v4l2_fourcc('G', 'B', '1', '4') +#endif +#ifndef V4L2_PIX_FMT_SGRBG14 +#define V4L2_PIX_FMT_SGRBG14 v4l2_fourcc('G', 'R', '1', '4') +#endif +#ifndef V4L2_PIX_FMT_SRGGB14 +#define V4L2_PIX_FMT_SRGGB14 v4l2_fourcc('R', 'G', '1', '4') +#endif +#ifndef V4L2_PIX_FMT_SBGGR14P +#define V4L2_PIX_FMT_SBGGR14P v4l2_fourcc('p', 'B', 'E', 'E') +#endif +#ifndef V4L2_PIX_FMT_SGBRG14P +#define V4L2_PIX_FMT_SGBRG14P v4l2_fourcc('p', 'G', 'E', 'E') +#endif +#ifndef V4L2_PIX_FMT_SGRBG14P +#define V4L2_PIX_FMT_SGRBG14P v4l2_fourcc('p', 'g', 'E', 'E') +#endif +#ifndef V4L2_PIX_FMT_SRGGB14P +#define V4L2_PIX_FMT_SRGGB14P v4l2_fourcc('p', 'R', 'E', 'E') +#endif +#ifndef V4L2_PIX_FMT_SBGGR16 +#define V4L2_PIX_FMT_SBGGR16 v4l2_fourcc('B', 'Y', 'R', '2') +#endif +#ifndef V4L2_PIX_FMT_SGBRG16 +#define V4L2_PIX_FMT_SGBRG16 v4l2_fourcc('G', 'B', '1', '6') +#endif +#ifndef V4L2_PIX_FMT_SGRBG16 +#define V4L2_PIX_FMT_SGRBG16 v4l2_fourcc('G', 'R', '1', '6') +#endif +#ifndef V4L2_PIX_FMT_SRGGB16 +#define V4L2_PIX_FMT_SRGGB16 v4l2_fourcc('R', 'G', '1', '6') +#endif +#ifndef V4L2_PIX_FMT_HSV24 +#define V4L2_PIX_FMT_HSV24 v4l2_fourcc('H', 'S', 'V', '3') +#endif +#ifndef V4L2_PIX_FMT_HSV32 +#define V4L2_PIX_FMT_HSV32 v4l2_fourcc('H', 'S', 'V', '4') +#endif +#ifndef V4L2_PIX_FMT_MJPEG +#define V4L2_PIX_FMT_MJPEG v4l2_fourcc('M', 'J', 'P', 'G') +#endif +#ifndef V4L2_PIX_FMT_JPEG +#define V4L2_PIX_FMT_JPEG v4l2_fourcc('J', 'P', 'E', 'G') +#endif +#ifndef V4L2_PIX_FMT_DV +#define V4L2_PIX_FMT_DV v4l2_fourcc('d', 'v', 's', 'd') +#endif +#ifndef V4L2_PIX_FMT_MPEG +#define V4L2_PIX_FMT_MPEG v4l2_fourcc('M', 'P', 'E', 'G') +#endif +#ifndef V4L2_PIX_FMT_H264 +#define V4L2_PIX_FMT_H264 v4l2_fourcc('H', '2', '6', '4') +#endif +#ifndef V4L2_PIX_FMT_H264_NO_SC +#define V4L2_PIX_FMT_H264_NO_SC v4l2_fourcc('A', 'V', 'C', '1') +#endif +#ifndef V4L2_PIX_FMT_H264_MVC +#define V4L2_PIX_FMT_H264_MVC v4l2_fourcc('M', '2', '6', '4') +#endif +#ifndef V4L2_PIX_FMT_H263 +#define V4L2_PIX_FMT_H263 v4l2_fourcc('H', '2', '6', '3') +#endif +#ifndef V4L2_PIX_FMT_MPEG1 +#define V4L2_PIX_FMT_MPEG1 v4l2_fourcc('M', 'P', 'G', '1') +#endif +#ifndef V4L2_PIX_FMT_MPEG2 +#define V4L2_PIX_FMT_MPEG2 v4l2_fourcc('M', 'P', 'G', '2') +#endif +#ifndef V4L2_PIX_FMT_MPEG2_SLICE +#define V4L2_PIX_FMT_MPEG2_SLICE v4l2_fourcc('M', 'G', '2', 'S') +#endif +#ifndef V4L2_PIX_FMT_MPEG4 +#define V4L2_PIX_FMT_MPEG4 v4l2_fourcc('M', 'P', 'G', '4') +#endif +#ifndef V4L2_PIX_FMT_XVID +#define V4L2_PIX_FMT_XVID v4l2_fourcc('X', 'V', 'I', 'D') +#endif +#ifndef V4L2_PIX_FMT_VC1_ANNEX_G +#define V4L2_PIX_FMT_VC1_ANNEX_G v4l2_fourcc('V', 'C', '1', 'G') +#endif +#ifndef V4L2_PIX_FMT_VC1_ANNEX_L +#define V4L2_PIX_FMT_VC1_ANNEX_L v4l2_fourcc('V', 'C', '1', 'L') +#endif +#ifndef V4L2_PIX_FMT_VP8 +#define V4L2_PIX_FMT_VP8 v4l2_fourcc('V', 'P', '8', '0') +#endif #ifndef V4L2_PIX_FMT_VP9 #define V4L2_PIX_FMT_VP9 v4l2_fourcc('V', 'P', '9', '0') #endif #ifndef V4L2_PIX_FMT_HEVC #define V4L2_PIX_FMT_HEVC v4l2_fourcc('H', 'E', 'V', 'C') #endif +#ifndef V4L2_PIX_FMT_FWHT +#define V4L2_PIX_FMT_FWHT v4l2_fourcc('F', 'W', 'H', 'T') +#endif +#ifndef V4L2_PIX_FMT_FWHT_STATELESS +#define V4L2_PIX_FMT_FWHT_STATELESS v4l2_fourcc('S', 'F', 'W', 'H') +#endif +#ifndef V4L2_PIX_FMT_H264_SLICE +#define V4L2_PIX_FMT_H264_SLICE v4l2_fourcc('S', '2', '6', '4') +#endif +#ifndef V4L2_PIX_FMT_CPIA1 +#define V4L2_PIX_FMT_CPIA1 v4l2_fourcc('C', 'P', 'I', 'A') +#endif +#ifndef V4L2_PIX_FMT_WNVA +#define V4L2_PIX_FMT_WNVA v4l2_fourcc('W', 'N', 'V', 'A') +#endif +#ifndef V4L2_PIX_FMT_SN9C10X +#define V4L2_PIX_FMT_SN9C10X v4l2_fourcc('S', '9', '1', '0') +#endif +#ifndef V4L2_PIX_FMT_SN9C20X_I420 +#define V4L2_PIX_FMT_SN9C20X_I420 v4l2_fourcc('S', '9', '2', '0') +#endif +#ifndef V4L2_PIX_FMT_PWC1 +#define V4L2_PIX_FMT_PWC1 v4l2_fourcc('P', 'W', 'C', '1') +#endif +#ifndef V4L2_PIX_FMT_PWC2 +#define V4L2_PIX_FMT_PWC2 v4l2_fourcc('P', 'W', 'C', '2') +#endif +#ifndef V4L2_PIX_FMT_ET61X251 +#define V4L2_PIX_FMT_ET61X251 v4l2_fourcc('E', '6', '2', '5') +#endif +#ifndef V4L2_PIX_FMT_SPCA501 +#define V4L2_PIX_FMT_SPCA501 v4l2_fourcc('S', '5', '0', '1') +#endif +#ifndef V4L2_PIX_FMT_SPCA505 +#define V4L2_PIX_FMT_SPCA505 v4l2_fourcc('S', '5', '0', '5') +#endif +#ifndef V4L2_PIX_FMT_SPCA508 +#define V4L2_PIX_FMT_SPCA508 v4l2_fourcc('S', '5', '0', '8') +#endif +#ifndef V4L2_PIX_FMT_SPCA561 +#define V4L2_PIX_FMT_SPCA561 v4l2_fourcc('S', '5', '6', '1') +#endif +#ifndef V4L2_PIX_FMT_PAC207 +#define V4L2_PIX_FMT_PAC207 v4l2_fourcc('P', '2', '0', '7') +#endif +#ifndef V4L2_PIX_FMT_MR97310A +#define V4L2_PIX_FMT_MR97310A v4l2_fourcc('M', '3', '1', '0') +#endif +#ifndef V4L2_PIX_FMT_JL2005BCD +#define V4L2_PIX_FMT_JL2005BCD v4l2_fourcc('J', 'L', '2', '0') +#endif +#ifndef V4L2_PIX_FMT_SN9C2028 +#define V4L2_PIX_FMT_SN9C2028 v4l2_fourcc('S', 'O', 'N', 'X') +#endif +#ifndef V4L2_PIX_FMT_SQ905C +#define V4L2_PIX_FMT_SQ905C v4l2_fourcc('9', '0', '5', 'C') +#endif +#ifndef V4L2_PIX_FMT_PJPG +#define V4L2_PIX_FMT_PJPG v4l2_fourcc('P', 'J', 'P', 'G') +#endif +#ifndef V4L2_PIX_FMT_OV511 +#define V4L2_PIX_FMT_OV511 v4l2_fourcc('O', '5', '1', '1') +#endif +#ifndef V4L2_PIX_FMT_OV518 +#define V4L2_PIX_FMT_OV518 v4l2_fourcc('O', '5', '1', '8') +#endif +#ifndef V4L2_PIX_FMT_STV0680 +#define V4L2_PIX_FMT_STV0680 v4l2_fourcc('S', '6', '8', '0') +#endif +#ifndef V4L2_PIX_FMT_TM6000 +#define V4L2_PIX_FMT_TM6000 v4l2_fourcc('T', 'M', '6', '0') +#endif +#ifndef V4L2_PIX_FMT_CIT_YYVYUY +#define V4L2_PIX_FMT_CIT_YYVYUY v4l2_fourcc('C', 'I', 'T', 'V') +#endif +#ifndef V4L2_PIX_FMT_KONICA420 +#define V4L2_PIX_FMT_KONICA420 v4l2_fourcc('K', 'O', 'N', 'I') +#endif +#ifndef V4L2_PIX_FMT_JPGL +#define V4L2_PIX_FMT_JPGL v4l2_fourcc('J', 'P', 'G', 'L') +#endif +#ifndef V4L2_PIX_FMT_SE401 +#define V4L2_PIX_FMT_SE401 v4l2_fourcc('S', '4', '0', '1') +#endif +#ifndef V4L2_PIX_FMT_S5C_UYVY_JPG +#define V4L2_PIX_FMT_S5C_UYVY_JPG v4l2_fourcc('S', '5', 'C', 'I') +#endif +#ifndef V4L2_PIX_FMT_Y8I +#define V4L2_PIX_FMT_Y8I v4l2_fourcc('Y', '8', 'I', ' ') +#endif +#ifndef V4L2_PIX_FMT_Y12I +#define V4L2_PIX_FMT_Y12I v4l2_fourcc('Y', '1', '2', 'I') +#endif +#ifndef V4L2_PIX_FMT_Z16 +#define V4L2_PIX_FMT_Z16 v4l2_fourcc('Z', '1', '6', ' ') +#endif +#ifndef V4L2_PIX_FMT_MT21C +#define V4L2_PIX_FMT_MT21C v4l2_fourcc('M', 'T', '2', '1') +#endif +#ifndef V4L2_PIX_FMT_INZI +#define V4L2_PIX_FMT_INZI v4l2_fourcc('I', 'N', 'Z', 'I') +#endif +#ifndef V4L2_PIX_FMT_SUNXI_TILED_NV12 +#define V4L2_PIX_FMT_SUNXI_TILED_NV12 v4l2_fourcc('S', 'T', '1', '2') +#endif +#ifndef V4L2_PIX_FMT_CNF4 +#define V4L2_PIX_FMT_CNF4 v4l2_fourcc('C', 'N', 'F', '4') +#endif +#ifndef V4L2_PIX_FMT_HI240 +#define V4L2_PIX_FMT_HI240 v4l2_fourcc('H', 'I', '2', '4') +#endif +#ifndef V4L2_PIX_FMT_IPU3_SBGGR10 +#define V4L2_PIX_FMT_IPU3_SBGGR10 v4l2_fourcc('i', 'p', '3', 'b') +#endif +#ifndef V4L2_PIX_FMT_IPU3_SGBRG10 +#define V4L2_PIX_FMT_IPU3_SGBRG10 v4l2_fourcc('i', 'p', '3', 'g') +#endif +#ifndef V4L2_PIX_FMT_IPU3_SGRBG10 +#define V4L2_PIX_FMT_IPU3_SGRBG10 v4l2_fourcc('i', 'p', '3', 'G') +#endif +#ifndef V4L2_PIX_FMT_IPU3_SRGGB10 +#define V4L2_PIX_FMT_IPU3_SRGGB10 v4l2_fourcc('i', 'p', '3', 'r') +#endif +#ifndef V4L2_SDR_FMT_CU8 +#define V4L2_SDR_FMT_CU8 v4l2_fourcc('C', 'U', '0', '8') +#endif +#ifndef V4L2_SDR_FMT_CU16LE +#define V4L2_SDR_FMT_CU16LE v4l2_fourcc('C', 'U', '1', '6') +#endif +#ifndef V4L2_SDR_FMT_CS8 +#define V4L2_SDR_FMT_CS8 v4l2_fourcc('C', 'S', '0', '8') +#endif +#ifndef V4L2_SDR_FMT_CS14LE +#define V4L2_SDR_FMT_CS14LE v4l2_fourcc('C', 'S', '1', '4') +#endif +#ifndef V4L2_SDR_FMT_RU12LE +#define V4L2_SDR_FMT_RU12LE v4l2_fourcc('R', 'U', '1', '2') +#endif +#ifndef V4L2_SDR_FMT_PCU16BE +#define V4L2_SDR_FMT_PCU16BE v4l2_fourcc('P', 'C', '1', '6') +#endif +#ifndef V4L2_SDR_FMT_PCU18BE +#define V4L2_SDR_FMT_PCU18BE v4l2_fourcc('P', 'C', '1', '8') +#endif +#ifndef V4L2_SDR_FMT_PCU20BE +#define V4L2_SDR_FMT_PCU20BE v4l2_fourcc('P', 'C', '2', '0') +#endif +#ifndef V4L2_TCH_FMT_DELTA_TD16 +#define V4L2_TCH_FMT_DELTA_TD16 v4l2_fourcc('T', 'D', '1', '6') +#endif +#ifndef V4L2_TCH_FMT_DELTA_TD08 +#define V4L2_TCH_FMT_DELTA_TD08 v4l2_fourcc('T', 'D', '0', '8') +#endif +#ifndef V4L2_TCH_FMT_TU16 +#define V4L2_TCH_FMT_TU16 v4l2_fourcc('T', 'U', '1', '6') +#endif +#ifndef V4L2_TCH_FMT_TU08 +#define V4L2_TCH_FMT_TU08 v4l2_fourcc('T', 'U', '0', '8') +#endif +#ifndef V4L2_META_FMT_VSP1_HGO +#define V4L2_META_FMT_VSP1_HGO v4l2_fourcc('V', 'S', 'P', 'H') +#endif +#ifndef V4L2_META_FMT_VSP1_HGT +#define V4L2_META_FMT_VSP1_HGT v4l2_fourcc('V', 'S', 'P', 'T') +#endif +#ifndef V4L2_META_FMT_UVC +#define V4L2_META_FMT_UVC v4l2_fourcc('U', 'V', 'C', 'H') +#endif +#ifndef V4L2_META_FMT_D4XX +#define V4L2_META_FMT_D4XX v4l2_fourcc('D', '4', 'X', 'X') +#endif +#ifndef V4L2_META_FMT_VIVID +#define V4L2_META_FMT_VIVID v4l2_fourcc('V', 'I', 'V', 'D') +#endif +#ifndef V4L2_META_FMT_RK_ISP1_PARAMS +#define V4L2_META_FMT_RK_ISP1_PARAMS v4l2_fourcc('R', 'K', '1', 'P') +#endif +#ifndef V4L2_META_FMT_RK_ISP1_STAT_3A +#define V4L2_META_FMT_RK_ISP1_STAT_3A v4l2_fourcc('R', 'K', '1', 'S') +#endif +static const struct v4l2l_format formats[] = { /* here come the packed formats */ { .name = "32 bpp RGB, le", @@ -31,62 +691,48 @@ static const struct v4l2l_format formats[] = { .depth = 24, .flags = 0, }, -#ifdef V4L2_PIX_FMT_RGB332 { .name = "8 bpp RGB-3-3-2", .fourcc = V4L2_PIX_FMT_RGB332, .depth = 8, .flags = 0, }, -#endif /* V4L2_PIX_FMT_RGB332 */ -#ifdef V4L2_PIX_FMT_RGB444 { .name = "16 bpp RGB (xxxxrrrr ggggbbbb)", .fourcc = V4L2_PIX_FMT_RGB444, .depth = 16, .flags = 0, }, -#endif /* V4L2_PIX_FMT_RGB444 */ -#ifdef V4L2_PIX_FMT_RGB555 { .name = "16 bpp RGB-5-5-5", .fourcc = V4L2_PIX_FMT_RGB555, .depth = 16, .flags = 0, }, -#endif /* V4L2_PIX_FMT_RGB555 */ -#ifdef V4L2_PIX_FMT_RGB565 { .name = "16 bpp RGB-5-6-5", .fourcc = V4L2_PIX_FMT_RGB565, .depth = 16, .flags = 0, }, -#endif /* V4L2_PIX_FMT_RGB565 */ -#ifdef V4L2_PIX_FMT_RGB555X { .name = "16 bpp RGB-5-5-5 BE", .fourcc = V4L2_PIX_FMT_RGB555X, .depth = 16, .flags = 0, }, -#endif /* V4L2_PIX_FMT_RGB555X */ -#ifdef V4L2_PIX_FMT_RGB565X { .name = "16 bpp RGB-5-6-5 BE", .fourcc = V4L2_PIX_FMT_RGB565X, .depth = 16, .flags = 0, }, -#endif /* V4L2_PIX_FMT_RGB565X */ -#ifdef V4L2_PIX_FMT_BGR666 { .name = "18 bpp BGR-6-6-6", .fourcc = V4L2_PIX_FMT_BGR666, .depth = 18, .flags = 0, }, -#endif /* V4L2_PIX_FMT_BGR666 */ { .name = "4:2:2, packed, YUYV", .fourcc = V4L2_PIX_FMT_YUYV, @@ -99,22 +745,18 @@ static const struct v4l2l_format formats[] = { .depth = 16, .flags = 0, }, -#ifdef V4L2_PIX_FMT_YVYU { .name = "4:2:2, packed YVYU", .fourcc = V4L2_PIX_FMT_YVYU, .depth = 16, .flags = 0, }, -#endif -#ifdef V4L2_PIX_FMT_VYUY { .name = "4:2:2, packed VYUY", .fourcc = V4L2_PIX_FMT_VYUY, .depth = 16, .flags = 0, }, -#endif { .name = "4:2:2, packed YYUV", .fourcc = V4L2_PIX_FMT_YYUV, @@ -133,102 +775,80 @@ static const struct v4l2l_format formats[] = { .depth = 8, .flags = 0, }, -#ifdef V4L2_PIX_FMT_Y4 { .name = "4 bpp Greyscale", .fourcc = V4L2_PIX_FMT_Y4, .depth = 4, .flags = 0, }, -#endif /* V4L2_PIX_FMT_Y4 */ -#ifdef V4L2_PIX_FMT_Y6 { .name = "6 bpp Greyscale", .fourcc = V4L2_PIX_FMT_Y6, .depth = 6, .flags = 0, }, -#endif /* V4L2_PIX_FMT_Y6 */ -#ifdef V4L2_PIX_FMT_Y10 { .name = "10 bpp Greyscale", .fourcc = V4L2_PIX_FMT_Y10, .depth = 10, .flags = 0, }, -#endif /* V4L2_PIX_FMT_Y10 */ -#ifdef V4L2_PIX_FMT_Y12 { .name = "12 bpp Greyscale", .fourcc = V4L2_PIX_FMT_Y12, .depth = 12, .flags = 0, }, -#endif /* V4L2_PIX_FMT_Y12 */ { .name = "16 bpp, Greyscale", .fourcc = V4L2_PIX_FMT_Y16, .depth = 16, .flags = 0, }, -#ifdef V4L2_PIX_FMT_YUV444 { .name = "16 bpp xxxxyyyy uuuuvvvv", .fourcc = V4L2_PIX_FMT_YUV444, .depth = 16, .flags = 0, }, -#endif /* V4L2_PIX_FMT_YUV444 */ -#ifdef V4L2_PIX_FMT_YUV555 { .name = "16 bpp YUV-5-5-5", .fourcc = V4L2_PIX_FMT_YUV555, .depth = 16, .flags = 0, }, -#endif /* V4L2_PIX_FMT_YUV555 */ -#ifdef V4L2_PIX_FMT_YUV565 { .name = "16 bpp YUV-5-6-5", .fourcc = V4L2_PIX_FMT_YUV565, .depth = 16, .flags = 0, }, -#endif /* V4L2_PIX_FMT_YUV565 */ -/* bayer formats */ -#ifdef V4L2_PIX_FMT_SRGGB8 + /* bayer formats */ { .name = "Bayer RGGB 8bit", .fourcc = V4L2_PIX_FMT_SRGGB8, .depth = 8, .flags = 0, }, -#endif /* V4L2_PIX_FMT_SRGGB8 */ -#ifdef V4L2_PIX_FMT_SGRBG8 { .name = "Bayer GRBG 8bit", .fourcc = V4L2_PIX_FMT_SGRBG8, .depth = 8, .flags = 0, }, -#endif /* V4L2_PIX_FMT_SGRBG8 */ -#ifdef V4L2_PIX_FMT_SGBRG8 { .name = "Bayer GBRG 8bit", .fourcc = V4L2_PIX_FMT_SGBRG8, .depth = 8, .flags = 0, }, -#endif /* V4L2_PIX_FMT_SGBRG8 */ -#ifdef V4L2_PIX_FMT_SBGGR8 { .name = "Bayer BA81 8bit", .fourcc = V4L2_PIX_FMT_SBGGR8, .depth = 8, .flags = 0, }, -#endif /* V4L2_PIX_FMT_SBGGR8 */ /* here come the planar formats */ { @@ -255,175 +875,397 @@ static const struct v4l2l_format formats[] = { .depth = 12, .flags = FORMAT_FLAGS_PLANAR, }, -#ifdef V4L2_PIX_FMT_YUV422P { .name = "16 bpp YVU422 planar", .fourcc = V4L2_PIX_FMT_YUV422P, .depth = 16, .flags = FORMAT_FLAGS_PLANAR, }, -#endif /* V4L2_PIX_FMT_YUV422P */ -#ifdef V4L2_PIX_FMT_YUV411P { .name = "16 bpp YVU411 planar", .fourcc = V4L2_PIX_FMT_YUV411P, .depth = 16, .flags = FORMAT_FLAGS_PLANAR, }, -#endif /* V4L2_PIX_FMT_YUV411P */ -#ifdef V4L2_PIX_FMT_Y41P { .name = "12 bpp YUV 4:1:1", .fourcc = V4L2_PIX_FMT_Y41P, .depth = 12, .flags = FORMAT_FLAGS_PLANAR, }, -#endif /* V4L2_PIX_FMT_Y41P */ -#ifdef V4L2_PIX_FMT_NV12 { .name = "12 bpp Y/CbCr 4:2:0 ", .fourcc = V4L2_PIX_FMT_NV12, .depth = 12, .flags = FORMAT_FLAGS_PLANAR, }, -#endif /* V4L2_PIX_FMT_NV12 */ -/* here come the compressed formats */ + /* here come the compressed formats */ -#ifdef V4L2_PIX_FMT_MJPEG { .name = "Motion-JPEG", .fourcc = V4L2_PIX_FMT_MJPEG, .depth = 32, .flags = FORMAT_FLAGS_COMPRESSED, }, -#endif /* V4L2_PIX_FMT_MJPEG */ -#ifdef V4L2_PIX_FMT_JPEG { .name = "JFIF JPEG", .fourcc = V4L2_PIX_FMT_JPEG, .depth = 32, .flags = FORMAT_FLAGS_COMPRESSED, }, -#endif /* V4L2_PIX_FMT_JPEG */ -#ifdef V4L2_PIX_FMT_DV { .name = "DV1394", .fourcc = V4L2_PIX_FMT_DV, .depth = 32, .flags = FORMAT_FLAGS_COMPRESSED, }, -#endif /* V4L2_PIX_FMT_DV */ -#ifdef V4L2_PIX_FMT_MPEG { .name = "MPEG-1/2/4 Multiplexed", .fourcc = V4L2_PIX_FMT_MPEG, .depth = 32, .flags = FORMAT_FLAGS_COMPRESSED, }, -#endif /* V4L2_PIX_FMT_MPEG */ -#ifdef V4L2_PIX_FMT_H264 { .name = "H264 with start codes", .fourcc = V4L2_PIX_FMT_H264, .depth = 32, .flags = FORMAT_FLAGS_COMPRESSED, }, -#endif /* V4L2_PIX_FMT_H264 */ -#ifdef V4L2_PIX_FMT_H264_NO_SC { .name = "H264 without start codes", .fourcc = V4L2_PIX_FMT_H264_NO_SC, .depth = 32, .flags = FORMAT_FLAGS_COMPRESSED, }, -#endif /* V4L2_PIX_FMT_H264_NO_SC */ -#ifdef V4L2_PIX_FMT_H264_MVC { .name = "H264 MVC", .fourcc = V4L2_PIX_FMT_H264_MVC, .depth = 32, .flags = FORMAT_FLAGS_COMPRESSED, }, -#endif /* V4L2_PIX_FMT_H264_MVC */ -#ifdef V4L2_PIX_FMT_H263 { .name = "H263", .fourcc = V4L2_PIX_FMT_H263, .depth = 32, .flags = FORMAT_FLAGS_COMPRESSED, }, -#endif /* V4L2_PIX_FMT_H263 */ -#ifdef V4L2_PIX_FMT_MPEG1 { .name = "MPEG-1 ES", .fourcc = V4L2_PIX_FMT_MPEG1, .depth = 32, .flags = FORMAT_FLAGS_COMPRESSED, }, -#endif /* V4L2_PIX_FMT_MPEG1 */ -#ifdef V4L2_PIX_FMT_MPEG2 { .name = "MPEG-2 ES", .fourcc = V4L2_PIX_FMT_MPEG2, .depth = 32, .flags = FORMAT_FLAGS_COMPRESSED, }, -#endif /* V4L2_PIX_FMT_MPEG2 */ -#ifdef V4L2_PIX_FMT_MPEG4 { .name = "MPEG-4 part 2 ES", .fourcc = V4L2_PIX_FMT_MPEG4, .depth = 32, .flags = FORMAT_FLAGS_COMPRESSED, }, -#endif /* V4L2_PIX_FMT_MPEG4 */ -#ifdef V4L2_PIX_FMT_XVID { .name = "Xvid", .fourcc = V4L2_PIX_FMT_XVID, .depth = 32, .flags = FORMAT_FLAGS_COMPRESSED, }, -#endif /* V4L2_PIX_FMT_XVID */ -#ifdef V4L2_PIX_FMT_VC1_ANNEX_G { .name = "SMPTE 421M Annex G compliant stream", .fourcc = V4L2_PIX_FMT_VC1_ANNEX_G, .depth = 32, .flags = FORMAT_FLAGS_COMPRESSED, }, -#endif /* V4L2_PIX_FMT_VC1_ANNEX_G */ -#ifdef V4L2_PIX_FMT_VC1_ANNEX_L { .name = "SMPTE 421M Annex L compliant stream", .fourcc = V4L2_PIX_FMT_VC1_ANNEX_L, .depth = 32, .flags = FORMAT_FLAGS_COMPRESSED, }, -#endif /* V4L2_PIX_FMT_VC1_ANNEX_L */ -#ifdef V4L2_PIX_FMT_VP8 { .name = "VP8", .fourcc = V4L2_PIX_FMT_VP8, .depth = 32, .flags = FORMAT_FLAGS_COMPRESSED, }, -#endif /* V4L2_PIX_FMT_VP8 */ -#ifdef V4L2_PIX_FMT_VP9 { .name = "VP9", .fourcc = V4L2_PIX_FMT_VP9, .depth = 32, .flags = FORMAT_FLAGS_COMPRESSED, }, -#endif /* V4L2_PIX_FMT_VP9 */ -#ifdef V4L2_PIX_FMT_HEVC { .name = "HEVC", .fourcc = V4L2_PIX_FMT_HEVC, .depth = 32, .flags = FORMAT_FLAGS_COMPRESSED, }, -#endif /* V4L2_PIX_FMT_HEVC */ }; + +/* The last kernel version synced: v5.11 */ +#ifdef __KERNEL__ +// clang-format off + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0) +static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) +{ + const unsigned sz = sizeof(fmt->description); + const char *descr = NULL; + __u32 flags = 0; + + /* + * We depart from the normal coding style here since the descriptions + * should be aligned so it is easy to see which descriptions will be + * longer than 31 characters (the max length for a description). + * And frankly, this is easier to read anyway. + * + * Note that gcc will use O(log N) comparisons to find the right case. + */ + switch (fmt->pixelformat) { + /* Max description length mask: descr = "0123456789012345678901234567890" */ + case V4L2_PIX_FMT_RGB332: descr = "8-bit RGB 3-3-2"; break; + case V4L2_PIX_FMT_RGB444: descr = "16-bit A/XRGB 4-4-4-4"; break; + case V4L2_PIX_FMT_ARGB444: descr = "16-bit ARGB 4-4-4-4"; break; + case V4L2_PIX_FMT_XRGB444: descr = "16-bit XRGB 4-4-4-4"; break; + case V4L2_PIX_FMT_RGBA444: descr = "16-bit RGBA 4-4-4-4"; break; + case V4L2_PIX_FMT_RGBX444: descr = "16-bit RGBX 4-4-4-4"; break; + case V4L2_PIX_FMT_ABGR444: descr = "16-bit ABGR 4-4-4-4"; break; + case V4L2_PIX_FMT_XBGR444: descr = "16-bit XBGR 4-4-4-4"; break; + case V4L2_PIX_FMT_BGRA444: descr = "16-bit BGRA 4-4-4-4"; break; + case V4L2_PIX_FMT_BGRX444: descr = "16-bit BGRX 4-4-4-4"; break; + case V4L2_PIX_FMT_RGB555: descr = "16-bit A/XRGB 1-5-5-5"; break; + case V4L2_PIX_FMT_ARGB555: descr = "16-bit ARGB 1-5-5-5"; break; + case V4L2_PIX_FMT_XRGB555: descr = "16-bit XRGB 1-5-5-5"; break; + case V4L2_PIX_FMT_ABGR555: descr = "16-bit ABGR 1-5-5-5"; break; + case V4L2_PIX_FMT_XBGR555: descr = "16-bit XBGR 1-5-5-5"; break; + case V4L2_PIX_FMT_RGBA555: descr = "16-bit RGBA 5-5-5-1"; break; + case V4L2_PIX_FMT_RGBX555: descr = "16-bit RGBX 5-5-5-1"; break; + case V4L2_PIX_FMT_BGRA555: descr = "16-bit BGRA 5-5-5-1"; break; + case V4L2_PIX_FMT_BGRX555: descr = "16-bit BGRX 5-5-5-1"; break; + case V4L2_PIX_FMT_RGB565: descr = "16-bit RGB 5-6-5"; break; + case V4L2_PIX_FMT_RGB555X: descr = "16-bit A/XRGB 1-5-5-5 BE"; break; + case V4L2_PIX_FMT_ARGB555X: descr = "16-bit ARGB 1-5-5-5 BE"; break; + case V4L2_PIX_FMT_XRGB555X: descr = "16-bit XRGB 1-5-5-5 BE"; break; + case V4L2_PIX_FMT_RGB565X: descr = "16-bit RGB 5-6-5 BE"; break; + case V4L2_PIX_FMT_BGR666: descr = "18-bit BGRX 6-6-6-14"; break; + case V4L2_PIX_FMT_BGR24: descr = "24-bit BGR 8-8-8"; break; + case V4L2_PIX_FMT_RGB24: descr = "24-bit RGB 8-8-8"; break; + case V4L2_PIX_FMT_BGR32: descr = "32-bit BGRA/X 8-8-8-8"; break; + case V4L2_PIX_FMT_ABGR32: descr = "32-bit BGRA 8-8-8-8"; break; + case V4L2_PIX_FMT_XBGR32: descr = "32-bit BGRX 8-8-8-8"; break; + case V4L2_PIX_FMT_RGB32: descr = "32-bit A/XRGB 8-8-8-8"; break; + case V4L2_PIX_FMT_ARGB32: descr = "32-bit ARGB 8-8-8-8"; break; + case V4L2_PIX_FMT_XRGB32: descr = "32-bit XRGB 8-8-8-8"; break; + case V4L2_PIX_FMT_BGRA32: descr = "32-bit ABGR 8-8-8-8"; break; + case V4L2_PIX_FMT_BGRX32: descr = "32-bit XBGR 8-8-8-8"; break; + case V4L2_PIX_FMT_RGBA32: descr = "32-bit RGBA 8-8-8-8"; break; + case V4L2_PIX_FMT_RGBX32: descr = "32-bit RGBX 8-8-8-8"; break; + case V4L2_PIX_FMT_GREY: descr = "8-bit Greyscale"; break; + case V4L2_PIX_FMT_Y4: descr = "4-bit Greyscale"; break; + case V4L2_PIX_FMT_Y6: descr = "6-bit Greyscale"; break; + case V4L2_PIX_FMT_Y10: descr = "10-bit Greyscale"; break; + case V4L2_PIX_FMT_Y12: descr = "12-bit Greyscale"; break; + case V4L2_PIX_FMT_Y14: descr = "14-bit Greyscale"; break; + case V4L2_PIX_FMT_Y16: descr = "16-bit Greyscale"; break; + case V4L2_PIX_FMT_Y16_BE: descr = "16-bit Greyscale BE"; break; + case V4L2_PIX_FMT_Y10BPACK: descr = "10-bit Greyscale (Packed)"; break; + case V4L2_PIX_FMT_Y10P: descr = "10-bit Greyscale (MIPI Packed)"; break; + case V4L2_PIX_FMT_Y8I: descr = "Interleaved 8-bit Greyscale"; break; + case V4L2_PIX_FMT_Y12I: descr = "Interleaved 12-bit Greyscale"; break; + case V4L2_PIX_FMT_Z16: descr = "16-bit Depth"; break; + case V4L2_PIX_FMT_INZI: descr = "Planar 10:16 Greyscale Depth"; break; + case V4L2_PIX_FMT_CNF4: descr = "4-bit Depth Confidence (Packed)"; break; + case V4L2_PIX_FMT_PAL8: descr = "8-bit Palette"; break; + case V4L2_PIX_FMT_UV8: descr = "8-bit Chrominance UV 4-4"; break; + case V4L2_PIX_FMT_YVU410: descr = "Planar YVU 4:1:0"; break; + case V4L2_PIX_FMT_YVU420: descr = "Planar YVU 4:2:0"; break; + case V4L2_PIX_FMT_YUYV: descr = "YUYV 4:2:2"; break; + case V4L2_PIX_FMT_YYUV: descr = "YYUV 4:2:2"; break; + case V4L2_PIX_FMT_YVYU: descr = "YVYU 4:2:2"; break; + case V4L2_PIX_FMT_UYVY: descr = "UYVY 4:2:2"; break; + case V4L2_PIX_FMT_VYUY: descr = "VYUY 4:2:2"; break; + case V4L2_PIX_FMT_YUV422P: descr = "Planar YUV 4:2:2"; break; + case V4L2_PIX_FMT_YUV411P: descr = "Planar YUV 4:1:1"; break; + case V4L2_PIX_FMT_Y41P: descr = "YUV 4:1:1 (Packed)"; break; + case V4L2_PIX_FMT_YUV444: descr = "16-bit A/XYUV 4-4-4-4"; break; + case V4L2_PIX_FMT_YUV555: descr = "16-bit A/XYUV 1-5-5-5"; break; + case V4L2_PIX_FMT_YUV565: descr = "16-bit YUV 5-6-5"; break; + case V4L2_PIX_FMT_YUV32: descr = "32-bit A/XYUV 8-8-8-8"; break; + case V4L2_PIX_FMT_AYUV32: descr = "32-bit AYUV 8-8-8-8"; break; + case V4L2_PIX_FMT_XYUV32: descr = "32-bit XYUV 8-8-8-8"; break; + case V4L2_PIX_FMT_VUYA32: descr = "32-bit VUYA 8-8-8-8"; break; + case V4L2_PIX_FMT_VUYX32: descr = "32-bit VUYX 8-8-8-8"; break; + case V4L2_PIX_FMT_YUV410: descr = "Planar YUV 4:1:0"; break; + case V4L2_PIX_FMT_YUV420: descr = "Planar YUV 4:2:0"; break; + case V4L2_PIX_FMT_HI240: descr = "8-bit Dithered RGB (BTTV)"; break; + case V4L2_PIX_FMT_HM12: descr = "YUV 4:2:0 (16x16 Macroblocks)"; break; + case V4L2_PIX_FMT_M420: descr = "YUV 4:2:0 (M420)"; break; + case V4L2_PIX_FMT_NV12: descr = "Y/CbCr 4:2:0"; break; + case V4L2_PIX_FMT_NV21: descr = "Y/CrCb 4:2:0"; break; + case V4L2_PIX_FMT_NV16: descr = "Y/CbCr 4:2:2"; break; + case V4L2_PIX_FMT_NV61: descr = "Y/CrCb 4:2:2"; break; + case V4L2_PIX_FMT_NV24: descr = "Y/CbCr 4:4:4"; break; + case V4L2_PIX_FMT_NV42: descr = "Y/CrCb 4:4:4"; break; + case V4L2_PIX_FMT_NV12M: descr = "Y/CbCr 4:2:0 (N-C)"; break; + case V4L2_PIX_FMT_NV21M: descr = "Y/CrCb 4:2:0 (N-C)"; break; + case V4L2_PIX_FMT_NV16M: descr = "Y/CbCr 4:2:2 (N-C)"; break; + case V4L2_PIX_FMT_NV61M: descr = "Y/CrCb 4:2:2 (N-C)"; break; + case V4L2_PIX_FMT_NV12MT: descr = "Y/CbCr 4:2:0 (64x32 MB, N-C)"; break; + case V4L2_PIX_FMT_NV12MT_16X16: descr = "Y/CbCr 4:2:0 (16x16 MB, N-C)"; break; + case V4L2_PIX_FMT_YUV420M: descr = "Planar YUV 4:2:0 (N-C)"; break; + case V4L2_PIX_FMT_YVU420M: descr = "Planar YVU 4:2:0 (N-C)"; break; + case V4L2_PIX_FMT_YUV422M: descr = "Planar YUV 4:2:2 (N-C)"; break; + case V4L2_PIX_FMT_YVU422M: descr = "Planar YVU 4:2:2 (N-C)"; break; + case V4L2_PIX_FMT_YUV444M: descr = "Planar YUV 4:4:4 (N-C)"; break; + case V4L2_PIX_FMT_YVU444M: descr = "Planar YVU 4:4:4 (N-C)"; break; + case V4L2_PIX_FMT_SBGGR8: descr = "8-bit Bayer BGBG/GRGR"; break; + case V4L2_PIX_FMT_SGBRG8: descr = "8-bit Bayer GBGB/RGRG"; break; + case V4L2_PIX_FMT_SGRBG8: descr = "8-bit Bayer GRGR/BGBG"; break; + case V4L2_PIX_FMT_SRGGB8: descr = "8-bit Bayer RGRG/GBGB"; break; + case V4L2_PIX_FMT_SBGGR10: descr = "10-bit Bayer BGBG/GRGR"; break; + case V4L2_PIX_FMT_SGBRG10: descr = "10-bit Bayer GBGB/RGRG"; break; + case V4L2_PIX_FMT_SGRBG10: descr = "10-bit Bayer GRGR/BGBG"; break; + case V4L2_PIX_FMT_SRGGB10: descr = "10-bit Bayer RGRG/GBGB"; break; + case V4L2_PIX_FMT_SBGGR10P: descr = "10-bit Bayer BGBG/GRGR Packed"; break; + case V4L2_PIX_FMT_SGBRG10P: descr = "10-bit Bayer GBGB/RGRG Packed"; break; + case V4L2_PIX_FMT_SGRBG10P: descr = "10-bit Bayer GRGR/BGBG Packed"; break; + case V4L2_PIX_FMT_SRGGB10P: descr = "10-bit Bayer RGRG/GBGB Packed"; break; + case V4L2_PIX_FMT_IPU3_SBGGR10: descr = "10-bit bayer BGGR IPU3 Packed"; break; + case V4L2_PIX_FMT_IPU3_SGBRG10: descr = "10-bit bayer GBRG IPU3 Packed"; break; + case V4L2_PIX_FMT_IPU3_SGRBG10: descr = "10-bit bayer GRBG IPU3 Packed"; break; + case V4L2_PIX_FMT_IPU3_SRGGB10: descr = "10-bit bayer RGGB IPU3 Packed"; break; + case V4L2_PIX_FMT_SBGGR10ALAW8: descr = "8-bit Bayer BGBG/GRGR (A-law)"; break; + case V4L2_PIX_FMT_SGBRG10ALAW8: descr = "8-bit Bayer GBGB/RGRG (A-law)"; break; + case V4L2_PIX_FMT_SGRBG10ALAW8: descr = "8-bit Bayer GRGR/BGBG (A-law)"; break; + case V4L2_PIX_FMT_SRGGB10ALAW8: descr = "8-bit Bayer RGRG/GBGB (A-law)"; break; + case V4L2_PIX_FMT_SBGGR10DPCM8: descr = "8-bit Bayer BGBG/GRGR (DPCM)"; break; + case V4L2_PIX_FMT_SGBRG10DPCM8: descr = "8-bit Bayer GBGB/RGRG (DPCM)"; break; + case V4L2_PIX_FMT_SGRBG10DPCM8: descr = "8-bit Bayer GRGR/BGBG (DPCM)"; break; + case V4L2_PIX_FMT_SRGGB10DPCM8: descr = "8-bit Bayer RGRG/GBGB (DPCM)"; break; + case V4L2_PIX_FMT_SBGGR12: descr = "12-bit Bayer BGBG/GRGR"; break; + case V4L2_PIX_FMT_SGBRG12: descr = "12-bit Bayer GBGB/RGRG"; break; + case V4L2_PIX_FMT_SGRBG12: descr = "12-bit Bayer GRGR/BGBG"; break; + case V4L2_PIX_FMT_SRGGB12: descr = "12-bit Bayer RGRG/GBGB"; break; + case V4L2_PIX_FMT_SBGGR12P: descr = "12-bit Bayer BGBG/GRGR Packed"; break; + case V4L2_PIX_FMT_SGBRG12P: descr = "12-bit Bayer GBGB/RGRG Packed"; break; + case V4L2_PIX_FMT_SGRBG12P: descr = "12-bit Bayer GRGR/BGBG Packed"; break; + case V4L2_PIX_FMT_SRGGB12P: descr = "12-bit Bayer RGRG/GBGB Packed"; break; + case V4L2_PIX_FMT_SBGGR14: descr = "14-bit Bayer BGBG/GRGR"; break; + case V4L2_PIX_FMT_SGBRG14: descr = "14-bit Bayer GBGB/RGRG"; break; + case V4L2_PIX_FMT_SGRBG14: descr = "14-bit Bayer GRGR/BGBG"; break; + case V4L2_PIX_FMT_SRGGB14: descr = "14-bit Bayer RGRG/GBGB"; break; + case V4L2_PIX_FMT_SBGGR14P: descr = "14-bit Bayer BGBG/GRGR Packed"; break; + case V4L2_PIX_FMT_SGBRG14P: descr = "14-bit Bayer GBGB/RGRG Packed"; break; + case V4L2_PIX_FMT_SGRBG14P: descr = "14-bit Bayer GRGR/BGBG Packed"; break; + case V4L2_PIX_FMT_SRGGB14P: descr = "14-bit Bayer RGRG/GBGB Packed"; break; + case V4L2_PIX_FMT_SBGGR16: descr = "16-bit Bayer BGBG/GRGR"; break; + case V4L2_PIX_FMT_SGBRG16: descr = "16-bit Bayer GBGB/RGRG"; break; + case V4L2_PIX_FMT_SGRBG16: descr = "16-bit Bayer GRGR/BGBG"; break; + case V4L2_PIX_FMT_SRGGB16: descr = "16-bit Bayer RGRG/GBGB"; break; + case V4L2_PIX_FMT_SN9C20X_I420: descr = "GSPCA SN9C20X I420"; break; + case V4L2_PIX_FMT_SPCA501: descr = "GSPCA SPCA501"; break; + case V4L2_PIX_FMT_SPCA505: descr = "GSPCA SPCA505"; break; + case V4L2_PIX_FMT_SPCA508: descr = "GSPCA SPCA508"; break; + case V4L2_PIX_FMT_STV0680: descr = "GSPCA STV0680"; break; + case V4L2_PIX_FMT_TM6000: descr = "A/V + VBI Mux Packet"; break; + case V4L2_PIX_FMT_CIT_YYVYUY: descr = "GSPCA CIT YYVYUY"; break; + case V4L2_PIX_FMT_KONICA420: descr = "GSPCA KONICA420"; break; + case V4L2_PIX_FMT_HSV24: descr = "24-bit HSV 8-8-8"; break; + case V4L2_PIX_FMT_HSV32: descr = "32-bit XHSV 8-8-8-8"; break; + case V4L2_SDR_FMT_CU8: descr = "Complex U8"; break; + case V4L2_SDR_FMT_CU16LE: descr = "Complex U16LE"; break; + case V4L2_SDR_FMT_CS8: descr = "Complex S8"; break; + case V4L2_SDR_FMT_CS14LE: descr = "Complex S14LE"; break; + case V4L2_SDR_FMT_RU12LE: descr = "Real U12LE"; break; + case V4L2_SDR_FMT_PCU16BE: descr = "Planar Complex U16BE"; break; + case V4L2_SDR_FMT_PCU18BE: descr = "Planar Complex U18BE"; break; + case V4L2_SDR_FMT_PCU20BE: descr = "Planar Complex U20BE"; break; + case V4L2_TCH_FMT_DELTA_TD16: descr = "16-bit Signed Deltas"; break; + case V4L2_TCH_FMT_DELTA_TD08: descr = "8-bit Signed Deltas"; break; + case V4L2_TCH_FMT_TU16: descr = "16-bit Unsigned Touch Data"; break; + case V4L2_TCH_FMT_TU08: descr = "8-bit Unsigned Touch Data"; break; + case V4L2_META_FMT_VSP1_HGO: descr = "R-Car VSP1 1-D Histogram"; break; + case V4L2_META_FMT_VSP1_HGT: descr = "R-Car VSP1 2-D Histogram"; break; + case V4L2_META_FMT_UVC: descr = "UVC Payload Header Metadata"; break; + case V4L2_META_FMT_D4XX: descr = "Intel D4xx UVC Metadata"; break; + case V4L2_META_FMT_VIVID: descr = "Vivid Metadata"; break; + case V4L2_META_FMT_RK_ISP1_PARAMS: descr = "Rockchip ISP1 3A Parameters"; break; + case V4L2_META_FMT_RK_ISP1_STAT_3A: descr = "Rockchip ISP1 3A Statistics"; break; + + default: + /* Compressed formats */ + flags = V4L2_FMT_FLAG_COMPRESSED; + switch (fmt->pixelformat) { + /* Max description length mask: descr = "0123456789012345678901234567890" */ + case V4L2_PIX_FMT_MJPEG: descr = "Motion-JPEG"; break; + case V4L2_PIX_FMT_JPEG: descr = "JFIF JPEG"; break; + case V4L2_PIX_FMT_DV: descr = "1394"; break; + case V4L2_PIX_FMT_MPEG: descr = "MPEG-1/2/4"; break; + case V4L2_PIX_FMT_H264: descr = "H.264"; break; + case V4L2_PIX_FMT_H264_NO_SC: descr = "H.264 (No Start Codes)"; break; + case V4L2_PIX_FMT_H264_MVC: descr = "H.264 MVC"; break; + case V4L2_PIX_FMT_H264_SLICE: descr = "H.264 Parsed Slice Data"; break; + case V4L2_PIX_FMT_H263: descr = "H.263"; break; + case V4L2_PIX_FMT_MPEG1: descr = "MPEG-1 ES"; break; + case V4L2_PIX_FMT_MPEG2: descr = "MPEG-2 ES"; break; + case V4L2_PIX_FMT_MPEG2_SLICE: descr = "MPEG-2 Parsed Slice Data"; break; + case V4L2_PIX_FMT_MPEG4: descr = "MPEG-4 Part 2 ES"; break; + case V4L2_PIX_FMT_XVID: descr = "Xvid"; break; + case V4L2_PIX_FMT_VC1_ANNEX_G: descr = "VC-1 (SMPTE 412M Annex G)"; break; + case V4L2_PIX_FMT_VC1_ANNEX_L: descr = "VC-1 (SMPTE 412M Annex L)"; break; + case V4L2_PIX_FMT_VP8: descr = "VP8"; break; + case V4L2_PIX_FMT_VP8_FRAME: descr = "VP8 Frame"; break; + case V4L2_PIX_FMT_VP9: descr = "VP9"; break; + case V4L2_PIX_FMT_HEVC: descr = "HEVC"; break; /* aka H.265 */ + case V4L2_PIX_FMT_HEVC_SLICE: descr = "HEVC Parsed Slice Data"; break; + case V4L2_PIX_FMT_FWHT: descr = "FWHT"; break; /* used in vicodec */ + case V4L2_PIX_FMT_FWHT_STATELESS: descr = "FWHT Stateless"; break; /* used in vicodec */ + case V4L2_PIX_FMT_CPIA1: descr = "GSPCA CPiA YUV"; break; + case V4L2_PIX_FMT_WNVA: descr = "WNVA"; break; + case V4L2_PIX_FMT_SN9C10X: descr = "GSPCA SN9C10X"; break; + case V4L2_PIX_FMT_PWC1: descr = "Raw Philips Webcam Type (Old)"; break; + case V4L2_PIX_FMT_PWC2: descr = "Raw Philips Webcam Type (New)"; break; + case V4L2_PIX_FMT_ET61X251: descr = "GSPCA ET61X251"; break; + case V4L2_PIX_FMT_SPCA561: descr = "GSPCA SPCA561"; break; + case V4L2_PIX_FMT_PAC207: descr = "GSPCA PAC207"; break; + case V4L2_PIX_FMT_MR97310A: descr = "GSPCA MR97310A"; break; + case V4L2_PIX_FMT_JL2005BCD: descr = "GSPCA JL2005BCD"; break; + case V4L2_PIX_FMT_SN9C2028: descr = "GSPCA SN9C2028"; break; + case V4L2_PIX_FMT_SQ905C: descr = "GSPCA SQ905C"; break; + case V4L2_PIX_FMT_PJPG: descr = "GSPCA PJPG"; break; + case V4L2_PIX_FMT_OV511: descr = "GSPCA OV511"; break; + case V4L2_PIX_FMT_OV518: descr = "GSPCA OV518"; break; + case V4L2_PIX_FMT_JPGL: descr = "JPEG Lite"; break; + case V4L2_PIX_FMT_SE401: descr = "GSPCA SE401"; break; + case V4L2_PIX_FMT_S5C_UYVY_JPG: descr = "S5C73MX interleaved UYVY/JPEG"; break; + case V4L2_PIX_FMT_MT21C: descr = "Mediatek Compressed Format"; break; + case V4L2_PIX_FMT_SUNXI_TILED_NV12: descr = "Sunxi Tiled NV12 Format"; break; + default: + if (fmt->description[0]) + return; + WARN(1, "Unknown pixelformat 0x%08x\n", fmt->pixelformat); + flags = 0; + snprintf(fmt->description, sz, "%c%c%c%c%s", + (char)(fmt->pixelformat & 0x7f), + (char)((fmt->pixelformat >> 8) & 0x7f), + (char)((fmt->pixelformat >> 16) & 0x7f), + (char)((fmt->pixelformat >> 24) & 0x7f), + (fmt->pixelformat & (1UL << 31)) ? "-BE" : ""); + break; + } + } + + if (descr) { + strncpy(fmt->description, descr, sz - 1); + fmt->description[sz - 1] = '\0'; + } + fmt->flags |= flags; +} +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0) */ + +// clang-format on +#endif /* __KERNEL__ */ From 608f86783894a8a6ebe671bde9c2448f554dbb53 Mon Sep 17 00:00:00 2001 From: You-Sheng Yang Date: Wed, 24 Mar 2021 22:42:40 +0800 Subject: [PATCH 2/5] utils: use v4l_fill_fmtdesc to retrieve format name Signed-off-by: You-Sheng Yang --- utils/v4l2loopback-ctl.c | 10 +++++++--- v4l2loopback_formats.h | 12 ++++++++---- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/utils/v4l2loopback-ctl.c b/utils/v4l2loopback-ctl.c index f8c85821..13c93eb5 100644 --- a/utils/v4l2loopback-ctl.c +++ b/utils/v4l2loopback-ctl.c @@ -316,11 +316,15 @@ static void help_setcaps(const char *program, int brief, int argc, char **argv) const size_t num_formats = sizeof(formats) / sizeof(*formats); size_t i = 0; for (i = 0; i < num_formats; i++) { - const struct v4l2l_format *fmt = formats + i; + struct v4l2_fmtdesc f; + memset(fourcc, 0, 5); + memset(&f, 0, sizeof(f)); + f.pixelformat = formats[i].fourcc; + v4l_fill_fmtdesc(&f); dprintf(2, "%4s\t%d\t%s\n", - fourcc2str(fmt->fourcc, fourcc), fmt->fourcc, - fmt->name); + fourcc2str(f.pixelformat, fourcc), + f.pixelformat, f.description); } } } diff --git a/v4l2loopback_formats.h b/v4l2loopback_formats.h index 6b5e9b0f..d21b4158 100644 --- a/v4l2loopback_formats.h +++ b/v4l2loopback_formats.h @@ -2,7 +2,13 @@ #include #if defined(__KERNEL__) #include +#else +#include + +#ifndef WARN +#define WARN(condition, fmt, ...) #endif +#endif /* defined(__KERNEL__) */ /* Fix build error: initializer element is not constant * @@ -1007,10 +1013,9 @@ static const struct v4l2l_format formats[] = { }; /* The last kernel version synced: v5.11 */ -#ifdef __KERNEL__ // clang-format off -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0) +#if !defined(__KERNEL__) || (LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0)) static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) { const unsigned sz = sizeof(fmt->description); @@ -1265,7 +1270,6 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) } fmt->flags |= flags; } -#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0) */ +#endif /* !defined(__KERNEL__) || (LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0)) */ // clang-format on -#endif /* __KERNEL__ */ From c10b4711759628f3ad9dae43a65e0d61ef8f8588 Mon Sep 17 00:00:00 2001 From: You-Sheng Yang Date: Mon, 29 Mar 2021 00:38:36 +0800 Subject: [PATCH 3/5] compliance: use kernel v4l2_fill_pixfmt() Signed-off-by: You-Sheng Yang --- v4l2loopback.c | 24 +---- v4l2loopback_formats.h | 196 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 198 insertions(+), 22 deletions(-) diff --git a/v4l2loopback.c b/v4l2loopback.c index 4faa0421..0ba69bb7 100644 --- a/v4l2loopback.c +++ b/v4l2loopback.c @@ -408,26 +408,6 @@ static const struct v4l2l_format *format_by_fourcc(int fourcc) return NULL; } -static void pix_format_set_size(struct v4l2_pix_format *f, - const struct v4l2l_format *fmt, - unsigned int width, unsigned int height) -{ - f->width = width; - f->height = height; - - if (fmt->flags & FORMAT_FLAGS_PLANAR) { - f->bytesperline = width; /* Y plane */ - f->sizeimage = (width * height * fmt->depth) >> 3; - } else if (fmt->flags & FORMAT_FLAGS_COMPRESSED) { - /* doesn't make sense for compressed formats */ - f->bytesperline = 0; - f->sizeimage = (width * height * fmt->depth) >> 3; - } else { - f->bytesperline = (width * fmt->depth) >> 3; - f->sizeimage = height * f->bytesperline; - } -} - static int set_timeperframe(struct v4l2_loopback_device *dev, struct v4l2_fract *tpf) { @@ -967,9 +947,9 @@ static int vidioc_try_fmt_out(struct file *file, void *fh, if (NULL == format) format = &formats[0]; - pix_format_set_size(&fmt->fmt.pix, format, w, h); + if (v4l2_fill_pixfmt(&fmt->fmt.pix, format->fourcc, w, h)) + return -EINVAL; - fmt->fmt.pix.pixelformat = format->fourcc; fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB; if (V4L2_FIELD_ANY == fmt->fmt.pix.field) diff --git a/v4l2loopback_formats.h b/v4l2loopback_formats.h index d21b4158..503b8ceb 100644 --- a/v4l2loopback_formats.h +++ b/v4l2loopback_formats.h @@ -10,6 +10,8 @@ #endif #endif /* defined(__KERNEL__) */ +#define LINUX_BACKPORT(__sym) backport_##__sym + /* Fix build error: initializer element is not constant * * See kernel commit ff3c65cb8115 ("media: videodev2.h: Fix shifting signed @@ -1015,6 +1017,200 @@ static const struct v4l2l_format formats[] = { /* The last kernel version synced: v5.11 */ // clang-format off +#if defined(__KERNEL__) && (LINUX_VERSION_CODE < KERNEL_VERSION(5, 5, 0)) +/** + * enum v4l2_pixel_encoding - specifies the pixel encoding value + * + * @V4L2_PIXEL_ENC_UNKNOWN: Pixel encoding is unknown/un-initialized + * @V4L2_PIXEL_ENC_YUV: Pixel encoding is YUV + * @V4L2_PIXEL_ENC_RGB: Pixel encoding is RGB + * @V4L2_PIXEL_ENC_BAYER: Pixel encoding is Bayer + */ +enum v4l2_pixel_encoding { + V4L2_PIXEL_ENC_UNKNOWN = 0, + V4L2_PIXEL_ENC_YUV = 1, + V4L2_PIXEL_ENC_RGB = 2, + V4L2_PIXEL_ENC_BAYER = 3, +}; +#endif /* defined(__KERNEL__) && (LINUX_VERSION_CODE < KERNEL_VERSION(5, 5, 0)) */ + +#if defined(__KERNEL__) && (LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0)) + +#ifdef v4l2_format_info +#undef v4l2_format_info +#endif +#define v4l2_format_info LINUX_BACKPORT(v4l2_format_info) + +/** + * struct v4l2_format_info - information about a V4L2 format + * @format: 4CC format identifier (V4L2_PIX_FMT_*) + * @pixel_enc: Pixel encoding (see enum v4l2_pixel_encoding above) + * @mem_planes: Number of memory planes, which includes the alpha plane (1 to 4). + * @comp_planes: Number of component planes, which includes the alpha plane (1 to 4). + * @bpp: Array of per-plane bytes per pixel + * @hdiv: Horizontal chroma subsampling factor + * @vdiv: Vertical chroma subsampling factor + * @block_w: Per-plane macroblock pixel width (optional) + * @block_h: Per-plane macroblock pixel height (optional) + */ +struct v4l2_format_info { + u32 format; + u8 pixel_enc; + u8 mem_planes; + u8 comp_planes; + u8 bpp[4]; + u8 hdiv; + u8 vdiv; + u8 block_w[4]; + u8 block_h[4]; +}; + +const struct v4l2_format_info *v4l2_format_info(u32 format) +{ + static const struct v4l2_format_info formats[] = { + /* RGB formats */ + { .format = V4L2_PIX_FMT_BGR24, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_RGB24, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_HSV24, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_BGR32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_XBGR32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_BGRX32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_RGB32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_XRGB32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_RGBX32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_HSV32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_ARGB32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_RGBA32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_ABGR32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_BGRA32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_RGB565, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_RGB555, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_BGR666, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + + /* YUV packed formats */ + { .format = V4L2_PIX_FMT_YUYV, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_YVYU, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_UYVY, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_VYUY, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 }, + + /* YUV planar formats */ + { .format = V4L2_PIX_FMT_NV12, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 }, + { .format = V4L2_PIX_FMT_NV21, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 }, + { .format = V4L2_PIX_FMT_NV16, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_NV61, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_NV24, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_NV42, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + + { .format = V4L2_PIX_FMT_YUV410, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 4, .vdiv = 4 }, + { .format = V4L2_PIX_FMT_YVU410, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 4, .vdiv = 4 }, + { .format = V4L2_PIX_FMT_YUV411P, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 4, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_YUV420, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 }, + { .format = V4L2_PIX_FMT_YVU420, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 }, + { .format = V4L2_PIX_FMT_YUV422P, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_GREY, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + + /* YUV planar formats, non contiguous variant */ + { .format = V4L2_PIX_FMT_YUV420M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 }, + { .format = V4L2_PIX_FMT_YVU420M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 }, + { .format = V4L2_PIX_FMT_YUV422M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_YVU422M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_YUV444M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_YVU444M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 1, .vdiv = 1 }, + + { .format = V4L2_PIX_FMT_NV12M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 }, + { .format = V4L2_PIX_FMT_NV21M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 }, + { .format = V4L2_PIX_FMT_NV16M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_NV61M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 }, + + /* Bayer RGB formats */ + { .format = V4L2_PIX_FMT_SBGGR8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_SGBRG8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_SGRBG8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_SRGGB8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_SBGGR10, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_SGBRG10, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_SGRBG10, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_SRGGB10, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_SBGGR10ALAW8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_SGBRG10ALAW8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_SGRBG10ALAW8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_SRGGB10ALAW8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_SBGGR10DPCM8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_SGBRG10DPCM8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_SGRBG10DPCM8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_SRGGB10DPCM8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_SBGGR12, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_SGBRG12, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_SGRBG12, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_SRGGB12, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + }; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(formats); ++i) + if (formats[i].format == format) + return &formats[i]; + return NULL; +} +#endif /* defined(__KERNEL__) && (LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0)) */ + +#if defined(__KERNEL__) && (LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0)) + +static inline unsigned int v4l2_format_block_width(const struct v4l2_format_info *info, int plane) +{ + if (!info->block_w[plane]) + return 1; + return info->block_w[plane]; +} + +static inline unsigned int v4l2_format_block_height(const struct v4l2_format_info *info, int plane) +{ + if (!info->block_h[plane]) + return 1; + return info->block_h[plane]; +} + +#ifdef v4l2_fill_pixfmt +#undef v4l2_fill_pixfmt +#endif +#define v4l2_fill_pixfmt LINUX_BACKPORT(v4l2_fill_pixfmt) + +int v4l2_fill_pixfmt(struct v4l2_pix_format *pixfmt, u32 pixelformat, + u32 width, u32 height) +{ + const struct v4l2_format_info *info; + int i; + + info = v4l2_format_info(pixelformat); + if (!info) + return -EINVAL; + + /* Single planar API cannot be used for multi plane formats. */ + if (info->mem_planes > 1) + return -EINVAL; + + pixfmt->width = width; + pixfmt->height = height; + pixfmt->pixelformat = pixelformat; + pixfmt->bytesperline = ALIGN(width, v4l2_format_block_width(info, 0)) * info->bpp[0]; + pixfmt->sizeimage = 0; + + for (i = 0; i < info->comp_planes; i++) { + unsigned int hdiv = (i == 0) ? 1 : info->hdiv; + unsigned int vdiv = (i == 0) ? 1 : info->vdiv; + unsigned int aligned_width; + unsigned int aligned_height; + + aligned_width = ALIGN(width, v4l2_format_block_width(info, i)); + aligned_height = ALIGN(height, v4l2_format_block_height(info, i)); + + pixfmt->sizeimage += info->bpp[i] * + DIV_ROUND_UP(aligned_width, hdiv) * + DIV_ROUND_UP(aligned_height, vdiv); + } + return 0; +} +#endif /* defined(__KERNEL__) && (LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0)) */ + #if !defined(__KERNEL__) || (LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0)) static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) { From 18aa16b6acbb897265b7216a952d2f2ed2d3272e Mon Sep 17 00:00:00 2001 From: You-Sheng Yang Date: Wed, 24 Mar 2021 16:57:24 +0800 Subject: [PATCH 4/5] compliance: drop v4l2l_format in favor of kernel v4l2_format_info In this change we expost formats array originally embedded in v4l2_format_info() as the formats we support. It follows: 1. v4l2l_format can now be purged, 2. while formats is also referenced in v4l2loopback-ctl, it has to adopt a few changes to enable compiling out of kernel, 3. v4l2_format_info() and v4l2_fill_pixfmt() shall be overridden always as it's to reference our own customized formats array. 4. v4l2_format_block_width()/v4l2_format_block_height() was defined in v4l2-commons.c statically, so there is no symbol collision problem, therefore no need to override. Signed-off-by: You-Sheng Yang --- doc/makeformats.sh | 24 -- doc/missingformats.h | 291 ----------------- utils/v4l2loopback-ctl.c | 10 +- v4l2loopback.c | 52 +-- v4l2loopback_formats.h | 675 ++++++++++----------------------------- 5 files changed, 187 insertions(+), 865 deletions(-) delete mode 100755 doc/makeformats.sh delete mode 100644 doc/missingformats.h diff --git a/doc/makeformats.sh b/doc/makeformats.sh deleted file mode 100755 index 2f47a574..00000000 --- a/doc/makeformats.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/sh - -## usage: -# echo "V4L2_PIX_FMT_MPEG4 MPEG-4 part 2 ES" | $0 -## normally it's more like: -# cat /usr/include/linux/videodev2.h \ -# | grep "define V4L2_PIX_FMT" \ -# | sed -e "s|^#define ||" -e "s|v4l2_fourcc('.', '.', '.', '.')||" -e 's|/\*||' -e 's|\*/||' \ -# | $0 - -DEPTH=0 -FLAGS=0 - -while read FOURCC NAME -do - echo "#ifdef ${FOURCC}" - echo "{" - echo " .name = \"${NAME}\"," - echo " .fourcc = ${FOURCC}," - echo " .depth = ${DEPTH}," - echo " .flags = ${FLAGS}," - echo " }," - echo "#endif /* ${FOURCC} */" -done diff --git a/doc/missingformats.h b/doc/missingformats.h deleted file mode 100644 index 89de33cb..00000000 --- a/doc/missingformats.h +++ /dev/null @@ -1,291 +0,0 @@ -#ifdef V4L2_PIX_FMT_Y10BPACK - }, { - .name = "10 bpp Greyscale bit-packed", - .fourcc = V4L2_PIX_FMT_Y10BPACK, - .depth = 10, - .flags = 0, -#endif /* V4L2_PIX_FMT_Y10BPACK */ -#ifdef V4L2_PIX_FMT_PAL8 - }, { - .name = "8 bpp 8-bit palette", - .fourcc = V4L2_PIX_FMT_PAL8, - .depth = 8, - .flags = 0, -#endif /* V4L2_PIX_FMT_PAL8 */ -#ifdef V4L2_PIX_FMT_UV8 - }, { - .name = "8 bpp UV 4:4", - .fourcc = V4L2_PIX_FMT_UV8, - .depth = 8, - .flags = 0, -#endif /* V4L2_PIX_FMT_UV8 */ - -#ifdef V4L2_PIX_FMT_HI240 - }, { - .name = "8 bpp 8-bit color ", - .fourcc = V4L2_PIX_FMT_HI240, - .depth = 8, - .flags = FORMAT_FLAGS_PLANAR, -#endif /* V4L2_PIX_FMT_HI240 */ -#ifdef V4L2_PIX_FMT_HM12 - }, { - .name = "8 bpp YUV 4:2:0 16x16 macroblocks", - .fourcc = V4L2_PIX_FMT_HM12, - .depth = 8, - .flags = FORMAT_FLAGS_PLANAR, -#endif /* V4L2_PIX_FMT_HM12 */ -#ifdef V4L2_PIX_FMT_M420 - }, { - .name = "12 bpp YUV 4:2:0 2 lines y, 1 line uv interleaved", - .fourcc = V4L2_PIX_FMT_M420, - .depth = 12, - .flags = FORMAT_FLAGS_PLANAR, -#endif /* V4L2_PIX_FMT_M420 */ - - - -#ifdef V4L2_PIX_FMT_NV12 - }, { - .name = "12 bpp Y/CbCr 4:2:0 ", - .fourcc = V4L2_PIX_FMT_NV12, - .depth = 12, - .flags = 0, -#endif /* V4L2_PIX_FMT_NV12 */ -#ifdef V4L2_PIX_FMT_NV21 - }, { - .name = "12 bpp Y/CrCb 4:2:0 ", - .fourcc = V4L2_PIX_FMT_NV21, - .depth = 12, - .flags = 0, -#endif /* V4L2_PIX_FMT_NV21 */ -#ifdef V4L2_PIX_FMT_NV16 - }, { - .name = "16 bpp Y/CbCr 4:2:2 ", - .fourcc = V4L2_PIX_FMT_NV16, - .depth = 16, - .flags = 0, -#endif /* V4L2_PIX_FMT_NV16 */ -#ifdef V4L2_PIX_FMT_NV61 - }, { - .name = "16 bpp Y/CrCb 4:2:2 ", - .fourcc = V4L2_PIX_FMT_NV61, - .depth = 16, - .flags = 0, -#endif /* V4L2_PIX_FMT_NV61 */ -#ifdef V4L2_PIX_FMT_NV24 - }, { - .name = "24 bpp Y/CbCr 4:4:4 ", - .fourcc = V4L2_PIX_FMT_NV24, - .depth = 24, - .flags = 0, -#endif /* V4L2_PIX_FMT_NV24 */ -#ifdef V4L2_PIX_FMT_NV42 - }, { - .name = "24 bpp Y/CrCb 4:4:4 ", - .fourcc = V4L2_PIX_FMT_NV42, - .depth = 24, - .flags = 0, -#endif /* V4L2_PIX_FMT_NV42 */ -#ifdef V4L2_PIX_FMT_NV12M - }, { - .name = "12 bpp Y/CbCr 4:2:0 ", - .fourcc = V4L2_PIX_FMT_NV12M, - .depth = 12, - .flags = 0, -#endif /* V4L2_PIX_FMT_NV12M */ -#ifdef V4L2_PIX_FMT_NV21M - }, { - .name = "21 bpp Y/CrCb 4:2:0 ", - .fourcc = V4L2_PIX_FMT_NV21M, - .depth = 21, - .flags = 0, -#endif /* V4L2_PIX_FMT_NV21M */ -#ifdef V4L2_PIX_FMT_NV16M - }, { - .name = "16 bpp Y/CbCr 4:2:2 ", - .fourcc = V4L2_PIX_FMT_NV16M, - .depth = 16, - .flags = 0, -#endif /* V4L2_PIX_FMT_NV16M */ -#ifdef V4L2_PIX_FMT_NV61M - }, { - .name = "16 bpp Y/CrCb 4:2:2 ", - .fourcc = V4L2_PIX_FMT_NV61M, - .depth = 16, - .flags = 0, -#endif /* V4L2_PIX_FMT_NV61M */ -#ifdef V4L2_PIX_FMT_NV12MT - }, { - .name = "12 bpp Y/CbCr 4:2:0 64x32 macroblocks", - .fourcc = V4L2_PIX_FMT_NV12MT, - .depth = 12, - .flags = 0, -#endif /* V4L2_PIX_FMT_NV12MT */ -#ifdef V4L2_PIX_FMT_NV12MT_16X16 - }, { - .name = "12 bpp Y/CbCr 4:2:0 16x16 macroblocks", - .fourcc = V4L2_PIX_FMT_NV12MT_16X16, - .depth = 12, - .flags = 0, -#endif /* V4L2_PIX_FMT_NV12MT_16X16 */ -#ifdef V4L2_PIX_FMT_YUV420M - }, { - .name = "12 bpp YUV420 planar", - .fourcc = V4L2_PIX_FMT_YUV420M, - .depth = 12, - .flags = 0, -#endif /* V4L2_PIX_FMT_YUV420M */ -#ifdef V4L2_PIX_FMT_YVU420M - }, { - .name = "12 bpp YVU420 planar", - .fourcc = V4L2_PIX_FMT_YVU420M, - .depth = 12, - .flags = 0, -#endif /* V4L2_PIX_FMT_YVU420M */ -#ifdef V4L2_PIX_FMT_SBGGR8 - }, { - .name = "8 bpp BGBG.. GRGR..", - .fourcc = V4L2_PIX_FMT_SBGGR8, - .depth = 8, - .flags = 0, -#endif /* V4L2_PIX_FMT_SBGGR8 */ -#ifdef V4L2_PIX_FMT_SGBRG8 - }, { - .name = "8 bpp GBGB.. RGRG..", - .fourcc = V4L2_PIX_FMT_SGBRG8, - .depth = 8, - .flags = 0, -#endif /* V4L2_PIX_FMT_SGBRG8 */ -#ifdef V4L2_PIX_FMT_SGRBG8 - }, { - .name = "8 bpp GRGR.. BGBG..", - .fourcc = V4L2_PIX_FMT_SGRBG8, - .depth = 8, - .flags = 0, -#endif /* V4L2_PIX_FMT_SGRBG8 */ -#ifdef V4L2_PIX_FMT_SRGGB8 - }, { - .name = "8 bpp RGRG.. GBGB..", - .fourcc = V4L2_PIX_FMT_SRGGB8, - .depth = 8, - .flags = 0, -#endif /* V4L2_PIX_FMT_SRGGB8 */ -#ifdef V4L2_PIX_FMT_SBGGR10 - }, { - .name = "10 bpp BGBG.. GRGR..", - .fourcc = V4L2_PIX_FMT_SBGGR10, - .depth = 10, - .flags = 0, -#endif /* V4L2_PIX_FMT_SBGGR10 */ -#ifdef V4L2_PIX_FMT_SGBRG10 - }, { - .name = "10 bpp GBGB.. RGRG..", - .fourcc = V4L2_PIX_FMT_SGBRG10, - .depth = 10, - .flags = 0, -#endif /* V4L2_PIX_FMT_SGBRG10 */ -#ifdef V4L2_PIX_FMT_SGRBG10 - }, { - .name = "10 bpp GRGR.. BGBG..", - .fourcc = V4L2_PIX_FMT_SGRBG10, - .depth = 10, - .flags = 0, -#endif /* V4L2_PIX_FMT_SGRBG10 */ -#ifdef V4L2_PIX_FMT_SRGGB10 - }, { - .name = "10 bpp RGRG.. GBGB..", - .fourcc = V4L2_PIX_FMT_SRGGB10, - .depth = 10, - .flags = 0, -#endif /* V4L2_PIX_FMT_SRGGB10 */ -#ifdef V4L2_PIX_FMT_SBGGR12 - }, { - .name = "12 bpp BGBG.. GRGR..", - .fourcc = V4L2_PIX_FMT_SBGGR12, - .depth = 12, - .flags = 0, -#endif /* V4L2_PIX_FMT_SBGGR12 */ -#ifdef V4L2_PIX_FMT_SGBRG12 - }, { - .name = "12 bpp GBGB.. RGRG..", - .fourcc = V4L2_PIX_FMT_SGBRG12, - .depth = 12, - .flags = 0, -#endif /* V4L2_PIX_FMT_SGBRG12 */ -#ifdef V4L2_PIX_FMT_SGRBG12 - }, { - .name = "12 bpp GRGR.. BGBG..", - .fourcc = V4L2_PIX_FMT_SGRBG12, - .depth = 12, - .flags = 0, -#endif /* V4L2_PIX_FMT_SGRBG12 */ -#ifdef V4L2_PIX_FMT_SRGGB12 - }, { - .name = "12 bpp RGRG.. GBGB..", - .fourcc = V4L2_PIX_FMT_SRGGB12, - .depth = 12, - .flags = 0, -#endif /* V4L2_PIX_FMT_SRGGB12 */ -#ifdef V4L2_PIX_FMT_SBGGR10ALAW8 - }, { - .name = "", - .fourcc = V4L2_PIX_FMT_SBGGR10ALAW8, - .depth = 0, - .flags = 0, -#endif /* V4L2_PIX_FMT_SBGGR10ALAW8 */ -#ifdef V4L2_PIX_FMT_SGBRG10ALAW8 - }, { - .name = "", - .fourcc = V4L2_PIX_FMT_SGBRG10ALAW8, - .depth = 0, - .flags = 0, -#endif /* V4L2_PIX_FMT_SGBRG10ALAW8 */ -#ifdef V4L2_PIX_FMT_SGRBG10ALAW8 - }, { - .name = "", - .fourcc = V4L2_PIX_FMT_SGRBG10ALAW8, - .depth = 0, - .flags = 0, -#endif /* V4L2_PIX_FMT_SGRBG10ALAW8 */ -#ifdef V4L2_PIX_FMT_SRGGB10ALAW8 - }, { - .name = "", - .fourcc = V4L2_PIX_FMT_SRGGB10ALAW8, - .depth = 0, - .flags = 0, -#endif /* V4L2_PIX_FMT_SRGGB10ALAW8 */ -#ifdef V4L2_PIX_FMT_SBGGR10DPCM8 - }, { - .name = "", - .fourcc = V4L2_PIX_FMT_SBGGR10DPCM8, - .depth = 0, - .flags = 0, -#endif /* V4L2_PIX_FMT_SBGGR10DPCM8 */ -#ifdef V4L2_PIX_FMT_SGBRG10DPCM8 - }, { - .name = "", - .fourcc = V4L2_PIX_FMT_SGBRG10DPCM8, - .depth = 0, - .flags = 0, -#endif /* V4L2_PIX_FMT_SGBRG10DPCM8 */ -#ifdef V4L2_PIX_FMT_SGRBG10DPCM8 - }, { - .name = "", - .fourcc = V4L2_PIX_FMT_SGRBG10DPCM8, - .depth = 0, - .flags = 0, -#endif /* V4L2_PIX_FMT_SGRBG10DPCM8 */ -#ifdef V4L2_PIX_FMT_SRGGB10DPCM8 - }, { - .name = "", - .fourcc = V4L2_PIX_FMT_SRGGB10DPCM8, - .depth = 0, - .flags = 0, -#endif /* V4L2_PIX_FMT_SRGGB10DPCM8 */ -#ifdef V4L2_PIX_FMT_SBGGR16 - }, { - .name = "16 bpp BGBG.. GRGR..", - .fourcc = V4L2_PIX_FMT_SBGGR16, - .depth = 16, - .flags = 0, -#endif /* V4L2_PIX_FMT_SBGGR16 */ diff --git a/utils/v4l2loopback-ctl.c b/utils/v4l2loopback-ctl.c index 13c93eb5..23e6686f 100644 --- a/utils/v4l2loopback-ctl.c +++ b/utils/v4l2loopback-ctl.c @@ -22,14 +22,6 @@ #define MARK() #endif -struct v4l2l_format { - char *name; - int fourcc; /* video4linux 2 */ - int depth; /* bit/pixel */ - int flags; -}; -#define FORMAT_FLAGS_PLANAR 0x01 -#define FORMAT_FLAGS_COMPRESSED 0x02 #include "../v4l2loopback_formats.h" /********************/ @@ -320,7 +312,7 @@ static void help_setcaps(const char *program, int brief, int argc, char **argv) memset(fourcc, 0, 5); memset(&f, 0, sizeof(f)); - f.pixelformat = formats[i].fourcc; + f.pixelformat = formats[i].format; v4l_fill_fmtdesc(&f); dprintf(2, "%4s\t%d\t%s\n", fourcc2str(f.pixelformat, fourcc), diff --git a/v4l2loopback.c b/v4l2loopback.c index 0ba69bb7..8b9459bb 100644 --- a/v4l2loopback.c +++ b/v4l2loopback.c @@ -368,21 +368,8 @@ struct v4l2_loopback_opener { #define fh_to_opener(ptr) container_of((ptr), struct v4l2_loopback_opener, fh) -/* this is heavily inspired by the bttv driver found in the linux kernel */ -struct v4l2l_format { - char *name; - int fourcc; /* video4linux 2 */ - int depth; /* bit/pixel */ - int flags; -}; -/* set the v4l2l_format.flags to PLANAR for non-packed formats */ -#define FORMAT_FLAGS_PLANAR 0x01 -#define FORMAT_FLAGS_COMPRESSED 0x02 - #include "v4l2loopback_formats.h" -static const unsigned int FORMATS = ARRAY_SIZE(formats); - static char *fourcc2str(unsigned int fourcc, char buf[4]) { buf[0] = (fourcc >> 0) & 0xFF; @@ -393,21 +380,6 @@ static char *fourcc2str(unsigned int fourcc, char buf[4]) return buf; } -static const struct v4l2l_format *format_by_fourcc(int fourcc) -{ - unsigned int i; - - for (i = 0; i < FORMATS; i++) { - if (formats[i].fourcc == fourcc) - return formats + i; - } - - dprintk("unsupported format '%c%c%c%c'\n", (fourcc >> 0) & 0xFF, - (fourcc >> 8) & 0xFF, (fourcc >> 16) & 0xFF, - (fourcc >> 24) & 0xFF); - return NULL; -} - static int set_timeperframe(struct v4l2_loopback_device *dev, struct v4l2_fract *tpf) { @@ -702,7 +674,7 @@ static int vidioc_enum_framesizes(struct file *file, void *fh, } else { /* if the format has not been negotiated yet, we accept anything */ - if (NULL == format_by_fourcc(argp->pixel_format)) + if (NULL == backport_v4l2_format_info(argp->pixel_format)) return -EINVAL; argp->type = V4L2_FRMSIZE_TYPE_CONTINUOUS; @@ -744,7 +716,7 @@ static int vidioc_enum_frameintervals(struct file *file, void *fh, argp->width > dev->max_width || argp->height < V4L2LOOPBACK_SIZE_MIN_HEIGHT || argp->height > dev->max_height || - NULL == format_by_fourcc(argp->pixel_format)) + NULL == backport_v4l2_format_info(argp->pixel_format)) return -EINVAL; argp->type = V4L2_FRMIVAL_TYPE_CONTINUOUS; @@ -855,31 +827,28 @@ static int vidioc_enum_fmt_out(struct file *file, void *fh, struct v4l2_fmtdesc *f) { struct v4l2_loopback_device *dev; - const struct v4l2l_format *fmt; dev = v4l2loopback_getdevice(file); if (dev->ready_for_capture) { - const __u32 format = dev->pix_format.pixelformat; + const struct v4l2_format_info *fmt; /* format has been fixed by the writer, so only one single format is supported */ if (f->index) return -EINVAL; - fmt = format_by_fourcc(format); + fmt = backport_v4l2_format_info(dev->pix_format.pixelformat); if (NULL == fmt) return -EINVAL; - f->pixelformat = dev->pix_format.pixelformat; + f->pixelformat = fmt->format; } else { /* fill in a dummy format */ /* coverity[unsigned_compare] */ - if (f->index < 0 || f->index >= FORMATS) + if (f->index < 0 || f->index >= ARRAY_SIZE(formats)) return -EINVAL; - fmt = &formats[f->index]; - - f->pixelformat = fmt->fourcc; + f->pixelformat = formats[f->index].format; } #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0) v4l_fill_fmtdesc(f); @@ -934,7 +903,8 @@ static int vidioc_try_fmt_out(struct file *file, void *fh, __u32 w = fmt->fmt.pix.width; __u32 h = fmt->fmt.pix.height; __u32 pixfmt = fmt->fmt.pix.pixelformat; - const struct v4l2l_format *format = format_by_fourcc(pixfmt); + const struct v4l2_format_info *format = + backport_v4l2_format_info(pixfmt); w = w ? clamp_val(w, V4L2LOOPBACK_SIZE_MIN_WIDTH, dev->max_width) : @@ -947,7 +917,7 @@ static int vidioc_try_fmt_out(struct file *file, void *fh, if (NULL == format) format = &formats[0]; - if (v4l2_fill_pixfmt(&fmt->fmt.pix, format->fourcc, w, h)) + if (v4l2_fill_pixfmt(&fmt->fmt.pix, format->format, w, h)) return -EINVAL; fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB; @@ -2284,7 +2254,7 @@ v4l2_loopback_add(struct v4l2_loopback_config *conf) /* Set initial format */ dev->pix_format.width = 0; /* V4L2LOOPBACK_SIZE_DEFAULT_WIDTH; */ dev->pix_format.height = 0; /* V4L2LOOPBACK_SIZE_DEFAULT_HEIGHT; */ - dev->pix_format.pixelformat = formats[0].fourcc; + dev->pix_format.pixelformat = formats[0].format; dev->pix_format.colorspace = V4L2_COLORSPACE_SRGB; /* do we need to set this ? */ dev->pix_format.field = V4L2_FIELD_NONE; diff --git a/v4l2loopback_formats.h b/v4l2loopback_formats.h index 503b8ceb..b189e03f 100644 --- a/v4l2loopback_formats.h +++ b/v4l2loopback_formats.h @@ -5,6 +5,22 @@ #else #include +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0])) +#endif + +#ifndef ALIGN +#define ALIGN(x, a) __ALIGN_KERNEL((x), (a)) +#endif + +#ifndef DIV_ROUND_UP +#if defined(__KERNEL_DIV_ROUND_UP) +#define DIV_ROUND_UP(n, d) __KERNEL_DIV_ROUND_UP((n), (d)) +#else +#define DIV_ROUND_UP(n, d) (((n) + ((d)-1)) / (d)) +#endif +#endif + #ifndef WARN #define WARN(condition, fmt, ...) #endif @@ -673,351 +689,10 @@ #define V4L2_META_FMT_RK_ISP1_STAT_3A v4l2_fourcc('R', 'K', '1', 'S') #endif -static const struct v4l2l_format formats[] = { - /* here come the packed formats */ - { - .name = "32 bpp RGB, le", - .fourcc = V4L2_PIX_FMT_BGR32, - .depth = 32, - .flags = 0, - }, - { - .name = "32 bpp RGB, be", - .fourcc = V4L2_PIX_FMT_RGB32, - .depth = 32, - .flags = 0, - }, - { - .name = "24 bpp RGB, le", - .fourcc = V4L2_PIX_FMT_BGR24, - .depth = 24, - .flags = 0, - }, - { - .name = "24 bpp RGB, be", - .fourcc = V4L2_PIX_FMT_RGB24, - .depth = 24, - .flags = 0, - }, - { - .name = "8 bpp RGB-3-3-2", - .fourcc = V4L2_PIX_FMT_RGB332, - .depth = 8, - .flags = 0, - }, - { - .name = "16 bpp RGB (xxxxrrrr ggggbbbb)", - .fourcc = V4L2_PIX_FMT_RGB444, - .depth = 16, - .flags = 0, - }, - { - .name = "16 bpp RGB-5-5-5", - .fourcc = V4L2_PIX_FMT_RGB555, - .depth = 16, - .flags = 0, - }, - { - .name = "16 bpp RGB-5-6-5", - .fourcc = V4L2_PIX_FMT_RGB565, - .depth = 16, - .flags = 0, - }, - { - .name = "16 bpp RGB-5-5-5 BE", - .fourcc = V4L2_PIX_FMT_RGB555X, - .depth = 16, - .flags = 0, - }, - { - .name = "16 bpp RGB-5-6-5 BE", - .fourcc = V4L2_PIX_FMT_RGB565X, - .depth = 16, - .flags = 0, - }, - { - .name = "18 bpp BGR-6-6-6", - .fourcc = V4L2_PIX_FMT_BGR666, - .depth = 18, - .flags = 0, - }, - { - .name = "4:2:2, packed, YUYV", - .fourcc = V4L2_PIX_FMT_YUYV, - .depth = 16, - .flags = 0, - }, - { - .name = "4:2:2, packed, UYVY", - .fourcc = V4L2_PIX_FMT_UYVY, - .depth = 16, - .flags = 0, - }, - { - .name = "4:2:2, packed YVYU", - .fourcc = V4L2_PIX_FMT_YVYU, - .depth = 16, - .flags = 0, - }, - { - .name = "4:2:2, packed VYUY", - .fourcc = V4L2_PIX_FMT_VYUY, - .depth = 16, - .flags = 0, - }, - { - .name = "4:2:2, packed YYUV", - .fourcc = V4L2_PIX_FMT_YYUV, - .depth = 16, - .flags = 0, - }, - { - .name = "YUV-8-8-8-8", - .fourcc = V4L2_PIX_FMT_YUV32, - .depth = 32, - .flags = 0, - }, - { - .name = "8 bpp, Greyscale", - .fourcc = V4L2_PIX_FMT_GREY, - .depth = 8, - .flags = 0, - }, - { - .name = "4 bpp Greyscale", - .fourcc = V4L2_PIX_FMT_Y4, - .depth = 4, - .flags = 0, - }, - { - .name = "6 bpp Greyscale", - .fourcc = V4L2_PIX_FMT_Y6, - .depth = 6, - .flags = 0, - }, - { - .name = "10 bpp Greyscale", - .fourcc = V4L2_PIX_FMT_Y10, - .depth = 10, - .flags = 0, - }, - { - .name = "12 bpp Greyscale", - .fourcc = V4L2_PIX_FMT_Y12, - .depth = 12, - .flags = 0, - }, - { - .name = "16 bpp, Greyscale", - .fourcc = V4L2_PIX_FMT_Y16, - .depth = 16, - .flags = 0, - }, - { - .name = "16 bpp xxxxyyyy uuuuvvvv", - .fourcc = V4L2_PIX_FMT_YUV444, - .depth = 16, - .flags = 0, - }, - { - .name = "16 bpp YUV-5-5-5", - .fourcc = V4L2_PIX_FMT_YUV555, - .depth = 16, - .flags = 0, - }, - { - .name = "16 bpp YUV-5-6-5", - .fourcc = V4L2_PIX_FMT_YUV565, - .depth = 16, - .flags = 0, - }, - - /* bayer formats */ - { - .name = "Bayer RGGB 8bit", - .fourcc = V4L2_PIX_FMT_SRGGB8, - .depth = 8, - .flags = 0, - }, - { - .name = "Bayer GRBG 8bit", - .fourcc = V4L2_PIX_FMT_SGRBG8, - .depth = 8, - .flags = 0, - }, - { - .name = "Bayer GBRG 8bit", - .fourcc = V4L2_PIX_FMT_SGBRG8, - .depth = 8, - .flags = 0, - }, - { - .name = "Bayer BA81 8bit", - .fourcc = V4L2_PIX_FMT_SBGGR8, - .depth = 8, - .flags = 0, - }, - - /* here come the planar formats */ - { - .name = "4:1:0, planar, Y-Cr-Cb", - .fourcc = V4L2_PIX_FMT_YVU410, - .depth = 9, - .flags = FORMAT_FLAGS_PLANAR, - }, - { - .name = "4:2:0, planar, Y-Cr-Cb", - .fourcc = V4L2_PIX_FMT_YVU420, - .depth = 12, - .flags = FORMAT_FLAGS_PLANAR, - }, - { - .name = "4:1:0, planar, Y-Cb-Cr", - .fourcc = V4L2_PIX_FMT_YUV410, - .depth = 9, - .flags = FORMAT_FLAGS_PLANAR, - }, - { - .name = "4:2:0, planar, Y-Cb-Cr", - .fourcc = V4L2_PIX_FMT_YUV420, - .depth = 12, - .flags = FORMAT_FLAGS_PLANAR, - }, - { - .name = "16 bpp YVU422 planar", - .fourcc = V4L2_PIX_FMT_YUV422P, - .depth = 16, - .flags = FORMAT_FLAGS_PLANAR, - }, - { - .name = "16 bpp YVU411 planar", - .fourcc = V4L2_PIX_FMT_YUV411P, - .depth = 16, - .flags = FORMAT_FLAGS_PLANAR, - }, - { - .name = "12 bpp YUV 4:1:1", - .fourcc = V4L2_PIX_FMT_Y41P, - .depth = 12, - .flags = FORMAT_FLAGS_PLANAR, - }, - { - .name = "12 bpp Y/CbCr 4:2:0 ", - .fourcc = V4L2_PIX_FMT_NV12, - .depth = 12, - .flags = FORMAT_FLAGS_PLANAR, - }, - - /* here come the compressed formats */ - - { - .name = "Motion-JPEG", - .fourcc = V4L2_PIX_FMT_MJPEG, - .depth = 32, - .flags = FORMAT_FLAGS_COMPRESSED, - }, - { - .name = "JFIF JPEG", - .fourcc = V4L2_PIX_FMT_JPEG, - .depth = 32, - .flags = FORMAT_FLAGS_COMPRESSED, - }, - { - .name = "DV1394", - .fourcc = V4L2_PIX_FMT_DV, - .depth = 32, - .flags = FORMAT_FLAGS_COMPRESSED, - }, - { - .name = "MPEG-1/2/4 Multiplexed", - .fourcc = V4L2_PIX_FMT_MPEG, - .depth = 32, - .flags = FORMAT_FLAGS_COMPRESSED, - }, - { - .name = "H264 with start codes", - .fourcc = V4L2_PIX_FMT_H264, - .depth = 32, - .flags = FORMAT_FLAGS_COMPRESSED, - }, - { - .name = "H264 without start codes", - .fourcc = V4L2_PIX_FMT_H264_NO_SC, - .depth = 32, - .flags = FORMAT_FLAGS_COMPRESSED, - }, - { - .name = "H264 MVC", - .fourcc = V4L2_PIX_FMT_H264_MVC, - .depth = 32, - .flags = FORMAT_FLAGS_COMPRESSED, - }, - { - .name = "H263", - .fourcc = V4L2_PIX_FMT_H263, - .depth = 32, - .flags = FORMAT_FLAGS_COMPRESSED, - }, - { - .name = "MPEG-1 ES", - .fourcc = V4L2_PIX_FMT_MPEG1, - .depth = 32, - .flags = FORMAT_FLAGS_COMPRESSED, - }, - { - .name = "MPEG-2 ES", - .fourcc = V4L2_PIX_FMT_MPEG2, - .depth = 32, - .flags = FORMAT_FLAGS_COMPRESSED, - }, - { - .name = "MPEG-4 part 2 ES", - .fourcc = V4L2_PIX_FMT_MPEG4, - .depth = 32, - .flags = FORMAT_FLAGS_COMPRESSED, - }, - { - .name = "Xvid", - .fourcc = V4L2_PIX_FMT_XVID, - .depth = 32, - .flags = FORMAT_FLAGS_COMPRESSED, - }, - { - .name = "SMPTE 421M Annex G compliant stream", - .fourcc = V4L2_PIX_FMT_VC1_ANNEX_G, - .depth = 32, - .flags = FORMAT_FLAGS_COMPRESSED, - }, - { - .name = "SMPTE 421M Annex L compliant stream", - .fourcc = V4L2_PIX_FMT_VC1_ANNEX_L, - .depth = 32, - .flags = FORMAT_FLAGS_COMPRESSED, - }, - { - .name = "VP8", - .fourcc = V4L2_PIX_FMT_VP8, - .depth = 32, - .flags = FORMAT_FLAGS_COMPRESSED, - }, - { - .name = "VP9", - .fourcc = V4L2_PIX_FMT_VP9, - .depth = 32, - .flags = FORMAT_FLAGS_COMPRESSED, - }, - { - .name = "HEVC", - .fourcc = V4L2_PIX_FMT_HEVC, - .depth = 32, - .flags = FORMAT_FLAGS_COMPRESSED, - }, -}; - /* The last kernel version synced: v5.11 */ // clang-format off -#if defined(__KERNEL__) && (LINUX_VERSION_CODE < KERNEL_VERSION(5, 5, 0)) +#if !defined(__KERNEL__) || (LINUX_VERSION_CODE < KERNEL_VERSION(5, 5, 0)) /** * enum v4l2_pixel_encoding - specifies the pixel encoding value * @@ -1032,9 +707,6 @@ enum v4l2_pixel_encoding { V4L2_PIXEL_ENC_RGB = 2, V4L2_PIXEL_ENC_BAYER = 3, }; -#endif /* defined(__KERNEL__) && (LINUX_VERSION_CODE < KERNEL_VERSION(5, 5, 0)) */ - -#if defined(__KERNEL__) && (LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0)) #ifdef v4l2_format_info #undef v4l2_format_info @@ -1054,162 +726,17 @@ enum v4l2_pixel_encoding { * @block_h: Per-plane macroblock pixel height (optional) */ struct v4l2_format_info { - u32 format; - u8 pixel_enc; - u8 mem_planes; - u8 comp_planes; - u8 bpp[4]; - u8 hdiv; - u8 vdiv; - u8 block_w[4]; - u8 block_h[4]; + __u32 format; + __u8 pixel_enc; + __u8 mem_planes; + __u8 comp_planes; + __u8 bpp[4]; + __u8 hdiv; + __u8 vdiv; + __u8 block_w[4]; + __u8 block_h[4]; }; - -const struct v4l2_format_info *v4l2_format_info(u32 format) -{ - static const struct v4l2_format_info formats[] = { - /* RGB formats */ - { .format = V4L2_PIX_FMT_BGR24, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, - { .format = V4L2_PIX_FMT_RGB24, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, - { .format = V4L2_PIX_FMT_HSV24, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, - { .format = V4L2_PIX_FMT_BGR32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, - { .format = V4L2_PIX_FMT_XBGR32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, - { .format = V4L2_PIX_FMT_BGRX32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, - { .format = V4L2_PIX_FMT_RGB32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, - { .format = V4L2_PIX_FMT_XRGB32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, - { .format = V4L2_PIX_FMT_RGBX32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, - { .format = V4L2_PIX_FMT_HSV32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, - { .format = V4L2_PIX_FMT_ARGB32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, - { .format = V4L2_PIX_FMT_RGBA32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, - { .format = V4L2_PIX_FMT_ABGR32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, - { .format = V4L2_PIX_FMT_BGRA32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, - { .format = V4L2_PIX_FMT_RGB565, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, - { .format = V4L2_PIX_FMT_RGB555, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, - { .format = V4L2_PIX_FMT_BGR666, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, - - /* YUV packed formats */ - { .format = V4L2_PIX_FMT_YUYV, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 }, - { .format = V4L2_PIX_FMT_YVYU, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 }, - { .format = V4L2_PIX_FMT_UYVY, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 }, - { .format = V4L2_PIX_FMT_VYUY, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 }, - - /* YUV planar formats */ - { .format = V4L2_PIX_FMT_NV12, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 }, - { .format = V4L2_PIX_FMT_NV21, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 }, - { .format = V4L2_PIX_FMT_NV16, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 }, - { .format = V4L2_PIX_FMT_NV61, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 }, - { .format = V4L2_PIX_FMT_NV24, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 1, .vdiv = 1 }, - { .format = V4L2_PIX_FMT_NV42, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 1, .vdiv = 1 }, - - { .format = V4L2_PIX_FMT_YUV410, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 4, .vdiv = 4 }, - { .format = V4L2_PIX_FMT_YVU410, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 4, .vdiv = 4 }, - { .format = V4L2_PIX_FMT_YUV411P, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 4, .vdiv = 1 }, - { .format = V4L2_PIX_FMT_YUV420, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 }, - { .format = V4L2_PIX_FMT_YVU420, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 }, - { .format = V4L2_PIX_FMT_YUV422P, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 1 }, - { .format = V4L2_PIX_FMT_GREY, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, - - /* YUV planar formats, non contiguous variant */ - { .format = V4L2_PIX_FMT_YUV420M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 }, - { .format = V4L2_PIX_FMT_YVU420M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 }, - { .format = V4L2_PIX_FMT_YUV422M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 1 }, - { .format = V4L2_PIX_FMT_YVU422M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 1 }, - { .format = V4L2_PIX_FMT_YUV444M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 1, .vdiv = 1 }, - { .format = V4L2_PIX_FMT_YVU444M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 1, .vdiv = 1 }, - - { .format = V4L2_PIX_FMT_NV12M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 }, - { .format = V4L2_PIX_FMT_NV21M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 }, - { .format = V4L2_PIX_FMT_NV16M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 }, - { .format = V4L2_PIX_FMT_NV61M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 }, - - /* Bayer RGB formats */ - { .format = V4L2_PIX_FMT_SBGGR8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, - { .format = V4L2_PIX_FMT_SGBRG8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, - { .format = V4L2_PIX_FMT_SGRBG8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, - { .format = V4L2_PIX_FMT_SRGGB8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, - { .format = V4L2_PIX_FMT_SBGGR10, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, - { .format = V4L2_PIX_FMT_SGBRG10, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, - { .format = V4L2_PIX_FMT_SGRBG10, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, - { .format = V4L2_PIX_FMT_SRGGB10, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, - { .format = V4L2_PIX_FMT_SBGGR10ALAW8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, - { .format = V4L2_PIX_FMT_SGBRG10ALAW8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, - { .format = V4L2_PIX_FMT_SGRBG10ALAW8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, - { .format = V4L2_PIX_FMT_SRGGB10ALAW8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, - { .format = V4L2_PIX_FMT_SBGGR10DPCM8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, - { .format = V4L2_PIX_FMT_SGBRG10DPCM8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, - { .format = V4L2_PIX_FMT_SGRBG10DPCM8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, - { .format = V4L2_PIX_FMT_SRGGB10DPCM8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, - { .format = V4L2_PIX_FMT_SBGGR12, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, - { .format = V4L2_PIX_FMT_SGBRG12, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, - { .format = V4L2_PIX_FMT_SGRBG12, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, - { .format = V4L2_PIX_FMT_SRGGB12, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, - }; - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(formats); ++i) - if (formats[i].format == format) - return &formats[i]; - return NULL; -} -#endif /* defined(__KERNEL__) && (LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0)) */ - -#if defined(__KERNEL__) && (LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0)) - -static inline unsigned int v4l2_format_block_width(const struct v4l2_format_info *info, int plane) -{ - if (!info->block_w[plane]) - return 1; - return info->block_w[plane]; -} - -static inline unsigned int v4l2_format_block_height(const struct v4l2_format_info *info, int plane) -{ - if (!info->block_h[plane]) - return 1; - return info->block_h[plane]; -} - -#ifdef v4l2_fill_pixfmt -#undef v4l2_fill_pixfmt -#endif -#define v4l2_fill_pixfmt LINUX_BACKPORT(v4l2_fill_pixfmt) - -int v4l2_fill_pixfmt(struct v4l2_pix_format *pixfmt, u32 pixelformat, - u32 width, u32 height) -{ - const struct v4l2_format_info *info; - int i; - - info = v4l2_format_info(pixelformat); - if (!info) - return -EINVAL; - - /* Single planar API cannot be used for multi plane formats. */ - if (info->mem_planes > 1) - return -EINVAL; - - pixfmt->width = width; - pixfmt->height = height; - pixfmt->pixelformat = pixelformat; - pixfmt->bytesperline = ALIGN(width, v4l2_format_block_width(info, 0)) * info->bpp[0]; - pixfmt->sizeimage = 0; - - for (i = 0; i < info->comp_planes; i++) { - unsigned int hdiv = (i == 0) ? 1 : info->hdiv; - unsigned int vdiv = (i == 0) ? 1 : info->vdiv; - unsigned int aligned_width; - unsigned int aligned_height; - - aligned_width = ALIGN(width, v4l2_format_block_width(info, i)); - aligned_height = ALIGN(height, v4l2_format_block_height(info, i)); - - pixfmt->sizeimage += info->bpp[i] * - DIV_ROUND_UP(aligned_width, hdiv) * - DIV_ROUND_UP(aligned_height, vdiv); - } - return 0; -} -#endif /* defined(__KERNEL__) && (LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0)) */ +#endif /* !defined(__KERNEL__) || (LINUX_VERSION_CODE < KERNEL_VERSION(5, 5, 0)) */ #if !defined(__KERNEL__) || (LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0)) static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) @@ -1469,3 +996,151 @@ static void v4l_fill_fmtdesc(struct v4l2_fmtdesc *fmt) #endif /* !defined(__KERNEL__) || (LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0)) */ // clang-format on + +static const struct v4l2_format_info formats[] = { + // clang-format off + /* RGB formats */ + { .format = V4L2_PIX_FMT_BGR24, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_RGB24, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_HSV24, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_BGR32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_XBGR32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_BGRX32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_RGB32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_XRGB32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_RGBX32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_HSV32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_ARGB32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_RGBA32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_ABGR32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_BGRA32, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_RGB565, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_RGB555, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_BGR666, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + + /* YUV packed formats */ + { .format = V4L2_PIX_FMT_YUYV, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_YVYU, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_UYVY, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_VYUY, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 }, + + /* YUV planar formats */ + { .format = V4L2_PIX_FMT_NV12, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 }, + { .format = V4L2_PIX_FMT_NV21, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 }, + { .format = V4L2_PIX_FMT_NV16, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_NV61, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_NV24, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_NV42, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + + { .format = V4L2_PIX_FMT_YUV410, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 4, .vdiv = 4 }, + { .format = V4L2_PIX_FMT_YVU410, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 4, .vdiv = 4 }, + { .format = V4L2_PIX_FMT_YUV411P, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 4, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_YUV420, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 }, + { .format = V4L2_PIX_FMT_YVU420, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 }, + { .format = V4L2_PIX_FMT_YUV422P, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_GREY, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + + /* YUV planar formats, non contiguous variant */ + { .format = V4L2_PIX_FMT_YUV420M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 }, + { .format = V4L2_PIX_FMT_YVU420M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 }, + { .format = V4L2_PIX_FMT_YUV422M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_YVU422M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_YUV444M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_YVU444M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 1, .vdiv = 1 }, + + { .format = V4L2_PIX_FMT_NV12M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 }, + { .format = V4L2_PIX_FMT_NV21M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 2 }, + { .format = V4L2_PIX_FMT_NV16M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_NV61M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 }, + + /* Bayer RGB formats */ + { .format = V4L2_PIX_FMT_SBGGR8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_SGBRG8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_SGRBG8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_SRGGB8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_SBGGR10, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_SGBRG10, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_SGRBG10, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_SRGGB10, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_SBGGR10ALAW8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_SGBRG10ALAW8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_SGRBG10ALAW8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_SRGGB10ALAW8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_SBGGR10DPCM8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_SGBRG10DPCM8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_SGRBG10DPCM8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_SRGGB10DPCM8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_SBGGR12, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_SGBRG12, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_SGRBG12, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_SRGGB12, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + // clang-format on +}; + +const struct v4l2_format_info *LINUX_BACKPORT(v4l2_format_info)(__u32 format) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(formats); ++i) + if (formats[i].format == format) + return &formats[i]; + return NULL; +} + +static inline unsigned int +v4l2_format_block_width(const struct v4l2_format_info *info, int plane) +{ + if (!info->block_w[plane]) + return 1; + return info->block_w[plane]; +} + +static inline unsigned int +v4l2_format_block_height(const struct v4l2_format_info *info, int plane) +{ + if (!info->block_h[plane]) + return 1; + return info->block_h[plane]; +} + +#ifdef v4l2_fill_pixfmt +#undef v4l2_fill_pixfmt +#endif +#define v4l2_fill_pixfmt LINUX_BACKPORT(v4l2_fill_pixfmt) +int v4l2_fill_pixfmt(struct v4l2_pix_format *pixfmt, __u32 pixelformat, + __u32 width, __u32 height) +{ + const struct v4l2_format_info *info; + int i; + + info = backport_v4l2_format_info(pixelformat); + if (!info) + return -EINVAL; + + /* Single planar API cannot be used for multi plane formats. */ + if (info->mem_planes > 1) + return -EINVAL; + + pixfmt->width = width; + pixfmt->height = height; + pixfmt->pixelformat = pixelformat; + pixfmt->bytesperline = + ALIGN(width, v4l2_format_block_width(info, 0)) * info->bpp[0]; + pixfmt->sizeimage = 0; + + for (i = 0; i < info->comp_planes; i++) { + unsigned int hdiv = (i == 0) ? 1 : info->hdiv; + unsigned int vdiv = (i == 0) ? 1 : info->vdiv; + unsigned int aligned_width; + unsigned int aligned_height; + + aligned_width = ALIGN(width, v4l2_format_block_width(info, i)); + aligned_height = + ALIGN(height, v4l2_format_block_height(info, i)); + + pixfmt->sizeimage += info->bpp[i] * + DIV_ROUND_UP(aligned_width, hdiv) * + DIV_ROUND_UP(aligned_height, vdiv); + } + return 0; +} From 586f44737ec9b99bebcc913d204226c4da77ba0f Mon Sep 17 00:00:00 2001 From: You-Sheng Yang Date: Sun, 28 Mar 2021 19:50:32 +0800 Subject: [PATCH 5/5] wip: formats: add more Signed-off-by: You-Sheng Yang --- v4l2loopback_formats.h | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/v4l2loopback_formats.h b/v4l2loopback_formats.h index b189e03f..6cd899a6 100644 --- a/v4l2loopback_formats.h +++ b/v4l2loopback_formats.h @@ -1017,6 +1017,10 @@ static const struct v4l2_format_info formats[] = { { .format = V4L2_PIX_FMT_RGB565, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, { .format = V4L2_PIX_FMT_RGB555, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, { .format = V4L2_PIX_FMT_BGR666, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_RGB332, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_RGB444, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_RGB555X, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_RGB565X, .pixel_enc = V4L2_PIXEL_ENC_RGB, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, /* YUV packed formats */ { .format = V4L2_PIX_FMT_YUYV, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 2, .vdiv = 1 }, @@ -1038,7 +1042,6 @@ static const struct v4l2_format_info formats[] = { { .format = V4L2_PIX_FMT_YUV420, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 }, { .format = V4L2_PIX_FMT_YVU420, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 }, { .format = V4L2_PIX_FMT_YUV422P, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 1 }, - { .format = V4L2_PIX_FMT_GREY, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, /* YUV planar formats, non contiguous variant */ { .format = V4L2_PIX_FMT_YUV420M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 3, .comp_planes = 3, .bpp = { 1, 1, 1, 0 }, .hdiv = 2, .vdiv = 2 }, @@ -1053,6 +1056,16 @@ static const struct v4l2_format_info formats[] = { { .format = V4L2_PIX_FMT_NV16M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 }, { .format = V4L2_PIX_FMT_NV61M, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 1, 2, 0, 0 }, .hdiv = 2, .vdiv = 1 }, + /* YUV luma-only formats */ + { .format = V4L2_PIX_FMT_GREY, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_Y10, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_Y10BPACK, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 10, 0, 0, 0 }, .hdiv = 8, .vdiv = 1, .block_w = { 2, 0, 0, 0 } }, + { .format = V4L2_PIX_FMT_Y10P, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_Y12, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_Y14, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_Y16, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + { .format = V4L2_PIX_FMT_Y16_BE, .pixel_enc = V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + /* Bayer RGB formats */ { .format = V4L2_PIX_FMT_SBGGR8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, { .format = V4L2_PIX_FMT_SGBRG8, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 1, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, @@ -1074,6 +1087,22 @@ static const struct v4l2_format_info formats[] = { { .format = V4L2_PIX_FMT_SGBRG12, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, { .format = V4L2_PIX_FMT_SGRBG12, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, { .format = V4L2_PIX_FMT_SRGGB12, .pixel_enc = V4L2_PIXEL_ENC_BAYER, .mem_planes = 1, .comp_planes = 1, .bpp = { 2, 0, 0, 0 }, .hdiv = 1, .vdiv = 1 }, + + /* Compressed formats. */ + { .format = V4L2_PIX_FMT_H263, .pixel_enc = V4L2_PIXEL_ENC_UNKNOWN, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 2, .vdiv = 2, .block_w = { 32, 0, 0, 0 }, .block_h = { 32, 0, 0, 0 } }, + { .format = V4L2_PIX_FMT_H264, .pixel_enc = V4L2_PIXEL_ENC_UNKNOWN, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 2, .vdiv = 2, .block_w = { 32, 0, 0, 0 }, .block_h = { 32, 0, 0, 0 } }, + { .format = V4L2_PIX_FMT_H264_MVC, .pixel_enc = V4L2_PIXEL_ENC_UNKNOWN, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 2, .vdiv = 2, .block_w = { 32, 0, 0, 0 }, .block_h = { 32, 0, 0, 0 } }, + { .format = V4L2_PIX_FMT_H264_NO_SC, .pixel_enc = V4L2_PIXEL_ENC_UNKNOWN, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 2, .vdiv = 2, .block_w = { 32, 0, 0, 0 }, .block_h = { 32, 0, 0, 0 } }, + { .format = V4L2_PIX_FMT_HEVC, .pixel_enc = V4L2_PIXEL_ENC_UNKNOWN, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 2, .vdiv = 2, .block_w = { 32, 0, 0, 0 }, .block_h = { 32, 0, 0, 0 } }, + { .format = V4L2_PIX_FMT_MPEG, .pixel_enc = V4L2_PIXEL_ENC_UNKNOWN, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 2, .vdiv = 2, .block_w = { 32, 0, 0, 0 }, .block_h = { 32, 0, 0, 0 } }, + { .format = V4L2_PIX_FMT_MPEG1, .pixel_enc = V4L2_PIXEL_ENC_UNKNOWN, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 2, .vdiv = 2, .block_w = { 32, 0, 0, 0 }, .block_h = { 32, 0, 0, 0 } }, + { .format = V4L2_PIX_FMT_MPEG2, .pixel_enc = V4L2_PIXEL_ENC_UNKNOWN, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 2, .vdiv = 2, .block_w = { 32, 0, 0, 0 }, .block_h = { 32, 0, 0, 0 } }, + { .format = V4L2_PIX_FMT_MPEG4, .pixel_enc = V4L2_PIXEL_ENC_UNKNOWN, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 2, .vdiv = 2, .block_w = { 32, 0, 0, 0 }, .block_h = { 32, 0, 0, 0 } }, + { .format = V4L2_PIX_FMT_VC1_ANNEX_G, .pixel_enc = V4L2_PIXEL_ENC_UNKNOWN, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 2, .vdiv = 2, .block_w = { 32, 0, 0, 0 }, .block_h = { 32, 0, 0, 0 } }, + { .format = V4L2_PIX_FMT_VC1_ANNEX_L, .pixel_enc = V4L2_PIXEL_ENC_UNKNOWN, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 2, .vdiv = 2, .block_w = { 32, 0, 0, 0 }, .block_h = { 32, 0, 0, 0 } }, + { .format = V4L2_PIX_FMT_VP8, .pixel_enc = V4L2_PIXEL_ENC_UNKNOWN, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 2, .vdiv = 2, .block_w = { 32, 0, 0, 0 }, .block_h = { 32, 0, 0, 0 } }, + { .format = V4L2_PIX_FMT_VP9, .pixel_enc = V4L2_PIXEL_ENC_UNKNOWN, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 2, .vdiv = 2, .block_w = { 32, 0, 0, 0 }, .block_h = { 32, 0, 0, 0 } }, + { .format = V4L2_PIX_FMT_XVID, .pixel_enc = V4L2_PIXEL_ENC_UNKNOWN, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0, 0 }, .hdiv = 2, .vdiv = 2, .block_w = { 32, 0, 0, 0 }, .block_h = { 32, 0, 0, 0 } }, // clang-format on };