struct NvfbcSession {
_lib: Library,
funcs: NVFBC_API_FUNCTION_LIST,
handle: u64,
capture_open: bool,
region: NVFBC_BOX,
size: NVFBC_SIZE,
with_cursor: bool,
}Expand description
A live NvFBC capture: the loaded library, the driver’s function table, the client handle, and the capture session bound to it.
The handle owns an OpenGL and a CUDA context that the driver binds to the thread that created it, and the captured device pointer belongs to whichever CUDA context was current at setup — which is why the whole object is built, used, and dropped on one thread, with NVENC’s own primary context pushed current. Sharing that context is what makes the capture zero-copy: the pointer the driver hands back is one NVENC can register directly.
Fields§
§_lib: Library§funcs: NVFBC_API_FUNCTION_LIST§handle: u64§capture_open: bool§region: NVFBC_BOXThe region of the framebuffer being captured, and the frame size it is delivered at.
size: NVFBC_SIZE§with_cursor: boolImplementations§
Source§impl NvfbcSession
impl NvfbcSession
Sourcefn load() -> Result<(Library, NVFBC_API_FUNCTION_LIST), String>
fn load() -> Result<(Library, NVFBC_API_FUNCTION_LIST), String>
Load libnvidia-fbc.so.1 and fill the driver’s function table, erroring when the library
is absent (no NVIDIA driver, or a container without the video capability) or too old to
answer for this API version.
Sourcefn last_error(&self) -> String
fn last_error(&self) -> String
The driver’s message for the last failure on this handle, for a log line that says what went wrong rather than only that something did.
Sourcefn fail(&self, what: &str, status: u32) -> NvfbcError
fn fail(&self, what: &str, status: u32) -> NvfbcError
Turn a driver status into an error carrying both the code and the driver’s own message.
Sourcefn open() -> Result<Self, String>
fn open() -> Result<Self, String>
Open a client handle on the X server named by the environment, letting NvFBC create and manage the OpenGL context it captures through.
The server is asked for NVIDIA_GLX first, over a connection of our own: it is what the
library looks up here too, and where it is missing the library’s own lookup is the call
that never returns.
The handle is bound to the calling thread, and every later call has to come from it.
Sourcefn status(&self) -> Result<NVFBC_GET_STATUS_PARAMS, NvfbcError>
fn status(&self) -> Result<NVFBC_GET_STATUS_PARAMS, NvfbcError>
Ask the driver whether capture is possible here and how large the framebuffer is.
Sourcefn start(
&mut self,
region: NVFBC_BOX,
size: NVFBC_SIZE,
with_cursor: bool,
) -> Result<(), NvfbcError>
fn start( &mut self, region: NVFBC_BOX, size: NVFBC_SIZE, with_cursor: bool, ) -> Result<(), NvfbcError>
Start capturing region of the framebuffer into video memory, delivered at size.
The session is programmed for latency rather than for throughput smoothing: push model, so the driver generates a frame when an application damages the screen instead of polling on a timer; direct capture allowed, so a fullscreen unoccluded application presents into the capture buffer without going through the X server (which the driver takes up only when the cursor is not composited); and the native BGRA format, which needs no conversion pass and so no extra copy. Modeset recovery is left to the driver, which rebuilds the session and resumes on its own.
Sourcefn grab(&mut self, timeout: Duration) -> Result<GrabbedFrame, NvfbcError>
fn grab(&mut self, timeout: Duration) -> Result<GrabbedFrame, NvfbcError>
Take the next frame, waiting at most timeout for the driver to produce one.
A frame the client has not seen yet is returned without waiting at all; otherwise the call
blocks until one is rendered or the timeout expires, and then returns the frame already in
the buffer with is_new false. Nothing is copied either way: the device pointer addresses
the driver’s own capture buffer, which stays valid until the next grab.
Sourcefn grab_with(
&mut self,
flags: u32,
timeout: Duration,
) -> Result<GrabbedFrame, NvfbcError>
fn grab_with( &mut self, flags: u32, timeout: Duration, ) -> Result<GrabbedFrame, NvfbcError>
The grab above, with the driver’s wait behavior named explicitly.
Trait Implementations§
Source§impl Drop for NvfbcSession
impl Drop for NvfbcSession
Auto Trait Implementations§
impl !Send for NvfbcSession
impl !Sync for NvfbcSession
impl Freeze for NvfbcSession
impl RefUnwindSafe for NvfbcSession
impl Unpin for NvfbcSession
impl UnsafeUnpin for NvfbcSession
impl UnwindSafe for NvfbcSession
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more