Skip to main content

ffmpeg_the_third/util/option/
traits.rs

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