1 | //! NOTE: this will be much better once specialization comes |
2 | |
3 | use std::ffi::CString; |
4 | use std::mem; |
5 | |
6 | use ffi::*; |
7 | use libc::{c_int, c_void}; |
8 | use util::format; |
9 | use {ChannelLayout, Error, Rational}; |
10 | |
11 | macro_rules! check { |
12 | ($expr:expr) => { |
13 | match $expr { |
14 | 0 => Ok(()), |
15 | e => Err(Error::from(e)), |
16 | } |
17 | }; |
18 | } |
19 | |
20 | pub unsafe trait Target { |
21 | fn as_ptr(&self) -> *const c_void; |
22 | fn as_mut_ptr(&mut self) -> *mut c_void; |
23 | } |
24 | |
25 | pub 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 | |
147 | pub trait Gettable: Target {} |
148 | |
149 | pub trait Iterable: Target {} |
150 | |