1use std::ffi::CStr;
2use std::marker::PhantomData;
3use std::str::from_utf8_unchecked;
4
5use super::{Flags, Pad};
6use ffi::*;
7
8pub struct Filter {
9 ptr: *mut AVFilter,
10}
11
12impl 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
26impl 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
82pub struct PadIter<'a> {
83 ptr: *const AVFilterPad,
84 count: isize,
85 cur: isize,
86
87 _marker: PhantomData<&'a ()>,
88}
89
90impl<'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
101impl<'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