mirror of
https://github.com/games-on-whales/wolf.git
synced 2026-10-15 13:02:03 +00:00
[GH-ISSUE #400] NVidia P100 GStreamer h264 Errors - transform could not transform #264
Labels
No labels
🧠 1 - 🤖 999
AMD
bug
bug
cannot reproduce
documentation
duplicate
easy
enhancement
enhancement
enhancement
fixed?
fixed?
good first issue
hard
help wanted
Intel
invalid
LXC
medium
moonlight-protocol
Multi GPU
nixos
not a bug
nvidia
pull-request
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
games-on-whales/wolf#264
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @tjacoby2006 on GitHub (Apr 24, 2026).
Original GitHub issue: https://github.com/games-on-whales/wolf/issues/400
I am having an issue with Wolf streaming using an NVidia P100. The Test Ball application works fine. It only occurs with h264 when running Wolf, HEVC works fine. I would stick with HEVC, but I have clients that will need h264.
@ABeltramo commented on GitHub (Apr 24, 2026):
Can you please post the full Wolf logs when the stream breaks with the added env variable
WOLF_LOG_LEVEL=DEBUG?@tjacoby2006 commented on GitHub (Apr 24, 2026):
Ok looks like reproducing is a little more nuanced as to when it fails and when it doesn't. It seems to work a bit more often when the debug log level is enabled (race condition somewhere?). Basically, I connect, start the test ball, then go to Wolf and it usually fails. Usually going even directly to Wolf fails as well, but it does succeed on occasion.
logs.txt
@ABeltramo commented on GitHub (Apr 24, 2026):
These logs don't capture any issue, sure there are warnings, but the stream was working for ~10 seconds until the client disconnected. Are you sure it's not a network issue between the client and the server? Moonlight clients have an automatic 10 second timeout if they don't receive any video packet..
@tjacoby2006 commented on GitHub (Apr 24, 2026):
Line 216?
wolf-1 | 13:50:02.927375123 ERROR | [GSTREAMER] Pipeline error: Internal data stream error.@ABeltramo commented on GitHub (Apr 24, 2026):
Right, missed that. I guess your card doesn't support some formats; you could try playing with the config.toml line
A couple of simple tests that you can do:
cudaconvertscale ...line and basically make it `video_params_zero_copy="cudaupload"NV12toBGRARemember to restart the Wolf container after you edit
config.toml@tjacoby2006 commented on GitHub (Apr 24, 2026):
I was not able to figure out a combination to get it working, and unfortunately I just don't understand the GStreamer pipelines very well, so I ended up just settling on doing a CPU conversion to get the format correct. Not ideal, but any added latency should not be the end of the world.
@ABeltramo commented on GitHub (Jun 14, 2026):
This might be fixed by https://github.com/games-on-whales/wolf/pull/425 would you be able to pull the latest
revert the changes in
config.tomland test it out again?@piotrminkina commented on GitHub (Sep 13, 2026):
Same failure signature here, on Blackwell rather than a P100. After a lot of testing I can reduce it to something more general than a codec problem: the shared CUDA context degrades with every session teardown. An H.264 pipeline fails after one teardown, an H.265 pipeline survives one and fails after two. H.264 is not special, only more sensitive — which is why it looks like an H.264 bug at first.
Minimal reproduction
One client, one codec, nothing else involved.
With H.264:
Pipeline error: Internal data stream error.With H.265 — the same thing, one step later:
Every further attempt also fails, and Wolf often dies outright after a few of them. Only restarting Wolf clears it.
Environment
ghcr.io/games-on-whales/wolf:stable, digestsha256:edb348d7…, built from wolf2273b2e(2026-09-07)Using h264 encoder: nvcodec,h265: nvcodec,av1: nvcodec; zero-copy pipeline on/dev/dri/renderD128Blackwell + driver 595 is the hardware family of #417 and #405, both closed.
The failure has two stages
One Wolf process, one client, H.264 only — every pipeline's codec read from caps on its own
capsfilterelement, so there is no attribution ambiguity and no H.265 anywhere in the log:capsfilter3capsfilter7could not transformx4capsfilter9could not transformx4capsfilter13capsfilter17capsfilter21Stage 1 —
cudaconvertscalecannot configure a conversion, while the CUDA context is still a valid object:Confirmed identical at 1920x1080 and 3840x2160.
Stage 2 — once two sessions have been torn down, the shared
GstCudaContextstops being a valid GObject at all. This does not require any failed attempt first: in the H.265-only run below it arrives immediately after two sessions that both streamed perfectly.These fire before the new session's
Wayland display readyline — the context is already dead when setup begins — and thecould not transformwarnings disappear, because the pipeline no longer gets far enough to negotiate.H.265 is never observed in stage 1. It tolerates the one-teardown damage level entirely, so by the time it fails the context is already dead and it goes straight to stage 2 — which is exactly what the tolerance table below predicts.
The client-side symptom tracks the stage: in stage 1 Moonlight reports a terminated stream but still offers to resume; in stage 2 it shows the generic "something went wrong on the host PC while starting the stream" dialog.
In one run this ended with Wolf dying (
exited: wolf (exit status 11; not expected)), with a stack that lands in Wolf's own context-sharing path:I read the two stages as one progressive corruption driven by teardowns: closing the first session leaves the shared context damaged but still alive, so a stage-1 pipeline passes the GObject assertions yet finds no usable CUDA resources; closing a second one finishes the object off. Teardowns of sessions that actually streamed appear to cost more than teardowns of ones that already failed — two of the former are enough, whereas the all-H.264 run needed one successful plus two failed. That is an interpretation, not a measurement.
What actually predicts the failure: teardown count
Counting teardowns that precede the first failure, across archived runs:
The H.265-only run reproduced twice inside one log, in two consecutive Wolf processes, with identical caps counts per pipeline (130 / 103 / 48 / 21) and no H.264 anywhere in the file: two sessions stream, the third fails with the stage-2 context assertions, then Wolf exits 11.
This also resolves a case that looked contradictory earlier: a run where a third pipeline on H.265 worked fine. There the first client's session was never closed, so only one teardown had happened — within H.265's tolerance.
So the pipeline's position in the process is a proxy. What the failure tracks is how many sessions have been torn down since Wolf started:
"First pipeline" means first in the process lifetime, not first socket
Wolf reuses Wayland socket names, but a reconnecting client always gets new elements:
The element counter is per process and resets only on restart, which is the only action that clears the bug. Reconnecting onto the socket name that just worked does not help. In every capture the first pipeline of a process is
cudaconvertscale3and succeeds. Position itself is not the cause — the teardown count is — but the element index is a convenient greppable marker for which pipeline in a process you are looking at.Ruled out by experiment
Each tested with that variable isolated:
wayland-Nand on reused ones alike.format=NV12; both codecs negotiateprofile=mainandchroma-format=4:2:0.preset=low-latency-hq+rc-mode=cbr-ld-hq, both flagged deprecated bygst-inspect, while h265 and av1 already usepreset=p1+tune+multi-pass. Replacing the h264 line with the modern equivalent did not fix it (the new parameters encode fine standalone). Unrelated to this bug, the inconsistency may still be worth tidying.nvh264encin the process as such — two of them in one process viateework fine.CUDAMemory BGRA also reaches pipelines that work
Which element emits the transform warning matters. In a Lutris session — the third pipeline created in that process —
cudaconvertscalenever complains, but acapsfilterdoes, exactly once:That pipeline streams with no error at all — and note it was the third pipeline in its process, with zero teardowns before it, because the two earlier sessions were still running. Position alone costs nothing. (I did not measure its own codec — the caps lines in its time window belong to the still-running first session — but the point here does not depend on it.) So a rejected candidate during negotiation is routine, and CUDAMemory BGRA reaches pipelines that succeed as well as ones that fail. Only the
<cudaconvertscale*>variant is fatal.This is not a stale image
My image is the current
stable(registry digest matches) and contains every relevant fix merged so far: #425, and gst-wayland-display016b4fcpinned by1173e1a5, which includes the July/August CUDA lifetime fixes —ce6535d5(pool config pinningGstCudaContext),01027bad(clearing a pool the query still owns), PR #42 (CUDA context refcount),ce354c19(reference the gst_cuda helpers' short-circuit never transferred), PR #36 (DMABuf→CUDA context teardown). The stage-2 assertions above happen with all of those applied.The deeper Blackwell fix mentioned in #417 ("I'm working on a fix for blackwell and non-blackwell architectures") does not appear to have landed — I found no merged or open PR for it.
Separately,
gst-cudastill logsFailed to load 'nvrtcGetCUBINSize' … libnvrtc.so: undefined symbolhere. games-on-whales/gow#331 addresses that, but by its own test plan it is a no-op for driver-volume setups like mine, and its author notes the missing symbols only disable CUBIN while PTX still works — mentioned for completeness rather than as a suspect.The open question
Both codecs share the same
video_params_zero_copy, socudaconvertscaleis asked for the same output caps either way:Same requested output either way — yet H.264 gives up after one teardown and H.265 after two. Since both eventually fail, this is a difference in sensitivity to a degraded context rather than a categorical one: something the H.264 pipeline needs from the context is unavailable a step sooner. My guess is that the two encoders advertise different sink template caps, so negotiation resolves to different requirements upstream, but I have not verified it.
The more useful question for whoever picks this up is probably the other one: what does tearing a session down do to the shared
GstCudaContextsuch that the next pipeline gets a damaged one, and the one after that gets an object that failsG_IS_OBJECT?Workaround
There is no real workaround, only a way to postpone it. Switching a client to HEVC buys exactly one more session per Wolf lifetime, at the cost of software decoding on clients without hardware HEVC decode; the third session fails anyway. The only reliable answer is restarting Wolf, which is not practical in normal use.
Logs for every run above are small (60–900 lines) and I can attach any of them. Given the Blackwell hardware, happy to move this to its own issue and link back if you prefer.
@tjacoby2006 commented on GitHub (Sep 15, 2026):
The latest is working for me on a fresh setup. Thanks!