linux/include/media/v4l2-uvc.h
Marek Vasut 638eeb0e8a media: uvcvideo: Add GUID for BGRA/X 8:8:8:8
[ Upstream commit 015d44c2b7 ]

The Cypress EZUSB FX3 UVC example can be configured to report pixel
format "e436eb7e-524f-11ce-9f53-0020af0ba770". This is its GUID for
BGRA/X 8:8:8:8.

The UVC 1.5 spec [1] only defines GUIDs for YUY2, NV12, M420 and I420.
This seems to be an extension documented in the Microsoft Windows Media
Format SDK[2]. This Media Format SDK defines this GUID as corresponding
to `MEDIASUBTYPE_RGB32`, which is confirmed by [4] as `MEDIASUBTYPE_ARGB32`
has different GUID.

Note that in my case, the FX3 UVC can output either channel order,
BGR or RGB or any other mix for that matter. Since Linux commit
1b8dc32286 ("[media] uvcvideo: Add GUID for BGR 8:8:8")
defined a GUID for `MEDIASUBTYPE_RGB24` channel order as BGR, keep
this change consistent and define `MEDIASUBTYPE_RGB32` as BGR as well.
Document [3] also indicates the channel order is BGR.

[1] https://www.usb.org/document-library/video-class-v15-document-set
[2] https://learn.microsoft.com/en-us/windows/win32/wmformat/media-type-identifiers
[3] https://learn.microsoft.com/en-us/windows/win32/directshow/uncompressed-rgb-video-subtypes
[4] https://gix.github.io/media-types/

Signed-off-by: Marek Vasut <marex@denx.de>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Ricardo Ribalda <ricardo@ribalda.com>
Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
Link: https://lore.kernel.org/r/20230126231456.3402323-2-m.grzeschik@pengutronix.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
2023-03-11 13:55:35 +01:00

368 lines
10 KiB
C

/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* v4l2 uvc internal API header
*
* Some commonly needed functions for uvc drivers
*/
#ifndef __LINUX_V4L2_UVC_H
#define __LINUX_V4L2_UVC_H
/* ------------------------------------------------------------------------
* GUIDs
*/
#define UVC_GUID_UVC_CAMERA \
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}
#define UVC_GUID_UVC_OUTPUT \
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}
#define UVC_GUID_UVC_MEDIA_TRANSPORT_INPUT \
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03}
#define UVC_GUID_UVC_PROCESSING \
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01}
#define UVC_GUID_UVC_SELECTOR \
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02}
#define UVC_GUID_EXT_GPIO_CONTROLLER \
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03}
#define UVC_GUID_FORMAT_MJPEG \
{ 'M', 'J', 'P', 'G', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_YUY2 \
{ 'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_YUY2_ISIGHT \
{ 'Y', 'U', 'Y', '2', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0x00, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_NV12 \
{ 'N', 'V', '1', '2', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_YV12 \
{ 'Y', 'V', '1', '2', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_I420 \
{ 'I', '4', '2', '0', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_UYVY \
{ 'U', 'Y', 'V', 'Y', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_Y800 \
{ 'Y', '8', '0', '0', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_Y8 \
{ 'Y', '8', ' ', ' ', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_Y10 \
{ 'Y', '1', '0', ' ', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_Y12 \
{ 'Y', '1', '2', ' ', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_Y16 \
{ 'Y', '1', '6', ' ', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_BY8 \
{ 'B', 'Y', '8', ' ', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_BA81 \
{ 'B', 'A', '8', '1', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_GBRG \
{ 'G', 'B', 'R', 'G', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_GRBG \
{ 'G', 'R', 'B', 'G', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_RGGB \
{ 'R', 'G', 'G', 'B', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_BG16 \
{ 'B', 'G', '1', '6', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_GB16 \
{ 'G', 'B', '1', '6', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_RG16 \
{ 'R', 'G', '1', '6', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_GR16 \
{ 'G', 'R', '1', '6', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_RGBP \
{ 'R', 'G', 'B', 'P', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_BGR3 \
{ 0x7d, 0xeb, 0x36, 0xe4, 0x4f, 0x52, 0xce, 0x11, \
0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}
#define UVC_GUID_FORMAT_BGR4 \
{ 0x7e, 0xeb, 0x36, 0xe4, 0x4f, 0x52, 0xce, 0x11, \
0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}
#define UVC_GUID_FORMAT_M420 \
{ 'M', '4', '2', '0', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_H264 \
{ 'H', '2', '6', '4', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_H265 \
{ 'H', '2', '6', '5', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_Y8I \
{ 'Y', '8', 'I', ' ', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_Y12I \
{ 'Y', '1', '2', 'I', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_Z16 \
{ 'Z', '1', '6', ' ', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_RW10 \
{ 'R', 'W', '1', '0', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_INVZ \
{ 'I', 'N', 'V', 'Z', 0x90, 0x2d, 0x58, 0x4a, \
0x92, 0x0b, 0x77, 0x3f, 0x1f, 0x2c, 0x55, 0x6b}
#define UVC_GUID_FORMAT_INZI \
{ 'I', 'N', 'Z', 'I', 0x66, 0x1a, 0x42, 0xa2, \
0x90, 0x65, 0xd0, 0x18, 0x14, 0xa8, 0xef, 0x8a}
#define UVC_GUID_FORMAT_INVI \
{ 'I', 'N', 'V', 'I', 0xdb, 0x57, 0x49, 0x5e, \
0x8e, 0x3f, 0xf4, 0x79, 0x53, 0x2b, 0x94, 0x6f}
#define UVC_GUID_FORMAT_CNF4 \
{ 'C', ' ', ' ', ' ', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_D3DFMT_L8 \
{0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_KSMEDIA_L8_IR \
{0x32, 0x00, 0x00, 0x00, 0x02, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
#define UVC_GUID_FORMAT_HEVC \
{ 'H', 'E', 'V', 'C', 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
/* ------------------------------------------------------------------------
* Video formats
*/
struct uvc_format_desc {
char *name;
u8 guid[16];
u32 fcc;
};
static struct uvc_format_desc uvc_fmts[] = {
{
.name = "YUV 4:2:2 (YUYV)",
.guid = UVC_GUID_FORMAT_YUY2,
.fcc = V4L2_PIX_FMT_YUYV,
},
{
.name = "YUV 4:2:2 (YUYV)",
.guid = UVC_GUID_FORMAT_YUY2_ISIGHT,
.fcc = V4L2_PIX_FMT_YUYV,
},
{
.name = "YUV 4:2:0 (NV12)",
.guid = UVC_GUID_FORMAT_NV12,
.fcc = V4L2_PIX_FMT_NV12,
},
{
.name = "MJPEG",
.guid = UVC_GUID_FORMAT_MJPEG,
.fcc = V4L2_PIX_FMT_MJPEG,
},
{
.name = "YVU 4:2:0 (YV12)",
.guid = UVC_GUID_FORMAT_YV12,
.fcc = V4L2_PIX_FMT_YVU420,
},
{
.name = "YUV 4:2:0 (I420)",
.guid = UVC_GUID_FORMAT_I420,
.fcc = V4L2_PIX_FMT_YUV420,
},
{
.name = "YUV 4:2:0 (M420)",
.guid = UVC_GUID_FORMAT_M420,
.fcc = V4L2_PIX_FMT_M420,
},
{
.name = "YUV 4:2:2 (UYVY)",
.guid = UVC_GUID_FORMAT_UYVY,
.fcc = V4L2_PIX_FMT_UYVY,
},
{
.name = "Greyscale 8-bit (Y800)",
.guid = UVC_GUID_FORMAT_Y800,
.fcc = V4L2_PIX_FMT_GREY,
},
{
.name = "Greyscale 8-bit (Y8 )",
.guid = UVC_GUID_FORMAT_Y8,
.fcc = V4L2_PIX_FMT_GREY,
},
{
.name = "Greyscale 8-bit (D3DFMT_L8)",
.guid = UVC_GUID_FORMAT_D3DFMT_L8,
.fcc = V4L2_PIX_FMT_GREY,
},
{
.name = "IR 8-bit (L8_IR)",
.guid = UVC_GUID_FORMAT_KSMEDIA_L8_IR,
.fcc = V4L2_PIX_FMT_GREY,
},
{
.name = "Greyscale 10-bit (Y10 )",
.guid = UVC_GUID_FORMAT_Y10,
.fcc = V4L2_PIX_FMT_Y10,
},
{
.name = "Greyscale 12-bit (Y12 )",
.guid = UVC_GUID_FORMAT_Y12,
.fcc = V4L2_PIX_FMT_Y12,
},
{
.name = "Greyscale 16-bit (Y16 )",
.guid = UVC_GUID_FORMAT_Y16,
.fcc = V4L2_PIX_FMT_Y16,
},
{
.name = "BGGR Bayer (BY8 )",
.guid = UVC_GUID_FORMAT_BY8,
.fcc = V4L2_PIX_FMT_SBGGR8,
},
{
.name = "BGGR Bayer (BA81)",
.guid = UVC_GUID_FORMAT_BA81,
.fcc = V4L2_PIX_FMT_SBGGR8,
},
{
.name = "GBRG Bayer (GBRG)",
.guid = UVC_GUID_FORMAT_GBRG,
.fcc = V4L2_PIX_FMT_SGBRG8,
},
{
.name = "GRBG Bayer (GRBG)",
.guid = UVC_GUID_FORMAT_GRBG,
.fcc = V4L2_PIX_FMT_SGRBG8,
},
{
.name = "RGGB Bayer (RGGB)",
.guid = UVC_GUID_FORMAT_RGGB,
.fcc = V4L2_PIX_FMT_SRGGB8,
},
{
.name = "RGB565",
.guid = UVC_GUID_FORMAT_RGBP,
.fcc = V4L2_PIX_FMT_RGB565,
},
{
.name = "BGR 8:8:8 (BGR3)",
.guid = UVC_GUID_FORMAT_BGR3,
.fcc = V4L2_PIX_FMT_BGR24,
},
{
.name = "BGRA/X 8:8:8:8 (BGR4)",
.guid = UVC_GUID_FORMAT_BGR4,
.fcc = V4L2_PIX_FMT_XBGR32,
},
{
.name = "H.264",
.guid = UVC_GUID_FORMAT_H264,
.fcc = V4L2_PIX_FMT_H264,
},
{
.name = "H.265",
.guid = UVC_GUID_FORMAT_H265,
.fcc = V4L2_PIX_FMT_HEVC,
},
{
.name = "Greyscale 8 L/R (Y8I)",
.guid = UVC_GUID_FORMAT_Y8I,
.fcc = V4L2_PIX_FMT_Y8I,
},
{
.name = "Greyscale 12 L/R (Y12I)",
.guid = UVC_GUID_FORMAT_Y12I,
.fcc = V4L2_PIX_FMT_Y12I,
},
{
.name = "Depth data 16-bit (Z16)",
.guid = UVC_GUID_FORMAT_Z16,
.fcc = V4L2_PIX_FMT_Z16,
},
{
.name = "Bayer 10-bit (SRGGB10P)",
.guid = UVC_GUID_FORMAT_RW10,
.fcc = V4L2_PIX_FMT_SRGGB10P,
},
{
.name = "Bayer 16-bit (SBGGR16)",
.guid = UVC_GUID_FORMAT_BG16,
.fcc = V4L2_PIX_FMT_SBGGR16,
},
{
.name = "Bayer 16-bit (SGBRG16)",
.guid = UVC_GUID_FORMAT_GB16,
.fcc = V4L2_PIX_FMT_SGBRG16,
},
{
.name = "Bayer 16-bit (SRGGB16)",
.guid = UVC_GUID_FORMAT_RG16,
.fcc = V4L2_PIX_FMT_SRGGB16,
},
{
.name = "Bayer 16-bit (SGRBG16)",
.guid = UVC_GUID_FORMAT_GR16,
.fcc = V4L2_PIX_FMT_SGRBG16,
},
{
.name = "Depth data 16-bit (Z16)",
.guid = UVC_GUID_FORMAT_INVZ,
.fcc = V4L2_PIX_FMT_Z16,
},
{
.name = "Greyscale 10-bit (Y10 )",
.guid = UVC_GUID_FORMAT_INVI,
.fcc = V4L2_PIX_FMT_Y10,
},
{
.name = "IR:Depth 26-bit (INZI)",
.guid = UVC_GUID_FORMAT_INZI,
.fcc = V4L2_PIX_FMT_INZI,
},
{
.name = "4-bit Depth Confidence (Packed)",
.guid = UVC_GUID_FORMAT_CNF4,
.fcc = V4L2_PIX_FMT_CNF4,
},
{
.name = "HEVC",
.guid = UVC_GUID_FORMAT_HEVC,
.fcc = V4L2_PIX_FMT_HEVC,
},
};
static inline struct uvc_format_desc *uvc_format_by_guid(const u8 guid[16])
{
unsigned int len = ARRAY_SIZE(uvc_fmts);
unsigned int i;
for (i = 0; i < len; ++i) {
if (memcmp(guid, uvc_fmts[i].guid, 16) == 0)
return &uvc_fmts[i];
}
return NULL;
}
#endif /* __LINUX_V4L2_UVC_H */