1use glib::translate::*;
4
5use crate::{ffi, relation_meta::*};
6
7#[derive(Debug)]
8pub enum AnalyticsODMtd {}
9
10mod sealed {
11 pub trait Sealed {}
12 impl<T: super::AnalyticsRelationMetaODExt> Sealed for T {}
13}
14
15pub trait AnalyticsRelationMetaODExt: sealed::Sealed {
16 fn add_od_mtd(
17 &mut self,
18 type_: glib::Quark,
19 x: i32,
20 y: i32,
21 w: i32,
22 h: i32,
23 loc_conf_lvl: f32,
24 ) -> Result<AnalyticsMtdRef<AnalyticsODMtd>, glib::BoolError>;
25
26 #[cfg(feature = "v1_26")]
27 #[allow(clippy::too_many_arguments)]
28 fn add_oriented_od_mtd(
29 &mut self,
30 type_: glib::Quark,
31 x: i32,
32 y: i32,
33 w: i32,
34 h: i32,
35 r: f32,
36 loc_conf_lvl: f32,
37 ) -> Result<AnalyticsMtdRef<AnalyticsODMtd>, glib::BoolError>;
38}
39
40impl AnalyticsRelationMetaODExt
41 for gst::MetaRefMut<'_, AnalyticsRelationMeta, gst::meta::Standalone>
42{
43 #[doc(alias = "gst_analytics_relation_meta_add_od_mtd")]
44 fn add_od_mtd(
45 &mut self,
46 type_: glib::Quark,
47 x: i32,
48 y: i32,
49 w: i32,
50 h: i32,
51 loc_conf_lvl: f32,
52 ) -> Result<AnalyticsMtdRef<AnalyticsODMtd>, glib::BoolError> {
53 unsafe {
54 let mut mtd = std::mem::MaybeUninit::uninit();
55 let ret = from_glib(ffi::gst_analytics_relation_meta_add_od_mtd(
56 self.as_mut_ptr(),
57 type_.into_glib(),
58 x,
59 y,
60 w,
61 h,
62 loc_conf_lvl,
63 mtd.as_mut_ptr(),
64 ));
65 let id = mtd.assume_init().id;
66
67 if ret {
68 Ok(AnalyticsMtdRef::from_meta(self.as_ref(), id))
69 } else {
70 Err(glib::bool_error!("Couldn't add more data"))
71 }
72 }
73 }
74
75 #[cfg(feature = "v1_26")]
76 #[cfg_attr(docsrs, doc(cfg(feature = "v1_26")))]
77 #[doc(alias = "gst_analytics_relation_meta_add_oriented_od_mtd")]
78 fn add_oriented_od_mtd(
79 &mut self,
80 type_: glib::Quark,
81 x: i32,
82 y: i32,
83 w: i32,
84 h: i32,
85 r: f32,
86 loc_conf_lvl: f32,
87 ) -> Result<AnalyticsMtdRef<AnalyticsODMtd>, glib::BoolError> {
88 unsafe {
89 let mut mtd = std::mem::MaybeUninit::uninit();
90 let ret = from_glib(ffi::gst_analytics_relation_meta_add_oriented_od_mtd(
91 self.as_mut_ptr(),
92 type_.into_glib(),
93 x,
94 y,
95 w,
96 h,
97 r,
98 loc_conf_lvl,
99 mtd.as_mut_ptr(),
100 ));
101 let id = mtd.assume_init().id;
102
103 if ret {
104 Ok(AnalyticsMtdRef::from_meta(self.as_ref(), id))
105 } else {
106 Err(glib::bool_error!("Couldn't add more data"))
107 }
108 }
109 }
110}
111
112#[derive(Clone, Copy, Default, Debug)]
113pub struct AnalyticsODLocation {
114 pub x: i32,
115 pub y: i32,
116 pub w: i32,
117 pub h: i32,
118 pub loc_conf_lvl: f32,
119}
120
121#[cfg(feature = "v1_26")]
122#[cfg_attr(docsrs, doc(cfg(feature = "v1_26")))]
123#[derive(Clone, Copy, Default, Debug)]
124pub struct AnalyticsODOrientedLocation {
125 pub x: i32,
126 pub y: i32,
127 pub w: i32,
128 pub h: i32,
129 pub r: f32,
130 pub loc_conf_lvl: f32,
131}
132
133unsafe impl AnalyticsMtd for AnalyticsODMtd {
134 #[doc(alias = "gst_analytics_od_mtd_get_mtd_type")]
135 fn mtd_type() -> ffi::GstAnalyticsMtdType {
136 unsafe { ffi::gst_analytics_od_mtd_get_mtd_type() }
137 }
138}
139
140unsafe fn from(t: ffi::GstAnalyticsMtd) -> ffi::GstAnalyticsODMtd {
141 std::mem::transmute(t)
142}
143
144impl AnalyticsMtdRef<'_, AnalyticsODMtd> {
145 #[doc(alias = "gst_analytics_od_mtd_get_obj_type")]
146 pub fn obj_type(&self) -> Option<glib::Quark> {
147 unsafe {
148 let mtd = from(ffi::GstAnalyticsMtd::unsafe_from(self));
149 let type_ = ffi::gst_analytics_od_mtd_get_obj_type(&mtd);
150 if type_ == 0 {
151 None
152 } else {
153 Some(glib::Quark::from_glib(type_))
154 }
155 }
156 }
157
158 #[doc(alias = "gst_analytics_od_mtd_get_location")]
159 pub fn location(&self) -> Result<AnalyticsODLocation, glib::BoolError> {
160 let mut loc = AnalyticsODLocation::default();
161
162 let success = unsafe {
163 let mtd = from(ffi::GstAnalyticsMtd::unsafe_from(self));
164 ffi::gst_analytics_od_mtd_get_location(
165 &mtd,
166 &mut loc.x,
167 &mut loc.y,
168 &mut loc.w,
169 &mut loc.h,
170 &mut loc.loc_conf_lvl,
171 )
172 };
173
174 if success != 0 {
175 Ok(loc)
176 } else {
177 Err(glib::bool_error!("Could retrieve location"))
178 }
179 }
180
181 #[cfg(feature = "v1_26")]
182 #[cfg_attr(docsrs, doc(cfg(feature = "v1_26")))]
183 #[doc(alias = "gst_analytics_od_mtd_get_oriented_location")]
184 pub fn oriented_location(&self) -> Result<AnalyticsODOrientedLocation, glib::BoolError> {
185 let mut loc = AnalyticsODOrientedLocation::default();
186
187 let success = unsafe {
188 let mtd = from(ffi::GstAnalyticsMtd::unsafe_from(self));
189 ffi::gst_analytics_od_mtd_get_oriented_location(
190 &mtd,
191 &mut loc.x,
192 &mut loc.y,
193 &mut loc.w,
194 &mut loc.h,
195 &mut loc.r,
196 &mut loc.loc_conf_lvl,
197 )
198 };
199
200 if success != 0 {
201 Ok(loc)
202 } else {
203 Err(glib::bool_error!("Could retrieve location"))
204 }
205 }
206
207 #[doc(alias = "gst_analytics_od_mtd_get_confidence_lvl")]
208 pub fn confidence_level(&self) -> f32 {
209 unsafe {
210 let mtd = from(ffi::GstAnalyticsMtd::unsafe_from(self));
211 let mut lvl: f32 = 0.0;
212 ffi::gst_analytics_od_mtd_get_confidence_lvl(&mtd, &mut lvl);
213 lvl
214 }
215 }
216}
217
218#[cfg(test)]
219mod tests {
220 use crate::*;
221
222 #[test]
223 fn object_detection() {
224 gst::init().unwrap();
225
226 assert_eq!(AnalyticsODMtd::type_name(), "object-detection");
227
228 let mut buf = gst::Buffer::new();
229 let mut meta = AnalyticsRelationMeta::add(buf.make_mut());
230
231 assert!(meta.is_empty());
232
233 let od = meta
234 .add_od_mtd(glib::Quark::from_str("blb"), 0, 1, 10, 20, 0.8)
235 .unwrap();
236
237 assert_eq!(od.obj_type().unwrap(), glib::Quark::from_str("blb"));
238
239 let loc = od.location().unwrap();
240
241 assert_eq!(loc.x, 0);
242 assert_eq!(loc.y, 1);
243 assert_eq!(loc.w, 10);
244 assert_eq!(loc.h, 20);
245 assert_eq!(loc.loc_conf_lvl, 0.8);
246 let meta = buf.meta::<AnalyticsRelationMeta>().unwrap();
247
248 assert!(meta.mtd::<AnalyticsODMtd>(1).is_none());
249
250 let meta2 = buf.meta::<AnalyticsRelationMeta>().unwrap();
251 let od2 = meta2.mtd::<AnalyticsODMtd>(0).unwrap();
252
253 assert_eq!(od2.obj_type().unwrap(), glib::Quark::from_str("blb"));
254 let loc = od2.location().unwrap();
255
256 assert_eq!(loc.x, 0);
257 assert_eq!(loc.y, 1);
258 assert_eq!(loc.w, 10);
259 assert_eq!(loc.h, 20);
260 assert_eq!(loc.loc_conf_lvl, 0.8);
261 }
262
263 #[cfg(feature = "v1_26")]
264 #[test]
265 fn oriented_object_detection() {
266 gst::init().unwrap();
267
268 let mut buf = gst::Buffer::new();
269 let mut meta = AnalyticsRelationMeta::add(buf.make_mut());
270
271 assert!(meta.is_empty());
272
273 let od = meta
274 .add_oriented_od_mtd(
275 glib::Quark::from_str("blb"),
276 30,
277 40,
278 10,
279 20,
280 std::f32::consts::FRAC_PI_4,
281 1.0,
282 )
283 .unwrap();
284
285 assert_eq!(od.obj_type().unwrap(), glib::Quark::from_str("blb"));
286
287 let loc = od.oriented_location().unwrap();
288
289 assert_eq!(loc.x, 30);
290 assert_eq!(loc.y, 40);
291 assert_eq!(loc.w, 10);
292 assert_eq!(loc.h, 20);
293 assert_eq!(loc.r, std::f32::consts::FRAC_PI_4);
294 assert_eq!(loc.loc_conf_lvl, 1.0);
295 let meta = buf.meta::<AnalyticsRelationMeta>().unwrap();
296
297 assert!(meta.mtd::<AnalyticsODMtd>(1).is_none());
298
299 let meta2 = buf.meta::<AnalyticsRelationMeta>().unwrap();
300 let od2 = meta2.mtd::<AnalyticsODMtd>(0).unwrap();
301
302 assert_eq!(od2.obj_type().unwrap(), glib::Quark::from_str("blb"));
303 let loc = od2.location().unwrap();
304
305 assert_eq!(loc.x, 24);
306 assert_eq!(loc.y, 39);
307 assert_eq!(loc.w, 22);
308 assert_eq!(loc.h, 22);
309 assert_eq!(loc.loc_conf_lvl, 1.0);
310 }
311}