Support for GRAY8 Camera Streaming on Jetson Xavier NX (JetPack 5.1.3) – Kernel Patch Guidance

Dear NVIDIA Support Team,

I am currently working with a Jetson Xavier NX running JetPack 5.1.3 (L4T 35.x) and integrating a monochrome camera that outputs GRAY8 (8-bit grayscale) format.

At present, I understand that GRAY8 pixel format is not supported by default in the Jetson kernel for this JetPack version. Due to this limitation, I am unable to directly stream the camera using standard pipelines (e.g., GStreamer, or libargus).

My requirement is to:

  • Capture and stream a GRAY8 (monochrome) camera

  • Use Jetson Xavier NX with JetPack 5.1.3

I would like to request guidance on the following points:

  1. Are there any official or recommended kernel patches from NVIDIA to enable GRAY8 support in the Jetson kernel for JetPack 5.1.3?

  2. Which kernel components typically require modification (e.g., pixel format definitions, CSI/VI drivers, or ISP-related modules) to support GRAY8?

  3. Are there any reference implementations or sample patches available that demonstrate successful GRAY8 camera integration on Xavier NX?

  4. Is there a preferred alternative approach (such as using a supported RAW Bayer format and converting to grayscale) that NVIDIA recommends for production use?

Any guidance, documentation, or best practices you could share would be greatly appreciated.

Thank you very much for your time and support.

Hello @cookiecooker249,

Typically, in order to enable Gray8 on NVIDIA Jetson you would only need the camera driver, a capture mode configuration on the DTB and to patch GStreamer if you pan to use v4l2src.

Otherwise, the rest should be straight forward.

Do you have a camera driver for your sensor?

best regards,
Andrew
Embedded Software Engineer at ProventusNova

hello cookiecooker249,

GRAY8 can be converted to GRAY8 or I420. other formats are not supported.
please convert to I420 first and then NV12.
you may check the source code of nvvidconv for more details, see-also jetson-linux-r3561 for [Driver Package (BSP) Sources].

here’re related topics for your reference.
such as.. Topic 175651, and Topic 352750.

Hello @JerryChang ,

Thank you for the guidance regarding GRAY → I420 → NV12 conversion and the nvvidconv reference. I have reviewed the BSP sources and attempted to add native grayscale support at the kernel level.

I would like to clarify that I am currently blocked earlier in the pipeline, as the GRAY format is not exposed by V4L2 at all, even after adding GRAY/Y10 support in the kernel.

What I have already modified

I added GRAY (Y10) support in the following kernel components:

  1. camera_common.c
/* GRAY */
{
    MEDIA_BUS_FMT_Y10_1X10,
    V4L2_COLORSPACE_RAW,
    V4L2_PIX_FMT_Y10,
},
  1. sensor_common.c
else if (strncmp(pixel_t, "gray_y10", size) == 0) {
    *format = V4L2_PIX_FMT_Y10;
}
  1. vi2_formats.h
/* GRAY */
TEGRA_VIDEO_FORMAT(RAW10, 10, Y10_1X10, 2, 1, T_R16_I,
                   RAW10, Y10, "GRAY10"),
  1. Device tree
mode_type = "gray";
pixel_phase = "y";
csi_pixel_bit_depth = "10";

Current behavior

After rebuilding and flashing the kernel, the camera probes correctly, but GRAY / GREY is still not advertised:

v4l2-ctl -d /dev/video0 --list-formats

ioctl: VIDIOC_ENUM_FMT
Type: Video Capture

[0]: 'UYVY' (UYVY 4:2:2)
[1]: 'NV16' (Y/CbCr 4:2:2)
[2]: 'UYVY' (UYVY 4:2:2)

Expected (at minimum):

[0]: 'GREY' (8-bit Greyscale)
or
[0]: 'Y10 ' (10-bit Greyscale)

clarification needed

  1. Which additional kernel components must be updated to expose GRAY formats via VIDIOC_ENUM_FMT?

    • VI capture driver?

    • tegra-video / tegra-channel format tables?

    • V4L2 ioctl handling?

  2. Is there an internal limitation in the VI or camera stack on JetPack 5.1.x that prevents GRAY formats from being enumerated, even if added to:

    • camera_common

    • sensor_common

    • vi2_formats

  3. Could you please share:

    • A complete reference patch (or list of required files) that successfully exposes GREY/Y10 in V4L2 on Xavier NX, or

    • Confirmation that native GRAY capture is not supported in JP 5.1.x and must be handled as RAW Bayer or YUV only.

At this point, I want to ensure I am not missing any required internal format registration or hard limitation in the Jetson camera stack.

Any concrete guidance or confirmation would be very helpful.

Thank you for your support.

hello cookiecooker249,

this looks incorrect, Xavier series were using VI version 5, you should have format extension to the header file, vi5_formats.h.

Hi @JerryChang ,

Thank you for the clarification , understood.
Yes, Xavier NX uses VI version 5, so extending vi2_formats.h was incorrect.

I will move the GRAY/Y10 format extension to vi5_formats.h instead.

Before proceeding, I would like to confirm the remaining required changes to ensure GRAY formats are correctly exposed via VIDIOC_ENUM_FMT:

  1. Besides adding the GRAY/Y10 entry in vi5_formats.h, are there additional VI5-specific tables or mappings that must also be updated (e.g. in tegra_channel.c or related format negotiation logic)?

  2. Should the GRAY format be registered as:

    • V4L2_PIX_FMT_GREY (8-bit), or

    • V4L2_PIX_FMT_Y10 (10-bit),
      for proper enumeration on VI5?

  3. Is there any hard limitation in the VI5 capture path (JP 5.1.x / L4T 35.x) that prevents GRAY formats from being advertised even after extending:

    • camera_common.c

    • sensor_common.c

    • vi5_formats.h

  4. If available, could you please share a minimal reference patch or file list that demonstrates a successful format addition on VI5?

Once the format is correctly enumerated, I can handle color conversion in user space as previously suggested.

Thanks again for your guidance.

hello cookiecooker249,

please modify VI driver to extend the GREY format supports,
you may add TEGRA_VIDEO_FORMAT(RAW8, 8, Y8_1X8, 1, 1, T_R8, RAW8, GREY, “GRAY8”) for 8-bit greyscale formats.
for instance,
$public_sources/kernel_src/kernel/nvidia-oot/drivers/media/platform/tegra/camera/vi/vi5_formats.h
enum tegra_image_format {...}
static const struct tegra_video_format vi5_video_formats[] = {...}

Hello @JerryChang ,

Thank you for the detailed suggestion to add the following line in vi5_formats.h to extend support for the 8-bit grayscale format:

TEGRA_VIDEO_FORMAT(RAW8, 8, Y8_1X8, 1, 1, T_R8, RAW8, GREY, “GRAY8”)

I have followed this recommendation, and the vi5_video_formats[] table is now correctly updated.

However, after rebuilding and flashing the kernel, I am still seeing the following formats in v4l2-ctl:

v4l2-ctl -d /dev/video0 --list-formats
ioctl: VIDIOC_ENUM_FMT
Type: Video Capture

[0]: 'UYVY' (UYVY 4:2:2)
[1]: 'NV16' (Y/CbCr 4:2:2)
[2]: 'UYVY' (UYVY 4:2:2)

The GRAY8 format still does not appear in the list, and I am unable to capture in grayscale.

DTS Configuration

In my device tree, I have the following settings for the camera:

mode_type = "gray";
csi_pixel_bit_depth = "8";
pixel_phase = "y";

Questions:

  1. Are there any additional updates required in camera_common.c or sensor_common.c to fully integrate the GRAY8 format (8-bit grayscale) on Xavier NX?

  2. Is there a need for further registration or format negotiation steps in these files to ensure that V4L2_PIX_FMT_GREY or V4L2_PIX_FMT_Y8 becomes properly exposed?

It seems like the format registration itself might be correct, but some additional step may be required to finalize the integration.

Thank you for your continued support.

hello cookiecooker249

yes.. it’s device tree to compose mode_type + pixel_phase + csi_pixel_bit_depth as a string for sending to VI driver, it’s driver side to distinguish its fourcc formats.
please update your device tree (to have corresponding format string), and also revise the function below in sensor_common.c to extend your pixel format mappings.
you may check below as an example,

static int extract_pixel_format(const char *pixel_t, u32 *format)
{
...
+        else if (strncmp(pixel_t, "bayer_gray8", size) == 0)  
+                *format = V4L2_PIX_FMT_GREY

Thank You @JerryChang :)