use crate::{avutil::AVPixelFormat, ffi, shared::*};
use std::ptr::{self, NonNull};
const AV_NUM_DATA_POINTERS: usize = ffi::AV_NUM_DATA_POINTERS as usize;
wrap! {
AVImage: Vec<u8>,
data: [*mut u8; AV_NUM_DATA_POINTERS] = [ptr::null_mut(); AV_NUM_DATA_POINTERS],
linesizes: [i32; AV_NUM_DATA_POINTERS] = [0; AV_NUM_DATA_POINTERS],
width: i32 = 0,
height: i32 = 0,
pix_fmt: AVPixelFormat = ffi::AV_PIX_FMT_NONE,
}
impl AVImage {
pub fn new(pix_fmt: AVPixelFormat, width: i32, height: i32, align: i32) -> Option<Self> {
let num_of_bytes = Self::get_buffer_size(pix_fmt, width, height, align)?;
let mut data = [ptr::null_mut(); AV_NUM_DATA_POINTERS];
let mut linesizes = [0; AV_NUM_DATA_POINTERS];
let mut linear = vec![0u8; num_of_bytes as usize];
match unsafe {
ffi::av_image_fill_arrays(
data.as_mut_ptr(),
linesizes.as_mut_ptr(),
linear.as_mut_ptr(),
pix_fmt,
width,
height,
align,
)
}
.upgrade()
{
Ok(_) => {}
Err(AVERROR_ENOMEM) => panic!(),
Err(_) => return None,
}
let linear = Box::leak(Box::new(linear));
let mut image = unsafe { AVImage::from_raw(NonNull::new(linear).unwrap()) };
image.data = data;
image.linesizes = linesizes;
image.width = width;
image.height = height;
image.pix_fmt = pix_fmt;
Some(image)
}
pub fn get_buffer_size(fmt: AVPixelFormat, width: i32, height: i32, align: i32) -> Option<i32> {
unsafe { ffi::av_image_get_buffer_size(fmt, width, height, align) }
.upgrade()
.ok()
}
pub fn data(&self) -> &[*mut u8; AV_NUM_DATA_POINTERS] {
&self.data
}
pub fn linesizes(&self) -> &[i32; AV_NUM_DATA_POINTERS] {
&self.linesizes
}
}
impl Drop for AVImage {
fn drop(&mut self) {
let _linear = unsafe { Box::from_raw(self.as_mut_ptr()) };
}
}
pub use ffi::av_image_fill_arrays;