playa_ffmpeg/util/option/
traits.rs

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