From 6b07a48679de0d44437e647b5e1356cd82091dd4 Mon Sep 17 00:00:00 2001 From: Josuah Demangeon Date: Sat, 12 Apr 2025 16:14:26 +0200 Subject: [PATCH 1/3] drivers: video: improve the format description docs @verbatim shows the leading comment '*' fence in the output. @code{.unparsed} allows extracting the text only. In some formats, the pixels are also not immediately packed into fixed number of bytes, like YUYV due to chroma subsampling. Disambiguate. Add numbers marks on top to help identify the individual pixels. Signed-off-by: Josuah Demangeon --- include/zephyr/drivers/video.h | 64 ++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 27 deletions(-) diff --git a/include/zephyr/drivers/video.h b/include/zephyr/drivers/video.h index 3788c9bad47d..7642e334b0d0 100644 --- a/include/zephyr/drivers/video.h +++ b/include/zephyr/drivers/video.h @@ -810,7 +810,7 @@ void video_closest_frmival(const struct device *dev, enum video_endpoint_id ep, /** * @defgroup video_pixel_formats Video pixel formats - * The @c | characters separate the pixels, and spaces separate the bytes. + * The '|' characters separate the pixels or logical blocks, and spaces separate the bytes. * The uppercase letter represents the most significant bit. * The lowercase letters represent the rest of the bits. * @{ @@ -856,38 +856,48 @@ void video_closest_frmival(const struct device *dev, enum video_endpoint_id ep, * * The full color information is spread over multiple pixels. * + * When the format includes more than 8-bit per pixel, a strategy becomes needed to pack + * the bits over multiple bytes, as illustrated for each format. + * + * The number above the 'R', 'r', 'G', 'g', 'B', 'b' are hints about which pixel number the + * following bits belong to. + * * @{ */ /** - * @verbatim - * | Bbbbbbbb | Gggggggg | Bbbbbbbb | Gggggggg | Bbbbbbbb | Gggggggg | ... - * | Gggggggg | Rrrrrrrr | Gggggggg | Rrrrrrrr | Gggggggg | Rrrrrrrr | ... - * @endverbatim + * @code{.unparsed} + * 0 1 2 3 + * | Bbbbbbbb | Gggggggg | Bbbbbbbb | Gggggggg | ... + * | Gggggggg | Rrrrrrrr | Gggggggg | Rrrrrrrr | ... + * @endcode */ #define VIDEO_PIX_FMT_BGGR8 VIDEO_FOURCC('B', 'A', '8', '1') /** - * @verbatim - * | Gggggggg | Bbbbbbbb | Gggggggg | Bbbbbbbb | Gggggggg | Bbbbbbbb | ... - * | Rrrrrrrr | Gggggggg | Rrrrrrrr | Gggggggg | Rrrrrrrr | Gggggggg | ... - * @endverbatim + * @code{.unparsed} + * 0 1 2 3 + * | Gggggggg | Bbbbbbbb | Gggggggg | Bbbbbbbb | ... + * | Rrrrrrrr | Gggggggg | Rrrrrrrr | Gggggggg | ... + * @endcode */ #define VIDEO_PIX_FMT_GBRG8 VIDEO_FOURCC('G', 'B', 'R', 'G') /** - * @verbatim - * | Gggggggg | Rrrrrrrr | Gggggggg | Rrrrrrrr | Gggggggg | Rrrrrrrr | ... - * | Bbbbbbbb | Gggggggg | Bbbbbbbb | Gggggggg | Bbbbbbbb | Gggggggg | ... - * @endverbatim + * @code{.unparsed} + * 0 1 2 3 + * | Gggggggg | Rrrrrrrr | Gggggggg | Rrrrrrrr | ... + * | Bbbbbbbb | Gggggggg | Bbbbbbbb | Gggggggg | ... + * @endcode */ #define VIDEO_PIX_FMT_GRBG8 VIDEO_FOURCC('G', 'R', 'B', 'G') /** - * @verbatim - * | Rrrrrrrr | Gggggggg | Rrrrrrrr | Gggggggg | Rrrrrrrr | Gggggggg | ... - * | Gggggggg | Bbbbbbbb | Gggggggg | Bbbbbbbb | Gggggggg | Bbbbbbbb | ... - * @endverbatim + * @code{.unparsed} + * 0 1 2 3 + * | Rrrrrrrr | Gggggggg | Rrrrrrrr | Gggggggg | ... + * | Gggggggg | Bbbbbbbb | Gggggggg | Bbbbbbbb | ... + * @endcode */ #define VIDEO_PIX_FMT_RGGB8 VIDEO_FOURCC('R', 'G', 'G', 'B') @@ -905,10 +915,10 @@ void video_closest_frmival(const struct device *dev, enum video_endpoint_id ep, * 5 red bits [15:11], 6 green bits [10:5], 5 blue bits [4:0]. * This 16-bit integer is then packed in big endian format over two bytes: * - * @verbatim + * @code{.unparsed} * 15.....8 7......0 * | RrrrrGgg gggBbbbb | ... - * @endverbatim + * @endcode */ #define VIDEO_PIX_FMT_RGB565X VIDEO_FOURCC('R', 'G', 'B', 'R') @@ -916,19 +926,19 @@ void video_closest_frmival(const struct device *dev, enum video_endpoint_id ep, * 5 red bits [15:11], 6 green bits [10:5], 5 blue bits [4:0]. * This 16-bit integer is then packed in little endian format over two bytes: * - * @verbatim + * @code{.unparsed} * 7......0 15.....8 * | gggBbbbb RrrrrGgg | ... - * @endverbatim + * @endcode */ #define VIDEO_PIX_FMT_RGB565 VIDEO_FOURCC('R', 'G', 'B', 'P') /** * The first byte is empty (X) for each pixel. * - * @verbatim + * @code{.unparsed} * | Xxxxxxxx Rrrrrrrr Gggggggg Bbbbbbbb | ... - * @endverbatim + * @endcode */ #define VIDEO_PIX_FMT_XRGB32 VIDEO_FOURCC('B', 'X', '2', '4') @@ -946,18 +956,18 @@ void video_closest_frmival(const struct device *dev, enum video_endpoint_id ep, * There is either a missing channel per pixel, U or V. * The value is to be averaged over 2 pixels to get the value of individual pixel. * - * @verbatim + * @code{.unparsed} * | Yyyyyyyy Uuuuuuuu | Yyyyyyyy Vvvvvvvv | ... - * @endverbatim + * @endcode */ #define VIDEO_PIX_FMT_YUYV VIDEO_FOURCC('Y', 'U', 'Y', 'V') /** * The first byte is empty (X) for each pixel. * - * @verbatim + * @code{.unparsed} * | Xxxxxxxx Yyyyyyyy Uuuuuuuu Vvvvvvvv | ... - * @endverbatim + * @endcode */ #define VIDEO_PIX_FMT_XYUV32 VIDEO_FOURCC('X', 'Y', 'U', 'V') From 93776b470d9f1174801c89a53a48ebe05dd375b5 Mon Sep 17 00:00:00 2001 From: Josuah Demangeon Date: Thu, 3 Apr 2025 22:06:44 +0000 Subject: [PATCH 2/3] drivers: video: formats: include bayer 10/12/14-bits formats In addition to the 8-bit, introduce all the other bayer formats described by MIPI-CSI2 specification. The 8-bit bayer formats description is shortened to just 4 bytes like the other formats, to help intuition while comparing the different formats. Signed-off-by: Josuah Demangeon --- include/zephyr/drivers/video.h | 126 +++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) diff --git a/include/zephyr/drivers/video.h b/include/zephyr/drivers/video.h index 7642e334b0d0..09372083a53b 100644 --- a/include/zephyr/drivers/video.h +++ b/include/zephyr/drivers/video.h @@ -901,6 +901,114 @@ void video_closest_frmival(const struct device *dev, enum video_endpoint_id ep, */ #define VIDEO_PIX_FMT_RGGB8 VIDEO_FOURCC('R', 'G', 'G', 'B') +/** + * @code{.unparsed} + * 0 1 2 3 3 2 1 0 + * | Bbbbbbbb | Gggggggg | Bbbbbbbb | Gggggggg | ggbbggbb | ... + * | Gggggggg | Rrrrrrrr | Gggggggg | Rrrrrrrr | rrggrrgg | ... + * @endcode + */ +#define VIDEO_PIX_FMT_SBGGR10P VIDEO_FOURCC('p', 'B', 'A', 'A') + +/** + * @code{.unparsed} + * 0 1 2 3 3 2 1 0 + * | Gggggggg | Bbbbbbbb | Gggggggg | Bbbbbbbb | bbggbbgg | ... + * | Rrrrrrrr | Gggggggg | Rrrrrrrr | Gggggggg | ggrrggrr | ... + * @endcode + */ +#define VIDEO_PIX_FMT_SGBRG10P VIDEO_FOURCC('p', 'G', 'A', 'A') + +/** + * @code{.unparsed} + * 0 1 2 3 3 2 1 0 + * | Gggggggg | Rrrrrrrr | Gggggggg | Rrrrrrrr | rrggrrgg | ... + * | Bbbbbbbb | Gggggggg | Bbbbbbbb | Gggggggg | ggbbggbb | ... + * @endcode + */ +#define VIDEO_PIX_FMT_SGRBG10P VIDEO_FOURCC('p', 'g', 'A', 'A') + +/** + * @code{.unparsed} + * 0 1 2 3 3 2 1 0 + * | Rrrrrrrr | Gggggggg | Rrrrrrrr | Gggggggg | ggrrggrr | ... + * | Gggggggg | Bbbbbbbb | Gggggggg | Bbbbbbbb | bbggbbgg | ... + * @endcode + */ +#define VIDEO_PIX_FMT_SRGGB10P VIDEO_FOURCC('p', 'R', 'A', 'A') + +/** + * @code{.unparsed} + * 0 1 1 0 2 3 3 2 + * | Bbbbbbbb | Gggggggg | ggggbbbb | Bbbbbbbb | Gggggggg | ggggbbbb | ... + * | Gggggggg | Rrrrrrrr | rrrrgggg | Gggggggg | Rrrrrrrr | rrrrgggg | ... + * @endcode + */ +#define VIDEO_PIX_FMT_SBGGR12P VIDEO_FOURCC('p', 'B', 'C', 'C') + +/** + * @code{.unparsed} + * 0 1 1 0 2 3 3 2 + * | Gggggggg | Bbbbbbbb | bbbbgggg | Gggggggg | Bbbbbbbb | bbbbgggg | ... + * | Rrrrrrrr | Gggggggg | ggggrrrr | Rrrrrrrr | Gggggggg | ggggrrrr | ... + * @endcode + */ +#define VIDEO_PIX_FMT_SGBRG12P VIDEO_FOURCC('p', 'G', 'C', 'C') + +/** + * @code{.unparsed} + * 0 1 1 0 2 3 3 2 + * | Gggggggg | Rrrrrrrr | rrrrgggg | Gggggggg | Rrrrrrrr | rrrrgggg | ... + * | Bbbbbbbb | Gggggggg | ggggbbbb | Bbbbbbbb | Gggggggg | ggggbbbb | ... + * @endcode + */ +#define VIDEO_PIX_FMT_SGRBG12P VIDEO_FOURCC('p', 'g', 'C', 'C') + +/** + * @code{.unparsed} + * 0 1 1 0 2 3 3 2 + * | Rrrrrrrr | Gggggggg | ggggrrrr | Rrrrrrrr | Gggggggg | ggggrrrr | ... + * | Gggggggg | Bbbbbbbb | bbbbgggg | Gggggggg | Bbbbbbbb | bbbbgggg | ... + * @endcode + */ +#define VIDEO_PIX_FMT_SRGGB12P VIDEO_FOURCC('p', 'R', 'C', 'C') + +/** + * @code{.unparsed} + * 0 1 2 3 1 0 2 1 3 2 + * | Bbbbbbbb | Gggggggg | Bbbbbbbb | Gggggggg | ggbbbbbb bbbbgggg ggggggbb | ... + * | Gggggggg | Rrrrrrrr | Gggggggg | Rrrrrrrr | rrgggggg ggggrrrr rrrrrrgg | ... + * @endcode + */ +#define VIDEO_PIX_FMT_SBGGR14P VIDEO_FOURCC('p', 'B', 'E', 'E') + +/** + * @code{.unparsed} + * 0 1 2 3 1 0 2 1 3 2 + * | Gggggggg | Bbbbbbbb | Gggggggg | Bbbbbbbb | bbgggggg ggggbbbb bbbbbbgg | ... + * | Rrrrrrrr | Gggggggg | Rrrrrrrr | Gggggggg | ggrrrrrr rrrrgggg ggggggrr | ... + * @endcode + */ +#define VIDEO_PIX_FMT_SGBRG14P VIDEO_FOURCC('p', 'G', 'E', 'E') + +/** + * @code{.unparsed} + * 0 1 2 3 1 0 2 1 3 2 + * | Gggggggg | Rrrrrrrr | Gggggggg | Rrrrrrrr | rrgggggg ggggrrrr rrrrrrgg | ... + * | Bbbbbbbb | Gggggggg | Bbbbbbbb | Gggggggg | ggbbbbbb bbbbgggg ggggggbb | ... + * @endcode + */ +#define VIDEO_PIX_FMT_SGRBG14P VIDEO_FOURCC('p', 'g', 'E', 'E') + +/** + * @code{.unparsed} + * 0 1 2 3 1 0 2 1 3 2 + * | Rrrrrrrr | Gggggggg | Rrrrrrrr | Gggggggg | ggrrrrrr rrrrgggg ggggggrr | ... + * | Gggggggg | Bbbbbbbb | Gggggggg | Bbbbbbbb | bbgggggg ggggbbbb bbbbbbgg | ... + * @endcode + */ +#define VIDEO_PIX_FMT_SRGGB14P VIDEO_FOURCC('p', 'R', 'E', 'E') + /** * @} */ @@ -1005,6 +1113,24 @@ static inline unsigned int video_bits_per_pixel(uint32_t pixfmt) case VIDEO_PIX_FMT_GRBG8: case VIDEO_PIX_FMT_RGGB8: return 8; + case VIDEO_PIX_FMT_SBGGR10P: + case VIDEO_PIX_FMT_SGBRG10P: + case VIDEO_PIX_FMT_SGRBG10P: + case VIDEO_PIX_FMT_SRGGB10P: + case VIDEO_PIX_FMT_Y10P: + return 10; + case VIDEO_PIX_FMT_SBGGR12P: + case VIDEO_PIX_FMT_SGBRG12P: + case VIDEO_PIX_FMT_SGRBG12P: + case VIDEO_PIX_FMT_SRGGB12P: + case VIDEO_PIX_FMT_Y12P: + return 12; + case VIDEO_PIX_FMT_SBGGR14P: + case VIDEO_PIX_FMT_SGBRG14P: + case VIDEO_PIX_FMT_SGRBG14P: + case VIDEO_PIX_FMT_SRGGB14P: + case VIDEO_PIX_FMT_Y14P: + return 14; case VIDEO_PIX_FMT_RGB565: case VIDEO_PIX_FMT_YUYV: return 16; From 95e96944cb83ce02a6c7aaca0e3325201a0f943e Mon Sep 17 00:00:00 2001 From: Josuah Demangeon Date: Fri, 4 Apr 2025 01:30:04 +0000 Subject: [PATCH 3/3] drivers: video: formats: add grayscale formats Add the grayscale formats in the same packing as defined by MIPI. The Linux V4L2 naming is preserved. Signed-off-by: Josuah Demangeon --- include/zephyr/drivers/video.h | 54 ++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/include/zephyr/drivers/video.h b/include/zephyr/drivers/video.h index 09372083a53b..f0632959e36e 100644 --- a/include/zephyr/drivers/video.h +++ b/include/zephyr/drivers/video.h @@ -1009,6 +1009,59 @@ void video_closest_frmival(const struct device *dev, enum video_endpoint_id ep, */ #define VIDEO_PIX_FMT_SRGGB14P VIDEO_FOURCC('p', 'R', 'E', 'E') +/** + * @} + */ + +/** + * @name Grayscale formats + * Luminance (Y) channel only, in various bit depth and packing. + * + * When the format includes more than 8-bit per pixel, a strategy becomes needed to pack + * the bits over multiple bytes, as illustrated for each format. + * + * The number above the 'Y', 'y' are hints about which pixel number the following bits belong to. + * + * @{ + */ + +/** + * Same as Y8 (8-bit luma-only) following the standard FOURCC naming, + * or L8 in some graphics libraries. + * + * @code{.unparsed} + * 0 1 2 3 + * | Yyyyyyyy | Yyyyyyyy | Yyyyyyyy | Yyyyyyyy | ... + * @endcode + */ +#define VIDEO_PIX_FMT_GREY VIDEO_FOURCC('G', 'R', 'E', 'Y') + +/** + * @code{.unparsed} + * 0 1 2 3 3 2 1 0 + * | Yyyyyyyy | Yyyyyyyy | Yyyyyyyy | Yyyyyyyy | yyyyyyyy | ... + * @endcode + */ +#define VIDEO_PIX_FMT_Y10P VIDEO_FOURCC('Y', '1', '0', 'P') + +/** + * @code{.unparsed} + * 0 1 1 0 2 3 3 2 + * | Yyyyyyyy | Yyyyyyyy | yyyyyyyy | Yyyyyyyy | Yyyyyyyy | yyyyyyyy | ... + * | Yyyyyyyy | Yyyyyyyy | yyyyyyyy | Yyyyyyyy | Yyyyyyyy | yyyyyyyy | ... + * @endcode + */ +#define VIDEO_PIX_FMT_Y12P VIDEO_FOURCC('Y', '1', '2', 'P') + +/** + * @code{.unparsed} + * 0 1 2 3 1 0 2 1 3 2 + * | Yyyyyyyy | Yyyyyyyy | Yyyyyyyy | Yyyyyyyy | yyyyyyyy yyyyyyyy yyyyyyyy | ... + * | Yyyyyyyy | Yyyyyyyy | Yyyyyyyy | Yyyyyyyy | yyyyyyyy yyyyyyyy yyyyyyyy | ... + * @endcode + */ +#define VIDEO_PIX_FMT_Y14P VIDEO_FOURCC('Y', '1', '4', 'P') + /** * @} */ @@ -1112,6 +1165,7 @@ static inline unsigned int video_bits_per_pixel(uint32_t pixfmt) case VIDEO_PIX_FMT_GBRG8: case VIDEO_PIX_FMT_GRBG8: case VIDEO_PIX_FMT_RGGB8: + case VIDEO_PIX_FMT_GREY: return 8; case VIDEO_PIX_FMT_SBGGR10P: case VIDEO_PIX_FMT_SGBRG10P: