ffmpeg_the_third/format/
mod.rs1#[cfg(feature = "ffmpeg_8_1")]
2pub use crate::util::format::AlphaMode;
3pub use crate::util::format::{pixel, Pixel};
4pub use crate::util::format::{sample, Sample};
5
6use crate::util::interrupt;
7
8pub mod stream;
9
10pub mod chapter;
11
12pub mod context;
13pub use self::context::Context;
14
15pub mod format;
16pub use self::format::{flag, Flags};
17pub use self::format::{Input, Output};
18
19pub mod network;
20
21use std::ffi::{CString, OsStr};
22use std::ptr;
23
24use crate::ffi::*;
25use crate::utils;
26use crate::{AsMutPtr, Error};
27
28pub fn version() -> u32 {
29 unsafe { avformat_version() }
30}
31
32pub fn configuration() -> &'static str {
33 unsafe { utils::str_from_c_ptr(avformat_configuration()) }
34}
35
36pub fn license() -> &'static str {
37 unsafe { utils::str_from_c_ptr(avformat_license()) }
38}
39
40pub fn input<P: AsRef<OsStr>>(path_or_url: P) -> Result<context::Input, Error> {
41 unsafe {
42 let mut ps = ptr::null_mut();
43 let path = from_os_str(path_or_url);
44
45 match avformat_open_input(&mut ps, path.as_ptr(), ptr::null_mut(), ptr::null_mut()) {
46 0 => match avformat_find_stream_info(ps, ptr::null_mut()) {
47 r if r >= 0 => Ok(context::Input::wrap(ps)),
48 e => {
49 avformat_close_input(&mut ps);
50 Err(Error::from(e))
51 }
52 },
53
54 e => Err(Error::from(e)),
55 }
56 }
57}
58
59pub fn input_with_dictionary<P, Dict>(
60 path_or_url: P,
61 mut options: Dict,
62) -> Result<context::Input, Error>
63where
64 Dict: AsMutPtr<*mut AVDictionary>,
65 P: AsRef<OsStr>,
66{
67 unsafe {
68 let mut ps = ptr::null_mut();
69 let path = from_os_str(path_or_url);
70 let res = avformat_open_input(
71 &mut ps,
72 path.as_ptr(),
73 ptr::null_mut(),
74 options.as_mut_ptr(),
75 );
76
77 match res {
78 0 => match avformat_find_stream_info(ps, ptr::null_mut()) {
79 r if r >= 0 => Ok(context::Input::wrap(ps)),
80 e => {
81 avformat_close_input(&mut ps);
82 Err(Error::from(e))
83 }
84 },
85
86 e => Err(Error::from(e)),
87 }
88 }
89}
90
91pub fn input_with_interrupt<P, F>(path_or_url: P, closure: F) -> Result<context::Input, Error>
92where
93 P: AsRef<OsStr>,
94 F: FnMut() -> bool,
95{
96 unsafe {
97 let mut ps = avformat_alloc_context();
98 let path = from_os_str(path_or_url);
99 (*ps).interrupt_callback = interrupt::new(Box::new(closure)).interrupt;
100
101 match avformat_open_input(&mut ps, path.as_ptr(), ptr::null_mut(), ptr::null_mut()) {
102 0 => match avformat_find_stream_info(ps, ptr::null_mut()) {
103 r if r >= 0 => Ok(context::Input::wrap(ps)),
104 e => {
105 avformat_close_input(&mut ps);
106 Err(Error::from(e))
107 }
108 },
109
110 e => Err(Error::from(e)),
111 }
112 }
113}
114
115fn from_os_str(path_or_url: impl AsRef<OsStr>) -> CString {
116 CString::new(path_or_url.as_ref().as_encoded_bytes()).unwrap()
117}
118
119fn alloc_context(
120 format_name: *const libc::c_char,
121 filename: *const libc::c_char,
122) -> Result<context::Output, Error> {
123 let mut ps = ptr::null_mut();
124
125 unsafe {
126 let res = avformat_alloc_output_context2(&mut ps, ptr::null(), format_name, filename);
127 if res >= 0 {
128 Ok(context::Output::wrap(ps))
129 } else {
130 Err(Error::from(res))
131 }
132 }
133}
134
135fn open_context_write(
136 ctx: &mut context::Output,
137 filename: *const libc::c_char,
138 opts: *mut *mut AVDictionary,
139) -> Result<(), Error> {
140 let res = unsafe {
141 avio_open2(
142 &mut (*ctx.as_mut_ptr()).pb,
143 filename,
144 AVIO_FLAG_WRITE,
145 ptr::null(),
146 opts,
147 )
148 };
149
150 if res >= 0 {
151 Ok(())
152 } else {
153 Err(Error::from(res))
154 }
155}
156
157pub fn output<P: AsRef<OsStr>>(path_or_url: P) -> Result<context::Output, Error> {
158 let filename = from_os_str(path_or_url);
159 let mut ctx = alloc_context(ptr::null(), filename.as_ptr())?;
160
161 if !ctx.format().flags().contains(Flags::NO_FILE) {
162 open_context_write(&mut ctx, filename.as_ptr(), ptr::null_mut())?;
163 }
164
165 Ok(ctx)
166}
167
168pub fn output_with<P, Dict>(path_or_url: P, mut options: Dict) -> Result<context::Output, Error>
169where
170 P: AsRef<OsStr>,
171 Dict: AsMutPtr<*mut AVDictionary>,
172{
173 let path = from_os_str(path_or_url);
174 let mut ctx = alloc_context(ptr::null(), path.as_ptr())?;
175
176 if !ctx.format().flags().contains(Flags::NO_FILE) {
177 open_context_write(&mut ctx, path.as_ptr(), options.as_mut_ptr())?;
178 }
179
180 Ok(ctx)
181}
182
183pub fn output_as<P: AsRef<OsStr>>(path_or_url: P, format: &str) -> Result<context::Output, Error> {
184 let path = from_os_str(path_or_url);
185 let format = CString::new(format).unwrap();
186 let mut ctx = alloc_context(format.as_ptr(), path.as_ptr())?;
187
188 if !ctx.format().flags().contains(Flags::NO_FILE) {
189 open_context_write(&mut ctx, path.as_ptr(), ptr::null_mut())?;
190 }
191
192 Ok(ctx)
193}
194
195pub fn output_as_with<P, Dict>(
196 path_or_url: P,
197 format: &str,
198 mut options: Dict,
199) -> Result<context::Output, Error>
200where
201 P: AsRef<OsStr>,
202 Dict: AsMutPtr<*mut AVDictionary>,
203{
204 let path = from_os_str(path_or_url);
205 let format = CString::new(format).unwrap();
206 let mut ctx = alloc_context(format.as_ptr(), path.as_ptr())?;
207
208 if !ctx.format().flags().contains(Flags::NO_FILE) {
209 open_context_write(&mut ctx, path.as_ptr(), options.as_mut_ptr())?;
210 }
211
212 Ok(ctx)
213}