Name and Version
.\build\bin\Release\llama-cli.exe --version
version: 9590 (d2462f8)
built with MSVC 19.44.35227.0 for x64
Operating systems
Windows
Which llama.cpp modules do you know to be affected?
llama-cli, Other (Please specify in the next section), llama-server
Command line
.\build\bin\Release\llama-cli.exe -m gemma-4-12B-it-qat-UD-Q4_K_XL.gguf -mm mmproj-F32.gguf -v
# then in chat:
# /video C:\Users\Ben\Videos\test.mp4
# Tell me about this video
Problem description & steps to reproduce
Name and Version
version: b9590 (d2462f8)
built for Windows x86_64, CUDA backend (RTX 3090)
Operating systems
Windows
Which llama.cpp modules do you know to be affected?
llama-cli, mtmd
Problem description & steps to reproduce
Video input on Windows hangs in two different ways depending on where the MP4 MOOV atom is located. Both appear to be in the ffmpeg/ffprobe subprocess pipe handling in tools/mtmd/mtmd-helper.cpp (mtmd_helper_video). This extends #24394 (silent zero-frame failure on Linux) with Windows repro data — on Windows it hangs rather than failing silently.
Case 1: MOOV atom at end of file (default ffmpeg output)
probe() succeeds (ffprobe has to read the entire piped input to find the moov, so it fully drains stdin and exits cleanly). The ffmpeg decode step then produces zero frames:
0.24.617.771 D start_ffmpeg: launching: ffmpeg -nostdin -i cache:pipe:0 -vf fps=4.000000 -f rawvideo -pix_fmt rgb24 pipe:1 -loglevel error
0.24.622.579 D start_ffmpeg: subprocess_create ret=0 proc_alive=1
0.24.622.583 D start_ffmpeg: starting feeder thread for 1194147-byte buffer
0.24.622.649 D read_next_frame: reading frame 0, expecting 2764800 bytes (720x1280)
0.24.668.259 D read_next_frame: fread returned 0 after 0/2764800 bytes (ferror=0)
0.24.668.268 D add_text: <|turn>system ...
0.24.668.306 D add_text: Video:
0.24.668.319 D add_text: Tell me about this video<turn|>
The prompt is assembled with the bare Video: text and no frames, and then llama-cli hangs (no generation, no error).
Case 2: MOOV atom at front (-movflags +faststart)
After remuxing the same file with ffmpeg -i test.mp4 -c copy -movflags +faststart test_fast.mp4, the hang moves earlier, into probe() itself. The log stops here and never prints the probe result line:
0.28.766.262 D res add_waiting_: add task 0 to waiting list. current waiting = 0 (before add)
0.28.766.269 D que post: new task, id = 0, front = 0
0.28.767.532 D probe: launching: ffprobe -v quiet -show_entries stream=width,height,r_frame_rate,nb_frames,duration -select_streams v:0 -of default=noprint_wrappers=1 pipe:0
(hangs indefinitely)
Isolation: ffprobe itself behaves correctly on the same file
Running the exact probe command manually with a real pipe (cmd.exe, binary-safe):
C:\Users\Ben>cmd /c "type C:\Users\Ben\Videos\test_fast.mp4 | ffprobe -v quiet -show_entries stream=width,height,r_frame_rate,nb_frames,duration -select_streams v:0 -of default=noprint_wrappers=1 pipe:0"
width=720
height=1280
r_frame_rate=30/1
duration=7.050391
nb_frames=211
The process tried to write to a nonexistent pipe.
ffprobe prints the metadata and exits promptly. Because the moov is at the front, it stops reading stdin early; the writer (type) gets the expected broken-pipe error and terminates. So the deadlock is in how mtmd_helper_video handles this early-exit case on Windows: the feeder thread is blocked in fwrite() on the child's stdin while the main thread is blocked in fgets() on the child's stdout, and neither unblocks when ffprobe stops reading / exits.
Minor side issue while debugging: the probe() debug line prints fps_target and a not-yet-assigned info.n_frames, e.g. probe: 720x1280 fps=4.00 duration=7.02s n_frames=0 for a 30 fps / 211-frame video — info.n_frames is assigned on the line after the LOG_DBG, and fps here is the sampling target, not the source fps. Made the logs confusing to interpret.
Test video: 720x1280, H.264, 7.05 s, 30 fps, ~1.2 MB. Happy to provide the file or more verbose logs if useful.
First Bad Commit
Video input is new in #24269 (b9577); also reproduces after the #24316 refactor.
Relevant log output
Logs
Name and Version
.\build\bin\Release\llama-cli.exe --version
version: 9590 (d2462f8)
built with MSVC 19.44.35227.0 for x64
Operating systems
Windows
Which llama.cpp modules do you know to be affected?
llama-cli, Other (Please specify in the next section), llama-server
Command line
Problem description & steps to reproduce
Name and Version
version: b9590 (d2462f8)
built for Windows x86_64, CUDA backend (RTX 3090)
Operating systems
Windows
Which llama.cpp modules do you know to be affected?
llama-cli, mtmd
Problem description & steps to reproduce
Video input on Windows hangs in two different ways depending on where the MP4 MOOV atom is located. Both appear to be in the ffmpeg/ffprobe subprocess pipe handling in
tools/mtmd/mtmd-helper.cpp(mtmd_helper_video). This extends #24394 (silent zero-frame failure on Linux) with Windows repro data — on Windows it hangs rather than failing silently.Case 1: MOOV atom at end of file (default ffmpeg output)
probe()succeeds (ffprobe has to read the entire piped input to find the moov, so it fully drains stdin and exits cleanly). The ffmpeg decode step then produces zero frames:The prompt is assembled with the bare
Video:text and no frames, and then llama-cli hangs (no generation, no error).Case 2: MOOV atom at front (
-movflags +faststart)After remuxing the same file with
ffmpeg -i test.mp4 -c copy -movflags +faststart test_fast.mp4, the hang moves earlier, intoprobe()itself. The log stops here and never prints the probe result line:Isolation: ffprobe itself behaves correctly on the same file
Running the exact probe command manually with a real pipe (cmd.exe, binary-safe):
ffprobe prints the metadata and exits promptly. Because the moov is at the front, it stops reading stdin early; the writer (
type) gets the expected broken-pipe error and terminates. So the deadlock is in howmtmd_helper_videohandles this early-exit case on Windows: the feeder thread is blocked infwrite()on the child's stdin while the main thread is blocked infgets()on the child's stdout, and neither unblocks when ffprobe stops reading / exits.Minor side issue while debugging: the
probe()debug line printsfps_targetand a not-yet-assignedinfo.n_frames, e.g.probe: 720x1280 fps=4.00 duration=7.02s n_frames=0for a 30 fps / 211-frame video —info.n_framesis assigned on the line after theLOG_DBG, andfpshere is the sampling target, not the source fps. Made the logs confusing to interpret.Test video: 720x1280, H.264, 7.05 s, 30 fps, ~1.2 MB. Happy to provide the file or more verbose logs if useful.
First Bad Commit
Video input is new in #24269 (b9577); also reproduces after the #24316 refactor.
Relevant log output
Logs