You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

183 lines
4.0 KiB
Rust

use crate::av::as_ptr::{AsMutPtr, AsPtr};
use crate::av::verify_response;
use ffmpeg_sys_next::{
av_frame_alloc, av_frame_free, av_frame_get_buffer, 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]
pub fn own(&mut self) {
self.owned = true
}
#[inline]
pub 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 sample_rate(&self) -> i32 {
unsafe { (*self.ptr).sample_rate }
}
#[inline]
pub fn set_sample_rate(&self, sample_rate: i32) {
unsafe { (*self.ptr).sample_rate = sample_rate }
}
#[inline]
pub fn channel_layout(&self) -> u64 {
unsafe { (*self.ptr).channel_layout }
}
#[inline]
pub fn set_channel_layout(&self, channel_layout: u64) {
unsafe { (*self.ptr).channel_layout = channel_layout }
}
#[inline]
pub fn set_nb_samples(&self, nb_samples: i32) {
unsafe { (*self.ptr).nb_samples = nb_samples }
}
#[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);
self.allocate()
}
pub fn allocate_audio(
&self,
sample_format: AVSampleFormat,
channel_layout: u64,
nb_samples: i32,
) -> Result<(), String> {
self.set_sample_format(sample_format);
self.set_channel_layout(channel_layout);
self.set_nb_samples(nb_samples);
self.allocate()
}
fn allocate(&self) -> Result<(), String> {
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<AVFrame> for Frame {
#[inline]
fn as_ptr(&self) -> *const AVFrame {
self.ptr
}
}
impl AsMutPtr<AVFrame> 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_free(&mut self.ptr) }
}
}