1//! NOTE: this will be much better once specialization comes
2
3use std::ffi::CString;
4use std::mem;
5
6use ffi::*;
7use libc::{c_int, c_void};
8use util::format;
9use {ChannelLayout, Error, Rational};
10
11macro_rules! check {
12 ($expr:expr) => {
13 match $expr {
14 0 => Ok(()),
15 e => Err(Error::from(e)),
16 }
17 };
18}
19
20pub unsafe trait Target {
21 fn as_ptr(&self) -> *const c_void;
22 fn as_mut_ptr(&mut self) -> *mut c_void;
23}
24
25pub trait Settable: Target {
26 fn set<T: 'static>(&mut self, name: &str, value: &T) -> Result<(), Error> {
27 unsafe {
28 let name = CString::new(name).unwrap();
29
30 check!(av_opt_set_bin(
31 self.as_mut_ptr(),
32 name.as_ptr(),
33 value as *const _ as *const _,
34 mem::size_of::<T>() as c_int,
35 AV_OPT_SEARCH_CHILDREN
36 ))
37 }
38 }
39
40 fn set_str(&mut self, name: &str, value: &str) -> Result<(), Error> {
41 unsafe {
42 let name = CString::new(name).unwrap();
43 let value = CString::new(value).unwrap();
44
45 check!(av_opt_set(
46 self.as_mut_ptr(),
47 name.as_ptr(),
48 value.as_ptr(),
49 AV_OPT_SEARCH_CHILDREN
50 ))
51 }
52 }
53
54 fn set_int(&mut self, name: &str, value: i64) -> Result<(), Error> {
55 unsafe {
56 let name = CString::new(name).unwrap();
57
58 check!(av_opt_set_int(
59 self.as_mut_ptr(),
60 name.as_ptr(),
61 value,
62 AV_OPT_SEARCH_CHILDREN
63 ))
64 }
65 }
66
67 fn set_double(&mut self, name: &str, value: f64) -> Result<(), Error> {
68 unsafe {
69 let name = CString::new(name).unwrap();
70
71 check!(av_opt_set_double(
72 self.as_mut_ptr(),
73 name.as_ptr(),
74 value,
75 AV_OPT_SEARCH_CHILDREN
76 ))
77 }
78 }
79
80 fn set_rational<T: Into<Rational>>(&mut self, name: &str, value: T) -> Result<(), Error> {
81 unsafe {
82 let name = CString::new(name).unwrap();
83
84 check!(av_opt_set_q(
85 self.as_mut_ptr(),
86 name.as_ptr(),
87 value.into().into(),
88 AV_OPT_SEARCH_CHILDREN
89 ))
90 }
91 }
92
93 fn set_image_size(&mut self, name: &str, w: u32, h: u32) -> Result<(), Error> {
94 unsafe {
95 let name = CString::new(name).unwrap();
96
97 check!(av_opt_set_image_size(
98 self.as_mut_ptr(),
99 name.as_ptr(),
100 w as c_int,
101 h as c_int,
102 AV_OPT_SEARCH_CHILDREN
103 ))
104 }
105 }
106
107 fn set_pixel_format(&mut self, name: &str, format: format::Pixel) -> Result<(), Error> {
108 unsafe {
109 let name = CString::new(name).unwrap();
110
111 check!(av_opt_set_pixel_fmt(
112 self.as_mut_ptr(),
113 name.as_ptr(),
114 format.into(),
115 AV_OPT_SEARCH_CHILDREN
116 ))
117 }
118 }
119
120 fn set_sample_format(&mut self, name: &str, format: format::Sample) -> Result<(), Error> {
121 unsafe {
122 let name = CString::new(name).unwrap();
123
124 check!(av_opt_set_sample_fmt(
125 self.as_mut_ptr(),
126 name.as_ptr(),
127 format.into(),
128 AV_OPT_SEARCH_CHILDREN
129 ))
130 }
131 }
132
133 fn set_channel_layout(&mut self, name: &str, layout: ChannelLayout) -> Result<(), Error> {
134 unsafe {
135 let name = CString::new(name).unwrap();
136
137 check!(av_opt_set_channel_layout(
138 self.as_mut_ptr(),
139 name.as_ptr(),
140 layout.bits() as i64,
141 AV_OPT_SEARCH_CHILDREN
142 ))
143 }
144 }
145}
146
147pub trait Gettable: Target {}
148
149pub trait Iterable: Target {}
150