From 0107b62f56b8994000fa1a0a6fad0927fca6b143 Mon Sep 17 00:00:00 2001 From: FreezyLemon Date: Tue, 30 Apr 2024 03:36:14 +0200 Subject: [PATCH] Fix avfiltergraph input output (#44) * Port append_inout to rust * impl Drop for filter::graph::Parser --- src/filter/graph.rs | 67 +++++++++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 29 deletions(-) diff --git a/src/filter/graph.rs b/src/filter/graph.rs index 9ef93d4..a962444 100644 --- a/src/filter/graph.rs +++ b/src/filter/graph.rs @@ -1,5 +1,5 @@ use std::ffi::{CStr, CString}; -use std::ptr; +use std::ptr::{self, NonNull}; use std::str::from_utf8_unchecked; use super::{Context, Filter}; @@ -145,24 +145,16 @@ impl<'a> Parser<'a> { pub fn input(mut self, name: &str, pad: usize) -> Result { unsafe { let mut context = self.graph.get(name).ok_or(Error::InvalidData)?; - let input = avfilter_inout_alloc(); - - if input.is_null() { - panic!("out of memory"); - } + let mut input = NonNull::new(avfilter_inout_alloc()).expect("out of memory"); let name = CString::new(name).unwrap(); - (*input).name = av_strdup(name.as_ptr()); - (*input).filter_ctx = context.as_mut_ptr(); - (*input).pad_idx = pad as c_int; - (*input).next = ptr::null_mut(); + input.as_mut().name = av_strdup(name.as_ptr()); + input.as_mut().filter_ctx = context.as_mut_ptr(); + input.as_mut().pad_idx = pad as c_int; + input.as_mut().next = ptr::null_mut(); - if self.inputs.is_null() { - self.inputs = input; - } else { - (*self.inputs).next = input; - } + append_inout(&mut self.inputs, input); } Ok(self) @@ -171,24 +163,16 @@ impl<'a> Parser<'a> { pub fn output(mut self, name: &str, pad: usize) -> Result { unsafe { let mut context = self.graph.get(name).ok_or(Error::InvalidData)?; - let output = avfilter_inout_alloc(); - - if output.is_null() { - panic!("out of memory"); - } + let mut output = NonNull::new(avfilter_inout_alloc()).expect("out of memory"); let name = CString::new(name).unwrap(); - (*output).name = av_strdup(name.as_ptr()); - (*output).filter_ctx = context.as_mut_ptr(); - (*output).pad_idx = pad as c_int; - (*output).next = ptr::null_mut(); + output.as_mut().name = av_strdup(name.as_ptr()); + output.as_mut().filter_ctx = context.as_mut_ptr(); + output.as_mut().pad_idx = pad as c_int; + output.as_mut().next = ptr::null_mut(); - if self.outputs.is_null() { - self.outputs = output; - } else { - (*self.outputs).next = output; - } + append_inout(&mut self.outputs, output); } Ok(self) @@ -217,6 +201,31 @@ impl<'a> Parser<'a> { } } +fn append_inout(list: &mut *mut AVFilterInOut, element: NonNull) { + 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 { fn default() -> Self { Self::new()