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