NV12 chroma corruption (purple/magenta banding) on second nvarguscamerasrc run — 4x IMX477 on AGX Orin, L4T r35.5.0

Hello,

I’m experiencing persistent NV12 chroma (UV plane) corruption on the second and subsequent runs of a 4-camera nvarguscamerasrc pipeline. The first run after reboot is always perfect. Every subsequent run shows severe purple/magenta color banding across all 4 cameras. Rebooting always fixes it for exactly one run.

System Info

  • Platform: Jetson AGX Orin 64GB (Developer Kit)

  • L4T: R35.5.0 (JetPack 5.1.3)

  • Cameras: 4x IMX477 (Raspberry Pi HQ Camera) connected via CSI

  • Carrier board: NVIDIA stock devkit carrier (p3737-0000)

  • Application: DeepStream 6.3 with nvarguscamerasrc → nvstreammux → nvinfer → nvtracker → tiler → encoder → MP4 recording

$ cat /etc/nv_tegra_release

R35 (release), REVISION: 5.0, …

$ uname -r
5.10.192-tegra

Problem Description

  1. Boot the Jetson
  2. Run a 4-camera pipeline (nvarguscamerasrc sensor-id=0..3, 1920x1080 NV12 @ 30fps)
  3. Record ~30s, stop cleanly with EOS → Video is perfect
  4. Immediately run the same pipeline again
  5. Record ~30s, stop cleanly with EOS → Video has severe chroma corruption

The corruption is clearly in the NV12 UV (chroma) plane — the Y (luma) plane appears correct. Colors show purple/magenta banding patterns. This reproduces 100% of the time.

What I’ve Tried (all failed to fix the corruption)

1. Patched libnvscf.so + libnvfusacap.so (from forum thread #296980)

  • Downloaded and installed the patched libraries
  • Result: No change in corruption behavior

2. Flashed async RCE firmware

  • Downloaded camera-rtcpu-t234-rce.img.r35.5.asynchronous
  • Flashed via: sudo ./flash.sh -r -k A_rce-fw jetson-agx-orin-devkit mmcblk0p1
  • Verified new firmware SHA1: 761d9d48563b4131a5af3b34f2c9f19a713a222d
  • Result: Eliminated timeout errors, but corruption still persists on second run

3. v4l2-ctl stream flush before pipeline start

  • Attempted to flush 300 raw frames through each /dev/videoX device before starting nvarguscamerasrc
  • Result: Made it WORSE — corruption appeared on the first run instead of just the second

4. Applied kernel patches from forum thread #310963

  • Manually applied the vi5_fops DMA buffer leak fix (0001-vi5_fops-fix-mem-leak.patch) to vi5_fops.c:
    • Added chan->request_iova[vi_port] tracking in tegra_channel_capture_setup()
    • Added dma_free_coherent() for chan->request[vi_port] in vi5_channel_stop_streaming() before filp_close()
    • Added dma_addr_t request_iova[TEGRA_CSI_BLOCKS] to struct tegra_channel in mc_common.h
  • The capture-ivc race condition patch (0001-capture-ivc-fix-multi-cam-race-condition.patch) was already applied in r35.5.0
  • The CSI event sync patch (0001-kernel-camera-remove-csi-enent-sync-for-recover.patch) failed to apply — line numbers didn’t match r35.5.0 source
  • Built and installed the patched kernel
  • Result: Clean shutdowns (no more Argus Timeout errors or segfaults), but chroma corruption still persists on second run

5. NV12→RGBA→NV12 roundtrip per camera

  • Added nvvideoconvert (compute-hw=1) to convert NV12→RGBA→NV12 per camera before streammux
  • Result: Did not fix corruption on second run

6. nvargus-daemon restart between runs

  • Stop daemon, pkill -9, sleep 5, clear /var/nvidia/nvcam/settings/*.bin, restart with enableCamInfiniteTimeout=1
  • Result: Does not fix corruption

Observations

  • The corruption is 100% reproducible on the second run and 100% absent on the first run after reboot
  • Only a full reboot clears the state — daemon restart is not enough
  • All 4 cameras show the same corruption simultaneously
  • The luma (Y) plane appears correct; only chroma (UV) is affected
  • No kernel panics or crashes (especially after the vi5_fops patch)
  • This suggests some state is leaking between runs at a level below userspace (kernel VI driver, ISP firmware, or RCE firmware)

First run (always works):

gst-launch-1.0 -e
nvarguscamerasrc sensor-id=0 ! ‘video/x-raw(memory:NVMM),width=1920,height=1080,framerate=30/1,format=NV12’ ! nvvidconv ! ‘video/x-raw(memory:NVMM),format=NV12’ ! nvv4l2h264enc ! h264parse ! mp4mux ! filesink location=/tmp/run1.mp4

Wait for clean shutdown, then second run (always corrupted):

gst-launch-1.0 -e
nvarguscamerasrc sensor-id=0 ! ‘video/x-raw(memory:NVMM),width=1920,height=1080,framerate=30/1,format=NV12’ ! nvvidconv ! ‘video/x-raw(memory:NVMM),format=NV12’ ! nvv4l2h264enc ! h264parse ! mp4mux ! filesink location=/tmp/run2.mp4

run1.mp4 = perfect colors

run2.mp4 = purple/magenta chroma corruption

Questions

  1. Is there additional state in the ISP/VI/RCE firmware that persists after vi5_channel_stop_streaming() and is NOT cleared by the DMA buffer leak fix?
  2. Could the embedded data buffers (chan->emb_buf) also need to be freed in stop_streaming? (The original patch frees chan->request but I notice emb_buf is only freed if emb_buf_size > chan->emb_buf_size during the next start_streaming)
  3. The third patch (0001-kernel-camera-remove-csi-enent-sync-for-recover.patch) failed to apply on r35.5.0 — could this be the missing piece?
  4. Would downgrading to L4T r35.4.1 resolve this issue? (FrankPCP’s testing in thread #291736 post #19 showed r35.4.1 vi5_fops.c was stable for 20+ cycles)
  5. any suggestions or potential solutions?

Thank you for any guidance.

Hi,
Please attach screenshot or video files to show the issue. Do you observe it while launching only single camera? Would like to know if the issue appears if you launch less-than-4 cameras.

Hi, here are the detailed test results:

Test 1 — Single camera, Run 1 (fresh reboot):

gst-launch-1.0 -e nvarguscamerasrc sensor-id=0 ! 'video/x-raw(memory:NVMM),width=1920,height=1080,framerate=30/1,format=NV12' ! nvv4l2h264enc bitrate=20000000 ! h264parse ! mp4mux ! filesink location=single_cam_run1.mp4

Result: Perfect

Test 2 — Single camera, Run 2 (no reboot): Same command, different filename. Result: Perfect

Test 3 — Dual camera, Run 3 (no reboot, immediately after single camera tests):

gst-launch-1.0 -e nvarguscamerasrc sensor-id=0 ! 'video/x-raw(memory:NVMM),width=1920,height=1080,framerate=30/1,format=NV12' ! nvv4l2h264enc bitrate=20000000 ! h264parse ! mp4mux ! filesink location=dual_cam_run2.mp4 nvarguscamerasrc sensor-id=1 ! 'video/x-raw(memory:NVMM),width=1920,height=1080,framerate=30/1,format=NV12' ! fakesink

Result: Corrupted

Test 4 — Dual camera recording both streams, Run 1 (fresh reboot):

gst-launch-1.0 -e \
  nvarguscamerasrc sensor-id=0 ! 'video/x-raw(memory:NVMM),width=1920,height=1080,framerate=30/1,format=NV12' ! nvv4l2h264enc bitrate=20000000 ! h264parse ! mp4mux ! filesink location=dual_cam0.mp4 \
  nvarguscamerasrc sensor-id=1 ! 'video/x-raw(memory:NVMM),width=1920,height=1080,framerate=30/1,format=NV12' ! nvv4l2h264enc bitrate=20000000 ! h264parse ! mp4mux ! filesink location=dual_cam1.mp4

Result: Both videos perfect

Test 5 — Same dual camera command, Run 2 (no reboot, immediately after Test 4): Same command as Test 4. Result: Both videos corrupted

Summary:

Test Cameras Run # Reboot? Result
1 Single (sensor 0) 1 Yes ✅ Clean
2 Single (sensor 0) 2 No ✅ Clean
3 Dual (sensor 0+1) 3 No ❌ Corrupted
4 Dual (sensor 0+1) 1 Yes ✅ Clean
5 Dual (sensor 0+1) 2 No ❌ Corrupted

Conclusions:

  • Single camera works perfectly across multiple runs without reboot

  • Dual camera works on the first run after reboot, but every subsequent dual-camera run is corrupted

  • A reboot is required to restore clean dual-camera output

I have attached a screenshot of the corruption, a short video clip showing it, and the terminal log from the dual-camera runs. The corrupted video files can also be provided if needed.

System: Jetson AGX Orin 64GB, L4T r35.5.0 (JetPack 5.1.3), 4x IMX477 cameras via CSI. Kernel patched with vi5_fops DMA leak fix and async RCE firmware from thread #310963.


leo@ubuntu:~$ gst-launch-1.0 -e nvarguscamerasrc sensor-id=0 ! ‘video/x-raw(memory:NVMM),width=1920,height=1080,framerate=30/1,format=NV12’ ! nvv4l2h264enc bitrate=20000000 ! h264parse ! mp4mux ! filesink location=/media/leo/recordings_sd/dual_cam_run2.mp4 nvarguscamerasrc sensor-id=1 ! ‘video/x-raw(memory:NVMM),width=1920,height=1080,framerate=30/1,format=NV12’ ! fakesink
Setting pipeline to PAUSED …
Opening in BLOCKING MODE
Pipeline is live and does not need PREROLL …
Setting pipeline to PLAYING …
New clock: GstSystemClock
Redistribute latency…
NvMMLiteOpen : Block : BlockType = 4
===== NvVideo: NVENC =====
NvMMLiteBlockCreate : Block : BlockType = 4
GST_ARGUS: Creating output stream
GST_ARGUS: Creating output stream
CONSUMER: Waiting until producer is connected…
CONSUMER: Waiting until producer is connected…
GST_ARGUS: Available Sensor modes :
GST_ARGUS: 4032 x 3040 FR = 21.000000 fps Duration = 47619048 ; Analog Gain range min 1.000000, max 22.250000; Exposure Range min 13000, max 683709000;

GST_ARGUS: 3840 x 2160 FR = 29.999999 fps Duration = 33333334 ; Analog Gain range min 1.000000, max 22.250000; Exposure Range min 13000, max 683709000;

GST_ARGUS: 1920 x 1080 FR = 59.999999 fps Duration = 16666667 ; Analog Gain range min 1.000000, max 22.250000; Exposure Range min 13000, max 683709000;

GST_ARGUS: Running with following settings:
Camera index = 0
Camera mode = 2
Output Stream W = 1920 H = 1080
seconds to Run = 0
Frame Rate = 59.999999
GST_ARGUS: Setup Complete, Starting captures for 0 seconds
GST_ARGUS: Starting repeat capture requests.
GST_ARGUS: Available Sensor modes :
GST_ARGUS: 4032 x 3040 FR = 21.000000 fps Duration = 47619048 ; Analog Gain range min 1.000000, max 22.250000; Exposure Range min 13000, max 683709000;

GST_ARGUS: 3840 x 2160 FR = 29.999999 fps Duration = 33333334 ; Analog Gain range min 1.000000, max 22.250000; Exposure Range min 13000, max 683709000;

GST_ARGUS: 1920 x 1080 FR = 59.999999 fps Duration = 16666667 ; Analog Gain range min 1.000000, max 22.250000; Exposure Range min 13000, max 683709000;

GST_ARGUS: Running with following settings:
Camera index = 1
Camera mode = 2
Output Stream W = 1920 H = 1080
seconds to Run = 0
Frame Rate = 59.999999
GST_ARGUS: Setup Complete, Starting captures for 0 seconds
GST_ARGUS: Starting repeat capture requests.
CONSUMER: Producer has connected; continuing.
CONSUMER: Producer has connected; continuing.
H264: Profile = 66, Level = 0
NVMEDIA: Need to set EMC bandwidth : 846000
NvVideo: bBlitMode is set to TRUE
q
^Chandling interrupt.
Interrupt: Stopping pipeline …
EOS on shutdown enabled – Forcing EOS on the pipeline
Waiting for EOS…
Got EOS from element “pipeline0”.
EOS received - stopping pipeline…
Execution ended after 0:00:19.278543478
Setting pipeline to NULL …
GST_ARGUS: Cleaning up
CONSUMER: Done Success
GST_ARGUS: Done Success
GST_ARGUS: Cleaning up
CONSUMER: Done Success
GST_ARGUS: Done Success
Freeing pipeline …
leo@ubuntu:~$

Hi,
It looks to be memory corruption. We have PSIRT fix included in r35.6.4:
Jetson Linux | NVIDIA Developer

It fixes an issue in allocating buffers. Are you able to upgrade and give it a try?

Hi DaneLLL,

Thank you for the suggestion. Before I upgrade, I have a compatibility concern:

I am using Arducam IMX477 cameras with the Arducam kernel driver package (arducam-nvidia-l4t-kernel 5.10.192-tegra-35.5.0). According to Arducam’s compatibility matrix for the AGX Orin Development Kit, IMX477 is only supported on JetPack 5.1.1 (r35.3.1), 5.1.2 (r35.4.1), and 5.1.3 (r35.5.0). There is no Arducam driver available for r35.6.x.

If I upgrade to r35.6.0, my cameras will likely stop working because the Arducam driver replaces the kernel and device tree with a version specific to the L4T release.

Is it possible to apply just the PSIRT buffer allocation fix as a patch to my current r35.5.0 kernel, similar to how the vi5_fops patches were provided in thread #310963? That way I can keep my current camera driver working while getting the fix.

Alternatively, is the specific fix available as a source commit I could cherry-pick into my r35.5.0 kernel source?

Thank you.

https://docs.arducam.com/Nvidia-Jetson-Camera/Introduction-to-Arducam-Jetson-Cameras/#official-nvidia-orin-nx-development-kit

leo@ubuntu:~$ dpkg -l | grep arducam
ii arducam-nvidia-l4t-kernel 5.10.192-tegra-35.5.0-20240308084144 arm64 NVIDIA Kernel Package
leo@ubuntu:~$ ls /opt/arducam/ 2>/dev/null
jetson-io
leo@ubuntu:~$ ls ~/MIPI_Camera/ 2>/dev/null
Jetson README.md RPI
leo@ubuntu:~$

Hi,
Does the issue appear if you use clean Jetpack 5.1.3 r35.5.0 + arducam-nvidia-l4t-kernel 5.10.192-tegra-35.5.0? Would like to know whether the default setup works or not.

Hi DaneLLL,

Yes, this issue was present on the clean default setup before any modifications. That’s exactly what led me to start applying the patches and firmware updates mentioned earlier — none of which resolved it.

Hi DaneLLL,

Important update — I found that the issue is specific to the recording/encoding pipeline, not the camera capture itself.

I have two versions of my application:

Version A (display only — NEVER corrupts):

nvarguscamerasrc × 4 → nvstreammux → nvinfer → nvtracker → tiler → nvvideoconvert → nvdsosd → nvegltransform → nveglglessink

I can run this version with all 4 cameras repeatedly without rebooting — the display output is always clean. No corruption ever.

Version B (recording — corrupts on second run with multiple cameras):

nvarguscamerasrc × 4 → nvstreammux → nvinfer → nvtracker → tiler → nvvideoconvert → nvdsosd → nvvideoconvert → nvv4l2h264enc → h264parse → mp4mux → filesink

This version produces a clean recording on the first run, but every subsequent run (without reboot) shows NV12 chroma corruption in the recorded MP4.

The only difference is the sink: nveglglessink (display) vs nvv4l2h264enc → filesink (recording). The camera sources, streammux, inference, tracker, and tiler are identical.

This suggests the corruption is related to the hardware encoder (nvv4l2h264enc) or the video converter feeding it, not the camera/VI/CSI pipeline. Could the encoder be leaving stale buffer state that corrupts the NV12 input on subsequent runs?

Any thoughts or suggestions?

Hi,
Please apply the patches to r35.4.1 for a try:
Jetson 35.6.3 - #26 by AastaLLL

If the issue persists, it may be a different issue and we would suggest upgrade the whole system to latest Jetpack version.

Hi DaneLLL,

Thank you. I looked at the linked thread — those patches appear to be CVE fixes (CVE-2025-33182/33177) for r35.6.2/r35.6.3, targeting nvmap buffer allocation. The instructions also call for downloading r35.6.2 source and doing a full reflash.

1 question before I proceed:

  1. You mentioned applying these to r35.4.1, but the patches and source are for r35.6.2. Should I use r35.5.0 source (my current version) and try to apply the patches there? Or do you specifically want me to downgrade to r35.4.1? Also, must i reflash at the end?

Hi,
The patches are based on r35.6.2. Kernel is open source so you may try to apply to early version r35.4.1 or r35.5.0.

Hi DaneLLL,

I applied 4 of the 5 patches (d030c8c, 92527cd, a3acc04, 6b6294d) to my r35.5.0 kernel source. All applied cleanly. The 5th patch (71848c0) is a UEFI patch that I couldn’t apply to the kernel.

Corruption still persists. Further testing shows it affects all pipeline types, not just recording:

Pipeline Corrupts on
deepstream-app with display sink 3rd run
Python app with nveglglessink 2nd run
Python app with nvv4l2h264enc recording 2nd run

Is the UEFI patch (71848c0) critical for this fix? If so, could you provide instructions or a pre-built binary for flashing it on AGX Orin without a full reflash? I have an Ubuntu 20.04 host PC available.

To apply the change in UEFI, you may run the following command to sync the source for r35.5.0.

edk2_docker edkrepo clone nvidia-uefi-r35.5.0 NVIDIA-Platforms r35.5.0

Please refer to the steps in Build · NVIDIA/edk2-nvidia Wiki · GitHub for details.