Nvarguscamerasrc fails, only single camera for Arducam Dual IMX477 on Jetson Orin NX

Hey everyone, I’m trying to get the Arducam IMX477 Dual Stereo Bundle working on a Jetson Orin NX 16GB with the Auvidea JNX42 carrier board. Running JetPack 5.1.2, kernel 5.15.148-tegra.

I’ve installed the Arducam package arducam-nvidia-l4t-kernel-t234-nx-5.15.148-tegra-36.4.3-*_imx477-stereo-rpi.deb and placed the device tree overlay tegra234-p3767-camera-p3768-imx477-dual.dtbo in /boot/arducam/dts/. My extlinux.conf has:

OVERLAYS /boot/arducam/dts/tegra234-p3767-camera-p3768-imx477-dual.dtbo

When I try a basic nvarguscamerasrc pipeline:

gst-launch-1.0 nvarguscamerasrc sensor-id=0 ! nvvidconv ! nveglglessink

It fails with:

Error BadParameter: Failed to create OutputStream
Error NotSupported: Failed to initialize EGLDisplay
Error ModuleNotPresent: V4L2Device not available

Anyone seen this before? The camera does show up under v4l2-ctl so I’m a bit confused.

Can you share the output of v4l2-ctl --all and also confirm which /dev/video* devices you have? That’ll help figure out whether the sensor is actually being detected properly at the V4L2 level before we dig into the Argus side.

Sure, here’s the output from v4l2-ctl --all:

Driver Info:
	Driver name      : tegra-video
	Card type        : vi-output, imx477 9-001a
	Bus info         : platform:tegra-capture-vi:2
	Driver version   : 5.15.148

Format Video Capture:
	Width/Height     : 4056/3040
	Pixel Format     : 'RG10' (10-bit Bayer RGRG/GBGB)
	Field            : None
	Frames per second: 10.00 (10/1)

So the sensor is detected as imx477 at i2c address 9-001a, /dev/video0 is there, and the format shows 4056x3040 @ 10fps. The camera seems to be alive at the V4L2 level.

Quick update — I tried capturing a raw frame with V4L2 directly:

v4l2-ctl -d /dev/video0 --stream-mmap --stream-count=1 --stream-to=frame.raw

This actually works. The frame.raw file is about 24MB and I can see the stereo pair images in it. So the hardware is definitely functional at the V4L2 level. But then I tried a GStreamer pipeline with v4l2src:

gst-launch-1.0 v4l2src device=/dev/video0 ! video/x-raw,format=GRAY16_LE ! ...

And this fails with:

ERROR: from element /GstPipeline:pipeline0/GstV4l2Src:v4l2src0: Internal data stream error.
reason not-negotiated (-4)

So raw capture via v4l2-ctl works but GStreamer won’t negotiate the format. Something’s off.

That not-negotiated error with GRAY16_LE makes sense — your sensor is producing RG10 (10-bit Bayer), not 16-bit grayscale. The raw capture via v4l2-ctl just dumps whatever the driver gives it, but GStreamer needs caps to match what the device actually outputs. Try using video/x-bayer,format=rggb,width=4056,height=3040 instead.

But the bigger issue is that nvarguscamerasrc isn’t working, and that usually means the Argus daemon can’t find the camera through the device tree. Can you check if the overlay is actually loaded?

cat /proc/device-tree/tegra-camera-platform/modules/module0/drivernode0/name

Ran that check:

cat /proc/device-tree/tegra-camera-platform/modules/module0/drivernode0/name

Output is just:

drivernode0

Which doesn’t look right — shouldn’t this be showing the sensor name? I verified the dtbo file does exist at /boot/arducam/dts/tegra234-p3767-camera-p3768-imx477-dual.dtbo and it’s referenced in extlinux.conf. But it seems like the overlay isn’t actually being applied properly.

Also noticed that /var/nvidia/nvcam/settings/camera_overrides.isp exists but doesn’t seem to be used, and there are no firmware files under /lib/firmware/imx477*. Starting to think the dtbo isn’t loading correctly at boot, and without that, Argus has no way to find a compatible camera module through the device tree.

Yeah, that device tree node returning just drivernode0 confirms the overlay isn’t being loaded properly. The Argus stack relies on the device tree to discover camera modules, and without the correct entries, nvarguscamerasrc will keep failing even though V4L2 sees the sensor.

A couple things to check:

  • Did you rebuild the initrd or run any post-install steps after placing the dtbo? On some setups you need to run update-initramfs or re-flash the DTB partition.
  • Also, the Auvidea JNX42 is a third-party carrier board — Arducam’s overlays are typically validated against NVIDIA’s official devkit carrier. The pinmux, CSI lane mapping, or camera I2C bus numbering could differ on the JNX42 compared to what the overlay expects.

That said, since V4L2 raw capture works and you can see stereo pairs in the raw frame, the hardware connection seems fine. This may be solvable with a modified dtbo that matches the JNX42’s device tree structure. Have you reached out to Auvidea about the camera DTS for their board?

I contacted Arducam support about this. Their response was basically: “you’re using a third-party carrier board, that’s the problem, we can’t help.” They suggested trying the Python script from GitHub - Dion4cen/jetson_quick_start_script · GitHub to simplify GStreamer commands.

I gave it a shot — ran start.py from that repo. It tries these pipelines internally:

gst-launch-1.0 nvarguscamerasrc sensor_id=0 ! video/x-raw(memory:NVMM),width=2028,height=1080,framerate=30/1,format=NV12 ! nvvidconv flip-method=0 ! video/x-raw,width=960,height=720 ! nvvidconv ! fpsdisplaysink -e

and

gst-launch-1.0 nvarguscamerasrc num-buffers=30 sensor_id=0 ! video/x-raw(memory:NVMM),width=2028,height=1080,framerate=30/1,format=NV12 ! nvjpegenc ! multifilesink location=isp_imx477-stereo_2028_1080_2025-04-08-12-03-50.jpeg

Both fail the same way. The error output from the script:

(Argus) Error BadParameter: (propagating from src/eglstream/FrameConsumerImpl.cpp, function initialize(), line 93)
(Argus) Error BadParameter: (propagating from src/eglstream/FrameConsumerImpl.cpp, function create(), line 44)
Error generated. /dvs/git/dirty/git-master_linux/multimedia/nvgstreamer/gst-nvarguscamera/gstnvarguscamerasrc.cpp, threadInitialize:318 Failed to create FrameConsumer
Error generated. /dvs/git/dirty/git-master_linux/multimedia/nvgstreamer/gst-nvarguscamera/gstnvarguscamerasrc.cpp, threadFunction:239 (propagating)
Error generated. /dvs/git/dirty/git-master_linux/multimedia/nvgstreamer/gst-nvarguscamera/gstnvarguscamerasrc.cpp, waitRunning:201 Invalid thread state 3
Error generated. /dvs/git/dirty/git-master_linux/multimedia/nvgstreamer/gst-nvarguscamera/gstnvarguscamerasrc.cpp, execute:849 (propagating)

Same FrameConsumerImpl failure. This really seems like Argus can’t initialize the EGL stream because it doesn’t have a proper camera module configured via device tree.

Did some more digging on the I2C buses. Here’s what I found:

Bus 9 (sudo i2cdetect -y -r 9):

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- UU -- -- -- -- --
20: -- -- -- 24 -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

Bus 10 (sudo i2cdetect -y -r 10):

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:                         -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

So bus 9 has the imx477 sensor at 0x1a (marked UU — in use by the driver) and something at 0x24. Bus 10 is completely empty.

And kernel logs from dmesg | grep imx:

[    9.687967] imx477 9-001a: tegracam sensor driver:imx477_v2.0.6
[    9.989559] tegra-camrtc-capture-vi tegra-capture-vi: subdev imx477 9-001a bound
[   10.024369] imx477 10-001a: tegracam sensor driver:imx477_v2.0.6
[   10.325007] imx477 10-001a: imx477_board_setup: error during i2c read probe (-121)
[   10.325036] imx477 10-001a: board setup failed
[   10.325113] imx477: probe of 10-001a failed with error -121

And v4l2-ctl --list-devices:

NVIDIA Tegra Video Input Device (platform:tegra-camrtc-ca):
	/dev/media0

vi-output, imx477 9-001a (platform:tegra-capture-vi:2):
	/dev/video0

So only one camera shows up. The probe failure on bus 10 at address 0x1a — is that expected? I thought maybe both cameras should appear on I2C, but I’m only seeing one. Or is this because the stereo bundle uses a sync/multiplexer board that combines both sensors into a single CSI stream?

The I2C results actually make perfect sense for your setup. The Arducam IMX477 Dual Bundle uses a sync/HAT board that combines two camera sensors into a single CSI stream — so you only use one CSI connector on the carrier board. That’s why you see only vi-output, imx477 9-001a on /dev/video0.

The probe failure on 10-001a is also expected. The device tree overlay is trying to probe for a second sensor on I2C bus 10 (which would be the other CSI lane on some reference designs), but on your board — and with the sync board — there’s nothing there. That -121 error (remote I/O error) just means no device responded at that address, which is normal in your configuration.

So the hardware detection at the V4L2 level is actually fine. One sensor on bus 9, recognized, raw capture works. The problem remains that Argus/nvarguscamerasrc can’t initialize — and that’s almost certainly the device tree overlay not being properly applied, or the overlay being incompatible with the JNX42’s base device tree.

Did Arducam provide any guidance beyond the third-party board excuse? Have they shared the actual DTS source for that overlay?

No, they pretty much shut it down — their response was that the imx477 10-001a: board setup failed error is normal behavior for the stereo bundle (only CSI-0 should succeed), but they still attribute the nvarguscamerasrc failure to the Auvidea JNX42 being a third-party carrier board and say they can’t assist further unless I’m using an official devkit carrier.

But here’s the thing — the Auvidea JNX42 has the exact same hardware-level CSI connections as NVIDIA’s official devkit carrier board. The CSI lanes, the I2C routing, it’s all identical at the electrical level. And the camera already shows partial functionality: /dev/video0 exists, raw capture works, I can see stereo pairs in the raw frames. That proves the hardware connection is valid.

This isn’t a hardware incompatibility — it’s a software/driver or device-tree configuration issue. The dtbo either isn’t loading correctly, or there’s some mismatch in how the overlay integrates with the JNX42’s base device tree. Just blaming the third-party board feels like a cop-out when V4L2-level capture is working perfectly.

I also tried to find their v4l2_fix utility that’s referenced in some Arducam documentation — the link they give is:

https://github.com/ArduCAM/python_v4l2.git

But that returns a 404. Does anyone have the correct link or the source code for their v4l2_fix tool? I want to see if that helps bridge the gap between V4L2 and the Argus stack.

You raise a fair point — if the CSI and I2C routing matches the reference design and V4L2 capture works, the problem isn’t the carrier board hardware. It’s more likely one of these:

  1. The dtbo was built against a different base DTB than what the JNX42 ships with, so the overlay fails to apply cleanly at boot (even if extlinux.conf references it). You can check this with dmesg | grep -i overlay or dmesg | grep -i "apply" to see if there are any overlay-related errors during boot.

  2. The camera module registration in the device tree (/proc/device-tree/tegra-camera-platform/...) still showing drivernode0 as a bare node name means the overlay isn’t populating the camera platform nodes. Without those, Argus has no module to match.

Regarding the broken v4l2_fix link — unfortunately I don’t have a mirror of that repo. The 404 suggests Arducam may have taken it down or moved it. You could try reaching out to them specifically about that broken link rather than the broader compatibility question — they might be more willing to provide the actual repo location.

In the meantime, have you tried extracting the dtbo to dts to inspect what it’s actually trying to do? Something like:

dtc -I dtb -O dts /boot/arducam/dts/tegra234-p3767-camera-p3768-imx477-dual.dtbo

That would let you see which bus numbers, CSI ports, and camera module nodes the overlay expects, and you can cross-reference that against what the JNX42’s base DTB provides.