Fix filter::filter::PadIter to actually iterate
Bug caught by clippy: error: offset calculation on zero-sized value --> src/filter/filter.rs:98:33 | 98 | let pad = Pad::wrap(self.ptr.offset(self.cur)); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `#[deny(clippy::zst_offset)]` on by default = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#zst_offset The problem is that `AVFilterPad` is zero-sized: #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct AVFilterPad { _unused: [u8; 0], } which is in turn due to `AVFilterPad` being an opaque type in `libavfilter/avfilter.h`: typedef struct AVFilterContext AVFilterContext; typedef struct AVFilterLink AVFilterLink; typedef struct AVFilterPad AVFilterPad; typedef struct AVFilterFormats AVFilterFormats; Doing pointer arithmetic on an opaque (incomplete) type doesn't work. We have to use the proper FFI calls to obtain info on individual pads. The API has to be tweaked a bit; hopefully it doesn't break user programs (if it does it should only break bugged ones...). Fixes #20.
This commit is contained in:
parent
ec7fed0333
commit
6639f02b80
@ -95,7 +95,7 @@ impl<'a> Iterator for PadIter<'a> {
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let pad = Pad::wrap(self.ptr.offset(self.cur));
|
let pad = Pad::wrap(self.ptr, self.cur);
|
||||||
self.cur += 1;
|
self.cur += 1;
|
||||||
|
|
||||||
Some(pad)
|
Some(pad)
|
||||||
|
@ -58,3 +58,21 @@ pub fn find(name: &str) -> Option<Filter> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_paditer() {
|
||||||
|
assert_eq!(
|
||||||
|
find("overlay")
|
||||||
|
.unwrap()
|
||||||
|
.inputs()
|
||||||
|
.unwrap()
|
||||||
|
.map(|input| input.name().unwrap().to_string())
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
vec!("main", "overlay")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -7,14 +7,16 @@ use media;
|
|||||||
|
|
||||||
pub struct Pad<'a> {
|
pub struct Pad<'a> {
|
||||||
ptr: *const AVFilterPad,
|
ptr: *const AVFilterPad,
|
||||||
|
idx: isize,
|
||||||
|
|
||||||
_marker: PhantomData<&'a ()>,
|
_marker: PhantomData<&'a ()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Pad<'a> {
|
impl<'a> Pad<'a> {
|
||||||
pub unsafe fn wrap(ptr: *const AVFilterPad) -> Self {
|
pub unsafe fn wrap(ptr: *const AVFilterPad, idx: isize) -> Self {
|
||||||
Pad {
|
Pad {
|
||||||
ptr: ptr,
|
ptr: ptr,
|
||||||
|
idx: idx,
|
||||||
_marker: PhantomData,
|
_marker: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -31,7 +33,7 @@ impl<'a> Pad<'a> {
|
|||||||
impl<'a> Pad<'a> {
|
impl<'a> Pad<'a> {
|
||||||
pub fn name(&self) -> Option<&str> {
|
pub fn name(&self) -> Option<&str> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let ptr = avfilter_pad_get_name(self.ptr, 0);
|
let ptr = avfilter_pad_get_name(self.ptr, self.idx as i32);
|
||||||
|
|
||||||
if ptr.is_null() {
|
if ptr.is_null() {
|
||||||
None
|
None
|
||||||
@ -42,6 +44,6 @@ impl<'a> Pad<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn medium(&self) -> media::Type {
|
pub fn medium(&self) -> media::Type {
|
||||||
unsafe { media::Type::from(avfilter_pad_get_type(self.ptr, 0)) }
|
unsafe { media::Type::from(avfilter_pad_get_type(self.ptr, self.idx as i32)) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user