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