Refactor crate::format (#73)

This commit is contained in:
FreezyLemon 2024-10-16 00:13:27 +02:00 committed by GitHub
parent 03db7c304b
commit e70779ad30
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 92 additions and 301 deletions

View File

@ -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<<Self as Iterator>::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<<Self as Iterator>::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))
}
}
}

View File

@ -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<<Self as Iterator>::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<<Self as Iterator>::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))
}
}
}

View File

@ -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<<Self as Iterator>::Item> {
fn next(&mut self) -> Option<Self::Item> {
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<Self::Item> {
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());
}
}
}

View File

@ -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 {

View File

@ -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<Self::Item> {
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<Self::Item> {
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());
}
}
}

View File

@ -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<P: AsRef<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<P: AsRef<Path>>(path: &P, format: &Format) -> Result<Context, Error> {
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<P: AsRef<Path>>(
path: &P,
format: &Format,
options: Dictionary,
) -> Result<Context, Error> {
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<P: AsRef<Path>>(path: &P) -> Result<context::Input, Error> {
unsafe {
let mut ps = ptr::null_mut();

View File

@ -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")]