corevm-guest 0.1.28

API/SDK for CoreVM guest programs
Documentation
#![allow(clippy::missing_safety_doc)]

use crate::c;
use corevm_types::{flags::ReadVideoFrame, InputVideoFrameFormat, VideoMode};

/// Get video input mode.
#[inline]
pub fn video_input_mode() -> Option<VideoMode> {
	let regs = unsafe { c::video_input_mode() };
	VideoMode::from_regs(regs).ok()
}

/// Copy the next frame from the video input into the supplied buffer.
///
/// Returns `None` if the there are no more frame in the video input.
///
/// This is a non-blocking variant of [`read_video_frame`].
#[cfg(feature = "alloc")]
pub fn try_read_video_frame(format: InputVideoFrameFormat) -> Option<alloc::vec::Vec<u8>> {
	let len =
		unsafe { c::read_video_frame(0, 0, format as u64, ReadVideoFrame::NON_BLOCKING.bits()) };
	if len == u64::MAX {
		return None;
	}
	let mut buf = alloc::vec::Vec::with_capacity(len as usize);
	unsafe {
		c::read_video_frame(
			buf.as_mut_ptr() as u64,
			len,
			format as u64,
			ReadVideoFrame::NON_BLOCKING.bits(),
		)
	};
	unsafe { buf.set_len(len as usize) };
	Some(buf)
}

/// Copy the next frame from the video input into the supplied buffer.
///
/// Returns `None` if the there are no more frame in the video input.
/// Returns `Some(Err(n))` where `n` is the frame size if the buffer is too small.
/// On success returns `Some(Ok(n))` where `n` is the frame size.
///
/// This is a non-blocking variant of [`read_video_frame_into`].
#[inline]
pub fn try_read_video_frame_into(
	buf: &mut [u8],
	format: InputVideoFrameFormat,
) -> Option<Result<usize, usize>> {
	let len = unsafe {
		c::read_video_frame(
			buf.as_mut_ptr() as u64,
			buf.len() as u64,
			format as u64,
			ReadVideoFrame::NON_BLOCKING.bits(),
		)
	};
	if len == u64::MAX {
		return None;
	}
	if len > buf.len() as u64 {
		return Some(Err(len as usize));
	}
	Some(Ok(len as usize))
}

/// Return the next frame from the video input.
///
/// Blocks execution if there are no more frames in the video input.
/// For a non-blocking variant see [`try_read_video_frame`].
#[cfg(feature = "alloc")]
pub fn read_video_frame(format: InputVideoFrameFormat) -> alloc::vec::Vec<u8> {
	let len = unsafe { c::read_video_frame(0, 0, 0, 0) };
	let mut buf = alloc::vec::Vec::with_capacity(len as usize);
	unsafe { c::read_video_frame(buf.as_mut_ptr() as u64, len, format as u64, 0) };
	unsafe { buf.set_len(len as usize) };
	buf
}

/// Copy the next frame from the video input into the supplied buffer.
///
/// Blocks execution if there are no more frames in the video input.
/// For a non-blocking variant see [`try_read_video_frame_into`].
///
/// Returns `Err(n)` where `n` is the frame size if the buffer is too small.
/// On success returns `Ok(n)` where `n` is the frame size.
#[inline]
pub fn read_video_frame_into(
	buf: &mut [u8],
	format: InputVideoFrameFormat,
) -> Result<usize, usize> {
	let len =
		unsafe { c::read_video_frame(buf.as_mut_ptr() as u64, buf.len() as u64, format as u64, 0) };
	if len > buf.len() as u64 {
		return Err(len as usize);
	}
	Ok(len as usize)
}