diff --git a/src/format/format/input.rs b/src/format/format/input.rs index 42a8d7a..aee359b 100644 --- a/src/format/format/input.rs +++ b/src/format/format/input.rs @@ -27,7 +27,15 @@ impl Input { } pub fn description(&self) -> &str { - unsafe { from_utf8_unchecked(CStr::from_ptr((*self.as_ptr()).long_name).to_bytes()) } + unsafe { + let long_name = (*self.as_ptr()).long_name; + + if long_name.is_null() { + "" + } else { + from_utf8_unchecked(CStr::from_ptr(long_name).to_bytes()) + } + } } pub fn extensions(&self) -> Vec<&str> { diff --git a/src/format/format/mod.rs b/src/format/format/mod.rs index d94826c..40fc450 100644 --- a/src/format/format/mod.rs +++ b/src/format/format/mod.rs @@ -12,6 +12,11 @@ mod iter; #[cfg(not(feature = "ffmpeg_5_0"))] pub use self::iter::Iter; +#[cfg(feature = "ffmpeg_4_0")] +mod new_iter; +#[cfg(feature = "ffmpeg_4_0")] +pub use self::new_iter::{DemuxerIter, MuxerIter}; + pub enum Format { Input(Input), Output(Output), @@ -51,3 +56,13 @@ impl Format { pub fn list() -> Iter { Iter::new() } + +#[cfg(feature = "ffmpeg_4_0")] +pub fn list_demuxers() -> DemuxerIter { + DemuxerIter::new() +} + +#[cfg(feature = "ffmpeg_4_0")] +pub fn list_muxers() -> MuxerIter { + MuxerIter::new() +} diff --git a/src/format/format/new_iter.rs b/src/format/format/new_iter.rs new file mode 100644 index 0000000..394e2fb --- /dev/null +++ b/src/format/format/new_iter.rs @@ -0,0 +1,93 @@ +use std::ptr::null_mut; + +use crate::ffi::*; +use crate::format::format::{Input, Output}; +use crate::format::Format; +use libc::c_void; + +pub struct DemuxerIter { + ptr: *mut c_void, +} + +impl DemuxerIter { + pub fn new() -> Self { + Self { ptr: null_mut() } + } +} + +impl Default for DemuxerIter { + fn default() -> Self { + Self::new() + } +} + +impl Iterator for DemuxerIter { + type Item = Format; + + fn next(&mut self) -> Option { + unsafe { + let next = av_demuxer_iterate(&mut self.ptr); + if next.is_null() { + None + } else { + Some(Format::Input(Input::wrap(next as _))) + } + } + } +} + +pub struct MuxerIter { + ptr: *mut c_void, +} + +impl MuxerIter { + pub fn new() -> Self { + Self { ptr: null_mut() } + } +} + +impl Default for MuxerIter { + fn default() -> Self { + Self::new() + } +} + +impl Iterator for MuxerIter { + type Item = Format; + + fn next(&mut self) -> Option { + unsafe { + let next = av_muxer_iterate(&mut self.ptr); + if next.is_null() { + None + } else { + Some(Format::Output(Output::wrap(next as _))) + } + } + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn muxer_iter() { + for f in MuxerIter::new() { + println!("{}:", f.name()); + println!("\t{}", f.description()); + println!("\t{:?}", f.extensions()); + println!("\t{:?}", f.mime_types()); + } + } + + #[test] + fn demuxer_iter() { + for f in DemuxerIter::new() { + println!("{}:", f.name()); + println!("\t{}", f.description()); + println!("\t{:?}", f.extensions()); + println!("\t{:?}", f.mime_types()); + } + } +} diff --git a/src/format/format/output.rs b/src/format/format/output.rs index 739c7cd..cdd7147 100644 --- a/src/format/format/output.rs +++ b/src/format/format/output.rs @@ -32,7 +32,15 @@ impl Output { } pub fn description(&self) -> &str { - unsafe { from_utf8_unchecked(CStr::from_ptr((*self.as_ptr()).long_name).to_bytes()) } + unsafe { + let long_name = (*self.as_ptr()).long_name; + + if long_name.is_null() { + "" + } else { + from_utf8_unchecked(CStr::from_ptr(long_name).to_bytes()) + } + } } pub fn extensions(&self) -> Vec<&str> {