Fix avfiltergraph input output (#44)

* Port append_inout to rust

* impl Drop for filter::graph::Parser
This commit is contained in:
FreezyLemon 2024-04-30 03:36:14 +02:00 committed by GitHub
parent 159e6f924d
commit 0107b62f56
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1,5 +1,5 @@
use std::ffi::{CStr, CString}; use std::ffi::{CStr, CString};
use std::ptr; use std::ptr::{self, NonNull};
use std::str::from_utf8_unchecked; use std::str::from_utf8_unchecked;
use super::{Context, Filter}; use super::{Context, Filter};
@ -145,24 +145,16 @@ impl<'a> Parser<'a> {
pub fn input(mut self, name: &str, pad: usize) -> Result<Self, Error> { pub fn input(mut self, name: &str, pad: usize) -> Result<Self, Error> {
unsafe { unsafe {
let mut context = self.graph.get(name).ok_or(Error::InvalidData)?; let mut context = self.graph.get(name).ok_or(Error::InvalidData)?;
let input = avfilter_inout_alloc(); let mut input = NonNull::new(avfilter_inout_alloc()).expect("out of memory");
if input.is_null() {
panic!("out of memory");
}
let name = CString::new(name).unwrap(); let name = CString::new(name).unwrap();
(*input).name = av_strdup(name.as_ptr()); input.as_mut().name = av_strdup(name.as_ptr());
(*input).filter_ctx = context.as_mut_ptr(); input.as_mut().filter_ctx = context.as_mut_ptr();
(*input).pad_idx = pad as c_int; input.as_mut().pad_idx = pad as c_int;
(*input).next = ptr::null_mut(); input.as_mut().next = ptr::null_mut();
if self.inputs.is_null() { append_inout(&mut self.inputs, input);
self.inputs = input;
} else {
(*self.inputs).next = input;
}
} }
Ok(self) Ok(self)
@ -171,24 +163,16 @@ impl<'a> Parser<'a> {
pub fn output(mut self, name: &str, pad: usize) -> Result<Self, Error> { pub fn output(mut self, name: &str, pad: usize) -> Result<Self, Error> {
unsafe { unsafe {
let mut context = self.graph.get(name).ok_or(Error::InvalidData)?; let mut context = self.graph.get(name).ok_or(Error::InvalidData)?;
let output = avfilter_inout_alloc(); let mut output = NonNull::new(avfilter_inout_alloc()).expect("out of memory");
if output.is_null() {
panic!("out of memory");
}
let name = CString::new(name).unwrap(); let name = CString::new(name).unwrap();
(*output).name = av_strdup(name.as_ptr()); output.as_mut().name = av_strdup(name.as_ptr());
(*output).filter_ctx = context.as_mut_ptr(); output.as_mut().filter_ctx = context.as_mut_ptr();
(*output).pad_idx = pad as c_int; output.as_mut().pad_idx = pad as c_int;
(*output).next = ptr::null_mut(); output.as_mut().next = ptr::null_mut();
if self.outputs.is_null() { append_inout(&mut self.outputs, output);
self.outputs = output;
} else {
(*self.outputs).next = output;
}
} }
Ok(self) Ok(self)
@ -217,6 +201,31 @@ impl<'a> Parser<'a> {
} }
} }
fn append_inout(list: &mut *mut AVFilterInOut, element: NonNull<AVFilterInOut>) {
unsafe {
if list.is_null() {
*list = element.as_ptr();
return;
}
let mut curr = *list;
while !(*curr).next.is_null() {
curr = (*curr).next;
}
(*curr).next = element.as_ptr();
}
}
impl<'a> Drop for Parser<'a> {
fn drop(&mut self) {
unsafe {
avfilter_inout_free(&mut self.inputs);
avfilter_inout_free(&mut self.outputs);
}
}
}
impl Default for Graph { impl Default for Graph {
fn default() -> Self { fn default() -> Self {
Self::new() Self::new()