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
140impl AnalyticsMtdRef<'_, AnalyticsODMtd> {
141 #[doc(alias = "gst_analytics_od_mtd_get_obj_type")]
142 pub fn obj_type(&self) -> Option<glib::Quark> {
143 unsafe {
144 let mtd = ffi::GstAnalyticsMtd::unsafe_from(self);
145 let type_ = ffi::gst_analytics_od_mtd_get_obj_type(
146 &mtd as *const _ as *const ffi::GstAnalyticsODMtd,
147 );
148 if type_ == 0 {
149 None
150 } else {
151 Some(glib::Quark::from_glib(type_))
152 }
153 }
154 }
155
156 #[doc(alias = "gst_analytics_od_mtd_get_location")]
157 pub fn location(&self) -> Result<AnalyticsODLocation, glib::BoolError> {
158 let mut loc = AnalyticsODLocation::default();
159
160 let success = unsafe {
161 let mtd = ffi::GstAnalyticsMtd::unsafe_from(self);
162 ffi::gst_analytics_od_mtd_get_location(
163 &mtd as *const _ as *const ffi::GstAnalyticsODMtd,
164 &mut loc.x,
165 &mut loc.y,
166 &mut loc.w,
167 &mut loc.h,
168 &mut loc.loc_conf_lvl,
169 )
170 };
171
172 if success != 0 {
173 Ok(loc)
174 } else {
175 Err(glib::bool_error!("Could retrieve location"))
176 }
177 }
178
179 #[cfg(feature = "v1_26")]
180 #[cfg_attr(docsrs, doc(cfg(feature = "v1_26")))]
181 #[doc(alias = "gst_analytics_od_mtd_get_oriented_location")]
182 pub fn oriented_location(&self) -> Result<AnalyticsODOrientedLocation, glib::BoolError> {
183 let mut loc = AnalyticsODOrientedLocation::default();
184
185 let success = unsafe {
186 let mtd = ffi::GstAnalyticsMtd::unsafe_from(self);
187 ffi::gst_analytics_od_mtd_get_oriented_location(
188 &mtd as *const _ as *const ffi::GstAnalyticsODMtd,
189 &mut loc.x,
190 &mut loc.y,
191 &mut loc.w,
192 &mut loc.h,
193 &mut loc.r,
194 &mut loc.loc_conf_lvl,
195 )
196 };
197
198 if success != 0 {
199 Ok(loc)
200 } else {
201 Err(glib::bool_error!("Could retrieve location"))
202 }
203 }
204
205 #[doc(alias = "gst_analytics_od_mtd_get_confidence_lvl")]
206 pub fn confidence_level(&self) -> f32 {
207 unsafe {
208 let mtd = ffi::GstAnalyticsMtd::unsafe_from(self);
209 let mut lvl: f32 = 0.0;
210 ffi::gst_analytics_od_mtd_get_confidence_lvl(
211 &mtd as *const _ as *const ffi::GstAnalyticsODMtd,
212 &mut lvl,
213 );
214 lvl
215 }
216 }
217}
218
219#[cfg(test)]
220mod tests {
221 use crate::*;
222
223 #[test]
224 fn object_detection() {
225 gst::init().unwrap();
226
227 assert_eq!(AnalyticsODMtd::type_name(), "object-detection");
228
229 let mut buf = gst::Buffer::new();
230 let mut meta = AnalyticsRelationMeta::add(buf.make_mut());
231
232 assert!(meta.is_empty());
233
234 let od = meta
235 .add_od_mtd(glib::Quark::from_str("blb"), 0, 1, 10, 20, 0.8)
236 .unwrap();
237
238 assert_eq!(od.obj_type().unwrap(), glib::Quark::from_str("blb"));
239
240 let loc = od.location().unwrap();
241
242 assert_eq!(loc.x, 0);
243 assert_eq!(loc.y, 1);
244 assert_eq!(loc.w, 10);
245 assert_eq!(loc.h, 20);
246 assert_eq!(loc.loc_conf_lvl, 0.8);
247 let meta = buf.meta::<AnalyticsRelationMeta>().unwrap();
248
249 assert!(meta.mtd::<AnalyticsODMtd>(1).is_none());
250
251 let meta2 = buf.meta::<AnalyticsRelationMeta>().unwrap();
252 let od2 = meta2.mtd::<AnalyticsODMtd>(0).unwrap();
253
254 assert_eq!(od2.obj_type().unwrap(), glib::Quark::from_str("blb"));
255 let loc = od2.location().unwrap();
256
257 assert_eq!(loc.x, 0);
258 assert_eq!(loc.y, 1);
259 assert_eq!(loc.w, 10);
260 assert_eq!(loc.h, 20);
261 assert_eq!(loc.loc_conf_lvl, 0.8);
262 }
263
264 #[cfg(feature = "v1_26")]
265 #[test]
266 fn oriented_object_detection() {
267 gst::init().unwrap();
268
269 let mut buf = gst::Buffer::new();
270 let mut meta = AnalyticsRelationMeta::add(buf.make_mut());
271
272 assert!(meta.is_empty());
273
274 let od = meta
275 .add_oriented_od_mtd(
276 glib::Quark::from_str("blb"),
277 30,
278 40,
279 10,
280 20,
281 std::f32::consts::FRAC_PI_4,
282 1.0,
283 )
284 .unwrap();
285
286 assert_eq!(od.obj_type().unwrap(), glib::Quark::from_str("blb"));
287
288 let loc = od.oriented_location().unwrap();
289
290 assert_eq!(loc.x, 30);
291 assert_eq!(loc.y, 40);
292 assert_eq!(loc.w, 10);
293 assert_eq!(loc.h, 20);
294 assert_eq!(loc.r, std::f32::consts::FRAC_PI_4);
295 assert_eq!(loc.loc_conf_lvl, 1.0);
296 let meta = buf.meta::<AnalyticsRelationMeta>().unwrap();
297
298 assert!(meta.mtd::<AnalyticsODMtd>(1).is_none());
299
300 let meta2 = buf.meta::<AnalyticsRelationMeta>().unwrap();
301 let od2 = meta2.mtd::<AnalyticsODMtd>(0).unwrap();
302
303 assert_eq!(od2.obj_type().unwrap(), glib::Quark::from_str("blb"));
304 let loc = od2.location().unwrap();
305
306 assert_eq!(loc.x, 24);
307 assert_eq!(loc.y, 39);
308 assert_eq!(loc.w, 22);
309 assert_eq!(loc.h, 22);
310 assert_eq!(loc.loc_conf_lvl, 1.0);
311 }
312}