Skip to main content

ffmpeg_next/filter/
filter.rs

1use std::ffi::CStr;
2use std::marker::PhantomData;
3use std::str::from_utf8_unchecked;
4
5use super::{Flags, Pad};
6use crate::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 = avfilter_filter_pad_count(self.as_ptr(), 0) 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 = avfilter_filter_pad_count(self.as_ptr(), 1) 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::wrap(self.ptr, self.cur);
111            self.cur += 1;
112
113            Some(pad)
114        }
115    }
116}