format: add interrupt callback support

This commit is contained in:
Tadas Barzdzius 2017-07-03 12:14:11 +03:00 committed by meh
parent 5ac0527bdc
commit 991bbc24e8
3 changed files with 52 additions and 2 deletions

View File

@ -1,5 +1,6 @@
pub use ::util::format::{sample, Sample}; pub use ::util::format::{sample, Sample};
pub use ::util::format::{pixel, Pixel}; pub use ::util::format::{pixel, Pixel};
use ::util::interrupt;
pub mod stream; pub mod stream;
@ -155,7 +156,7 @@ pub fn input<P: AsRef<Path>>(path: &P) -> Result<context::Input, Error> {
} }
} }
pub fn input_with<P: AsRef<Path>>(path: &P, options: Dictionary) -> Result<context::Input, Error> { pub fn input_with_dictionary<P: AsRef<Path>>(path: &P, options: Dictionary) -> Result<context::Input, Error> {
unsafe { unsafe {
let mut ps = ptr::null_mut(); let mut ps = ptr::null_mut();
let path = from_path(path); let path = from_path(path);
@ -171,7 +172,27 @@ pub fn input_with<P: AsRef<Path>>(path: &P, options: Dictionary) -> Result<conte
e => Err(Error::from(e)), e => Err(Error::from(e)),
} }
} }
e => Err(Error::from(e))
}
}
}
pub fn input_with_interrupt<P: AsRef<Path>, F>(path: &P, closure: F) -> Result<context::Input, Error>
where F: FnMut() -> bool {
unsafe {
let mut ps = context::Input::wrap(avformat_alloc_context());
let path = from_path(path);
(*ps.as_mut_ptr()).interrupt_callback = interrupt::new(Box::new(closure)).interrupt;
match avformat_open_input(&mut ps.as_mut_ptr(), path.as_ptr(), ptr::null_mut(), ptr::null_mut()) {
0 => {
match avformat_find_stream_info(ps.as_mut_ptr(), ptr::null_mut()) {
r if r >= 0 => Ok(ps),
e => Err(Error::from(e)),
}
}
e => Err(Error::from(e)) e => Err(Error::from(e))
} }
} }

28
src/util/interrupt.rs Normal file
View File

@ -0,0 +1,28 @@
use std::panic;
use std::process;
use ffi::*;
use libc::{c_void, c_int};
pub struct Interrupt {
pub interrupt: AVIOInterruptCB,
}
extern "C" fn callback<F>(opaque: *mut c_void) -> c_int
where F: FnMut() -> bool
{
match panic::catch_unwind(|| (unsafe { &mut *(opaque as *mut F) })()) {
Ok(ret) => ret as c_int,
Err(_) => process::abort(),
}
}
pub fn new<F>(opaque: Box<F>) -> Interrupt
where F: FnMut() -> bool
{
let interrupt_cb = AVIOInterruptCB {
callback: Some(callback::<F>),
opaque: Box::into_raw(opaque) as *mut c_void,
};
Interrupt { interrupt: interrupt_cb }
}

View File

@ -13,6 +13,7 @@ pub mod channel_layout;
pub mod option; pub mod option;
pub mod range; pub mod range;
pub mod mathematics; pub mod mathematics;
pub mod interrupt;
use std::ffi::CStr; use std::ffi::CStr;
use std::str::from_utf8_unchecked; use std::str::from_utf8_unchecked;