ffmpeg_next_crossfix/format/
mod.rs

1pub use util::format::{pixel, Pixel};
2pub use util::format::{sample, Sample};
3use util::interrupt;
4
5pub mod stream;
6
7pub mod chapter;
8
9pub mod context;
10pub use self::context::Context;
11
12pub mod format;
13pub use self::format::{flag, Flags};
14pub use self::format::{list, Input, Output};
15
16pub mod network;
17
18use std::ffi::{CStr, CString};
19use std::path::Path;
20use std::ptr;
21use std::str::from_utf8_unchecked;
22
23use ffi::*;
24use {Dictionary, Error, Format};
25
26pub fn register_all() {
27    unsafe {
28        av_register_all();
29    }
30}
31
32pub fn register(format: &Format) {
33    match *format {
34        Format::Input(ref format) => unsafe {
35            av_register_input_format(format.as_ptr() as *mut _);
36        },
37
38        Format::Output(ref format) => unsafe {
39            av_register_output_format(format.as_ptr() as *mut _);
40        },
41    }
42}
43
44pub fn version() -> u32 {
45    unsafe { avformat_version() }
46}
47
48pub fn configuration() -> &'static str {
49    unsafe { from_utf8_unchecked(CStr::from_ptr(avformat_configuration()).to_bytes()) }
50}
51
52pub fn license() -> &'static str {
53    unsafe { from_utf8_unchecked(CStr::from_ptr(avformat_license()).to_bytes()) }
54}
55
56// XXX: use to_cstring when stable
57fn from_path<P: AsRef<Path>>(path: &P) -> CString {
58    CString::new(path.as_ref().as_os_str().to_str().unwrap()).unwrap()
59}
60
61// NOTE: this will be better with specialization or anonymous return types
62pub fn open<P: AsRef<Path>>(path: &P, format: &Format) -> Result<Context, Error> {
63    unsafe {
64        let mut ps = ptr::null_mut();
65        let path = from_path(path);
66
67        match *format {
68            Format::Input(ref format) => match avformat_open_input(
69                &mut ps,
70                path.as_ptr(),
71                format.as_ptr() as *mut _,
72                ptr::null_mut(),
73            ) {
74                0 => match avformat_find_stream_info(ps, ptr::null_mut()) {
75                    r if r >= 0 => Ok(Context::Input(context::Input::wrap(ps))),
76                    e => Err(Error::from(e)),
77                },
78
79                e => Err(Error::from(e)),
80            },
81
82            Format::Output(ref format) => match avformat_alloc_output_context2(
83                &mut ps,
84                format.as_ptr() as *mut _,
85                ptr::null(),
86                path.as_ptr(),
87            ) {
88                0 => match avio_open(&mut (*ps).pb, path.as_ptr(), AVIO_FLAG_WRITE) {
89                    0 => Ok(Context::Output(context::Output::wrap(ps))),
90                    e => Err(Error::from(e)),
91                },
92
93                e => Err(Error::from(e)),
94            },
95        }
96    }
97}
98
99pub fn open_with<P: AsRef<Path>>(
100    path: &P,
101    format: &Format,
102    options: Dictionary,
103) -> Result<Context, Error> {
104    unsafe {
105        let mut ps = ptr::null_mut();
106        let path = from_path(path);
107        let mut opts = options.disown();
108
109        match *format {
110            Format::Input(ref format) => {
111                let res = avformat_open_input(
112                    &mut ps,
113                    path.as_ptr(),
114                    format.as_ptr() as *mut _,
115                    &mut opts,
116                );
117
118                Dictionary::own(opts);
119
120                match res {
121                    0 => match avformat_find_stream_info(ps, ptr::null_mut()) {
122                        r if r >= 0 => Ok(Context::Input(context::Input::wrap(ps))),
123                        e => Err(Error::from(e)),
124                    },
125
126                    e => Err(Error::from(e)),
127                }
128            }
129
130            Format::Output(ref format) => match avformat_alloc_output_context2(
131                &mut ps,
132                format.as_ptr() as *mut _,
133                ptr::null(),
134                path.as_ptr(),
135            ) {
136                0 => match avio_open(&mut (*ps).pb, path.as_ptr(), AVIO_FLAG_WRITE) {
137                    0 => Ok(Context::Output(context::Output::wrap(ps))),
138                    e => Err(Error::from(e)),
139                },
140
141                e => Err(Error::from(e)),
142            },
143        }
144    }
145}
146
147pub fn input<P: AsRef<Path>>(path: &P) -> Result<context::Input, Error> {
148    unsafe {
149        let mut ps = ptr::null_mut();
150        let path = from_path(path);
151
152        match avformat_open_input(&mut ps, path.as_ptr(), ptr::null_mut(), ptr::null_mut()) {
153            0 => match avformat_find_stream_info(ps, ptr::null_mut()) {
154                r if r >= 0 => Ok(context::Input::wrap(ps)),
155                e => {
156                    avformat_close_input(&mut ps);
157                    Err(Error::from(e))
158                }
159            },
160
161            e => Err(Error::from(e)),
162        }
163    }
164}
165
166pub fn input_with_dictionary<P: AsRef<Path>>(
167    path: &P,
168    options: Dictionary,
169) -> Result<context::Input, Error> {
170    unsafe {
171        let mut ps = ptr::null_mut();
172        let path = from_path(path);
173        let mut opts = options.disown();
174        let res = avformat_open_input(&mut ps, path.as_ptr(), ptr::null_mut(), &mut opts);
175
176        Dictionary::own(opts);
177
178        match res {
179            0 => match avformat_find_stream_info(ps, ptr::null_mut()) {
180                r if r >= 0 => Ok(context::Input::wrap(ps)),
181                e => {
182                    avformat_close_input(&mut ps);
183                    Err(Error::from(e))
184                }
185            },
186
187            e => Err(Error::from(e)),
188        }
189    }
190}
191
192pub fn input_with_interrupt<P: AsRef<Path>, F>(
193    path: &P,
194    closure: F,
195) -> Result<context::Input, Error>
196where
197    F: FnMut() -> bool,
198{
199    unsafe {
200        let mut ps = avformat_alloc_context();
201        let path = from_path(path);
202        (*ps).interrupt_callback = interrupt::new(Box::new(closure)).interrupt;
203
204        match avformat_open_input(&mut ps, path.as_ptr(), ptr::null_mut(), ptr::null_mut()) {
205            0 => match avformat_find_stream_info(ps, ptr::null_mut()) {
206                r if r >= 0 => Ok(context::Input::wrap(ps)),
207                e => {
208                    avformat_close_input(&mut ps);
209                    Err(Error::from(e))
210                }
211            },
212
213            e => Err(Error::from(e)),
214        }
215    }
216}
217
218pub fn output<P: AsRef<Path>>(path: &P) -> Result<context::Output, Error> {
219    unsafe {
220        let mut ps = ptr::null_mut();
221        let path = from_path(path);
222
223        match avformat_alloc_output_context2(&mut ps, ptr::null_mut(), ptr::null(), path.as_ptr()) {
224            0 => match avio_open(&mut (*ps).pb, path.as_ptr(), AVIO_FLAG_WRITE) {
225                0 => Ok(context::Output::wrap(ps)),
226                e => Err(Error::from(e)),
227            },
228
229            e => Err(Error::from(e)),
230        }
231    }
232}
233
234pub fn output_with<P: AsRef<Path>>(
235    path: &P,
236    options: Dictionary,
237) -> Result<context::Output, Error> {
238    unsafe {
239        let mut ps = ptr::null_mut();
240        let path = from_path(path);
241        let mut opts = options.disown();
242
243        match avformat_alloc_output_context2(&mut ps, ptr::null_mut(), ptr::null(), path.as_ptr()) {
244            0 => {
245                let res = avio_open2(
246                    &mut (*ps).pb,
247                    path.as_ptr(),
248                    AVIO_FLAG_WRITE,
249                    ptr::null(),
250                    &mut opts,
251                );
252
253                Dictionary::own(opts);
254
255                match res {
256                    0 => Ok(context::Output::wrap(ps)),
257                    e => Err(Error::from(e)),
258                }
259            }
260
261            e => Err(Error::from(e)),
262        }
263    }
264}
265
266pub fn output_as<P: AsRef<Path>>(path: &P, format: &str) -> Result<context::Output, Error> {
267    unsafe {
268        let mut ps = ptr::null_mut();
269        let path = from_path(path);
270        let format = CString::new(format).unwrap();
271
272        match avformat_alloc_output_context2(
273            &mut ps,
274            ptr::null_mut(),
275            format.as_ptr(),
276            path.as_ptr(),
277        ) {
278            0 => match avio_open(&mut (*ps).pb, path.as_ptr(), AVIO_FLAG_WRITE) {
279                0 => Ok(context::Output::wrap(ps)),
280                e => Err(Error::from(e)),
281            },
282
283            e => Err(Error::from(e)),
284        }
285    }
286}
287
288pub fn output_as_with<P: AsRef<Path>>(
289    path: &P,
290    format: &str,
291    options: Dictionary,
292) -> Result<context::Output, Error> {
293    unsafe {
294        let mut ps = ptr::null_mut();
295        let path = from_path(path);
296        let format = CString::new(format).unwrap();
297        let mut opts = options.disown();
298
299        match avformat_alloc_output_context2(
300            &mut ps,
301            ptr::null_mut(),
302            format.as_ptr(),
303            path.as_ptr(),
304        ) {
305            0 => {
306                let res = avio_open2(
307                    &mut (*ps).pb,
308                    path.as_ptr(),
309                    AVIO_FLAG_WRITE,
310                    ptr::null(),
311                    &mut opts,
312                );
313
314                Dictionary::own(opts);
315
316                match res {
317                    0 => Ok(context::Output::wrap(ps)),
318                    e => Err(Error::from(e)),
319                }
320            }
321
322            e => Err(Error::from(e)),
323        }
324    }
325}