Skip to main content

Crate dxgi_capture_rs

Crate dxgi_capture_rs 

Source
Available on Windows only.
Expand description

High-performance screen capturing with DXGI Desktop Duplication API for Windows.

This library provides a Rust interface to the Windows DXGI Desktop Duplication API, enabling efficient screen capture with minimal performance overhead.

§Features

  • High Performance: Direct access to DXGI Desktop Duplication API
  • Multiple Monitor Support: Capture from any available display
  • Flexible Output: Get pixel data as BGRA8 or raw component bytes
  • Frame Metadata: Access dirty rectangles, moved rectangles, and timing information
  • Comprehensive Error Handling: Robust error types for production use
  • Windows Optimized: Specifically designed for Windows platforms

§Platform Requirements

  • Windows 8 or later (DXGI 1.2+ required)
  • Compatible graphics driver supporting Desktop Duplication
  • Active desktop session (not suitable for headless environments)

§Quick Start

use dxgi_capture_rs::{DXGIManager, CaptureError};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut manager = DXGIManager::new(1000)?;
     
    match manager.capture_frame() {
        Ok((pixels, (width, height))) => {
            println!("Captured {}x{} frame", width, height);
            // Process pixels (Vec<BGRA8>)
        }
        Err(CaptureError::Timeout) => {
            // No new frame - normal occurrence
        }
        Err(e) => eprintln!("Capture failed: {:?}", e),
    }
    Ok(())
}

§Multi-Monitor Support

let mut manager = DXGIManager::new(1000)?;

manager.set_capture_source_index(0); // Primary monitor
let (pixels, dimensions) = manager.capture_frame()?;

manager.set_capture_source_index(1); // Secondary monitor
let (pixels, dimensions) = manager.capture_frame()?;

§Frame Metadata for Streaming Applications

The library provides detailed frame metadata including dirty rectangles and moved rectangles, which is crucial for optimizing streaming and remote desktop applications.

let mut manager = DXGIManager::new(1000)?;

match manager.capture_frame_with_metadata() {
    Ok((pixels, (width, height), metadata)) => {
        // Only process frame if there are actual changes
        if metadata.has_updates() {
            println!("Frame has {} dirty rects and {} move rects",
                     metadata.dirty_rects.len(), metadata.move_rects.len());
             
            // Process moved rectangles first (as per Microsoft recommendation)
            for move_rect in &metadata.move_rects {
                let (src_x, src_y) = move_rect.source_point;
                let (dst_left, dst_top, dst_right, dst_bottom) = move_rect.destination_rect;
                 
                // Copy pixels from source to destination
                // This is much more efficient than re-encoding the entire area
                copy_rectangle(&pixels, src_x, src_y, dst_left, dst_top,
                              dst_right - dst_left, dst_bottom - dst_top);
            }
             
            // Then process dirty rectangles
            for &(left, top, right, bottom) in &metadata.dirty_rects {
                let width = (right - left) as usize;
                let height = (bottom - top) as usize;
                 
                // Only encode/transmit the changed region
                encode_region(&pixels, left as usize, top as usize, width, height);
            }
        }
         
        // Check for mouse cursor updates
        if metadata.has_mouse_updates() {
            if let Some((x, y)) = metadata.pointer_position {
                println!("Mouse cursor at ({}, {}), visible: {}", x, y, metadata.pointer_visible);
            }
        }
    }
    Err(e) => eprintln!("Capture failed: {:?}", e),
}

§Error Handling

let mut manager = DXGIManager::new(1000)?;

match manager.capture_frame() {
    Ok((pixels, dimensions)) => { /* Process successful capture */ }
    Err(CaptureError::Timeout) => { /* No new frame - normal */ }
    Err(CaptureError::AccessDenied) => { /* Protected content */ }
    Err(CaptureError::AccessLost) => { /* Display mode changed */ }
    Err(e) => eprintln!("Capture failed: {:?}", e),
}

§Performance Considerations

  • Use appropriate timeout values based on your frame rate requirements
  • Consider using DXGIManager::capture_frame_components for raw byte data
  • Memory usage scales with screen resolution
  • The library automatically handles screen rotation
  • Use metadata to optimize streaming by only processing changed regions
  • Process move rectangles before dirty rectangles for correct visual output

§Thread Safety

DXGIManager is not thread-safe. Create separate instances for each thread if you need concurrent capture operations.

Structs§

BGRA8
A pixel color in BGRA8 format.
DXGIManager
The main manager for handling DXGI desktop duplication.
FrameMetadata
Metadata about a captured frame.
MoveRect
Represents a rectangle that has been moved from one location to another.

Enums§

CaptureError
Errors that can occur during screen capture operations.
OutputDuplicationError
Errors that can occur during output duplication initialization.

Functions§

hr_failedDeprecated
Checks whether a Windows HRESULT represents a failure condition.

Type Aliases§

CaptureFrameComponentsWithMetadataResult
CaptureFrameWithMetadataResult