Hi NVIDIA team,
We have been investigating colorimetry metadata propagation when encoding video on a Jetson AGX Orin DevKit using the V4L2 encoder C++ API.
Our current platform is:
L4T | R36.4.7
Kernel | 5.15.148-tegra arm64
Device | Jetson AGX Orin DevKit
We are trying to correctly signal colorimetry metadata for encoded video streams.
From our testing, `V4L2_COLORSPACE_SMPTE170M` and `V4L2_COLORSPACE_REC709` appear to be propagated correctly to the encoded output metadata. However, `V4L2_COLORSPACE_BT2020` appears to be silently ignored or replaced by `V4L2_COLORSPACE_SMPTE170M`, which seems to be the default. Similarly, attempts to use full range appear to fall back to limited range.
For example, this works for SMPTE170M and REC709, but not for BT.2020:
encoderTry(m_encoder->setOutputPlaneFormat(V4L2_PIX_FMT_NV12M, inputWidth, inputHeight, V4L2_COLORSPACE_BT2020));
We also tried setting the detailed V4L2 colorimetry fields directly:
struct v4l2_format fmt = {};
if (m_encoder->output_plane.getFormat(fmt) == 0) {
fmt.fmt.pix_mp.ycbcr_enc = V4L2_YCBCR_ENC_BT2020;
fmt.fmt.pix_mp.quantization = V4L2_QUANTIZATION_FULL_RANGE;
fmt.fmt.pix_mp.xfer_func = V4L2_XFER_FUNC_709;
fmt.fmt.pix_mp.flags |= V4L2_PIX_FMT_FLAG_SET_CSC;
m_encoder->output_plane.setFormat(fmt);
}
This `VIDIOC_S_FMT` call returns `EINVAL` for all colorimetry configurations we tried, not only BT.2020. A subsequent `VIDIOC_G_FMT` readback shows `colorspace = 0`, which suggests that the driver does not retain the sub-fields.
In a previous discussion with NVIDIA, it was confirmed that full colorimetry support is currently missing in the `tegrav4l2` encoder layer. The configurations mentioned as needing V4L2 support were:
- BT.601 and BT.709, limited and full range, for H.264, H.265, and AV1
- BT.2020 for 10-bit H.265 and 10-bit AV1
Other Color Spaces (sRGB, OptRGB, DCI_P3) haven’t been discussed. My understanding from that discussion is that the Orin encoder hardware supports these configurations, but the V4L2 layer currently does not propagate all of them correctly. It would be interesting to know if supporting a wider set of color spaces and full range would be possible?
Additional question regarding the current behaviour:
In our current pipeline, we feed the encoder with already-converted YCbCr/NV12 data. If the input content is, for example, BT.2020 full-range but the encoder incorrectly signals it as SMPTE170M limited-range, are the input sample values still encoded unchanged, with only the VUI/container metadata being wrong? Or does the encoder/driver perform any conversion, clamping, or range remapping based on these colorimetry fields?
This distinction is important for us because if the issue is metadata-only, we can work around it for now by injecting the correct color fields at the bitstream or muxer level. If the encoded pixel data itself can be affected, then the workaround would not be sufficient.
Many thanks for your help.