Skip to main content

gstreamer_analytics/
keypoint.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 AnalyticsKeypointMtd {}
9
10pub type AnalyticsKeypointDimensions = crate::KeypointDimensions;
11pub type AnalyticsKeypointVisibility = crate::KeypointVisibility;
12
13#[derive(Clone, Copy, Debug)]
14pub struct AnalyticsKeypointPosition {
15    pub x: i32,
16    pub y: i32,
17    pub z: i32,
18    pub dimension: AnalyticsKeypointDimensions,
19}
20
21impl Default for AnalyticsKeypointPosition {
22    fn default() -> Self {
23        Self {
24            x: 0,
25            y: 0,
26            z: 0,
27            dimension: AnalyticsKeypointDimensions::_2d,
28        }
29    }
30}
31
32mod sealed {
33    pub trait Sealed {}
34    impl<T: super::AnalyticsRelationMetaKeypointExt> Sealed for T {}
35}
36
37pub trait AnalyticsRelationMetaKeypointExt: sealed::Sealed {
38    fn add_keypoint_mtd(
39        &mut self,
40        dimension: AnalyticsKeypointDimensions,
41        x: i32,
42        y: i32,
43        z: i32,
44        visibility_flags: AnalyticsKeypointVisibility,
45        confidence: f32,
46    ) -> Result<AnalyticsMtdRef<'_, AnalyticsKeypointMtd>, glib::BoolError>;
47
48    fn add_keypoint_mtd_from_position(
49        &mut self,
50        position: AnalyticsKeypointPosition,
51        visibility_flags: AnalyticsKeypointVisibility,
52        confidence: f32,
53    ) -> Result<AnalyticsMtdRef<'_, AnalyticsKeypointMtd>, glib::BoolError> {
54        self.add_keypoint_mtd(
55            position.dimension,
56            position.x,
57            position.y,
58            position.z,
59            visibility_flags,
60            confidence,
61        )
62    }
63}
64
65impl AnalyticsRelationMetaKeypointExt
66    for gst::MetaRefMut<'_, AnalyticsRelationMeta, gst::meta::Standalone>
67{
68    #[doc(alias = "gst_analytics_relation_meta_add_keypoint_mtd")]
69    fn add_keypoint_mtd(
70        &mut self,
71        dimension: AnalyticsKeypointDimensions,
72        x: i32,
73        y: i32,
74        z: i32,
75        visibility_flags: AnalyticsKeypointVisibility,
76        confidence: f32,
77    ) -> Result<AnalyticsMtdRef<'_, AnalyticsKeypointMtd>, glib::BoolError> {
78        unsafe {
79            let mut mtd = std::mem::MaybeUninit::uninit();
80            let ret = from_glib(ffi::gst_analytics_relation_meta_add_keypoint_mtd(
81                self.as_mut_ptr(),
82                dimension.into_glib(),
83                x,
84                y,
85                z,
86                visibility_flags.into_glib() as u8,
87                confidence,
88                mtd.as_mut_ptr(),
89            ));
90            let id = mtd.assume_init().id;
91
92            if ret {
93                Ok(AnalyticsMtdRef::from_meta(self.as_ref(), id))
94            } else {
95                Err(glib::bool_error!("Couldn't add keypoint metadata"))
96            }
97        }
98    }
99}
100
101unsafe impl AnalyticsMtd for AnalyticsKeypointMtd {
102    #[doc(alias = "gst_analytics_keypoint_mtd_get_mtd_type")]
103    fn mtd_type() -> ffi::GstAnalyticsMtdType {
104        unsafe { ffi::gst_analytics_keypoint_mtd_get_mtd_type() }
105    }
106}
107
108impl AnalyticsMtdRef<'_, AnalyticsKeypointMtd> {
109    #[doc(alias = "gst_analytics_keypoint_mtd_get_position")]
110    pub fn position(&self) -> Result<AnalyticsKeypointPosition, glib::BoolError> {
111        let mut pos = AnalyticsKeypointPosition::default();
112        let mut dimension = AnalyticsKeypointDimensions::_2d.into_glib();
113
114        let ret = unsafe {
115            let mtd = ffi::GstAnalyticsMtd::unsafe_from(self);
116            ffi::gst_analytics_keypoint_mtd_get_position(
117                &mtd as *const _ as *const ffi::GstAnalyticsKeypointMtd,
118                &mut pos.x,
119                &mut pos.y,
120                &mut pos.z,
121                &mut dimension,
122            )
123        };
124
125        if unsafe { from_glib(ret) } {
126            pos.dimension = unsafe { from_glib(dimension) };
127            Ok(pos)
128        } else {
129            Err(glib::bool_error!("Could not retrieve keypoint position"))
130        }
131    }
132
133    #[doc(alias = "gst_analytics_keypoint_mtd_get_confidence")]
134    pub fn confidence(&self) -> Result<f32, glib::BoolError> {
135        let mut confidence: f32 = 0.0;
136        let ret = unsafe {
137            let mtd = ffi::GstAnalyticsMtd::unsafe_from(self);
138            ffi::gst_analytics_keypoint_mtd_get_confidence(
139                &mtd as *const _ as *const ffi::GstAnalyticsKeypointMtd,
140                &mut confidence,
141            )
142        };
143
144        if unsafe { from_glib(ret) } {
145            Ok(confidence)
146        } else {
147            Err(glib::bool_error!("Could not retrieve keypoint confidence"))
148        }
149    }
150
151    #[doc(alias = "gst_analytics_keypoint_mtd_get_visibility_flags")]
152    pub fn visibility_flags(&self) -> Result<AnalyticsKeypointVisibility, glib::BoolError> {
153        let mut visibility_flags: u8 = 0;
154        let ret = unsafe {
155            let mtd = ffi::GstAnalyticsMtd::unsafe_from(self);
156            ffi::gst_analytics_keypoint_mtd_get_visibility_flags(
157                &mtd as *const _ as *const ffi::GstAnalyticsKeypointMtd,
158                &mut visibility_flags,
159            )
160        };
161
162        if unsafe { from_glib(ret) } {
163            Ok(unsafe { from_glib(visibility_flags as ffi::GstAnalyticsKeypointVisibility) })
164        } else {
165            Err(glib::bool_error!(
166                "Could not retrieve keypoint visibility flags"
167            ))
168        }
169    }
170}
171
172#[cfg(test)]
173mod tests {
174    use crate::*;
175
176    #[test]
177    fn keypoint_mtd() {
178        gst::init().unwrap();
179
180        let type_name = AnalyticsKeypointMtd::type_name();
181        assert_eq!(type_name, "keypoint-mtd");
182
183        let mut buf = gst::Buffer::new();
184        let mut meta = AnalyticsRelationMeta::add(buf.make_mut());
185
186        let keypoint = meta
187            .add_keypoint_mtd_from_position(
188                AnalyticsKeypointPosition {
189                    x: 12,
190                    y: 34,
191                    z: 0,
192                    dimension: AnalyticsKeypointDimensions::_2d,
193                },
194                AnalyticsKeypointVisibility::VISIBLE,
195                0.75,
196            )
197            .unwrap();
198
199        let position = keypoint.position().unwrap();
200        assert_eq!(position.dimension, AnalyticsKeypointDimensions::_2d);
201        assert_eq!(position.x, 12);
202        assert_eq!(position.y, 34);
203        assert_eq!(position.z, 0);
204
205        assert_eq!(keypoint.confidence().unwrap(), 0.75);
206        assert_eq!(
207            keypoint.visibility_flags().unwrap(),
208            AnalyticsKeypointVisibility::VISIBLE
209        );
210    }
211}