Skip to main content

gstreamer_analytics/
tracking.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use glib::translate::*;
4
5use crate::{ffi, relation_meta::*};
6
7#[derive(Debug)]
8pub enum AnalyticsTrackingMtd {}
9
10mod sealed {
11    pub trait Sealed {}
12    impl<T: super::AnalyticsRelationMetaTrackingExt> Sealed for T {}
13}
14
15pub trait AnalyticsRelationMetaTrackingExt: sealed::Sealed {
16    fn add_tracking_mtd(
17        &mut self,
18        tracking_id: u64,
19        tracking_first_seen: gst::ClockTime,
20    ) -> Result<AnalyticsMtdRef<'_, AnalyticsTrackingMtd>, glib::BoolError>;
21}
22
23impl AnalyticsRelationMetaTrackingExt
24    for gst::MetaRefMut<'_, AnalyticsRelationMeta, gst::meta::Standalone>
25{
26    #[doc(alias = "gst_analytics_relation_meta_add_tracking_mtd")]
27    fn add_tracking_mtd(
28        &mut self,
29        tracking_id: u64,
30        tracking_first_seen: gst::ClockTime,
31    ) -> Result<AnalyticsMtdRef<'_, AnalyticsTrackingMtd>, glib::BoolError> {
32        unsafe {
33            let mut mtd = std::mem::MaybeUninit::uninit();
34            let ret = from_glib(ffi::gst_analytics_relation_meta_add_tracking_mtd(
35                self.as_mut_ptr(),
36                tracking_id,
37                tracking_first_seen.into_glib(),
38                mtd.as_mut_ptr(),
39            ));
40            let id = mtd.assume_init().id;
41
42            if ret {
43                Ok(AnalyticsMtdRef::from_meta(self.as_ref(), id))
44            } else {
45                Err(glib::bool_error!("Couldn't add more data"))
46            }
47        }
48    }
49}
50
51unsafe impl AnalyticsMtd for AnalyticsTrackingMtd {
52    #[doc(alias = "gst_analytics_tracking_mtd_get_mtd_type")]
53    fn mtd_type() -> ffi::GstAnalyticsMtdType {
54        unsafe { ffi::gst_analytics_tracking_mtd_get_mtd_type() }
55    }
56}
57
58impl AnalyticsMtdRef<'_, AnalyticsTrackingMtd> {
59    #[doc(alias = "gst_analytics_tracking_mtd_get_info")]
60    pub fn info(&self) -> (u64, gst::ClockTime, gst::ClockTime, bool) {
61        let mut tracking_id: u64 = 0;
62        let mut tracking_first_seen: u64 = 0;
63        let mut tracking_last_seen: u64 = 0;
64        let mut tracking_lost: i32 = 0;
65
66        unsafe {
67            let mtd = ffi::GstAnalyticsMtd::unsafe_from(self);
68            ffi::gst_analytics_tracking_mtd_get_info(
69                &mtd as *const _ as *const ffi::GstAnalyticsTrackingMtd,
70                &mut tracking_id,
71                &mut tracking_first_seen,
72                &mut tracking_last_seen,
73                &mut tracking_lost,
74            );
75        };
76
77        (
78            tracking_id,
79            gst::ClockTime::from_nseconds(tracking_first_seen),
80            gst::ClockTime::from_nseconds(tracking_last_seen),
81            tracking_lost != 0,
82        )
83    }
84}
85
86impl AnalyticsMtdRefMut<'_, AnalyticsTrackingMtd> {
87    #[doc(alias = "gst_analytics_tracking_mtd_update_last_seen")]
88    pub fn update_last_seen(&mut self, last_seen: gst::ClockTime) -> Result<(), glib::BoolError> {
89        let ret: bool = unsafe {
90            let mut mtd = ffi::GstAnalyticsMtd::unsafe_from(self);
91            from_glib(ffi::gst_analytics_tracking_mtd_update_last_seen(
92                &mut mtd as *mut _ as *mut ffi::GstAnalyticsTrackingMtd,
93                last_seen.into_glib(),
94            ))
95        };
96        assert!(ret);
97        Ok(())
98    }
99
100    #[doc(alias = "gst_analytics_tracking_mtd_set_lost")]
101    pub fn set_lost(&mut self) -> Result<(), glib::BoolError> {
102        let ret: bool = unsafe {
103            let mut mtd = ffi::GstAnalyticsMtd::unsafe_from(self);
104            from_glib(ffi::gst_analytics_tracking_mtd_set_lost(
105                &mut mtd as *mut _ as *mut ffi::GstAnalyticsTrackingMtd,
106            ))
107        };
108        assert!(ret);
109        Ok(())
110    }
111}
112
113#[cfg(test)]
114mod tests {
115    use crate::*;
116
117    #[test]
118    fn tracking() {
119        gst::init().unwrap();
120
121        assert_eq!(AnalyticsTrackingMtd::type_name(), "object-tracking");
122
123        let mut buf = gst::Buffer::new();
124        let mut meta = AnalyticsRelationMeta::add(buf.make_mut());
125
126        assert!(meta.is_empty());
127
128        let track = meta
129            .add_tracking_mtd(10, gst::ClockTime::from_seconds(10))
130            .unwrap();
131
132        let (tracking_id, tracking_first_seen, tracking_last_seen, tracking_lost) = track.info();
133
134        assert_eq!(tracking_id, 10);
135        assert_eq!(tracking_first_seen, gst::ClockTime::from_seconds(10));
136        assert_eq!(tracking_last_seen, gst::ClockTime::from_seconds(10));
137        assert!(!tracking_lost);
138
139        let track_id = track.id();
140
141        let mut tracking_mut = meta.mtd_mut::<AnalyticsTrackingMtd>(track_id).unwrap();
142
143        tracking_mut
144            .update_last_seen(gst::ClockTime::from_seconds(20))
145            .unwrap();
146        tracking_mut.set_lost().unwrap();
147
148        let tracking: AnalyticsMtdRef<_> = tracking_mut.into();
149        let (tracking_id, tracking_first_seen, tracking_last_seen, tracking_lost) = tracking.info();
150
151        assert_eq!(tracking_id, 10);
152        assert_eq!(tracking_first_seen, gst::ClockTime::from_seconds(10));
153        assert_eq!(tracking_last_seen, gst::ClockTime::from_seconds(20));
154        assert!(tracking_lost);
155    }
156}