diff --git a/src/device/input.rs b/src/device/input.rs index 1374848..032f31b 100644 --- a/src/device/input.rs +++ b/src/device/input.rs @@ -2,12 +2,11 @@ use std::ptr; use crate::ffi::*; use crate::format; -use crate::Format; pub struct AudioIter(*mut AVInputFormat); impl Iterator for AudioIter { - type Item = Format; + type Item = format::Input; fn next(&mut self) -> Option<::Item> { unsafe { @@ -18,7 +17,7 @@ impl Iterator for AudioIter { } else { self.0 = ptr; - Some(Format::Input(format::Input::wrap(ptr))) + Some(format::Input::wrap(ptr)) } } } @@ -31,7 +30,7 @@ pub fn audio() -> AudioIter { pub struct VideoIter(*mut AVInputFormat); impl Iterator for VideoIter { - type Item = Format; + type Item = format::Input; fn next(&mut self) -> Option<::Item> { unsafe { @@ -42,7 +41,7 @@ impl Iterator for VideoIter { } else { self.0 = ptr; - Some(Format::Input(format::Input::wrap(ptr))) + Some(format::Input::wrap(ptr)) } } } diff --git a/src/device/output.rs b/src/device/output.rs index faf774a..d68180b 100644 --- a/src/device/output.rs +++ b/src/device/output.rs @@ -2,12 +2,11 @@ use std::ptr; use crate::ffi::*; use crate::format; -use crate::Format; pub struct AudioIter(*mut AVOutputFormat); impl Iterator for AudioIter { - type Item = Format; + type Item = format::Output; fn next(&mut self) -> Option<::Item> { unsafe { @@ -18,7 +17,7 @@ impl Iterator for AudioIter { } else { self.0 = ptr as *mut AVOutputFormat; - Some(Format::Output(format::Output::wrap(ptr))) + Some(format::Output::wrap(ptr)) } } } @@ -31,7 +30,7 @@ pub fn audio() -> AudioIter { pub struct VideoIter(*mut AVOutputFormat); impl Iterator for VideoIter { - type Item = Format; + type Item = format::Output; fn next(&mut self) -> Option<::Item> { unsafe { @@ -42,7 +41,7 @@ impl Iterator for VideoIter { } else { self.0 = ptr as *mut AVOutputFormat; - Some(Format::Output(format::Output::wrap(ptr))) + Some(format::Output::wrap(ptr)) } } } diff --git a/src/format/format/iter.rs b/src/format/format/iter.rs index 9db1100..884375c 100644 --- a/src/format/format/iter.rs +++ b/src/format/format/iter.rs @@ -1,72 +1,92 @@ -use std::ptr; +use std::ptr::null_mut; -use super::{Format, Input, Output}; use crate::ffi::*; +use crate::format::format::{Input, Output}; +use libc::c_void; -pub struct Iter { - input: *mut AVInputFormat, - output: *mut AVOutputFormat, - step: Step, +pub struct DemuxerIter { + ptr: *mut c_void, } -enum Step { - Input, - Output, - Done, -} - -impl Iter { +impl DemuxerIter { pub fn new() -> Self { - Iter { - input: ptr::null_mut(), - output: ptr::null_mut(), - step: Step::Input, - } + Self { ptr: null_mut() } } } -impl Default for Iter { +impl Default for DemuxerIter { fn default() -> Self { Self::new() } } -impl Iterator for Iter { - type Item = Format; +impl Iterator for DemuxerIter { + type Item = Input; - fn next(&mut self) -> Option<::Item> { + fn next(&mut self) -> Option { unsafe { - match self.step { - Step::Input => { - let ptr = av_iformat_next(self.input); - - if ptr.is_null() && !self.input.is_null() { - self.step = Step::Output; - - self.next() - } else { - self.input = ptr; - - Some(Format::Input(Input::wrap(ptr))) - } - } - - Step::Output => { - let ptr = av_oformat_next(self.output); - - if ptr.is_null() && !self.output.is_null() { - self.step = Step::Done; - - self.next() - } else { - self.output = ptr; - - Some(Format::Output(Output::wrap(ptr))) - } - } - - Step::Done => None, + let next = av_demuxer_iterate(&mut self.ptr); + if next.is_null() { + None + } else { + Some(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 = Output; + + fn next(&mut self) -> Option { + unsafe { + let next = av_muxer_iterate(&mut self.ptr); + if next.is_null() { + None + } else { + Some(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/mod.rs b/src/format/format/mod.rs index 40fc450..9ed9cbd 100644 --- a/src/format/format/mod.rs +++ b/src/format/format/mod.rs @@ -7,55 +7,10 @@ pub use self::input::Input; mod output; pub use self::output::Output; -#[cfg(not(feature = "ffmpeg_5_0"))] +#[cfg(feature = "ffmpeg_4_0")] 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), -} - -impl Format { - pub fn name(&self) -> &str { - match *self { - Format::Input(ref f) => f.name(), - Format::Output(ref f) => f.name(), - } - } - - pub fn description(&self) -> &str { - match *self { - Format::Input(ref f) => f.description(), - Format::Output(ref f) => f.description(), - } - } - - pub fn extensions(&self) -> Vec<&str> { - match *self { - Format::Input(ref f) => f.extensions(), - Format::Output(ref f) => f.extensions(), - } - } - - pub fn mime_types(&self) -> Vec<&str> { - match *self { - Format::Input(ref f) => f.mime_types(), - Format::Output(ref f) => f.mime_types(), - } - } -} - -#[cfg(not(feature = "ffmpeg_5_0"))] -pub fn list() -> Iter { - Iter::new() -} +pub use self::iter::{DemuxerIter, MuxerIter}; #[cfg(feature = "ffmpeg_4_0")] pub fn list_demuxers() -> DemuxerIter { diff --git a/src/format/format/new_iter.rs b/src/format/format/new_iter.rs deleted file mode 100644 index 394e2fb..0000000 --- a/src/format/format/new_iter.rs +++ /dev/null @@ -1,93 +0,0 @@ -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/mod.rs b/src/format/mod.rs index 6e833cc..ff6c1ac 100644 --- a/src/format/mod.rs +++ b/src/format/mod.rs @@ -10,8 +10,6 @@ pub mod context; pub use self::context::Context; pub mod format; -#[cfg(not(feature = "ffmpeg_5_0"))] -pub use self::format::list; pub use self::format::{flag, Flags}; pub use self::format::{Input, Output}; @@ -23,7 +21,7 @@ use std::ptr; use std::str::from_utf8_unchecked; use crate::ffi::*; -use crate::{Dictionary, Error, Format}; +use crate::{Dictionary, Error}; #[cfg(not(feature = "ffmpeg_5_0"))] pub fn register_all() { @@ -33,15 +31,16 @@ pub fn register_all() { } #[cfg(not(feature = "ffmpeg_5_0"))] -pub fn register(format: &Format) { - match *format { - Format::Input(ref format) => unsafe { - av_register_input_format(format.as_ptr() as *mut _); - }, +pub fn register_input(mut format: Input) { + unsafe { + av_register_input_format(format.as_mut_ptr()); + } +} - Format::Output(ref format) => unsafe { - av_register_output_format(format.as_ptr() as *mut _); - }, +#[cfg(not(feature = "ffmpeg_5_0"))] +pub fn register_output(mut format: Output) { + unsafe { + av_register_output_format(format.as_mut_ptr()); } } @@ -62,92 +61,6 @@ fn from_path>(path: &P) -> CString { CString::new(path.as_ref().as_os_str().to_str().unwrap()).unwrap() } -// NOTE: this will be better with specialization or anonymous return types -pub fn open>(path: &P, format: &Format) -> Result { - unsafe { - let mut ps = ptr::null_mut(); - let path = from_path(path); - - match *format { - Format::Input(ref format) => match avformat_open_input( - &mut ps, - path.as_ptr(), - format.as_ptr() as *mut _, - ptr::null_mut(), - ) { - 0 => match avformat_find_stream_info(ps, ptr::null_mut()) { - r if r >= 0 => Ok(Context::Input(context::Input::wrap(ps))), - e => Err(Error::from(e)), - }, - - e => Err(Error::from(e)), - }, - - Format::Output(ref format) => match avformat_alloc_output_context2( - &mut ps, - format.as_ptr() as *mut _, - ptr::null(), - path.as_ptr(), - ) { - 0 => match avio_open(&mut (*ps).pb, path.as_ptr(), AVIO_FLAG_WRITE) { - 0 => Ok(Context::Output(context::Output::wrap(ps))), - e => Err(Error::from(e)), - }, - - e => Err(Error::from(e)), - }, - } - } -} - -pub fn open_with>( - path: &P, - format: &Format, - options: Dictionary, -) -> Result { - unsafe { - let mut ps = ptr::null_mut(); - let path = from_path(path); - let mut opts = options.disown(); - - match *format { - Format::Input(ref format) => { - let res = avformat_open_input( - &mut ps, - path.as_ptr(), - format.as_ptr() as *mut _, - &mut opts, - ); - - Dictionary::own(opts); - - match res { - 0 => match avformat_find_stream_info(ps, ptr::null_mut()) { - r if r >= 0 => Ok(Context::Input(context::Input::wrap(ps))), - e => Err(Error::from(e)), - }, - - e => Err(Error::from(e)), - } - } - - Format::Output(ref format) => match avformat_alloc_output_context2( - &mut ps, - format.as_ptr() as *mut _, - ptr::null(), - path.as_ptr(), - ) { - 0 => match avio_open(&mut (*ps).pb, path.as_ptr(), AVIO_FLAG_WRITE) { - 0 => Ok(Context::Output(context::Output::wrap(ps))), - e => Err(Error::from(e)), - }, - - e => Err(Error::from(e)), - }, - } - } -} - pub fn input>(path: &P) -> Result { unsafe { let mut ps = ptr::null_mut(); diff --git a/src/lib.rs b/src/lib.rs index ad6774b..71cfddb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -44,8 +44,6 @@ pub mod format; #[cfg(feature = "format")] pub use crate::format::chapter::{Chapter, ChapterMut}; #[cfg(feature = "format")] -pub use crate::format::format::Format; -#[cfg(feature = "format")] pub use crate::format::stream::{Stream, StreamMut}; #[cfg(feature = "codec")]