filter: add avfilter wrapper
This commit is contained in:
parent
67a2c60a33
commit
2a3a4e6169
68
src/filter/context/context.rs
Normal file
68
src/filter/context/context.rs
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
|
use ffi::*;
|
||||||
|
use libc::c_void;
|
||||||
|
use ::{option, format, Error, ChannelLayout};
|
||||||
|
use super::{Source, Sink};
|
||||||
|
|
||||||
|
pub struct Context<'a> {
|
||||||
|
ptr: *mut AVFilterContext,
|
||||||
|
|
||||||
|
_marker: PhantomData<&'a ()>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Context<'a> {
|
||||||
|
pub unsafe fn wrap(ptr: *mut AVFilterContext) -> Self {
|
||||||
|
Context { ptr: ptr, _marker: PhantomData }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn as_ptr(&self) -> *const AVFilterContext {
|
||||||
|
self.ptr as *const _
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn as_mut_ptr(&mut self) -> *mut AVFilterContext {
|
||||||
|
self.ptr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Context<'a> {
|
||||||
|
pub fn source(&'a mut self) -> Source<'a> {
|
||||||
|
unsafe {
|
||||||
|
Source::wrap(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn sink(&'a mut self) -> Sink<'a> {
|
||||||
|
unsafe {
|
||||||
|
Sink::wrap(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_pixel_format(&mut self, value: format::Pixel) -> Result<(), Error> {
|
||||||
|
option::Settable::set::<AVPixelFormat>(self, "pix_fmts", &value.into())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_sample_format(&mut self, value: format::Sample) -> Result<(), Error> {
|
||||||
|
option::Settable::set::<AVSampleFormat>(self, "sample_fmts", &value.into())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_sample_rate(&mut self, value: u32) -> Result<(), Error> {
|
||||||
|
option::Settable::set(self, "sample_rates", &(value as i64))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_channel_layout(&mut self, value: ChannelLayout) -> Result<(), Error> {
|
||||||
|
option::Settable::set(self, "channel_layouts", &value.bits())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl<'a> option::Target for Context<'a> {
|
||||||
|
fn as_ptr(&self) -> *const c_void {
|
||||||
|
self.ptr as *const _
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_mut_ptr(&mut self) -> *mut c_void {
|
||||||
|
self.ptr as *mut _
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> option::Settable for Context<'a> { }
|
8
src/filter/context/mod.rs
Normal file
8
src/filter/context/mod.rs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
mod context;
|
||||||
|
pub use self::context::Context;
|
||||||
|
|
||||||
|
mod source;
|
||||||
|
pub use self::source::Source;
|
||||||
|
|
||||||
|
mod sink;
|
||||||
|
pub use self::sink::Sink;
|
34
src/filter/context/sink.rs
Normal file
34
src/filter/context/sink.rs
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
use ffi::*;
|
||||||
|
use libc::c_int;
|
||||||
|
use ::{Frame, Error};
|
||||||
|
use super::Context;
|
||||||
|
|
||||||
|
pub struct Sink<'a> {
|
||||||
|
ctx: &'a mut Context<'a>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Sink<'a> {
|
||||||
|
pub unsafe fn wrap<'b>(ctx: &'b mut Context<'b>) -> Sink<'b> {
|
||||||
|
Sink { ctx: ctx }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Sink<'a> {
|
||||||
|
pub fn frame(&mut self, frame: &mut Frame) -> Result<(), Error> {
|
||||||
|
unsafe {
|
||||||
|
match av_buffersink_get_frame(self.ctx.as_mut_ptr(), frame.as_mut_ptr()) {
|
||||||
|
n if n >= 0 => Ok(()),
|
||||||
|
e => Err(Error::from(e)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn samples(&mut self, frame: &mut Frame, samples: usize) -> Result<(), Error> {
|
||||||
|
unsafe {
|
||||||
|
match av_buffersink_get_samples(self.ctx.as_mut_ptr(), frame.as_mut_ptr(), samples as c_int) {
|
||||||
|
n if n >= 0 => Ok(()),
|
||||||
|
e => Err(Error::from(e)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
30
src/filter/context/source.rs
Normal file
30
src/filter/context/source.rs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
use ffi::*;
|
||||||
|
use ::{Error, Frame};
|
||||||
|
use super::Context;
|
||||||
|
|
||||||
|
pub struct Source<'a> {
|
||||||
|
ctx: &'a mut Context<'a>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Source<'a> {
|
||||||
|
pub unsafe fn wrap<'b>(ctx: &'b mut Context<'b>) -> Source<'b> {
|
||||||
|
Source { ctx: ctx }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Source<'a> {
|
||||||
|
pub fn failed_requests(&self) -> usize {
|
||||||
|
unsafe {
|
||||||
|
av_buffersrc_get_nb_failed_requests(self.ctx.as_ptr()) as usize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add(&mut self, frame: &Frame) -> Result<(), Error> {
|
||||||
|
unsafe {
|
||||||
|
match av_buffersrc_add_frame(self.ctx.as_mut_ptr(), frame.as_ptr() as *mut _) {
|
||||||
|
0 => Ok(()),
|
||||||
|
e => Err(Error::from(e)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
107
src/filter/filter.rs
Normal file
107
src/filter/filter.rs
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
use std::ffi::CStr;
|
||||||
|
use std::str::from_utf8_unchecked;
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
|
use ffi::*;
|
||||||
|
use super::{Pad, Flags};
|
||||||
|
|
||||||
|
pub struct Filter {
|
||||||
|
ptr: *mut AVFilter,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Filter {
|
||||||
|
pub unsafe fn wrap(ptr: *mut AVFilter) -> Self {
|
||||||
|
Filter { ptr: ptr }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn as_ptr(&self) -> *const AVFilter {
|
||||||
|
self.ptr as *const _
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn as_mut_ptr(&mut self) -> *mut AVFilter {
|
||||||
|
self.ptr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Filter {
|
||||||
|
pub fn name(&self) -> &str {
|
||||||
|
unsafe {
|
||||||
|
from_utf8_unchecked(CStr::from_ptr((*self.as_ptr()).name).to_bytes())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn description(&self) -> Option<&str> {
|
||||||
|
unsafe {
|
||||||
|
let ptr = (*self.as_ptr()).description;
|
||||||
|
|
||||||
|
if ptr.is_null() {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Some(from_utf8_unchecked(CStr::from_ptr(ptr).to_bytes()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn inputs(&self) -> Option<PadIter> {
|
||||||
|
unsafe {
|
||||||
|
let ptr = (*self.as_ptr()).inputs;
|
||||||
|
|
||||||
|
if ptr.is_null() {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Some(PadIter::new((*self.as_ptr()).inputs))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn outputs(&self) -> Option<PadIter> {
|
||||||
|
unsafe {
|
||||||
|
let ptr = (*self.as_ptr()).outputs;
|
||||||
|
|
||||||
|
if ptr.is_null() {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Some(PadIter::new((*self.as_ptr()).outputs))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn flags(&self) -> Flags {
|
||||||
|
unsafe {
|
||||||
|
Flags::from_bits_truncate((*self.as_ptr()).flags)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct PadIter<'a> {
|
||||||
|
ptr: *const AVFilterPad,
|
||||||
|
cur: isize,
|
||||||
|
|
||||||
|
_marker: PhantomData<&'a ()>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> PadIter<'a> {
|
||||||
|
pub fn new(ptr: *const AVFilterPad) -> Self {
|
||||||
|
PadIter { ptr: ptr, cur: 0, _marker: PhantomData }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Iterator for PadIter<'a> {
|
||||||
|
type Item = Pad<'a>;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
unsafe {
|
||||||
|
if self.cur >= avfilter_pad_count(self.ptr) as isize {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let pad = Pad::wrap(self.ptr.offset(self.cur));
|
||||||
|
self.cur += 1;
|
||||||
|
|
||||||
|
Some(pad)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
13
src/filter/flag.rs
Normal file
13
src/filter/flag.rs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
use libc::c_int;
|
||||||
|
use ffi::*;
|
||||||
|
|
||||||
|
bitflags! {
|
||||||
|
flags Flags: c_int {
|
||||||
|
const DYNAMIC_INPUTS = AVFILTER_FLAG_DYNAMIC_INPUTS,
|
||||||
|
const DYNAMIC_OUTPUTS = AVFILTER_FLAG_DYNAMIC_OUTPUTS,
|
||||||
|
const SLICE_THREADS = AVFILTER_FLAG_SLICE_THREADS,
|
||||||
|
const SUPPORT_TIMELINE_GENERIC = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC,
|
||||||
|
const SUPPORT_TIMELINE_INTERNAL = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
|
||||||
|
const SUPPORT_TIMELINE = AVFILTER_FLAG_SUPPORT_TIMELINE,
|
||||||
|
}
|
||||||
|
}
|
180
src/filter/graph.rs
Normal file
180
src/filter/graph.rs
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
use std::ptr;
|
||||||
|
use std::ffi::CString;
|
||||||
|
|
||||||
|
use ffi::*;
|
||||||
|
use libc::c_int;
|
||||||
|
use ::Error;
|
||||||
|
use super::{Context, Filter};
|
||||||
|
|
||||||
|
pub struct Graph {
|
||||||
|
ptr: *mut AVFilterGraph,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Graph {
|
||||||
|
pub unsafe fn wrap(ptr: *mut AVFilterGraph) -> Self {
|
||||||
|
Graph { ptr: ptr }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn as_ptr(&self) -> *const AVFilterGraph {
|
||||||
|
self.ptr as *const _
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn as_mut_ptr(&mut self) -> *mut AVFilterGraph {
|
||||||
|
self.ptr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Graph {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
unsafe {
|
||||||
|
let ptr = avfilter_graph_alloc();
|
||||||
|
|
||||||
|
if ptr.is_null() {
|
||||||
|
panic!("out of memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
Graph::wrap(ptr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn validate(&mut self) -> Result<(), Error> {
|
||||||
|
unsafe {
|
||||||
|
match avfilter_graph_config(self.as_mut_ptr(), ptr::null_mut()) {
|
||||||
|
0 => Ok(()),
|
||||||
|
e => Err(Error::from(e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add<'a, 'b>(&'a mut self, filter: &Filter, name: &str, args: &str) -> Result<Context<'b>, Error> where 'a: 'b {
|
||||||
|
unsafe {
|
||||||
|
let mut context = ptr::null_mut();
|
||||||
|
|
||||||
|
match avfilter_graph_create_filter(&mut context as *mut *mut AVFilterContext,
|
||||||
|
filter.as_ptr(),
|
||||||
|
CString::new(name).unwrap().as_ptr(),
|
||||||
|
CString::new(args).unwrap().as_ptr(),
|
||||||
|
ptr::null_mut(),
|
||||||
|
self.as_mut_ptr())
|
||||||
|
{
|
||||||
|
n if n >= 0 => Ok(Context::wrap(context)),
|
||||||
|
e => Err(Error::from(e)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get<'a, 'b>(&'b mut self, name: &str) -> Option<Context<'b>> where 'a: 'b {
|
||||||
|
unsafe {
|
||||||
|
let ptr = avfilter_graph_get_filter(self.as_mut_ptr(), CString::new(name).unwrap().as_ptr());
|
||||||
|
|
||||||
|
if ptr.is_null() {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Some(Context::wrap(ptr))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn input(&mut self, name: &str, pad: usize) -> Result<Parser, Error> {
|
||||||
|
Parser::new(self).input(name, pad)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn output(&mut self, name: &str, pad: usize) -> Result<Parser, Error> {
|
||||||
|
Parser::new(self).output(name, pad)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse(&mut self, spec: &str) -> Result<(), Error> {
|
||||||
|
Parser::new(self).parse(spec)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for Graph {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
avfilter_graph_free(&mut self.as_mut_ptr());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Parser<'a> {
|
||||||
|
graph: &'a mut Graph,
|
||||||
|
inputs: *mut AVFilterInOut,
|
||||||
|
outputs: *mut AVFilterInOut,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Parser<'a> {
|
||||||
|
pub fn new(graph: &mut Graph) -> Parser {
|
||||||
|
Parser {
|
||||||
|
graph: graph,
|
||||||
|
inputs: ptr::null_mut(),
|
||||||
|
outputs: ptr::null_mut(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn input(mut self, name: &str, pad: usize) -> Result<Self, Error> {
|
||||||
|
unsafe {
|
||||||
|
let mut context = try!(self.graph.get(name).ok_or(Error::InvalidData));
|
||||||
|
let mut input = avfilter_inout_alloc();
|
||||||
|
|
||||||
|
if input.is_null() {
|
||||||
|
panic!("out of memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
(*input).name = av_strdup(CString::new(name).unwrap().as_ptr());
|
||||||
|
(*input).filter_ctx = context.as_mut_ptr();
|
||||||
|
(*input).pad_idx = pad as c_int;
|
||||||
|
(*input).next = ptr::null_mut();
|
||||||
|
|
||||||
|
if self.inputs.is_null() {
|
||||||
|
self.inputs = input;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
(*self.inputs).next = input;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn output(mut self, name: &str, pad: usize) -> Result<Self, Error> {
|
||||||
|
unsafe {
|
||||||
|
let mut context = try!(self.graph.get(name).ok_or(Error::InvalidData));
|
||||||
|
let mut output = avfilter_inout_alloc();
|
||||||
|
|
||||||
|
if output.is_null() {
|
||||||
|
panic!("out of memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
(*output).name = av_strdup(CString::new(name).unwrap().as_ptr());
|
||||||
|
(*output).filter_ctx = context.as_mut_ptr();
|
||||||
|
(*output).pad_idx = pad as c_int;
|
||||||
|
(*output).next = ptr::null_mut();
|
||||||
|
|
||||||
|
if self.outputs.is_null() {
|
||||||
|
self.outputs = output;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
(*self.outputs).next = output;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse(mut self, spec: &str) -> Result<(), Error> {
|
||||||
|
unsafe {
|
||||||
|
let result = avfilter_graph_parse_ptr(self.graph.as_mut_ptr(),
|
||||||
|
CString::new(spec).unwrap().as_ptr(), &mut self.inputs, &mut self.outputs,
|
||||||
|
ptr::null_mut());
|
||||||
|
|
||||||
|
avfilter_inout_free(&mut self.inputs);
|
||||||
|
avfilter_inout_free(&mut self.outputs);
|
||||||
|
|
||||||
|
match result {
|
||||||
|
n if n >= 0 => Ok(()),
|
||||||
|
e => Err(Error::from(e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
66
src/filter/mod.rs
Normal file
66
src/filter/mod.rs
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
pub mod flag;
|
||||||
|
pub use self::flag::Flags;
|
||||||
|
|
||||||
|
pub mod pad;
|
||||||
|
pub use self::pad::Pad;
|
||||||
|
|
||||||
|
pub mod filter;
|
||||||
|
pub use self::filter::Filter;
|
||||||
|
|
||||||
|
pub mod context;
|
||||||
|
pub use self::context::{Context, Source, Sink};
|
||||||
|
|
||||||
|
pub mod graph;
|
||||||
|
pub use self::graph::Graph;
|
||||||
|
|
||||||
|
use std::ffi::{CString, CStr};
|
||||||
|
use std::str::from_utf8_unchecked;
|
||||||
|
|
||||||
|
use ffi::*;
|
||||||
|
use ::Error;
|
||||||
|
|
||||||
|
pub fn register_all() {
|
||||||
|
unsafe {
|
||||||
|
avfilter_register_all();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn register(filter: &Filter) -> Result<(), Error> {
|
||||||
|
unsafe {
|
||||||
|
match avfilter_register(filter.as_ptr()) {
|
||||||
|
0 => Ok(()),
|
||||||
|
_ => Err(Error::InvalidData),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn version() -> u32 {
|
||||||
|
unsafe {
|
||||||
|
avfilter_version()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn configuration() -> &'static str {
|
||||||
|
unsafe {
|
||||||
|
from_utf8_unchecked(CStr::from_ptr(avfilter_configuration()).to_bytes())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn license() -> &'static str {
|
||||||
|
unsafe {
|
||||||
|
from_utf8_unchecked(CStr::from_ptr(avfilter_license()).to_bytes())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn find(name: &str) -> Option<Filter> {
|
||||||
|
unsafe {
|
||||||
|
let ptr = avfilter_get_by_name(CString::new(name).unwrap().as_ptr());
|
||||||
|
|
||||||
|
if ptr.is_null() {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Some(Filter::wrap(ptr))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
47
src/filter/pad.rs
Normal file
47
src/filter/pad.rs
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
use std::ffi::CStr;
|
||||||
|
use std::str::from_utf8_unchecked;
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
|
use ffi::*;
|
||||||
|
use ::media;
|
||||||
|
|
||||||
|
pub struct Pad<'a> {
|
||||||
|
ptr: *const AVFilterPad,
|
||||||
|
|
||||||
|
_marker: PhantomData<&'a ()>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Pad<'a> {
|
||||||
|
pub unsafe fn wrap(ptr: *const AVFilterPad) -> Self {
|
||||||
|
Pad { ptr: ptr, _marker: PhantomData }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn as_ptr(&self) -> *const AVFilterPad {
|
||||||
|
self.ptr
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn as_mut_ptr(&mut self) -> *mut AVFilterPad {
|
||||||
|
self.ptr as *mut _
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Pad<'a> {
|
||||||
|
pub fn name(&self) -> Option<&str> {
|
||||||
|
unsafe {
|
||||||
|
let ptr = avfilter_pad_get_name(self.ptr, 0);
|
||||||
|
|
||||||
|
if ptr.is_null() {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Some(from_utf8_unchecked(CStr::from_ptr(ptr).to_bytes()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn medium(&self) -> media::Type {
|
||||||
|
unsafe {
|
||||||
|
media::Type::from(avfilter_pad_get_type(self.ptr, 0))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
18
src/lib.rs
18
src/lib.rs
@ -1,10 +1,12 @@
|
|||||||
#![allow(raw_pointer_derive, non_camel_case_types)]
|
#![allow(raw_pointer_derive, non_camel_case_types)]
|
||||||
|
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
extern crate ffmpeg_sys as ffi;
|
extern crate ffmpeg_sys as sys;
|
||||||
#[macro_use] extern crate bitflags;
|
#[macro_use] extern crate bitflags;
|
||||||
#[cfg(feature = "image")] extern crate image;
|
#[cfg(feature = "image")] extern crate image;
|
||||||
|
|
||||||
|
pub use sys as ffi;
|
||||||
|
|
||||||
pub mod util;
|
pub mod util;
|
||||||
pub use util::error::Error;
|
pub use util::error::Error;
|
||||||
pub use util::dictionary::Dictionary;
|
pub use util::dictionary::Dictionary;
|
||||||
@ -49,6 +51,11 @@ pub use codec::threading;
|
|||||||
#[cfg(feature = "device")]
|
#[cfg(feature = "device")]
|
||||||
pub mod device;
|
pub mod device;
|
||||||
|
|
||||||
|
#[cfg(feature = "filter")]
|
||||||
|
pub mod filter;
|
||||||
|
#[cfg(feature = "filter")]
|
||||||
|
pub use filter::Filter;
|
||||||
|
|
||||||
pub mod software;
|
pub mod software;
|
||||||
|
|
||||||
fn init_error() {
|
fn init_error() {
|
||||||
@ -71,10 +78,19 @@ fn init_device() {
|
|||||||
#[cfg(not(feature = "device"))]
|
#[cfg(not(feature = "device"))]
|
||||||
fn init_device() { }
|
fn init_device() { }
|
||||||
|
|
||||||
|
#[cfg(feature = "filter")]
|
||||||
|
fn init_filter() {
|
||||||
|
filter::register_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "filter"))]
|
||||||
|
fn init_filter() { }
|
||||||
|
|
||||||
pub fn init() -> Result<(), Error> {
|
pub fn init() -> Result<(), Error> {
|
||||||
init_error();
|
init_error();
|
||||||
init_format();
|
init_format();
|
||||||
init_device();
|
init_device();
|
||||||
|
init_filter();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user