1use std::fmt;
2use std::mem;
3use std::ptr;
4use std::rc::Rc;
5
6use super::destructor::{self, Destructor};
7use ffi::*;
8use libc::{c_int, c_uint};
9use {media, Chapter, ChapterMut, DictionaryRef, Stream, StreamMut};
10
11pub struct Context {
12 ptr: *mut AVFormatContext,
13 dtor: Rc<Destructor>,
14}
15
16unsafe impl Send for Context {}
17
18impl Context {
19 pub unsafe fn wrap(ptr: *mut AVFormatContext, mode: destructor::Mode) -> Self {
20 Context {
21 ptr,
22 dtor: Rc::new(Destructor::new(ptr, mode)),
23 }
24 }
25
26 pub unsafe fn as_ptr(&self) -> *const AVFormatContext {
27 self.ptr as *const _
28 }
29
30 pub unsafe fn as_mut_ptr(&mut self) -> *mut AVFormatContext {
31 self.ptr
32 }
33
34 pub unsafe fn destructor(&self) -> Rc<Destructor> {
35 Rc::clone(&self.dtor)
36 }
37}
38
39impl Context {
40 #[inline]
41 pub fn nb_streams(&self) -> u32 {
42 unsafe { (*self.as_ptr()).nb_streams }
43 }
44
45 pub fn stream<'a, 'b>(&'a self, index: usize) -> Option<Stream<'b>>
46 where
47 'a: 'b,
48 {
49 unsafe {
50 if index >= self.nb_streams() as usize {
51 None
52 } else {
53 Some(Stream::wrap(self, index))
54 }
55 }
56 }
57
58 pub fn stream_mut<'a, 'b>(&'a mut self, index: usize) -> Option<StreamMut<'b>>
59 where
60 'a: 'b,
61 {
62 unsafe {
63 if index >= self.nb_streams() as usize {
64 None
65 } else {
66 Some(StreamMut::wrap(self, index))
67 }
68 }
69 }
70
71 pub fn streams(&self) -> StreamIter {
72 StreamIter::new(self)
73 }
74
75 pub fn streams_mut(&mut self) -> StreamIterMut {
76 StreamIterMut::new(self)
77 }
78
79 pub fn bit_rate(&self) -> i64 {
80 unsafe { (*self.as_ptr()).bit_rate }
81 }
82
83 pub fn duration(&self) -> i64 {
84 unsafe { (*self.as_ptr()).duration }
85 }
86
87 #[inline]
88 pub fn nb_chapters(&self) -> u32 {
89 unsafe { (*self.as_ptr()).nb_chapters }
90 }
91
92 pub fn chapter<'a, 'b>(&'a self, index: usize) -> Option<Chapter<'b>>
93 where
94 'a: 'b,
95 {
96 unsafe {
97 if index >= self.nb_chapters() as usize {
98 None
99 } else {
100 Some(Chapter::wrap(self, index))
101 }
102 }
103 }
104
105 pub fn chapter_mut<'a, 'b>(&'a mut self, index: usize) -> Option<ChapterMut<'b>>
106 where
107 'a: 'b,
108 {
109 unsafe {
110 if index >= self.nb_chapters() as usize {
111 None
112 } else {
113 Some(ChapterMut::wrap(self, index))
114 }
115 }
116 }
117
118 pub fn chapters(&self) -> ChapterIter {
119 ChapterIter::new(self)
120 }
121
122 pub fn chapters_mut(&mut self) -> ChapterIterMut {
123 ChapterIterMut::new(self)
124 }
125
126 pub fn metadata(&self) -> DictionaryRef {
127 unsafe { DictionaryRef::wrap((*self.as_ptr()).metadata) }
128 }
129}
130
131pub struct Best<'a> {
132 context: &'a Context,
133
134 wanted: i32,
135 related: i32,
136}
137
138impl<'a> Best<'a> {
139 pub unsafe fn new<'b, 'c: 'b>(context: &'c Context) -> Best<'b> {
140 Best {
141 context,
142
143 wanted: -1,
144 related: -1,
145 }
146 }
147
148 pub fn wanted<'b>(mut self, stream: &'b Stream) -> Best<'a>
149 where
150 'a: 'b,
151 {
152 self.wanted = stream.index() as i32;
153 self
154 }
155
156 pub fn related<'b>(mut self, stream: &'b Stream) -> Best<'a>
157 where
158 'a: 'b,
159 {
160 self.related = stream.index() as i32;
161 self
162 }
163
164 pub fn best<'b>(self, kind: media::Type) -> Option<Stream<'b>>
165 where
166 'a: 'b,
167 {
168 unsafe {
169 let decoder = ptr::null_mut();
170 let index = av_find_best_stream(
171 self.context.ptr,
172 kind.into(),
173 self.wanted as c_int,
174 self.related as c_int,
175 decoder,
176 0,
177 );
178
179 if index >= 0 {
180 Some(Stream::wrap(self.context, index as usize))
181 } else {
182 None
183 }
184 }
185 }
186}
187
188pub struct StreamIter<'a> {
189 context: &'a Context,
190 current: c_uint,
191}
192
193impl<'a> StreamIter<'a> {
194 pub fn new<'s, 'c: 's>(context: &'c Context) -> StreamIter<'s> {
195 StreamIter {
196 context,
197 current: 0,
198 }
199 }
200}
201
202impl<'a> StreamIter<'a> {
203 pub fn wanted<'b, 'c>(&self, stream: &'b Stream) -> Best<'c>
204 where
205 'a: 'b,
206 'a: 'c,
207 {
208 unsafe { Best::new(self.context).wanted(stream) }
209 }
210
211 pub fn related<'b, 'c>(&self, stream: &'b Stream) -> Best<'c>
212 where
213 'a: 'b,
214 'a: 'c,
215 {
216 unsafe { Best::new(self.context).related(stream) }
217 }
218
219 pub fn best<'b>(&self, kind: media::Type) -> Option<Stream<'b>>
220 where
221 'a: 'b,
222 {
223 unsafe { Best::new(self.context).best(kind) }
224 }
225}
226
227impl<'a> Iterator for StreamIter<'a> {
228 type Item = Stream<'a>;
229
230 fn next(&mut self) -> Option<<Self as Iterator>::Item> {
231 unsafe {
232 if self.current >= self.context.nb_streams() {
233 return None;
234 }
235
236 self.current += 1;
237
238 Some(Stream::wrap(self.context, (self.current - 1) as usize))
239 }
240 }
241
242 fn size_hint(&self) -> (usize, Option<usize>) {
243 let length: usize = self.context.nb_streams() as usize;
244
245 (
246 length - self.current as usize,
247 Some(length - self.current as usize),
248 )
249 }
250}
251
252impl<'a> ExactSizeIterator for StreamIter<'a> {}
253
254pub struct StreamIterMut<'a> {
255 context: &'a mut Context,
256 current: c_uint,
257}
258
259impl<'a> StreamIterMut<'a> {
260 pub fn new<'s, 'c: 's>(context: &'c mut Context) -> StreamIterMut<'s> {
261 StreamIterMut {
262 context,
263 current: 0,
264 }
265 }
266}
267
268impl<'a> Iterator for StreamIterMut<'a> {
269 type Item = StreamMut<'a>;
270
271 fn next(&mut self) -> Option<<Self as Iterator>::Item> {
272 if self.current >= self.context.nb_streams() {
273 return None;
274 }
275 self.current += 1;
276
277 unsafe {
278 Some(StreamMut::wrap(
279 mem::transmute_copy(&self.context),
280 (self.current - 1) as usize,
281 ))
282 }
283 }
284
285 fn size_hint(&self) -> (usize, Option<usize>) {
286 let length = self.context.nb_streams() as usize;
287
288 (
289 length - self.current as usize,
290 Some(length - self.current as usize),
291 )
292 }
293}
294
295impl<'a> ExactSizeIterator for StreamIterMut<'a> {}
296
297pub struct ChapterIter<'a> {
298 context: &'a Context,
299 current: c_uint,
300}
301
302impl<'a> ChapterIter<'a> {
303 pub fn new<'s, 'c: 's>(context: &'c Context) -> ChapterIter<'s> {
304 ChapterIter {
305 context,
306 current: 0,
307 }
308 }
309}
310
311impl<'a> Iterator for ChapterIter<'a> {
312 type Item = Chapter<'a>;
313
314 fn next(&mut self) -> Option<<Self as Iterator>::Item> {
315 unsafe {
316 if self.current >= (*self.context.as_ptr()).nb_chapters {
317 return None;
318 }
319
320 self.current += 1;
321
322 Some(Chapter::wrap(self.context, (self.current - 1) as usize))
323 }
324 }
325
326 fn size_hint(&self) -> (usize, Option<usize>) {
327 unsafe {
328 let length = (*self.context.as_ptr()).nb_chapters as usize;
329
330 (
331 length - self.current as usize,
332 Some(length - self.current as usize),
333 )
334 }
335 }
336}
337
338impl<'a> ExactSizeIterator for ChapterIter<'a> {}
339
340pub struct ChapterIterMut<'a> {
341 context: &'a mut Context,
342 current: c_uint,
343}
344
345impl<'a> ChapterIterMut<'a> {
346 pub fn new<'s, 'c: 's>(context: &'c mut Context) -> ChapterIterMut<'s> {
347 ChapterIterMut {
348 context,
349 current: 0,
350 }
351 }
352}
353
354impl<'a> Iterator for ChapterIterMut<'a> {
355 type Item = ChapterMut<'a>;
356
357 fn next(&mut self) -> Option<<Self as Iterator>::Item> {
358 unsafe {
359 if self.current >= (*self.context.as_ptr()).nb_chapters {
360 return None;
361 }
362
363 self.current += 1;
364
365 Some(ChapterMut::wrap(
366 mem::transmute_copy(&self.context),
367 (self.current - 1) as usize,
368 ))
369 }
370 }
371
372 fn size_hint(&self) -> (usize, Option<usize>) {
373 unsafe {
374 let length = (*self.context.as_ptr()).nb_chapters as usize;
375
376 (
377 length - self.current as usize,
378 Some(length - self.current as usize),
379 )
380 }
381 }
382}
383
384impl<'a> ExactSizeIterator for ChapterIterMut<'a> {}
385
386impl fmt::Debug for Context {
387 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
388 let mut s: DebugStruct<'_, '_> = fmt.debug_struct(name:"AVFormatContext");
389 s.field(name:"bit_rate", &self.bit_rate());
390 s.field(name:"duration", &self.duration());
391 s.field(name:"nb_chapters", &self.nb_chapters());
392 s.field(name:"nb_streams", &self.nb_streams());
393 s.finish()
394 }
395}
396