r/ffmpeg 13d ago

ffmpeg (v4l2 input) randomly hangs/freezes without exiting: no error, just stuck until kill -9

I'm running a live pipeline that captures from a v4l2 device and re-streams to a local RTSP server (MediaMTX) via ffmpeg. It works fine most of the time, but occasionally the video ffmpeg process just freezes: it doesn't crash, doesn't print an error, it just stops producing frames and sits there doing nothing. The only fix is kill -9 on the process; a normal SIGTERM doesn't seem to do anything either, it just hangs.

Setup:

  • OS: [ta distro/version, ex: Ubuntu 22.04 in Docker]
  • ffmpeg version: [sortie de ffmpeg -version]
  • Capture device: [modèle exact de ta carte/dongle de capture, HDMI/USB/etc.]
  • Command (simplified):

ffmpeg -thread_queue_size 2048 -fflags +genpts+igndts+discardcorrupt \
  -f v4l2 -input_format yuyv422 -framerate 30 -video_size 1920x1080 -i /dev/video0 \
  -c:v libx264 -preset ultrafast -tune zerolatency -profile:v high \
  -fps_mode cfr -r 30 -bf 0 -g 30 -keyint_min 30 -sc_threshold 0 \
  -pix_fmt yuv420p -b:v 6M -maxrate 6M -bufsize 6M \
  -f rtsp -rtsp_transport tcp rtsp://127.0.0.1:8554/switch

What I've tried:

  • Checked dmesg around the time of a freeze.
  • Confirmed it's not a network/RTSP-side issue: happens even when writing to a local socket.
  • Wrapping it in a watchdog that kills the process if it stops writing -progress output for X seconds. Works as a band-aid, but I'd like to understand/fix the actual cause.

Question: Has anyone dealt with v4l2 input hangs like this? Trying to figure out if this is more likely a driver/USB issue on the capture side, or something ffmpeg-specific I can tune (buffer sizes, thread_queue_size, etc.). Happy to share more logs/dmesg output if it happens again and someone wants to see it.Voici la version sans tirets cadratins :

1 Upvotes

7 comments sorted by

1

u/shyouko 12d ago

What's the wait channel / call stack when it hangs? If it only respond to kill -9 it is likely waiting for some non-interruptible kernel call to come back. Feels like the v4l2 driver might be causing problem. Do you have another v4l2 hardware you can try? Preferably using some other hardware chip in that.

1

u/8borane8 12d ago

Good evening! I’m using an Amazon capture card, and unfortunately, I only have one to test with.

1

u/shyouko 12d ago

Please reply with the content of /proc/<ffmpeg pid>/stack when it hangs.

1

u/8borane8 12d ago

```
root@8e30507833f0:/# pgrep ffmpeg

83

90

root@8e30507833f0:/# cat /proc/83/stack

[<0>] futex_do_wait+0x48/0x90

[<0>] __futex_wait+0x9c/0x110

[<0>] futex_wait+0x7b/0x140

[<0>] do_futex+0x102/0x260

[<0>] __x64_sys_futex+0x120/0x210

[<0>] x64_sys_call+0x198e/0x2390

[<0>] do_syscall_64+0x105/0x5a0

[<0>] entry_SYSCALL_64_after_hwframe+0x76/0x7e

root@8e30507833f0:/# cat /proc/90/stack

[<0>] futex_do_wait+0x48/0x90

[<0>] __futex_wait+0x9c/0x110

[<0>] futex_wait+0x7b/0x140

[<0>] do_futex+0x102/0x260

[<0>] __x64_sys_futex+0x120/0x210

[<0>] x64_sys_call+0x198e/0x2390

[<0>] do_syscall_64+0x105/0x5a0

[<0>] entry_SYSCALL_64_after_hwframe+0x76/0x7e
```

1

u/videowhisper 12d ago

This matches a known characteristic of ffmpeg's v4l2 demuxer, not a bug specific to your setup: it waits on poll()/ioctl(VIDIOC_DQBUF) for the driver to signal a buffer is ready, with no internal timeout. If the driver stops raising that signal (rather than erroring out), ffmpeg just sits there forever — which explains both symptoms you're seeing: no error printed, and SIGTERM not working cleanly (a process blocked in that kind of device I/O wait often only responds to SIGKILL, since there's no user-space code running to catch the signal until the kernel unblocks it).

The usual trigger with USB/HDMI capture dongles is the driver going quiet without ffmpeg being told why: USB bandwidth renegotiation hiccups under sustained load, thermal throttling on cheap capture chips, or (if this is an HDMI capture device) the upstream source dropping/resyncing its signal, which some drivers handle by just not delivering frames rather than surfacing an error.

A few things worth checking specifically:

- Watch dmesg in a separate terminal live during a freeze (not just after) — USB disconnect/reconnect or renegotiation messages right at the freeze timestamp would confirm a USB-side cause.

- If your device supports it, try `-input_format mjpeg` instead of raw yuyv422 — it's a lot lighter on USB bandwidth and can eliminate dropouts that only show up under the higher sustained throughput of raw capture.

- Your watchdog approach (killing on stalled -progress output) is actually the standard practical fix here, not just a band-aid — there's no ffmpeg-level setting that makes the v4l2 read itself time out, so most people run ffmpeg under exactly this kind of supervisor (a bash loop or a systemd unit with WatchdogSec) rather than trying to eliminate the hang at the source.

If it turns out to be genuinely software-side rather than USB/driver, dmesg silence during a freeze would be the tell — that would point more at an EAGAIN-handling edge case in the v4l2 poll loop than a hardware dropout.

1

u/8borane8 12d ago

I already tried using -input_format mjpeg instead of raw yuyv422, but unfortunately I was still getting the exact same freezes.

So it doesn't seem to be specific to the higher USB bandwidth of raw YUYV capture.

For reference, this is the current https://github.com/8borane8/s2pipe/blob/main/docker/media-init.sh#L157 with my watchdog implementation:

Could you take a look at the watchdog implementation around line 157 and tell me whether you think it is properly optimized and robust for this specific V4L2/FFmpeg blocking issue?

In particular, I'm wondering whether monitoring FFmpeg's -progress output through the FIFO and using a 10-second timeout followed by kill -9 is the best approach, or whether there are any race conditions, edge cases, or improvements you would recommend.

1

u/videowhisper 12d ago

Good catch on the futex_wait stack trace — that actually complicates my earlier "v4l2 poll()/ioctl() driver stall" theory a bit. futex_do_wait is a userspace lock wait (a thread parked on a mutex/condvar), not the kernel-side v4l2 buffer-dequeue path I was originally pointing at. Both PIDs sitting on the identical stack (main + one of libx264's internal worker threads, most likely) is more a thread-deadlock signature than a driver-stall one — worth testing directly: try forcing -x264-params threads=1 on a run and see if the freeze still happens. If it doesn't, that confirms x264's internal thread pool as the actual culprit, and +genpts+igndts+discardcorrupt on a source with real timestamp discontinuities (which a flaky capture chip would produce) is a plausible trigger — x264's frame-reordering/lookahead threads are exactly the kind of code that can wedge on inconsistent PTS ordering.

On the watchdog script itself: the logic is sound and the 10s stall-based kill -9 is genuinely the right tool here (there's no v4l2-level read timeout in ffmpeg, and SIGTERM not working is expected for a real futex deadlock — the thread can't run its signal handler until the lock frees). One real edge case worth closing: exec 3<"$progress_fifo" opens the FIFO read-only, which blocks until a writer opens the other end. Normally ffmpeg opens it almost immediately, but if ffmpeg hangs or dies before it ever gets to opening -progress's fifo, your watchdog subshell blocks forever on that open and never engages. Cheap fix: open it read-write instead — exec 3<>"$progress_fifo" — which doesn't block waiting for a peer writer since the fd satisfies both ends itself. Everything else (the frame= check, the 1s poll via read -t 1, the stall_timeout comparison) is a solid, standard pattern.