Skip to main content

ffmpeg_next/util/option/
traits.rs

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            #[cfg(not(feature = "ffmpeg_7_0"))]
138            {
139                check!(av_opt_set_channel_layout(
140                    self.as_mut_ptr(),
141                    name.as_ptr(),
142                    layout.bits() as i64,
143                    AV_OPT_SEARCH_CHILDREN
144                ))
145            }
146
147            #[cfg(feature = "ffmpeg_7_0")]
148            {
149                check!(av_opt_set_chlayout(
150                    self.as_mut_ptr(),
151                    name.as_ptr(),
152                    &layout.into(),
153                    AV_OPT_SEARCH_CHILDREN
154                ))
155            }
156        }
157    }
158}
159
160pub trait Gettable: Target {}
161
162pub trait Iterable: Target {}