This project wraps NVIDIA Video Codec SDK 11.0 for use in Rust. Both unsafe FFI and safe higher-level bindings are provided.
The project requires the libnvcuvid.so and libnvidia-encode.so libraries to be installed on the
system. They are tied to a particular Nvidia driver and often shipped in a system package.
- Arch Linux:
nvidia-utils. - Debian:
libnvcuvid1,libnvidia-encode1. - Gentoo:
nvidia-drivers. - Ubuntu:
libnvidia-decode-XXXandlibnvidia-encode-XXX, whereXXXis the driver version.
The main interface is provided by NvEncoder<ResourceManager>.
impl<ResourceManager> NvEncoder<ResourceManager> {
pub fn create_encoder(&mut self, encoder_params: &NvEncoderParams) -> NvEncoderResult<()>;
pub fn destroy_encoder(&mut self) -> NvEncoderResult<()>;
pub fn get_next_input_frame(&mut self) -> &mut NvEncInputFrame;
pub fn get_next_input_resource(&mut self) -> ResourceManager::InputResourceRef<'_>;
pub fn encode_frame(
&mut self,
packet: &mut Vec<&[u8]>,
pic_flags: EncodePicFlags,
) -> NvEncoderResult<()>;
pub fn end_encode(&mut self, packet: &mut Vec<&[u8]>) -> NvEncoderResult<()>;
}Method get_next_input_resource() provides a GPU resource that should be used as a target
to upload the frame data. Once uploaded, encode_frame() processes the frame and returns
the encoded data.
This trait specifies what kind of resources are used to back the frames used for encoding.
pub trait NvEncoderResourceManager {
type InputResource;
fn allocate_input_buffers(
encoder: &mut NvEncoder<Self>,
num_input_buffers: u32,
) -> Result<(), NvEncoderError>;
fn release_input_buffers(encoder: &mut NvEncoder<Self>) -> Result<(), NvEncoderError>;
}This is a thin wrapper over NvEncoder<NvEncoderGLResourceManager> that can be used to feed the encoder with OpenGL textures.
The decoder uses a different architecture reflecting the underlying SDK.
struct NvDecoder { ... }
impl NvDecoder {
pub fn builder(context: Context, codec: Codec) -> NvDecoderBuilder { ... }
pub fn decode(
&mut self,
data: &[u8],
flags: DecoderPacketFlags,
timestamp: i64,
) -> Result<usize, NvDecoderError> { ... }
pub fn get_frame(&mut self) -> Option<MappedMutexGuard<'_, Frame<'a>>> { ... }
pub fn get_width(&self) -> u32 { ... }
pub fn get_height(&self) -> u32 { ... }
}NvDecodercan be obtained withNvDecoder::builder().x().y().z().build(), provided acudarcCudaContexthas been created.- The decoder is then fed with
NvDecoder::decode(data, ...), which makes it parse and process thedata. - If decoding is successful the results can be queried with methods like
NvDecoder::get_width(),NvDecoder::get_height()andNvDecoder::get_frame()to get the actual data.- The frame data locality can be controlled with
NvDecoderBuilder::use_device_frame(). - There does not seem to be any code yet to process the device pointers when opting for
use_device_frame(true).
- The frame data locality can be controlled with