ffmpeg_next_crossfix/device/
extensions.rs

1use std::marker::PhantomData;
2use std::ptr;
3
4use device;
5use ffi::*;
6use format::context::common::Context;
7use libc::c_int;
8use Error;
9
10impl Context {
11    pub fn devices(&self) -> Result<DeviceIter, Error> {
12        unsafe { DeviceIter::wrap(self.as_ptr()) }
13    }
14}
15
16pub struct DeviceIter<'a> {
17    ptr: *mut AVDeviceInfoList,
18    cur: c_int,
19
20    _marker: PhantomData<&'a ()>,
21}
22
23impl<'a> DeviceIter<'a> {
24    pub unsafe fn wrap(ctx: *const AVFormatContext) -> Result<Self, Error> {
25        let mut ptr: *mut AVDeviceInfoList = ptr::null_mut();
26
27        match avdevice_list_devices(ctx as *mut _, &mut ptr) {
28            n if n < 0 => Err(Error::from(n)),
29
30            _ => Ok(DeviceIter {
31                ptr,
32                cur: 0,
33                _marker: PhantomData,
34            }),
35        }
36    }
37}
38
39impl<'a> DeviceIter<'a> {
40    pub fn default(&self) -> usize {
41        unsafe { (*self.ptr).default_device as usize }
42    }
43}
44
45impl<'a> Drop for DeviceIter<'a> {
46    fn drop(&mut self) {
47        unsafe {
48            avdevice_free_list_devices(&mut self.ptr);
49        }
50    }
51}
52
53impl<'a> Iterator for DeviceIter<'a> {
54    type Item = device::Info<'a>;
55
56    fn next(&mut self) -> Option<<Self as Iterator>::Item> {
57        unsafe {
58            if self.cur >= (*self.ptr).nb_devices {
59                None
60            } else {
61                self.cur += 1;
62                Some(device::Info::wrap(
63                    *(*self.ptr).devices.offset((self.cur - 1) as isize),
64                ))
65            }
66        }
67    }
68
69    fn size_hint(&self) -> (usize, Option<usize>) {
70        unsafe {
71            let length = (*self.ptr).nb_devices as usize;
72
73            (length - self.cur as usize, Some(length - self.cur as usize))
74        }
75    }
76}
77
78impl<'a> ExactSizeIterator for DeviceIter<'a> {}