use crate::av::as_ptr::{AsMutPtr, AsPtr}; use crate::av::verify_response; use ffmpeg_sys_next::{ av_frame_alloc, av_frame_get_buffer, av_frame_unref, AVFrame, AVPictureType, AVPixelFormat, AVSampleFormat, }; #[derive(Debug)] pub struct Frame { ptr: *mut AVFrame, owned: bool, } impl Frame { pub fn alloc() -> Frame { let frame = unsafe { av_frame_alloc() }; if frame.is_null() { panic!("Can't alloc frame"); } Frame { ptr: frame, owned: true, } } #[inline] fn own(&mut self) { self.owned = true } #[inline] fn disown(&mut self) { self.owned = false } #[inline] pub fn width(&self) -> i32 { unsafe { (*self.ptr).width } } #[inline] pub fn height(&self) -> i32 { unsafe { (*self.ptr).height } } #[inline] pub fn pict_type(&self) -> AVPictureType { unsafe { (*self.ptr).pict_type } } #[inline] pub fn set_pict_type(&self, pict_type: AVPictureType) { unsafe { (*self.ptr).pict_type = pict_type } } #[inline] pub fn set_width(&self, width: i32) { unsafe { (*self.ptr).width = width } } #[inline] pub fn set_height(&self, height: i32) { unsafe { (*self.ptr).height = height } } #[inline] pub fn set_pixel_format(&self, pixel_format: AVPixelFormat) { unsafe { (*self.ptr).format = std::mem::transmute(pixel_format) } } #[inline] pub fn pixel_format(&self) -> AVPixelFormat { unsafe { std::mem::transmute::<_, AVPixelFormat>((*self.ptr).format) } } #[inline] pub fn set_sample_format(&self, sample_format: AVSampleFormat) { unsafe { (*self.ptr).format = std::mem::transmute(sample_format) } } #[inline] pub fn sample_format(&self) -> AVSampleFormat { unsafe { std::mem::transmute::<_, AVSampleFormat>((*self.ptr).format) } } #[inline] pub fn nb_samples(&self) -> i32 { unsafe { (*self.ptr).nb_samples } } pub fn allocate_video( &mut self, pixel_format: AVPixelFormat, width: i32, height: i32, ) -> Result<(), String> { self.set_pixel_format(pixel_format); self.set_width(width); self.set_height(height); verify_response("Failed to allocate frame", unsafe { av_frame_get_buffer(self.ptr, 32) })?; Ok(()) } #[inline] pub fn pts(&self) -> i64 { unsafe { (*self.ptr).pts } } #[inline] pub fn set_pts(&self, pts: i64) { unsafe { (*self.ptr).pts = pts } } } impl AsPtr for Frame { #[inline] fn as_ptr(&self) -> *const AVFrame { self.ptr } } impl AsMutPtr for Frame { #[inline] fn as_mut_ptr(&self) -> *mut AVFrame { self.ptr } } impl Drop for Frame { fn drop(&mut self) { if !self.owned { return; } unsafe { av_frame_unref(self.ptr) } } }