Hello,
I have an application where I have an MJPEG USB webcam I am trying to integrate into a Nitros graph on a Jetson Orin Nano Super. My approach has been to use a gstreamer pipeline to take the image from a v4l2src and pass it to a nvvideodecoder set to decode MJPEG, then pass it to nvvideoconvert and lastly to a custom gstreamer sink that takes the surfacebuffer from nvvideoconvert and publishes it via a Nitros Image (doing the EGLimage thing for full zero-copy goodness).
Shockingly this works, and works fairly well, but most of the downstream ROS Isaac nodes want rgb8 or bgr8, and nvvideoconvert only does RGBA as an RGB-adjacent planar image type - I have gotten the entire thing working by throwing an Isaac image format converter shim in the way, but it takes a fair amount of processing power that probably doesn’t need to be spent. What I really want to do is use NV12, since nvvideoconverter supports it and the majority of downstream blocks do as well.
I have been working my way through the process and think I have a reasonable handle on it:
-
Nitros ImageBuilder doesn’t strictly do semi-planar types, but will treat nv12 types as contiguous with a Y plane followed by a half-height UV plane, and there is a constructor in the ImageBuilder that handles it
-
nvvideoconvert seems to put the Y and UV planes on 256-byte boundaries, so for most practical image sizes there will be a gap between Y and UV, so doing a quick cudamemcpy to make the planes contiguous is often necessary
-
Subscribing to a nv12 Nitros Image type via something like rqt_image will trigger a CPU copy and conversion to RGB8, so one can rarely actually see the nv12 image type but can see the image post-conversion.
Annoyingly, the image that I get out of rqt_image shows the Y channel perfectly well (full black-and-white frame, looking accurate) but the chroma channels appear to take up the upper half of the image (red, green, and blue are present, but the chroma channel is squished to half-height and only appears in the top half of the image) and the lower half of the image is tinted strongly green (usually associated with a zero in the chroma channel). It’s like the nv12 conversion to RGB8 isn’t properly respecting the half-height chroma, and instead assembling the other frame channels incorrectly. I have attempted simply cudamemcpying the Y and UV channels directly, with no respect for pitch, and even doubled the UV channel to see if it got rid of the green tint at the bottom half of the image, and I don’t see any change. Is there a bug in nv12 conversion with Isaac ROS 3.1 around nv12 image conversion? Barring that, is there an example somewhere of creating an nv12 image with Nitros ImageBuilder?
Thanks in advance!