chalkydri/cameras/
providers.rs1use tokio::sync::mpsc;
2
3use gstreamer::{
4 Bus, BusSyncReply, Device, DeviceProvider, DeviceProviderFactory, Message, MessageView,
5 Structure, prelude::*,
6};
7
8pub(crate) enum ProviderEvent {
10 Connected(String, Device),
11 Disconnected(String, Device),
12}
13
14pub trait CamProvider {
15 fn init() -> Self
16 where
17 Self: Sized;
18 fn get_id(dev: &Device) -> String;
20 fn inner(&self) -> &DeviceProvider;
21
22 fn register_handler(&self, tx: mpsc::Sender<ProviderEvent>) {
23 self.inner()
24 .bus()
25 .set_sync_handler(move |_bus: &Bus, msg: &Message| {
26 match msg.view() {
27 MessageView::DeviceAdded(msg) => {
28 let dev = msg.device();
29 let id = Self::get_id(&dev);
30
31 tx.blocking_send(ProviderEvent::Connected(id, dev)).unwrap();
32 }
33 MessageView::DeviceRemoved(msg) => {
34 let dev = msg.device();
35 let id = Self::get_id(&dev);
36
37 tx.blocking_send(ProviderEvent::Disconnected(id, dev))
38 .unwrap();
39 }
40 _ => unimplemented!(),
41 }
42
43 BusSyncReply::Pass
44 });
45 }
46
47 fn unregister_handler(&self) {
48 self.inner().bus().unset_sync_handler();
49 }
50
51 fn start(&self) {
52 if !self.inner().is_started() {
53 self.inner().start().unwrap();
54 }
55 }
56
57 fn stop(&self) {
58 self.inner().stop();
59 }
60}
61
62pub struct V4l2Provider {
63 inner: DeviceProvider,
64}
65impl CamProvider for V4l2Provider {
66 fn init() -> Self {
67 let inner = DeviceProviderFactory::find("v4l2deviceprovider")
68 .unwrap()
69 .load()
70 .unwrap()
71 .get()
72 .unwrap();
73
74 Self { inner }
75 }
76 fn get_id(dev: &Device) -> String {
77 dev.property::<Structure>("properties")
78 .get::<String>("device.serial")
79 .unwrap()
80 }
81 fn inner(&self) -> &DeviceProvider {
82 &self.inner
83 }
84}