Skip to main content

Module nvfbc

Module nvfbc 

Source
Expand description

NVIDIA Framebuffer Capture (NvFBC): the zero-copy X11 capture path, where the NVIDIA driver composites the X screen straight into video memory and NVENC encodes it there.

The XShm path in super is the general one, and it copies once: the X server blits the screen into a shared-memory surface, and a hardware session then uploads that surface across PCIe. NvFBC removes both. The capture subsystem lives in the NVIDIA X driver, composites each frame into a buffer it owns in video memory, and hands back a CUdeviceptr — which is registered with NVENC in place, exactly as a Wayland dmabuf is, so a frame is never read, written, or copied by the CPU between the screen and the bitstream.

Three properties follow from that, and the module is built around keeping all three:

  1. Zero copy. The device pointers are stable for as long as the geometry is (recent drivers alternate between two), so each is registered and mapped once (NvencEncoder::encode_cuda_pitch) and every later frame from it reuses that registration.
  2. Lowest latency. The session runs in push model — the driver generates a frame when an application damages the screen rather than on a sampling timer — and each grab is issued with NOWAIT_IF_NEW_FRAME_READY, so a frame that already exists is taken immediately and one that does not is waited for only until the frame deadline. Direct capture is allowed, which lets the driver attach to a fullscreen unoccluded application and have it present into the capture buffer, bypassing the X server entirely.
  3. Unrestricted frame rate. Capture and encode share one thread with no hand-off, and neither does any per-pixel CPU work: no shm round-trip, no content hashing on the host (the GPU hashes a new frame’s bands where it lies), no cursor blend. What the loop can sustain is what NVENC can sustain.

Requirements are checked rather than assumed, because none of them holds everywhere: the session must encode on NVENC (the device pointer is meaningless to any other encoder), the X server must be one the NVIDIA driver drives, the driver must offer NvFBC on this GPU and X server, and a watermark keeps the XShm path since blending it would mean reading the frame back. open reports what it found and returns None, and the caller streams through XShm instead. The X server is asked first and over our own connection, because the library’s own answer is the one that may never come.

The API is reached the way NVENC’s is: libnvidia-fbc.so.1 is loaded at run time and every entry point comes from the function table NvFBCCreateInstance fills, so the build links no NVIDIA library and one binary runs wherever a driver is installed. The structures below are the ABI of NvFBC 1.8 (nvcodec-sys/headers/NvFBC.h); each carries a version word packing its own size_of, which is what makes the layout assertions in abi_tests a real check.

Structs§

GpuCapture 🔒
A running zero-copy capture: the NvFBC session and the NVENC session it feeds, on the thread that owns both contexts.
GrabbedFrame 🔒
One frame the driver composited into video memory.
NVFBC_API_FUNCTION_LIST 🔒
The driver’s entry points, as NvFBCCreateInstance fills them. The retired slots are the deprecated hardware-encoder interface and are never called.
NVFBC_BOX 🔒
A region of the tracked framebuffer, in its own coordinates.
NVFBC_CREATE_CAPTURE_SESSION_PARAMS 🔒
NVFBC_CREATE_HANDLE_PARAMS 🔒
NVFBC_FRAME_GRAB_INFO 🔒
What the driver reports about a captured frame: its geometry and byte size, whether it is one the client has not seen, how many the driver generated meanwhile, and whether it needed a conversion pass or came straight from a fullscreen application.
NVFBC_GET_STATUS_PARAMS 🔒
What the driver says about capture on this X server: whether it is possible at all, whether a session can be created right now, the framebuffer size, and the connected outputs.
NVFBC_RANDR_OUTPUT_INFO 🔒
One RandR output of the tracked X screen, as NvFBCGetStatus reports it.
NVFBC_SIZE 🔒
A frame’s pixel dimensions.
NVFBC_TOCUDA_GRAB_FRAME_PARAMS 🔒
NVFBC_TOCUDA_SETUP_PARAMS 🔒
NVFBC_VERSION_ONLY_PARAMS 🔒
The only parameter block of the destroy / context calls: a version word.
NvfbcError 🔒
A driver call that failed: the status the driver returned, and its own account of it.
NvfbcSession 🔒
A live NvFBC capture: the loaded library, the driver’s function table, the client handle, and the capture session bound to it.
RootWatch 🔒
The X server’s word that its root window changed size (a RandR resize), on a connection of our own: the capture polls it every frame without a round trip, where asking the driver (NvFBCGetStatus) took 15 ms a call on an NVIDIA Xorg, a frame and more at 240 fps.

Enums§

Recovery 🔒
What a failed driver call leaves the capture able to do.

Constants§

GEOMETRY_POLL_FRAMES 🔒
Frames between framebuffer-size polls, matching the XShm path’s geometry cadence.
NVFBC_BUFFER_FORMAT_BGRA 🔒
The driver’s native buffer format: B,G,R,A in memory, 32 bpp, needing no conversion pass.
NVFBC_CAPTURE_SHARED_CUDA 🔒
Capture into a CUDA buffer in video memory, the only capture type this module uses.
NVFBC_ERR_MUST_RECREATE 🔒
A modeset invalidated the session; recreating it resumes capture.
NVFBC_ERR_X 🔒
The X server is gone; the handle cannot be reused, only destroyed and recreated.
NVFBC_FALSE 🔒
NVFBC_LIBRARY 🔒
Runtime name of the NvFBC library. The NVIDIA container toolkit injects it under the video driver capability, alongside libnvidia-encode.so.1.
NVFBC_OUTPUT_MAX 🔒
NVFBC_OUTPUT_NAME_LEN 🔒
NVFBC_SUCCESS 🔒
NVFBC_TOCUDA_GRAB_FLAGS_NOWAIT 🔒
Return whatever is in the capture buffer without waiting for the driver to render.
NVFBC_TOCUDA_GRAB_FLAGS_NOWAIT_IF_NEW_FRAME_READY 🔒
Take a frame that is already waiting without blocking, otherwise wait for one.
NVFBC_TRACKING_SCREEN 🔒
Track the entire X screen (the framebuffer), rather than one RandR output.
NVFBC_TRUE 🔒
NVFBC_VERSION 🔒
NvFBC API version this module speaks: minor in the low byte, major above it.
NVIDIA_GLX 🔒
The extension the NVIDIA driver’s GLX registers, and the one libnvidia-fbc resolves on its own X connection before it will do anything: NvFBC captures the screen through a GLX context only that driver provides. An X server without it — an Xvfb, a Mesa-driven Xorg — has nothing for the library to attach to, and the lookup there is not merely futile: it can block inside the library and never return, which costs the capture thread and then the display’s stop path.
PROBE_TIMEOUT 🔒
How long the driver may take to answer whether it can capture this X server at all.

Functions§

answered_within 🔒
Run f on a thread of its own and wait at most timeout for its answer. A call into a driver library that never returns then costs a bounded wait and a leaked thread instead of the caller, whose name what gives the refusal.
declined 🔒
Why the NvFBC path was not taken, for the one line that says so.
foreign_libxcb 🔒
The libxcb this process’s libX11 calls, when that is another copy than the host’s libxcb.so.1, which is the one the NVIDIA library calls. The manylinux policy leaves libX11 to the host but lets a wheel bundle libxcb, and a wheel whose libraries load libX11 first binds the host’s libX11 to its own copy (a pcmflux wheel whose libpulse carries libxcb does). NvFBC opens its display through libX11 and then calls the host’s libxcb on that connection, whose structure is laid out by the other build: a mutex read at a shifted offset makes glibc abort the process, and a flag read at one leaves the library waiting forever.
frame_pitch 🔒
The row stride of a captured frame: the driver’s own, derived from the buffer size it reports, or the packed width when that size is not a whole number of rows.
nvidia_driven_x_server 🔒
Whether the X server this session would capture is driven by the NVIDIA driver. Asked over a connection of our own, so it costs one round trip and is answered by the X server rather than by the library whose answer cannot be relied on to come.
open 🔒
Build the zero-copy capture for these settings, or report why it cannot serve them.
recovery_for 🔒
reopen_handle 🔒
Replace the client handle, for the one failure the API offers no other way back from: the X server the handle was opened on is gone. The capture session on it is created again by the loop’s geometry step, against the root the new handle reports.
resolve_region 🔒
The capture region and delivered frame size for a set of settings against a framebuffer of screen, in the terms the XShm path resolves them: the origin clamped into the screen, the size following the root when auto-adjust is on and clamped to what is left of it otherwise, and both dimensions even because every video codec needs them to be.
restart_session 🔒
Restart the capture session at a new region, size, or cursor mode, and bring NVENC to the same geometry. The device pointer the driver returns afterwards is a new one, which the encoder’s registration follows on the next frame.
run_capture
Run the zero-copy X11 capture until controls.stop is set, or report that it cannot start.
struct_ver 🔒
The version word an NvFBC parameter struct carries: its own size, its revision, and the API version, packed as the SDK’s NVFBC_STRUCT_VERSION macro packs them (the API version lands at bit 24, where only its low byte survives the 32-bit result).

Type Aliases§

NVFBCSTATUS 🔒
NVFBC_BOOL 🔒
NVFBC_SESSION_HANDLE 🔒
NvFBCCreateInstanceFn 🔒