fix(capture): capture CPU frames once the encoder proves it can't import dmabufs
audit / cargo-audit (push) Successful in 2m13s
audit / bun-audit (push) Failing after 13s
ci / web (push) Successful in 57s
ci / docs-site (push) Successful in 1m3s
windows-host / package (push) Successful in 10m18s
ci / bench (push) Successful in 6m41s
android / android (push) Successful in 12m26s
decky / build-publish (push) Successful in 21s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 14s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 13s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 9s
arch / build-publish (push) Successful in 12m30s
windows-msix / package (arm64, C:\Users\Public\ffmpeg-arm64, --no-default-features, aarch64-pc-windows-msvc, C:\t-a64) (push) Successful in 2m10s
ci / rust-arm64 (push) Successful in 11m46s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 11s
windows-msix / package (x64, C:\Users\Public\ffmpeg, , x86_64-pc-windows-msvc, C:\t) (push) Successful in 3m17s
deb / build-publish (push) Successful in 11m17s
windows / build (aarch64-pc-windows-msvc) (push) Successful in 1m13s
deb / build-publish-host (push) Successful in 12m35s
deb / build-publish-client-arm64 (push) Successful in 8m23s
windows / build (x86_64-pc-windows-msvc) (push) Successful in 2m5s
docker / build-push (ci, ci/rust-ci-noble.Dockerfile, punktfunk-rust-ci-noble) (push) Successful in 7m40s
apple / swift (push) Successful in 5m28s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 8m6s
docker / deploy-docs (push) Successful in 14s
ci / rust (push) Successful in 21m44s
docker / build-push-arm64cross (push) Successful in 7m18s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Successful in 17m37s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Successful in 17m14s
flatpak / build-publish (push) Successful in 6m38s
release / apple (push) Successful in 29m56s
apple / screenshots (push) Successful in 25m36s
audit / cargo-audit (push) Successful in 2m13s
audit / bun-audit (push) Failing after 13s
ci / web (push) Successful in 57s
ci / docs-site (push) Successful in 1m3s
windows-host / package (push) Successful in 10m18s
ci / bench (push) Successful in 6m41s
android / android (push) Successful in 12m26s
decky / build-publish (push) Successful in 21s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 14s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 13s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 9s
arch / build-publish (push) Successful in 12m30s
windows-msix / package (arm64, C:\Users\Public\ffmpeg-arm64, --no-default-features, aarch64-pc-windows-msvc, C:\t-a64) (push) Successful in 2m10s
ci / rust-arm64 (push) Successful in 11m46s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 11s
windows-msix / package (x64, C:\Users\Public\ffmpeg, , x86_64-pc-windows-msvc, C:\t) (push) Successful in 3m17s
deb / build-publish (push) Successful in 11m17s
windows / build (aarch64-pc-windows-msvc) (push) Successful in 1m13s
deb / build-publish-host (push) Successful in 12m35s
deb / build-publish-client-arm64 (push) Successful in 8m23s
windows / build (x86_64-pc-windows-msvc) (push) Successful in 2m5s
docker / build-push (ci, ci/rust-ci-noble.Dockerfile, punktfunk-rust-ci-noble) (push) Successful in 7m40s
apple / swift (push) Successful in 5m28s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 8m6s
docker / deploy-docs (push) Successful in 14s
ci / rust (push) Successful in 21m44s
docker / build-push-arm64cross (push) Successful in 7m18s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Successful in 17m37s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Successful in 17m14s
flatpak / build-publish (push) Successful in 6m38s
release / apple (push) Successful in 29m56s
apple / screenshots (push) Successful in 25m36s
A dmabuf import the GPU driver refuses is refused identically on every retry, but the only recovery above it was the encode-stall ladder: five in-place encoder rebuilds, then the video session ends. So a host whose driver will not take what its compositor allocates lost every session on its first frame, and every reconnect repeated it — while the very same host streamed fine with `PUNKTFUNK_ZEROCOPY=0`. The software knew how to run that machine and never chose to. Latch it, exactly as the sibling CUDA-import path already does after repeated worker deaths: three consecutive import failures with no frame in between disable the raw-dmabuf passthrough for the host process, and capture negotiates CPU frames from the next session on. Three sits below the encoder's rebuild budget, so the latch is set before the session it doomed ends — one bad session, then a working (if slower) host, with a log line saying which and why instead of an operator having to find an environment variable. Only the two stages that ARE the import are counted — the buffersrc push of the DRM-PRIME descriptor and the buffersink pull where `hwmap` maps it into a VA surface. `avcodec_send_frame` is deliberately left out: that one is the encoder stalling, which the in-place rebuild exists to recover, and taking zero-copy away permanently over a transient fault would be a bad trade. The latch lives in pf-zerocopy because it is the leaf both sides can see — the capture→encode edge is one-way by design, so pf-capture cannot ask pf-encode anything.
This commit is contained in:
@@ -1025,8 +1025,18 @@ impl DmabufInner {
|
||||
ffi::AV_BUFFERSRC_FLAG_KEEP_REF as c_int,
|
||||
);
|
||||
ffi::av_frame_free(&mut drm);
|
||||
// These two stages ARE the import: the push hands libav our DRM-PRIME descriptor, and
|
||||
// the pull is where `hwmap` actually maps it into a VA surface (and `scale_vaapi` runs
|
||||
// the CSC). A failure here means this driver would not take this compositor's dmabuf —
|
||||
// which no encoder rebuild can fix — so tell the process-wide latch, and capture
|
||||
// negotiates CPU frames from the next session on. `avcodec_send_frame` below is
|
||||
// deliberately NOT counted: that one is the encoder stalling, which the in-place
|
||||
// rebuild above us exists to recover, and disabling zero-copy over it would be a
|
||||
// permanent penalty for a transient fault.
|
||||
if r < 0 {
|
||||
bail!("av_buffersrc_add_frame failed ({r})");
|
||||
let e = format!("av_buffersrc_add_frame failed ({r})");
|
||||
pf_zerocopy::note_raw_dmabuf_import_failure(&e);
|
||||
bail!("{e}");
|
||||
}
|
||||
t_push = t0.elapsed();
|
||||
let mut nv12 = ffi::av_frame_alloc();
|
||||
@@ -1036,8 +1046,11 @@ impl DmabufInner {
|
||||
let r = ffi::av_buffersink_get_frame(self.sink, nv12);
|
||||
if r < 0 {
|
||||
ffi::av_frame_free(&mut nv12);
|
||||
bail!("av_buffersink_get_frame failed ({r})");
|
||||
let e = format!("av_buffersink_get_frame failed ({r})");
|
||||
pf_zerocopy::note_raw_dmabuf_import_failure(&e);
|
||||
bail!("{e}");
|
||||
}
|
||||
pf_zerocopy::note_raw_dmabuf_import_ok();
|
||||
t_pull = t0.elapsed() - t_push;
|
||||
(*nv12).pts = pts;
|
||||
(*nv12).pict_type = if idr {
|
||||
|
||||
Reference in New Issue
Block a user