21pages f05f86dc80 444
Signed-off-by: 21pages <pages21@163.com>
2023-10-30 18:46:56 +08:00

72 lines
1.6 KiB
Rust

use std::{ops, ptr, slice};
use super::ffi::*;
pub struct Frame {
surface: IOSurfaceRef,
inner: &'static [u8],
bgra: Vec<u8>,
bgra_stride: usize,
}
impl Frame {
pub unsafe fn new(surface: IOSurfaceRef) -> Frame {
CFRetain(surface);
IOSurfaceIncrementUseCount(surface);
IOSurfaceLock(surface, SURFACE_LOCK_READ_ONLY, ptr::null_mut());
let inner = slice::from_raw_parts(
IOSurfaceGetBaseAddress(surface) as *const u8,
IOSurfaceGetAllocSize(surface),
);
Frame {
surface,
inner,
bgra: Vec::new(),
bgra_stride: 0,
}
}
#[inline]
pub fn inner(&self) -> &[u8] {
self.inner
}
pub fn stride(&self) -> usize {
self.bgra_stride
}
pub fn surface_to_bgra<'a>(&'a mut self, h: usize) {
unsafe {
let plane0 = IOSurfaceGetBaseAddressOfPlane(self.surface, 0);
self.bgra_stride = IOSurfaceGetBytesPerRowOfPlane(self.surface, 0);
self.bgra.resize(self.bgra_stride * h, 0);
std::ptr::copy_nonoverlapping(
plane0 as _,
self.bgra.as_mut_ptr(),
self.bgra_stride * h,
);
}
}
}
impl ops::Deref for Frame {
type Target = [u8];
fn deref<'a>(&'a self) -> &'a [u8] {
&self.bgra
}
}
impl Drop for Frame {
fn drop(&mut self) {
unsafe {
IOSurfaceUnlock(self.surface, SURFACE_LOCK_READ_ONLY, ptr::null_mut());
IOSurfaceDecrementUseCount(self.surface);
CFRelease(self.surface);
}
}
}