use std::{error::Error, mem::ManuallyDrop};
use image::{Rgb, ImageBuffer};
use nvfbc::cuda::CaptureMethod;
use nvfbc::{BufferFormat, CudaCapturer};
use rustacuda::{
CudaFlags,
device::Device,
};
use rustacuda::context::{Context, ContextFlags};
use rustacuda::prelude::{DeviceBuffer, CopyDestination};
use rustacuda::memory::LockedBuffer;
use rustacuda_core::DevicePointer;
fn main() -> Result<(), Box<dyn Error>> {
rustacuda::init(CudaFlags::empty())?;
let device = Device::get_device(0)?;
let _context = Context::create_and_push(
ContextFlags::MAP_HOST | ContextFlags::SCHED_AUTO, device)?;
let mut capturer = CudaCapturer::new()?;
let status = capturer.status()?;
println!("get_status: {:#?}", status);
if !status.can_create_now {
panic!("Can't create a CUDA capture session.");
}
capturer.start(BufferFormat::Rgb, 30)?;
let frame_info = capturer.next_frame(CaptureMethod::NoWaitIfNewFrame, None)?;
println!("{:#?}", frame_info);
let device_buffer = ManuallyDrop::new(unsafe { DeviceBuffer::from_raw_parts(
DevicePointer::wrap(frame_info.device_buffer as *mut u8),
frame_info.device_buffer_len as usize,
) });
let mut data: LockedBuffer<u8> = unsafe { LockedBuffer::uninitialized(frame_info.device_buffer_len as usize) }?;
device_buffer.copy_to(&mut data)?;
let slice = data.as_slice();
let frame = ImageBuffer::<Rgb<u8>, &[u8]>::from_raw(frame_info.width, frame_info.height, slice).unwrap();
frame.save("frame.png")?;
capturer.stop()?;
Ok(())
}