From 2ff14a20437ca464cb40497f4f0c2fe06c0537a6 Mon Sep 17 00:00:00 2001 From: meh Date: Tue, 12 May 2015 03:25:29 +0200 Subject: [PATCH] util/frame: add Frame, frame::Video and frame::Audio --- src/lib.rs | 3 +- src/util/frame/mod.rs | 273 ++++++++++++++++++++++++++++++++++++ src/util/frame/side_data.rs | 97 +++++++++++++ src/util/mod.rs | 1 + 4 files changed, 372 insertions(+), 2 deletions(-) create mode 100644 src/util/frame/mod.rs create mode 100644 src/util/frame/side_data.rs diff --git a/src/lib.rs b/src/lib.rs index fe07444..9f2c85b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,5 +12,4 @@ pub use util::rational::Rational; pub use util::color_space::ColorSpace; pub use util::color_range::ColorRange; pub use util::media; -pub use util::sample_format::SampleFormat; -pub use util::pixel_format::PixelFormat; +pub use util::frame::{self, Frame}; diff --git a/src/util/frame/mod.rs b/src/util/frame/mod.rs new file mode 100644 index 0000000..5f618d8 --- /dev/null +++ b/src/util/frame/mod.rs @@ -0,0 +1,273 @@ +pub mod side_data; +pub use self::side_data::SideData; + +use libc::c_int; +use std::ptr; +use std::mem; +use std::ops::Deref; + +use ffi::*; +use ::{Dictionary, ColorSpace, ColorRange}; +use ::util::pixel_format::PixelFormat; +use ::util::sample_format::SampleFormat; + +pub struct Packet { + pub duration: isize, + pub position: isize, + pub size: usize, +} + +pub struct Frame { + pub ptr: *mut AVFrame, +} + +impl Frame { + pub fn new() -> Self { + unsafe { + Frame { ptr: av_frame_alloc() } + } + } + + pub fn make_unique(&mut self) -> &mut Self { + unsafe { + av_frame_make_writable(self.ptr); + } + + self + } + + pub fn is_unique(&self) -> bool { + unsafe { + av_frame_is_writable(self.ptr) == 0 + } + } + + pub fn is_key(&self) -> bool { + unsafe { + (*self.ptr).key_frame == 1 + } + } + + pub fn packet(&self) -> Packet { + unsafe { + Packet { + duration: av_frame_get_pkt_duration(self.ptr) as isize, + position: av_frame_get_pkt_pos(self.ptr) as isize, + size: av_frame_get_pkt_size(self.ptr) as usize, + } + } + } + + pub fn best_effort_timestamp(&self) -> isize { + unsafe { + av_frame_get_best_effort_timestamp(self.ptr) as isize + } + } + + pub fn metadata<'a>(&'a self) -> Dictionary<'a> { + unsafe { + Dictionary::wrap(av_frame_get_metadata(self.ptr)) + } + } + + pub fn set_metadata(&mut self, mut value: Dictionary) { + unsafe { + av_frame_set_metadata(self.ptr, value.take()); + } + } + + pub fn side_data<'a>(&'a self, kind: side_data::Type) -> Option> { + unsafe { + let ptr = av_frame_get_side_data(self.ptr, kind.into()); + + if ptr == ptr::null_mut() { + None + } + else { + Some(SideData::wrap(ptr)) + } + } + } + + pub fn new_side_data<'a>(&'a mut self, kind: side_data::Type, size: usize) -> Option> { + unsafe { + let ptr = av_frame_new_side_data(self.ptr, kind.into(), size as c_int); + + if ptr == ptr::null_mut() { + None + } + else { + Some(SideData::wrap(ptr)) + } + } + } + + pub fn remove_side_data(&mut self, kind: side_data::Type) { + unsafe { + av_frame_remove_side_data(self.ptr, kind.into()); + } + } +} + +impl Clone for Frame { + fn clone(&self) -> Self { + unsafe { + Frame { ptr: av_frame_clone(self.ptr) } + } + } + + fn clone_from(&mut self, source: &Self) { + unsafe { + av_frame_copy(self.ptr, source.ptr); + av_frame_copy_props(self.ptr, source.ptr); + } + } +} + +impl Drop for Frame { + fn drop(&mut self) { + unsafe { + av_frame_free(&mut self.ptr); + } + } +} + +pub struct Audio(Frame); + +impl Audio { + pub fn new() -> Self { + Audio(Frame::new()) + } + + pub fn format(&self) -> SampleFormat { + unsafe { + SampleFormat::from(mem::transmute::<_, AVSampleFormat>(((*self.ptr).format))) + } + } + + pub fn channel_layout(&self) -> i64 { + unsafe { + av_frame_get_channel_layout(self.0.ptr) + } + } + + pub fn set_channel_layout(&mut self, value: i64) { + unsafe { + av_frame_set_channel_layout(self.0.ptr, value); + } + } + + pub fn channels(&self) -> usize { + unsafe { + av_frame_get_channels(self.0.ptr) as usize + } + } + + pub fn set_channels(&mut self, value: usize) { + unsafe { + av_frame_set_channels(self.0.ptr, value as c_int); + } + } + + pub fn sample_rate(&self) -> i32 { + unsafe { + av_frame_get_sample_rate(self.0.ptr) + } + } + + pub fn set_sample_rate(&mut self, value: i32) { + unsafe { + av_frame_set_sample_rate(self.0.ptr, value); + } + } +} + +impl Deref for Audio { + type Target = Frame; + + fn deref(&self) -> &Frame { + &self.0 + } +} + +impl Into for Audio { + fn into(self) -> Frame { + self.0 + } +} + +impl Into