1use glib::translate::*;
4use gst::prelude::*;
5use std::marker::PhantomData;
6
7use crate::{RelTypes, ffi};
8
9#[repr(transparent)]
10#[doc(alias = "GstAnalyticsRelationMeta")]
11pub struct AnalyticsRelationMeta(ffi::GstAnalyticsRelationMeta);
12
13unsafe impl Send for AnalyticsRelationMeta {}
14unsafe impl Sync for AnalyticsRelationMeta {}
15
16#[derive(Debug, Copy, Clone)]
17#[doc(alias = "GstAnalyticsRelationMetaInitParams")]
18pub struct AnalyticsRelationMetaInitParams(ffi::GstAnalyticsRelationMetaInitParams);
19
20impl Default for AnalyticsRelationMetaInitParams {
21 fn default() -> Self {
22 Self(ffi::GstAnalyticsRelationMetaInitParams {
23 initial_relation_order: 0,
24 initial_buf_size: 0,
25 })
26 }
27}
28
29impl AnalyticsRelationMetaInitParams {
30 pub fn new(initial_relation_order: usize, initial_buf_size: usize) -> Self {
31 skip_assert_initialized!();
32 Self(ffi::GstAnalyticsRelationMetaInitParams {
33 initial_relation_order,
34 initial_buf_size,
35 })
36 }
37}
38
39#[derive(Debug, Clone)]
40pub struct AnalyticsMtdRef<'a, T: AnalyticsMtd> {
41 id: u32,
42 meta: gst::MetaRef<'a, AnalyticsRelationMeta>,
43 mtd_type: PhantomData<&'a T>,
44}
45
46#[derive(Debug)]
47pub struct AnalyticsMtdRefMut<'a, T: AnalyticsMtd> {
48 id: u32,
49 meta: &'a mut gst::MetaRefMut<'a, AnalyticsRelationMeta, gst::meta::Standalone>,
50 mtd_type: PhantomData<&'a T>,
51}
52
53pub struct AnalyticsRelationPath {
54 garray: *mut glib::ffi::GArray,
55}
56
57impl std::fmt::Debug for AnalyticsRelationMeta {
58 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
59 f.debug_struct("AnalyticsRelationMeta")
60 .field("len", &self.len())
61 .finish()
62 }
63}
64
65impl AnalyticsRelationMeta {
66 #[doc(alias = "gst_buffer_add_analytics_relation_meta")]
67 pub fn add(buffer: &mut gst::BufferRef) -> gst::MetaRefMut<'_, Self, gst::meta::Standalone> {
68 skip_assert_initialized!();
69
70 unsafe {
71 let meta_ptr = ffi::gst_buffer_add_analytics_relation_meta(buffer.as_mut_ptr());
72 Self::from_mut_ptr(buffer, meta_ptr)
73 }
74 }
75
76 #[doc(alias = "gst_buffer_add_analytics_relation_meta_full")]
77 pub fn add_full<'a>(
78 buffer: &'a mut gst::BufferRef,
79 init_params: &AnalyticsRelationMetaInitParams,
80 ) -> gst::MetaRefMut<'a, Self, gst::meta::Standalone> {
81 skip_assert_initialized!();
82
83 unsafe {
84 let meta_ptr = ffi::gst_buffer_add_analytics_relation_meta_full(
85 buffer.as_mut_ptr(),
86 mut_override(&init_params.0),
87 );
88 Self::from_mut_ptr(buffer, meta_ptr)
89 }
90 }
91
92 #[doc(alias = "gst_analytics_relation_get_length")]
93 pub fn len(&self) -> usize {
94 unsafe { ffi::gst_analytics_relation_get_length(self.as_mut_ptr()) }
95 }
96
97 pub fn is_empty(&self) -> bool {
98 self.len() == 0
99 }
100
101 #[doc(alias = "gst_analytics_relation_meta_set_relation")]
102 pub fn set_relation(
103 &mut self,
104 type_: crate::RelTypes,
105 an_meta_first_id: u32,
106 an_meta_second_id: u32,
107 ) -> Result<(), glib::BoolError> {
108 let ret = unsafe {
109 from_glib(ffi::gst_analytics_relation_meta_set_relation(
110 self.as_mut_ptr(),
111 type_.into_glib(),
112 an_meta_first_id,
113 an_meta_second_id,
114 ))
115 };
116
117 if ret {
118 Ok(())
119 } else {
120 Err(glib::bool_error!(
121 "Could not set relation {:}->{:} of type {:?}",
122 an_meta_first_id,
123 an_meta_second_id,
124 type_
125 ))
126 }
127 }
128
129 #[doc(alias = "gst_analytics_relation_meta_get_relation")]
130 pub fn relation(&self, an_meta_first_id: u32, an_meta_second_id: u32) -> crate::RelTypes {
131 unsafe {
132 from_glib(ffi::gst_analytics_relation_meta_get_relation(
133 self.as_mut_ptr(),
134 an_meta_first_id,
135 an_meta_second_id,
136 ))
137 }
138 }
139
140 #[doc(alias = "gst_analytics_relation_meta_exist")]
141 pub fn exist(
142 &self,
143 an_meta_first_id: u32,
144 an_meta_second_id: u32,
145 relation_span: i32,
146 cond_types: crate::RelTypes,
147 ) -> bool {
148 unsafe {
149 from_glib(ffi::gst_analytics_relation_meta_exist(
150 self.as_mut_ptr(),
151 an_meta_first_id,
152 an_meta_second_id,
153 relation_span,
154 cond_types.into_glib(),
155 std::ptr::null_mut(),
156 ))
157 }
158 }
159
160 #[doc(alias = "gst_analytics_relation_meta_exist")]
161 pub fn exist_path(
162 &self,
163 an_meta_first_id: u32,
164 an_meta_second_id: u32,
165 relation_span: i32,
166 cond_types: crate::RelTypes,
167 ) -> Result<AnalyticsRelationPath, glib::BoolError> {
168 let mut array = std::ptr::null_mut::<glib::ffi::GArray>();
169 let ret = unsafe {
170 from_glib(ffi::gst_analytics_relation_meta_exist(
171 self.as_mut_ptr(),
172 an_meta_first_id,
173 an_meta_second_id,
174 relation_span,
175 cond_types.into_glib(),
176 &mut array,
177 ))
178 };
179
180 if ret {
181 Ok(AnalyticsRelationPath { garray: array })
182 } else {
183 Err(glib::bool_error!("Such relation doesn't exist"))
184 }
185 }
186
187 pub unsafe fn as_mut_ptr(&self) -> *mut ffi::GstAnalyticsRelationMeta {
188 mut_override(&self.0)
189 }
190}
191
192impl UnsafeFrom<&AnalyticsRelationMeta> for ffi::GstAnalyticsMtd {
193 unsafe fn unsafe_from(t: &AnalyticsRelationMeta) -> Self {
194 unsafe {
195 ffi::GstAnalyticsMtd {
196 id: 0,
197 meta: t.as_mut_ptr(),
198 }
199 }
200 }
201}
202
203impl AnalyticsRelationPath {
204 pub fn as_slice(&self) -> &[u32] {
205 unsafe {
206 std::slice::from_raw_parts(
207 (*self.garray).data as *const u32,
208 (*self.garray).len as usize,
209 )
210 }
211 }
212}
213
214impl Drop for AnalyticsRelationPath {
215 fn drop(&mut self) {
216 unsafe {
217 glib::ffi::g_array_free(self.garray, glib::ffi::GTRUE);
218 }
219 }
220}
221
222mod sealed {
223 pub trait Sealed {}
224 impl<T> Sealed for T {}
225}
226
227pub trait AnalyticsMetaRefExt<'a>: sealed::Sealed {
228 #[doc(alias = "gst_analytics_relation_meta_get_mtd")]
229 fn mtd<T: AnalyticsMtd>(&self, an_meta_id: u32) -> Option<AnalyticsMtdRef<'a, T>>;
230 fn iter<T: AnalyticsMtd>(&'a self) -> AnalyticsMtdIter<'a, T>;
231 fn iter_direct_related<T: AnalyticsMtd>(
232 &'a self,
233 an_meta_id: u32,
234 rel_type: RelTypes,
235 ) -> AnalyticsMtdIter<'a, T>;
236}
237
238impl<'a> AnalyticsMetaRefExt<'a> for gst::MetaRef<'a, AnalyticsRelationMeta> {
239 fn mtd<T: AnalyticsMtd>(&self, an_meta_id: u32) -> Option<AnalyticsMtdRef<'a, T>> {
240 unsafe {
241 let mut mtd = std::mem::MaybeUninit::uninit();
242 let ret = from_glib(ffi::gst_analytics_relation_meta_get_mtd(
243 self.as_mut_ptr(),
244 an_meta_id,
245 T::mtd_type(),
246 mtd.as_mut_ptr(),
247 ));
248 let id = mtd.assume_init().id;
249
250 if ret {
251 Some(AnalyticsMtdRef::from_meta(self, id))
252 } else {
253 None
254 }
255 }
256 }
257
258 fn iter<T: AnalyticsMtd>(&'a self) -> AnalyticsMtdIter<'a, T> {
259 AnalyticsMtdIter::new(self)
260 }
261 fn iter_direct_related<T: AnalyticsMtd>(
262 &'a self,
263 an_meta_id: u32,
264 rel_type: RelTypes,
265 ) -> AnalyticsMtdIter<'a, T> {
266 AnalyticsMtdIter::new_direct_related(self, an_meta_id, rel_type.into_glib())
267 }
268}
269
270impl<'a, T: AnalyticsMtd> AnalyticsMtdRef<'a, T> {
271 pub fn id(&self) -> u32 {
272 self.id
273 }
274
275 #[cfg(feature = "v1_28")]
276 pub(crate) fn meta_ref(&self) -> &gst::MetaRef<'a, AnalyticsRelationMeta> {
277 &self.meta
278 }
279
280 pub unsafe fn from_meta(meta: &gst::MetaRef<'a, AnalyticsRelationMeta>, id: u32) -> Self {
281 skip_assert_initialized!();
282 AnalyticsMtdRef {
283 meta: meta.clone(),
284 id,
285 mtd_type: PhantomData,
286 }
287 }
288
289 #[doc(alias = "gst_analytics_mtd_get_mtd_type")]
290 pub fn mtd_type(&self) -> ffi::GstAnalyticsMtdType {
291 unsafe {
292 let mtd = ffi::GstAnalyticsMtd::unsafe_from(self);
293 ffi::gst_analytics_mtd_get_mtd_type(&mtd)
294 }
295 }
296}
297impl<'a> AnalyticsMtdRef<'a, AnalyticsAnyMtd> {
298 pub fn downcast<T: AnalyticsMtd>(
299 self,
300 ) -> Result<AnalyticsMtdRef<'a, T>, AnalyticsMtdRef<'a, AnalyticsAnyMtd>> {
301 if self.mtd_type() == T::mtd_type() {
302 Ok(AnalyticsMtdRef {
303 id: self.id,
304 meta: self.meta,
305 mtd_type: PhantomData,
306 })
307 } else {
308 Err(self)
309 }
310 }
311
312 pub fn downcast_ref<T: AnalyticsMtd>(&self) -> Option<&AnalyticsMtdRef<'a, T>> {
313 unsafe {
314 if self.mtd_type() == T::mtd_type() {
315 Some(&*(self as *const _ as *const _))
316 } else {
317 None
318 }
319 }
320 }
321}
322
323impl<'a> AnalyticsMtdRefMut<'a, AnalyticsAnyMtd> {
324 pub fn downcast_mut<T: AnalyticsMtd>(&mut self) -> Option<&mut AnalyticsMtdRefMut<'a, T>> {
325 unsafe {
326 if self.as_ref().mtd_type() == T::mtd_type() {
327 Some(&mut *(self as *mut _ as *mut _))
328 } else {
329 None
330 }
331 }
332 }
333}
334
335impl<'a, T: AnalyticsMtd> UnsafeFrom<&AnalyticsMtdRef<'a, T>> for ffi::GstAnalyticsMtd {
336 unsafe fn unsafe_from(t: &AnalyticsMtdRef<'a, T>) -> Self {
337 unsafe {
338 ffi::GstAnalyticsMtd {
339 id: t.id,
340 meta: t.meta.as_mut_ptr(),
341 }
342 }
343 }
344}
345
346pub trait AnalyticsMetaRefMutExt<'a>: sealed::Sealed {
347 #[doc(alias = "gst_analytics_relation_meta_get_mtd")]
348 fn mtd_mut<T: AnalyticsMtd>(&'a mut self, an_meta_id: u32)
349 -> Option<AnalyticsMtdRefMut<'a, T>>;
350
351 fn iter_mut<T: AnalyticsMtd>(&'a mut self) -> AnalyticsMtdIterMut<'a, T>;
352 fn iter_direct_related_mut<T: AnalyticsMtd>(
353 &'a mut self,
354 an_meta_id: u32,
355 rel_type: RelTypes,
356 ) -> AnalyticsMtdIterMut<'a, T>;
357}
358
359impl<'a> AnalyticsMetaRefMutExt<'a>
360 for gst::MetaRefMut<'a, AnalyticsRelationMeta, gst::meta::Standalone>
361{
362 fn mtd_mut<T: AnalyticsMtd>(
363 &'a mut self,
364 an_meta_id: u32,
365 ) -> Option<AnalyticsMtdRefMut<'a, T>> {
366 unsafe {
367 let mut mtd = std::mem::MaybeUninit::uninit();
368 let ret = from_glib(ffi::gst_analytics_relation_meta_get_mtd(
369 self.as_mut_ptr(),
370 an_meta_id,
371 T::mtd_type(),
372 mtd.as_mut_ptr(),
373 ));
374 let id = mtd.assume_init().id;
375
376 if ret {
377 Some(AnalyticsMtdRefMut::from_meta(self, id))
378 } else {
379 None
380 }
381 }
382 }
383
384 fn iter_mut<T: AnalyticsMtd>(&'a mut self) -> AnalyticsMtdIterMut<'a, T> {
385 AnalyticsMtdIterMut::new(self)
386 }
387 fn iter_direct_related_mut<T: AnalyticsMtd>(
388 &'a mut self,
389 an_meta_id: u32,
390 rel_type: RelTypes,
391 ) -> AnalyticsMtdIterMut<'a, T> {
392 AnalyticsMtdIterMut::new_direct_related(self, an_meta_id, rel_type.into_glib())
393 }
394}
395
396unsafe impl MetaAPI for AnalyticsRelationMeta {
397 type GstType = ffi::GstAnalyticsRelationMeta;
398
399 #[doc(alias = "gst_analytics_relation_meta_api_get_type")]
400 #[inline]
401 fn meta_api() -> glib::Type {
402 unsafe { from_glib(ffi::gst_analytics_relation_meta_api_get_type()) }
403 }
404}
405
406pub unsafe trait AnalyticsMtd {
407 fn mtd_type() -> ffi::GstAnalyticsMtdType;
408}
409
410pub trait AnalyticsMtdExt: AnalyticsMtd {
411 #[doc(alias = "gst_analytics_mtd_type_get_name")]
412 fn type_name() -> &'static str {
413 unsafe {
414 let ptr = ffi::gst_analytics_mtd_type_get_name(Self::mtd_type());
415 std::ffi::CStr::from_ptr(ptr).to_str().unwrap()
416 }
417 }
418}
419
420impl<T: AnalyticsMtd> AnalyticsMtdExt for T {}
421
422impl<'a, T: AnalyticsMtd> AnalyticsMtdRefMut<'a, T> {
423 pub fn id(&self) -> u32 {
424 self.id
425 }
426
427 pub unsafe fn from_meta(
428 meta: &'a mut gst::MetaRefMut<'a, AnalyticsRelationMeta, gst::meta::Standalone>,
429 id: u32,
430 ) -> Self {
431 skip_assert_initialized!();
432 AnalyticsMtdRefMut {
433 meta,
434 id,
435 mtd_type: PhantomData,
436 }
437 }
438}
439
440impl<'a, T: AnalyticsMtd> UnsafeFrom<&mut AnalyticsMtdRefMut<'a, T>> for ffi::GstAnalyticsMtd {
441 unsafe fn unsafe_from(t: &mut AnalyticsMtdRefMut<'a, T>) -> Self {
442 ffi::GstAnalyticsMtd {
443 id: t.id,
444 meta: t.meta.as_mut_ptr(),
445 }
446 }
447}
448
449impl<'a, T: AnalyticsMtd> From<AnalyticsMtdRefMut<'a, T>> for AnalyticsMtdRef<'a, T> {
450 fn from(value: AnalyticsMtdRefMut<'a, T>) -> Self {
451 skip_assert_initialized!();
452 AnalyticsMtdRef {
453 meta: value.meta.as_ref().clone(),
454 id: value.id,
455 mtd_type: value.mtd_type,
456 }
457 }
458}
459
460impl<'a, T: AnalyticsMtd> From<&mut AnalyticsMtdRefMut<'a, T>> for AnalyticsMtdRef<'a, T> {
461 fn from(value: &mut AnalyticsMtdRefMut<'a, T>) -> Self {
462 skip_assert_initialized!();
463 AnalyticsMtdRef {
464 meta: value.meta.as_ref().clone(),
465 id: value.id,
466 mtd_type: value.mtd_type,
467 }
468 }
469}
470
471impl<'a, T: AnalyticsMtd> AsRef<AnalyticsMtdRef<'a, T>> for AnalyticsMtdRefMut<'a, T> {
472 #[inline]
473 fn as_ref(&self) -> &AnalyticsMtdRef<'a, T> {
474 unsafe { &*(self as *const AnalyticsMtdRefMut<'a, T> as *const AnalyticsMtdRef<'a, T>) }
475 }
476}
477
478macro_rules! define_mtd_iter {
479 ($name:ident, $metaref:ty, $itemref:ty, $copy_meta:expr) => {
480 #[must_use = "iterators are lazy and do nothing unless consumed"]
481 pub struct $name<'a, T: AnalyticsMtd> {
482 meta: $metaref,
483 state: glib::ffi::gpointer,
484 mtd_type: ffi::GstAnalyticsMtdType,
485 an_meta_id: u32,
486 rel_type: ffi::GstAnalyticsRelTypes,
487 phantom: std::marker::PhantomData<T>,
488 }
489
490 impl<'a, T: AnalyticsMtd> $name<'a, T> {
491 fn new(meta: $metaref) -> Self {
492 skip_assert_initialized!();
493 $name {
494 meta,
495 state: std::ptr::null_mut(),
496 mtd_type: T::mtd_type(),
497 an_meta_id: u32::MAX,
498 rel_type: RelTypes::ANY.into_glib(),
499 phantom: PhantomData,
500 }
501 }
502 fn new_direct_related(
503 meta: $metaref,
504 an_meta_id: u32,
505 rel_type: ffi::GstAnalyticsRelTypes,
506 ) -> Self {
507 skip_assert_initialized!();
508 $name {
509 meta,
510 state: std::ptr::null_mut(),
511 mtd_type: T::mtd_type(),
512 an_meta_id,
513 rel_type,
514 phantom: PhantomData,
515 }
516 }
517 }
518
519 impl<'a, T: AnalyticsMtd + 'a> Iterator for $name<'a, T> {
520 type Item = $itemref;
521
522 fn next(&mut self) -> Option<Self::Item> {
523 unsafe {
524 let mut mtd = ffi::GstAnalyticsMtd::unsafe_from(&**self.meta);
525 let ret = {
526 if self.an_meta_id == u32::MAX {
527 ffi::gst_analytics_relation_meta_iterate(
528 self.meta.as_mut_ptr(),
529 &mut self.state,
530 self.mtd_type,
531 &mut mtd,
532 )
533 } else {
534 ffi::gst_analytics_relation_meta_get_direct_related(
535 self.meta.as_mut_ptr(),
536 self.an_meta_id,
537 self.rel_type,
538 self.mtd_type,
539 &mut self.state,
540 &mut mtd,
541 )
542 }
543 };
544 if from_glib(ret) {
545 #[allow(clippy::redundant_closure_call)]
548 Some(Self::Item::from_meta($copy_meta(self.meta), mtd.id))
549 } else {
550 None
551 }
552 }
553 }
554 }
555 };
556}
557
558define_mtd_iter!(
559 AnalyticsMtdIter,
560 &'a gst::MetaRef<'a, AnalyticsRelationMeta>,
561 AnalyticsMtdRef<'a, T>,
562 |meta| meta
563);
564
565define_mtd_iter!(
566 AnalyticsMtdIterMut,
567 &'a mut gst::MetaRefMut<'a, AnalyticsRelationMeta, gst::meta::Standalone>,
568 AnalyticsMtdRefMut<'a, T>,
569 |meta: &mut _| &mut *(meta as *mut gst::MetaRefMut<
570 'a,
571 AnalyticsRelationMeta,
572 gst::meta::Standalone,
573 >)
574);
575
576#[derive(Debug)]
577pub enum AnalyticsAnyMtd {}
578
579unsafe impl AnalyticsMtd for AnalyticsAnyMtd {
580 fn mtd_type() -> ffi::GstAnalyticsMtdType {
581 ffi::GST_ANALYTICS_MTD_TYPE_ANY as ffi::GstAnalyticsMtdType
582 }
583}
584
585#[cfg(test)]
586mod tests {
587 use crate::*;
588
589 #[test]
590 fn build_relation_meta() {
591 gst::init().unwrap();
592
593 let mut buf = gst::Buffer::new();
594
595 let meta = AnalyticsRelationMeta::add(buf.make_mut());
596
597 assert!(meta.is_empty());
598 }
599
600 #[test]
601 fn build_relation_meta_full() {
602 gst::init().unwrap();
603
604 let mut buf = gst::Buffer::new();
605
606 let params = AnalyticsRelationMetaInitParams::new(10, 10);
607 let meta = AnalyticsRelationMeta::add_full(buf.make_mut(), ¶ms);
608
609 assert!(meta.is_empty());
610 }
611
612 #[test]
613 fn relations() {
614 gst::init().unwrap();
615
616 let mut buf = gst::Buffer::new();
617 let _ = AnalyticsRelationMeta::add(buf.make_mut());
618
619 let mut meta = buf.make_mut().meta_mut::<AnalyticsRelationMeta>().unwrap();
620 let od = meta
621 .add_od_mtd(glib::Quark::from_str("blb"), 0, 1, 10, 20, 0.8)
622 .unwrap();
623 let od1_id = od.id();
624
625 let od = meta
626 .add_od_mtd(glib::Quark::from_str("blb"), 0, 1, 10, 20, 0.8)
627 .unwrap();
628 let od2_id = od.id();
629
630 let od: AnalyticsMtdRef<'_, AnalyticsODMtd> = meta
631 .add_od_mtd(glib::Quark::from_str("blb"), 0, 1, 10, 20, 0.8)
632 .unwrap();
633 let od3_id = od.id();
634
635 meta.set_relation(RelTypes::IS_PART_OF, od1_id, od2_id)
636 .unwrap();
637 meta.set_relation(RelTypes::IS_PART_OF, od2_id, od3_id)
638 .unwrap();
639
640 meta.set_relation(RelTypes::IS_PART_OF, 8888, 9999)
641 .expect_err("Invalid id");
642
643 let meta = buf.meta::<AnalyticsRelationMeta>().unwrap();
644 assert!(meta.relation(od1_id, od2_id) == crate::RelTypes::IS_PART_OF);
645 assert!(meta.relation(od2_id, od3_id) == crate::RelTypes::IS_PART_OF);
646
647 assert!(meta.exist(od1_id, od2_id, 1, crate::RelTypes::IS_PART_OF));
648 assert!(meta.exist(od1_id, od3_id, 2, crate::RelTypes::IS_PART_OF));
649 assert!(!meta.exist(od2_id, od1_id, 1, crate::RelTypes::IS_PART_OF));
650 assert!(!meta.exist(od1_id, od3_id, 1, crate::RelTypes::IS_PART_OF));
651 assert!(!meta.exist(od1_id, od2_id, 1, crate::RelTypes::CONTAIN));
652
653 let path = meta
654 .exist_path(od1_id, od3_id, 3, crate::RelTypes::ANY)
655 .unwrap();
656
657 assert_eq!(path.as_slice().len(), 3);
658 assert_eq!(path.as_slice()[0], od1_id);
659 assert_eq!(path.as_slice()[1], od2_id);
660 assert_eq!(path.as_slice()[2], od3_id);
661
662 assert_eq!(meta.len(), meta.iter::<AnalyticsAnyMtd>().count());
663 assert_eq!(meta.len(), meta.iter::<AnalyticsODMtd>().count());
664 for mtd in meta.iter::<AnalyticsODMtd>() {
665 assert_eq!(mtd.obj_type().unwrap(), glib::Quark::from_str("blb"))
666 }
667
668 assert_eq!(meta.len(), meta.iter::<AnalyticsAnyMtd>().count());
669 for mtd in meta.iter::<AnalyticsAnyMtd>() {
670 if let Ok(mtd) = mtd.downcast::<AnalyticsODMtd>() {
671 assert_eq!(mtd.obj_type().unwrap(), glib::Quark::from_str("blb"))
672 }
673 }
674
675 assert_eq!(
676 meta.iter_direct_related::<AnalyticsODMtd>(od1_id, crate::RelTypes::IS_PART_OF)
677 .count(),
678 1
679 );
680 assert_eq!(
681 meta.iter_direct_related::<AnalyticsODMtd>(od2_id, crate::RelTypes::IS_PART_OF)
682 .count(),
683 1
684 );
685 assert_eq!(
686 meta.iter_direct_related::<AnalyticsODMtd>(od3_id, crate::RelTypes::IS_PART_OF)
687 .count(),
688 0
689 );
690 assert_eq!(
691 meta.iter_direct_related::<AnalyticsODMtd>(od1_id, crate::RelTypes::CONTAIN)
692 .count(),
693 0
694 );
695
696 assert_eq!(
697 meta.iter_direct_related::<AnalyticsAnyMtd>(od1_id, crate::RelTypes::CONTAIN)
698 .count(),
699 0
700 );
701 for mtd in meta.iter_direct_related::<AnalyticsODMtd>(od1_id, crate::RelTypes::IS_PART_OF) {
702 assert_eq!(mtd.obj_type().unwrap(), glib::Quark::from_str("blb"))
703 }
704
705 let mut meta = buf.make_mut().meta_mut::<AnalyticsRelationMeta>().unwrap();
706 assert_eq!(meta.len(), meta.iter_mut::<AnalyticsAnyMtd>().count());
707
708 let mut meta = buf.make_mut().meta_mut::<AnalyticsRelationMeta>().unwrap();
709 let _ = meta.add_tracking_mtd(10, gst::ClockTime::from_seconds(10));
710 let _ = meta.add_tracking_mtd(10, gst::ClockTime::from_seconds(10));
711
712 for mut item in meta.iter_mut::<AnalyticsTrackingMtd>() {
713 item.set_lost().unwrap();
714 }
715 }
716}