A Vulkan-based video encoding library for Rust, supporting H.264, H.265, and AV1 codecs.
- Hardware-accelerated video encoding using Vulkan Video extensions.
- Multiple codec support: H.264/AVC, H.265/HEVC, AV1.
- GPU color conversion: RGB/BGR → YUV via Vulkan compute shaders (BT.709, BT.2020, sRGB→BT.2020+PQ, scRGB-linear→BT.2020+PQ).
- HDR support: 10-bit encoding (P010, YUV444P10), PQ transfer function, BT.2020 color space.
- GPU-native API: Encode directly from Vulkan images (
vk::Image). - Flexible configuration: Rate control (CBR, VBR, CQP), quality levels, GOP settings.
- Multiple input formats: BGRx, RGBx, BGRA, RGBA, ABGR2101010 (10-bit packed), RGBA16F (FP16).
- Utility helpers: [
InputImage] for easy YUV data upload to GPU. - Optional DMA-BUF support: Zero-copy image import from external processes (Linux only).
Note: B-frame support is not yet implemented. Setting
b_frame_count > 0will panic.
| Codec | Encode |
|---|---|
| H.264/AVC | ✓ |
| H.265/HEVC | ✓ |
| AV1 | ✓ |
- A GPU with Vulkan video encoding support (e.g., NVIDIA RTX series, AMD RDNA2+, Intel Arc)
Add this to your Cargo.toml:
[dependencies]
pixelforge = "0.1"| Feature | Description |
|---|---|
dmabuf | Enable DMA-BUF support for zero-copy image import from external processes (Linux only). Adds Vulkan extensions: VK_KHR_external_memory, VK_KHR_external_memory_fd, VK_EXT_external_memory_dma_buf, VK_EXT_image_drm_format_modifier. |
To enable DMA-BUF support:
[dependencies]
pixelforge = { version = "0.1", features = ["dmabuf"] }use pixelforge::{Codec,VideoContextBuilder};fnmain() -> Result<(),Box<dyn std::error::Error>>{let context = VideoContextBuilder::new().app_name("My App").build()?;for codec in[Codec::H264,Codec::H265,Codec::AV1]{println!("{:?}: encode={}",
codec,
context.supports_encode(codec));}Ok(())}use pixelforge::{Codec,EncodeBitDepth,EncodeConfig,Encoder,InputImage,PixelFormat,RateControlMode,VideoContextBuilder,};fnmain() -> Result<(),Box<dyn std::error::Error>>{let context = VideoContextBuilder::new().app_name("Encoder Example").require_encode(Codec::H264).build()?;let config = EncodeConfig::h264(1920,1080).with_rate_control(RateControlMode::Vbr).with_target_bitrate(5_000_000).with_frame_rate(30,1).with_gop_size(60);// Create an InputImage helper for uploading YUV data to the GPU.letmut input_image = InputImage::new(
context.clone(),Codec::H264,1920,1080,EncodeBitDepth::Eight,PixelFormat::Yuv420,)?;letmut encoder = Encoder::new(context, config)?;// For each frame: upload YUV data and encode.// let yuv_data: &[u8] = ...; // YUV420 frame data// input_image.upload_yuv420(yuv_data)?;// let packets = encoder.encode(input_image.image())?;Ok(())}PixelForge includes a GPU compute shader for converting RGB input to YUV output, supporting multiple color spaces:
| Color Space | Description |
|---|---|
Bt709 | Standard SDR (BT.709 coefficients) |
Bt2020 | HDR passthrough (BT.2020 coefficients, PQ-encoded input) |
SrgbToBt2020Pq | SDR-in-HDR (sRGB → linear → BT.2020 gamut → PQ OETF) |
Bt709LinearToBt2020Pq | scRGB HDR (linear BT.709 → BT.2020 gamut → PQ OETF). sdr_reference_white_nits sets the interpretation of 1.0; per the scRGB spec (IEC 61966-2-2), 80 nits. |
Supported input formats: BGRx, RGBx, BGRA, RGBA, ABGR2101010 (10-bit packed), RGBA16F (FP16). Supported output formats: NV12 (8-bit), I420 (8-bit), YUV444 (8-bit), P010 (10-bit), YUV444P10 (10-bit).
use pixelforge::{ColorConverter,ColorConverterConfig,ColorSpace,InputFormat,OutputFormat,VideoContextBuilder};let context = VideoContextBuilder::new().app_name("Color Converter").build()?;letmut config = ColorConverterConfig::new(1920,1080,InputFormat::BGRx,OutputFormat::NV12);
config.color_space = ColorSpace::SrgbToBt2020Pq;letmut converter = ColorConverter::new(context.clone(), config)?;// converter.convert(input_image, output_buffer)?;Run the encode latency benchmark with:
cargo run --example encode_bench
Run the examples with:
# Query codec capabilities
cargo run --example query_capabilities
# H.264 encoding example
cargo run --example encode_h264
# H.265 encoding example
cargo run --example encode_h265
# AV1 encoding example
cargo run --example encode_av1
# Verify all codecs and formats
cargo run --example verify_all
The color conversion shader is precompiled to SPIR-V and embedded at build time. See shader/README.md for details on editing and recompiling shaders.
- [] Decoding.
- [] B-frames support.
Contributions are welcome! Please feel free to submit a Pull Request.
This project was heavily inspired by the vk_video_samples repository by NVIDIA, which provided invaluable reference for Vulkan Video encoding.
License: BSD-2-Clause