Skip to content

drivers: video: formats: add most of the raw formats #88138

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Apr 14, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
244 changes: 217 additions & 27 deletions include/zephyr/drivers/video.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
* @{
Expand Down Expand Up @@ -856,41 +856,212 @@ 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')

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

/**
* @}
*/

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

/**
* @}
*/
Expand All @@ -905,30 +1076,30 @@ 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')

/**
* 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')

Expand All @@ -946,18 +1117,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')

Expand Down Expand Up @@ -994,7 +1165,26 @@ 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:
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;
Expand Down