util/option: add some basic options handling

This commit is contained in:
meh 2015-09-04 16:34:02 +02:00
parent ffb193ac68
commit 67a2c60a33
4 changed files with 192 additions and 0 deletions

View File

@ -16,6 +16,7 @@ pub use util::chroma;
pub use util::time; pub use util::time;
pub use util::frame::{self, Frame}; pub use util::frame::{self, Frame};
pub use util::channel_layout::{self, ChannelLayout}; pub use util::channel_layout::{self, ChannelLayout};
pub use util::option;
#[cfg(feature = "format")] #[cfg(feature = "format")]
pub mod format; pub mod format;

View File

@ -9,6 +9,7 @@ pub mod frame;
pub mod chroma; pub mod chroma;
pub mod time; pub mod time;
pub mod channel_layout; pub mod channel_layout;
pub mod option;
use std::ffi::CStr; use std::ffi::CStr;
use std::str::from_utf8_unchecked; use std::str::from_utf8_unchecked;

76
src/util/option/mod.rs Normal file
View File

@ -0,0 +1,76 @@
mod traits;
pub use self::traits::{Target, Settable, Gettable, Iterable};
use ffi::*;
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
pub enum Type {
Flags,
Int,
Int64,
Double,
Float,
String,
Rational,
Binary,
Dictionary,
Constant,
ImageSize,
PixelFormat,
SampleFormat,
VideoRate,
Duration,
Color,
ChannelLayout,
}
impl From<AVOptionType> for Type {
fn from(value: AVOptionType) -> Self {
match value {
AV_OPT_TYPE_FLAGS => Type::Flags,
AV_OPT_TYPE_INT => Type::Int,
AV_OPT_TYPE_INT64 => Type::Int64,
AV_OPT_TYPE_DOUBLE => Type::Double,
AV_OPT_TYPE_FLOAT => Type::Float,
AV_OPT_TYPE_STRING => Type::String,
AV_OPT_TYPE_RATIONAL => Type::Rational,
AV_OPT_TYPE_BINARY => Type::Binary,
AV_OPT_TYPE_DICT => Type::Dictionary,
AV_OPT_TYPE_CONST => Type::Constant,
AV_OPT_TYPE_IMAGE_SIZE => Type::ImageSize,
AV_OPT_TYPE_PIXEL_FMT => Type::PixelFormat,
AV_OPT_TYPE_SAMPLE_FMT => Type::SampleFormat,
AV_OPT_TYPE_VIDEO_RATE => Type::VideoRate,
AV_OPT_TYPE_DURATION => Type::Duration,
AV_OPT_TYPE_COLOR => Type::Color,
AV_OPT_TYPE_CHANNEL_LAYOUT => Type::ChannelLayout,
}
}
}
impl Into<AVOptionType> for Type {
fn into(self) -> AVOptionType {
match self {
Type::Flags => AV_OPT_TYPE_FLAGS,
Type::Int => AV_OPT_TYPE_INT,
Type::Int64 => AV_OPT_TYPE_INT64,
Type::Double => AV_OPT_TYPE_DOUBLE,
Type::Float => AV_OPT_TYPE_FLOAT,
Type::String => AV_OPT_TYPE_STRING,
Type::Rational => AV_OPT_TYPE_RATIONAL,
Type::Binary => AV_OPT_TYPE_BINARY,
Type::Dictionary => AV_OPT_TYPE_DICT,
Type::Constant => AV_OPT_TYPE_CONST,
Type::ImageSize => AV_OPT_TYPE_IMAGE_SIZE,
Type::PixelFormat => AV_OPT_TYPE_PIXEL_FMT,
Type::SampleFormat => AV_OPT_TYPE_SAMPLE_FMT,
Type::VideoRate => AV_OPT_TYPE_VIDEO_RATE,
Type::Duration => AV_OPT_TYPE_DURATION,
Type::Color => AV_OPT_TYPE_COLOR,
Type::ChannelLayout => AV_OPT_TYPE_CHANNEL_LAYOUT,
}
}
}

114
src/util/option/traits.rs Normal file
View File

@ -0,0 +1,114 @@
//! NOTE: this will be much better once specialization comes
use std::mem;
use std::ffi::CString;
use ffi::*;
use libc::{c_void, c_int, int64_t};
use ::{Error, Rational, ChannelLayout};
use util::format;
macro_rules! check {
($expr:expr) => (
match $expr {
0 => Ok(()),
e => Err(Error::from(e)),
}
)
}
pub unsafe trait Target {
fn as_ptr(&self) -> *const c_void;
fn as_mut_ptr(&mut self) -> *mut c_void;
}
pub trait Settable: Target {
fn set<T: 'static>(&mut self, name: &str, value: &T) -> Result<(), Error> {
unsafe {
check!(av_opt_set_bin(self.as_mut_ptr(),
CString::new(name).unwrap().as_ptr(),
value as *const _ as *const _, mem::size_of::<T>() as c_int,
AV_OPT_SEARCH_CHILDREN))
}
}
fn set_str(&mut self, name: &str, value: &str) -> Result<(), Error> {
unsafe {
check!(av_opt_set(self.as_mut_ptr(),
CString::new(name).unwrap().as_ptr(),
CString::new(value).unwrap().as_ptr(),
AV_OPT_SEARCH_CHILDREN))
}
}
fn set_int(&mut self, name: &str, value: i64) -> Result<(), Error> {
unsafe {
check!(av_opt_set_int(self.as_mut_ptr(),
CString::new(name).unwrap().as_ptr(),
value as int64_t,
AV_OPT_SEARCH_CHILDREN))
}
}
fn set_double(&mut self, name: &str, value: f64) -> Result<(), Error> {
unsafe {
check!(av_opt_set_double(self.as_mut_ptr(),
CString::new(name).unwrap().as_ptr(),
value,
AV_OPT_SEARCH_CHILDREN))
}
}
fn set_rational<T: Into<Rational>>(&mut self, name: &str, value: T) -> Result<(), Error> {
unsafe {
check!(av_opt_set_q(self.as_mut_ptr(),
CString::new(name).unwrap().as_ptr(),
value.into().into(),
AV_OPT_SEARCH_CHILDREN))
}
}
fn set_image_size(&mut self, name: &str, w: u32, h: u32) -> Result<(), Error> {
unsafe {
check!(av_opt_set_image_size(self.as_mut_ptr(),
CString::new(name).unwrap().as_ptr(),
w as c_int, h as c_int,
AV_OPT_SEARCH_CHILDREN))
}
}
fn set_pixel_format(&mut self, name: &str, format: format::Pixel) -> Result<(), Error> {
unsafe {
check!(av_opt_set_pixel_fmt(self.as_mut_ptr(),
CString::new(name).unwrap().as_ptr(),
format.into(),
AV_OPT_SEARCH_CHILDREN))
}
}
fn set_sample_format(&mut self, name: &str, format: format::Sample) -> Result<(), Error> {
unsafe {
check!(av_opt_set_sample_fmt(self.as_mut_ptr(),
CString::new(name).unwrap().as_ptr(),
format.into(),
AV_OPT_SEARCH_CHILDREN))
}
}
fn set_channel_layout(&mut self, name: &str, layout: ChannelLayout) -> Result<(), Error> {
unsafe {
check!(av_opt_set_channel_layout(self.as_mut_ptr(),
CString::new(name).unwrap().as_ptr(),
layout.bits() as int64_t,
AV_OPT_SEARCH_CHILDREN))
}
}
}
pub trait Gettable: Target {
}
pub trait Iterable: Target {
}