1 | use std::ffi::CStr; |
2 | use std::marker::PhantomData; |
3 | use std::str::from_utf8_unchecked; |
4 | |
5 | use super::{Flags, Pad}; |
6 | use ffi::*; |
7 | |
8 | pub struct Filter { |
9 | ptr: *mut AVFilter, |
10 | } |
11 | |
12 | impl Filter { |
13 | pub unsafe fn wrap(ptr: *mut AVFilter) -> Self { |
14 | Filter { ptr } |
15 | } |
16 | |
17 | pub unsafe fn as_ptr(&self) -> *const AVFilter { |
18 | self.ptr as *const _ |
19 | } |
20 | |
21 | pub unsafe fn as_mut_ptr(&mut self) -> *mut AVFilter { |
22 | self.ptr |
23 | } |
24 | } |
25 | |
26 | impl Filter { |
27 | pub fn name(&self) -> &str { |
28 | unsafe { from_utf8_unchecked(CStr::from_ptr((*self.as_ptr()).name).to_bytes()) } |
29 | } |
30 | |
31 | pub fn description(&self) -> Option<&str> { |
32 | unsafe { |
33 | let ptr = (*self.as_ptr()).description; |
34 | |
35 | if ptr.is_null() { |
36 | None |
37 | } else { |
38 | Some(from_utf8_unchecked(CStr::from_ptr(ptr).to_bytes())) |
39 | } |
40 | } |
41 | } |
42 | |
43 | pub fn inputs(&self) -> Option<PadIter> { |
44 | unsafe { |
45 | let ptr = (*self.as_ptr()).inputs; |
46 | |
47 | if ptr.is_null() { |
48 | None |
49 | } else { |
50 | #[cfg (not(feature = "ffmpeg_6_0" ))] |
51 | let nb_inputs = avfilter_pad_count((*self.as_ptr()).inputs) as isize; |
52 | #[cfg (feature = "ffmpeg_6_0" )] |
53 | let nb_inputs = (*self.as_ptr()).nb_inputs as isize; |
54 | |
55 | Some(PadIter::new((*self.as_ptr()).inputs, nb_inputs)) |
56 | } |
57 | } |
58 | } |
59 | |
60 | pub fn outputs(&self) -> Option<PadIter> { |
61 | unsafe { |
62 | let ptr = (*self.as_ptr()).outputs; |
63 | |
64 | if ptr.is_null() { |
65 | None |
66 | } else { |
67 | #[cfg (not(feature = "ffmpeg_6_0" ))] |
68 | let nb_outputs = avfilter_pad_count((*self.as_ptr()).outputs) as isize; |
69 | #[cfg (feature = "ffmpeg_6_0" )] |
70 | let nb_outputs = (*self.as_ptr()).nb_outputs as isize; |
71 | |
72 | Some(PadIter::new((*self.as_ptr()).outputs, nb_outputs)) |
73 | } |
74 | } |
75 | } |
76 | |
77 | pub fn flags(&self) -> Flags { |
78 | unsafe { Flags::from_bits_truncate((*self.as_ptr()).flags) } |
79 | } |
80 | } |
81 | |
82 | pub struct PadIter<'a> { |
83 | ptr: *const AVFilterPad, |
84 | count: isize, |
85 | cur: isize, |
86 | |
87 | _marker: PhantomData<&'a ()>, |
88 | } |
89 | |
90 | impl<'a> PadIter<'a> { |
91 | pub fn new(ptr: *const AVFilterPad, count: isize) -> Self { |
92 | PadIter { |
93 | ptr, |
94 | count, |
95 | cur: 0, |
96 | _marker: PhantomData, |
97 | } |
98 | } |
99 | } |
100 | |
101 | impl<'a> Iterator for PadIter<'a> { |
102 | type Item = Pad<'a>; |
103 | |
104 | fn next(&mut self) -> Option<Self::Item> { |
105 | unsafe { |
106 | if self.cur >= self.count { |
107 | return None; |
108 | } |
109 | |
110 | let pad: Pad<'_> = Pad::wrap(self.ptr, self.cur); |
111 | self.cur += 1; |
112 | |
113 | Some(pad) |
114 | } |
115 | } |
116 | } |
117 | |