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
58unsafe fn from(t: ffi::GstAnalyticsMtd) -> ffi::GstAnalyticsTrackingMtd {
59    std::mem::transmute(t)
60}
61
62impl AnalyticsMtdRef<'_, AnalyticsTrackingMtd> {
63    #[doc(alias = "gst_analytics_tracking_mtd_get_info")]
64    pub fn info(&self) -> (u64, gst::ClockTime, gst::ClockTime, bool) {
65        let mut tracking_id: u64 = 0;
66        let mut tracking_first_seen: u64 = 0;
67        let mut tracking_last_seen: u64 = 0;
68        let mut tracking_lost: i32 = 0;
69
70        unsafe {
71            let mtd = from(ffi::GstAnalyticsMtd::unsafe_from(self));
72            ffi::gst_analytics_tracking_mtd_get_info(
73                &mtd,
74                &mut tracking_id,
75                &mut tracking_first_seen,
76                &mut tracking_last_seen,
77                &mut tracking_lost,
78            );
79        };
80
81        (
82            tracking_id,
83            gst::ClockTime::from_nseconds(tracking_first_seen),
84            gst::ClockTime::from_nseconds(tracking_last_seen),
85            tracking_lost != 0,
86        )
87    }
88}
89
90impl AnalyticsMtdRefMut<'_, AnalyticsTrackingMtd> {
91    #[doc(alias = "gst_analytics_tracking_mtd_update_last_seen")]
92    pub fn update_last_seen(&mut self, last_seen: gst::ClockTime) -> Result<(), glib::BoolError> {
93        let ret: bool = unsafe {
94            let mut mtd = from(ffi::GstAnalyticsMtd::unsafe_from(self));
95            from_glib(ffi::gst_analytics_tracking_mtd_update_last_seen(
96                &mut mtd,
97                last_seen.into_glib(),
98            ))
99        };
100        assert!(ret);
101        Ok(())
102    }
103
104    #[doc(alias = "gst_analytics_tracking_mtd_set_lost")]
105    pub fn set_lost(&mut self) -> Result<(), glib::BoolError> {
106        let ret: bool = unsafe {
107            let mut mtd = from(ffi::GstAnalyticsMtd::unsafe_from(self));
108            from_glib(ffi::gst_analytics_tracking_mtd_set_lost(&mut mtd))
109        };
110        assert!(ret);
111        Ok(())
112    }
113}
114
115#[cfg(test)]
116mod tests {
117    use crate::*;
118
119    #[test]
120    fn tracking() {
121        gst::init().unwrap();
122
123        assert_eq!(AnalyticsTrackingMtd::type_name(), "object-tracking");
124
125        let mut buf = gst::Buffer::new();
126        let mut meta = AnalyticsRelationMeta::add(buf.make_mut());
127
128        assert!(meta.is_empty());
129
130        let track = meta
131            .add_tracking_mtd(10, gst::ClockTime::from_seconds(10))
132            .unwrap();
133
134        let (tracking_id, tracking_first_seen, tracking_last_seen, tracking_lost) = track.info();
135
136        assert_eq!(tracking_id, 10);
137        assert_eq!(tracking_first_seen, gst::ClockTime::from_seconds(10));
138        assert_eq!(tracking_last_seen, gst::ClockTime::from_seconds(10));
139        assert!(!tracking_lost);
140
141        let track_id = track.id();
142
143        let mut tracking_mut = meta.mtd_mut::<AnalyticsTrackingMtd>(track_id).unwrap();
144
145        tracking_mut
146            .update_last_seen(gst::ClockTime::from_seconds(20))
147            .unwrap();
148        tracking_mut.set_lost().unwrap();
149
150        let tracking: AnalyticsMtdRef<_> = tracking_mut.into();
151        let (tracking_id, tracking_first_seen, tracking_last_seen, tracking_lost) = tracking.info();
152
153        assert_eq!(tracking_id, 10);
154        assert_eq!(tracking_first_seen, gst::ClockTime::from_seconds(10));
155        assert_eq!(tracking_last_seen, gst::ClockTime::from_seconds(20));
156        assert!(tracking_lost);
157    }
158}