1use std::{mem, ops, path, ptr};
4
5use glib::translate::*;
6use gst::prelude::*;
7
8use crate::{ffi, TestClock};
9
10#[derive(Debug)]
11#[doc(alias = "GstHarness")]
12#[repr(transparent)]
13pub struct Harness(ptr::NonNull<ffi::GstHarness>);
14
15impl Drop for Harness {
16 #[inline]
17 fn drop(&mut self) {
18 unsafe {
19 ffi::gst_harness_teardown(self.0.as_ptr());
20 }
21 }
22}
23
24unsafe impl Send for Harness {}
25unsafe impl Sync for Harness {}
26
27impl Harness {
28 #[doc(alias = "gst_harness_add_element_full")]
29 pub fn add_element_full<P: IsA<gst::Element>>(
30 &mut self,
31 element: &P,
32 hsrc: Option<&gst::StaticPadTemplate>,
33 element_sinkpad_name: Option<&str>,
34 hsink: Option<&gst::StaticPadTemplate>,
35 element_srcpad_name: Option<&str>,
36 ) {
37 let element_sinkpad_name = element_sinkpad_name.to_glib_none();
38 let element_srcpad_name = element_srcpad_name.to_glib_none();
39 unsafe {
40 ffi::gst_harness_add_element_full(
41 self.0.as_ptr(),
42 element.as_ref().to_glib_none().0,
43 hsrc.to_glib_none().0 as *mut _,
44 element_sinkpad_name.0,
45 hsink.to_glib_none().0 as *mut _,
46 element_srcpad_name.0,
47 );
48 }
49 }
50
51 #[doc(alias = "gst_harness_add_element_sink_pad")]
52 pub fn add_element_sink_pad<P: IsA<gst::Pad>>(&mut self, sinkpad: &P) {
53 unsafe {
54 ffi::gst_harness_add_element_sink_pad(
55 self.0.as_ptr(),
56 sinkpad.as_ref().to_glib_none().0,
57 );
58 }
59 }
60
61 #[doc(alias = "gst_harness_add_element_src_pad")]
62 pub fn add_element_src_pad<P: IsA<gst::Pad>>(&mut self, srcpad: &P) {
63 unsafe {
64 ffi::gst_harness_add_element_src_pad(self.0.as_ptr(), srcpad.as_ref().to_glib_none().0);
65 }
66 }
67
68 #[doc(alias = "gst_harness_add_parse")]
69 pub fn add_parse(&mut self, launchline: &str) {
70 unsafe {
71 ffi::gst_harness_add_parse(self.0.as_ptr(), launchline.to_glib_none().0);
72 }
73 }
74
75 pub fn add_probe<F>(
76 &mut self,
77 element_name: &str,
78 pad_name: &str,
79 mask: gst::PadProbeType,
80 func: F,
81 ) where
82 F: Fn(&gst::Pad, &mut gst::PadProbeInfo) -> gst::PadProbeReturn + Send + Sync + 'static,
83 {
84 let element = self.find_element(element_name).expect("Element not found");
87 let pad = element.static_pad(pad_name).expect("Pad not found");
88 pad.add_probe(mask, func);
89 }
90
91 #[cfg(feature = "v1_16")]
92 #[cfg_attr(docsrs, doc(cfg(feature = "v1_16")))]
93 #[doc(alias = "gst_harness_add_propose_allocation_meta")]
94 pub fn add_propose_allocation_meta(
95 &mut self,
96 api: glib::types::Type,
97 params: Option<&gst::StructureRef>,
98 ) {
99 unsafe {
100 let params = params.map(|p| p.as_ptr()).unwrap_or(ptr::null_mut());
101 ffi::gst_harness_add_propose_allocation_meta(self.0.as_ptr(), api.into_glib(), params);
102 }
103 }
104
105 #[doc(alias = "gst_harness_add_sink")]
106 pub fn add_sink(&mut self, sink_element_name: &str) {
107 unsafe {
108 ffi::gst_harness_add_sink(self.0.as_ptr(), sink_element_name.to_glib_none().0);
109 }
110 }
111
112 #[doc(alias = "gst_harness_add_sink_harness")]
113 pub fn add_sink_harness(&mut self, sink_harness: Harness) {
114 unsafe {
115 let sink_harness = mem::ManuallyDrop::new(sink_harness);
116 ffi::gst_harness_add_sink_harness(self.0.as_ptr(), sink_harness.0.as_ptr());
117 }
118 }
119
120 #[doc(alias = "gst_harness_add_sink_parse")]
121 pub fn add_sink_parse(&mut self, launchline: &str) {
122 unsafe {
123 ffi::gst_harness_add_sink_parse(self.0.as_ptr(), launchline.to_glib_none().0);
124 }
125 }
126
127 #[doc(alias = "gst_harness_add_src")]
128 pub fn add_src(&mut self, src_element_name: &str, has_clock_wait: bool) {
129 unsafe {
130 ffi::gst_harness_add_src(
131 self.0.as_ptr(),
132 src_element_name.to_glib_none().0,
133 has_clock_wait.into_glib(),
134 );
135 }
136 }
137
138 #[doc(alias = "gst_harness_add_src_harness")]
139 pub fn add_src_harness(&mut self, src_harness: Harness, has_clock_wait: bool) {
140 unsafe {
141 let src_harness = mem::ManuallyDrop::new(src_harness);
142 ffi::gst_harness_add_src_harness(
143 self.0.as_ptr(),
144 src_harness.0.as_ptr(),
145 has_clock_wait.into_glib(),
146 );
147 }
148 }
149
150 #[doc(alias = "gst_harness_add_src_parse")]
151 pub fn add_src_parse(&mut self, launchline: &str, has_clock_wait: bool) {
152 unsafe {
153 ffi::gst_harness_add_src_parse(
154 self.0.as_ptr(),
155 launchline.to_glib_none().0,
156 has_clock_wait.into_glib(),
157 );
158 }
159 }
160
161 #[doc(alias = "gst_harness_buffers_in_queue")]
162 pub fn buffers_in_queue(&self) -> u32 {
163 unsafe { ffi::gst_harness_buffers_in_queue(self.0.as_ptr()) }
164 }
165
166 #[doc(alias = "gst_harness_buffers_received")]
167 pub fn buffers_received(&self) -> u32 {
168 unsafe { ffi::gst_harness_buffers_received(self.0.as_ptr()) }
169 }
170
171 #[doc(alias = "gst_harness_crank_multiple_clock_waits")]
172 pub fn crank_multiple_clock_waits(&mut self, waits: u32) -> Result<(), glib::BoolError> {
173 unsafe {
174 glib::result_from_gboolean!(
175 ffi::gst_harness_crank_multiple_clock_waits(self.0.as_ptr(), waits),
176 "Failed to crank multiple clock waits",
177 )
178 }
179 }
180
181 #[doc(alias = "gst_harness_crank_single_clock_wait")]
182 pub fn crank_single_clock_wait(&mut self) -> Result<(), glib::BoolError> {
183 unsafe {
184 glib::result_from_gboolean!(
185 ffi::gst_harness_crank_single_clock_wait(self.0.as_ptr()),
186 "Failed to crank single clock wait",
187 )
188 }
189 }
190
191 #[doc(alias = "gst_harness_create_buffer")]
192 pub fn create_buffer(&mut self, size: usize) -> Result<gst::Buffer, glib::BoolError> {
193 unsafe {
194 Option::<_>::from_glib_full(ffi::gst_harness_create_buffer(self.0.as_ptr(), size))
195 .ok_or_else(|| glib::bool_error!("Failed to create new buffer"))
196 }
197 }
198
199 #[doc(alias = "gst_harness_dump_to_file")]
200 pub fn dump_to_file(&mut self, filename: impl AsRef<path::Path>) {
201 let filename = filename.as_ref();
202 unsafe {
203 ffi::gst_harness_dump_to_file(self.0.as_ptr(), filename.to_glib_none().0);
204 }
205 }
206
207 #[doc(alias = "gst_harness_events_in_queue")]
208 pub fn events_in_queue(&self) -> u32 {
209 unsafe { ffi::gst_harness_events_in_queue(self.0.as_ptr()) }
210 }
211
212 #[doc(alias = "gst_harness_events_received")]
213 pub fn events_received(&self) -> u32 {
214 unsafe { ffi::gst_harness_events_received(self.0.as_ptr()) }
215 }
216
217 #[doc(alias = "gst_harness_find_element")]
218 pub fn find_element(&mut self, element_name: &str) -> Option<gst::Element> {
219 unsafe {
220 let ptr = ffi::gst_harness_find_element(self.0.as_ptr(), element_name.to_glib_none().0);
222
223 if ptr.is_null() {
224 return None;
225 }
226
227 if glib::gobject_ffi::g_object_is_floating(ptr as *mut _) != glib::ffi::GFALSE {
229 glib::gobject_ffi::g_object_ref_sink(ptr as *mut _);
230 }
231
232 from_glib_full(ptr)
233 }
234 }
235
236 #[doc(alias = "get_last_pushed_timestamp")]
245 #[doc(alias = "gst_harness_get_last_pushed_timestamp")]
246 pub fn last_pushed_timestamp(&self) -> Option<gst::ClockTime> {
247 unsafe { from_glib(ffi::gst_harness_get_last_pushed_timestamp(self.0.as_ptr())) }
248 }
249
250 #[doc(alias = "get_testclock")]
251 #[doc(alias = "gst_harness_get_testclock")]
252 pub fn testclock(&self) -> Option<TestClock> {
253 unsafe { from_glib_full(ffi::gst_harness_get_testclock(self.0.as_ptr())) }
254 }
255
256 #[doc(alias = "gst_harness_play")]
257 pub fn play(&mut self) {
258 unsafe {
259 ffi::gst_harness_play(self.0.as_ptr());
260 }
261 }
262
263 #[doc(alias = "gst_harness_pull")]
264 pub fn pull(&mut self) -> Result<gst::Buffer, glib::BoolError> {
265 unsafe {
266 Option::<_>::from_glib_full(ffi::gst_harness_pull(self.0.as_ptr()))
267 .ok_or_else(|| glib::bool_error!("Failed to pull buffer"))
268 }
269 }
270
271 #[cfg(feature = "v1_18")]
272 #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))]
273 #[doc(alias = "gst_harness_pull_until_eos")]
274 pub fn pull_until_eos(&mut self) -> Result<Option<gst::Buffer>, glib::BoolError> {
275 unsafe {
276 let mut buffer = ptr::null_mut();
277 let res = ffi::gst_harness_pull_until_eos(self.0.as_ptr(), &mut buffer);
278 if from_glib(res) {
279 Ok(from_glib_full(buffer))
280 } else {
281 Err(glib::bool_error!("Failed to pull buffer or EOS"))
282 }
283 }
284 }
285
286 #[doc(alias = "gst_harness_pull_event")]
287 pub fn pull_event(&mut self) -> Result<gst::Event, glib::BoolError> {
288 unsafe {
289 Option::<_>::from_glib_full(ffi::gst_harness_pull_event(self.0.as_ptr()))
290 .ok_or_else(|| glib::bool_error!("Failed to pull event"))
291 }
292 }
293
294 #[doc(alias = "gst_harness_pull_upstream_event")]
295 pub fn pull_upstream_event(&mut self) -> Result<gst::Event, glib::BoolError> {
296 unsafe {
297 Option::<_>::from_glib_full(ffi::gst_harness_pull_upstream_event(self.0.as_ptr()))
298 .ok_or_else(|| glib::bool_error!("Failed to pull event"))
299 }
300 }
301
302 #[doc(alias = "gst_harness_push")]
303 pub fn push(&mut self, buffer: gst::Buffer) -> Result<gst::FlowSuccess, gst::FlowError> {
304 unsafe {
305 try_from_glib(ffi::gst_harness_push(
306 self.0.as_ptr(),
307 buffer.into_glib_ptr(),
308 ))
309 }
310 }
311
312 #[doc(alias = "gst_harness_push_and_pull")]
313 pub fn push_and_pull(&mut self, buffer: gst::Buffer) -> Result<gst::Buffer, glib::BoolError> {
314 unsafe {
315 Option::<_>::from_glib_full(ffi::gst_harness_push_and_pull(
316 self.0.as_ptr(),
317 buffer.into_glib_ptr(),
318 ))
319 .ok_or_else(|| glib::bool_error!("Failed to push and pull buffer"))
320 }
321 }
322
323 #[doc(alias = "gst_harness_push_event")]
324 pub fn push_event(&mut self, event: gst::Event) -> bool {
325 unsafe {
326 from_glib(ffi::gst_harness_push_event(
327 self.0.as_ptr(),
328 event.into_glib_ptr(),
329 ))
330 }
331 }
332
333 #[doc(alias = "gst_harness_push_from_src")]
334 pub fn push_from_src(&mut self) -> Result<gst::FlowSuccess, gst::FlowError> {
335 unsafe { try_from_glib(ffi::gst_harness_push_from_src(self.0.as_ptr())) }
336 }
337
338 #[doc(alias = "gst_harness_push_to_sink")]
339 pub fn push_to_sink(&mut self) -> Result<gst::FlowSuccess, gst::FlowError> {
340 unsafe { try_from_glib(ffi::gst_harness_push_to_sink(self.0.as_ptr())) }
341 }
342
343 #[doc(alias = "gst_harness_push_upstream_event")]
344 pub fn push_upstream_event(&mut self, event: gst::Event) -> bool {
345 unsafe {
346 from_glib(ffi::gst_harness_push_upstream_event(
347 self.0.as_ptr(),
348 event.into_glib_ptr(),
349 ))
350 }
351 }
352
353 #[doc(alias = "gst_harness_query_latency")]
354 pub fn query_latency(&self) -> Option<gst::ClockTime> {
355 unsafe { from_glib(ffi::gst_harness_query_latency(self.0.as_ptr())) }
356 }
357
358 #[doc(alias = "gst_harness_set_blocking_push_mode")]
363 pub fn set_blocking_push_mode(&mut self) {
364 unsafe {
365 ffi::gst_harness_set_blocking_push_mode(self.0.as_ptr());
366 }
367 }
368
369 #[doc(alias = "gst_harness_set_caps")]
370 pub fn set_caps(&mut self, in_: gst::Caps, out: gst::Caps) {
371 unsafe {
372 ffi::gst_harness_set_caps(self.0.as_ptr(), in_.into_glib_ptr(), out.into_glib_ptr());
373 }
374 }
375
376 #[doc(alias = "gst_harness_set_caps_str")]
377 pub fn set_caps_str(&mut self, in_: &str, out: &str) {
378 unsafe {
379 ffi::gst_harness_set_caps_str(
380 self.0.as_ptr(),
381 in_.to_glib_none().0,
382 out.to_glib_none().0,
383 );
384 }
385 }
386
387 #[doc(alias = "gst_harness_set_drop_buffers")]
388 pub fn set_drop_buffers(&mut self, drop_buffers: bool) {
389 unsafe {
390 ffi::gst_harness_set_drop_buffers(self.0.as_ptr(), drop_buffers.into_glib());
391 }
392 }
393
394 #[doc(alias = "gst_harness_set_forwarding")]
395 pub fn set_forwarding(&mut self, forwarding: bool) {
396 unsafe {
397 ffi::gst_harness_set_forwarding(self.0.as_ptr(), forwarding.into_glib());
398 }
399 }
400
401 #[doc(alias = "gst_harness_set_live")]
402 #[cfg(feature = "v1_20")]
403 #[cfg_attr(docsrs, doc(cfg(feature = "v1_20")))]
404 pub fn set_live(&mut self, is_live: bool) {
405 unsafe { ffi::gst_harness_set_live(self.0.as_ptr(), is_live.into_glib()) }
406 }
407
408 #[doc(alias = "gst_harness_set_sink_caps")]
413 pub fn set_sink_caps(&mut self, caps: gst::Caps) {
414 unsafe {
415 ffi::gst_harness_set_sink_caps(self.0.as_ptr(), caps.into_glib_ptr());
416 }
417 }
418
419 #[doc(alias = "gst_harness_set_sink_caps_str")]
420 pub fn set_sink_caps_str(&mut self, str: &str) {
421 unsafe {
422 ffi::gst_harness_set_sink_caps_str(self.0.as_ptr(), str.to_glib_none().0);
423 }
424 }
425
426 #[doc(alias = "gst_harness_set_src_caps")]
427 pub fn set_src_caps(&mut self, caps: gst::Caps) {
428 unsafe {
429 ffi::gst_harness_set_src_caps(self.0.as_ptr(), caps.into_glib_ptr());
430 }
431 }
432
433 #[doc(alias = "gst_harness_set_src_caps_str")]
434 pub fn set_src_caps_str(&mut self, str: &str) {
435 unsafe {
436 ffi::gst_harness_set_src_caps_str(self.0.as_ptr(), str.to_glib_none().0);
437 }
438 }
439
440 #[doc(alias = "gst_harness_set_time")]
441 pub fn set_time(&mut self, time: gst::ClockTime) -> Result<(), glib::BoolError> {
442 unsafe {
443 glib::result_from_gboolean!(
444 ffi::gst_harness_set_time(self.0.as_ptr(), time.into_glib()),
445 "Failed to set time",
446 )
447 }
448 }
449
450 #[doc(alias = "gst_harness_set_upstream_latency")]
451 pub fn set_upstream_latency(&mut self, latency: gst::ClockTime) {
452 unsafe {
453 ffi::gst_harness_set_upstream_latency(self.0.as_ptr(), latency.into_glib());
454 }
455 }
456
457 #[doc(alias = "gst_harness_sink_push_many")]
458 pub fn sink_push_many(&mut self, pushes: u32) -> Result<gst::FlowSuccess, gst::FlowError> {
459 unsafe {
460 try_from_glib(ffi::gst_harness_sink_push_many(
461 self.0.as_ptr(),
462 pushes as i32,
463 ))
464 }
465 }
466
467 #[doc(alias = "gst_harness_src_crank_and_push_many")]
468 pub fn src_crank_and_push_many(
469 &mut self,
470 cranks: u32,
471 pushes: u32,
472 ) -> Result<gst::FlowSuccess, gst::FlowError> {
473 unsafe {
474 try_from_glib(ffi::gst_harness_src_crank_and_push_many(
475 self.0.as_ptr(),
476 cranks as i32,
477 pushes as i32,
478 ))
479 }
480 }
481
482 #[doc(alias = "gst_harness_src_push_event")]
483 pub fn src_push_event(&mut self) -> bool {
484 unsafe { from_glib(ffi::gst_harness_src_push_event(self.0.as_ptr())) }
485 }
486
487 #[doc(alias = "gst_harness_take_all_data_as_buffer")]
528 pub fn take_all_data_as_buffer(&mut self) -> Result<gst::Buffer, glib::BoolError> {
529 unsafe {
530 Option::<_>::from_glib_full(ffi::gst_harness_take_all_data_as_buffer(self.0.as_ptr()))
531 .ok_or_else(|| glib::bool_error!("Failed to take all data as buffer"))
532 }
533 }
534
535 #[doc(alias = "gst_harness_take_all_data_as_bytes")]
536 pub fn take_all_data_as_bytes(&mut self) -> Result<glib::Bytes, glib::BoolError> {
537 unsafe {
538 Option::<_>::from_glib_full(ffi::gst_harness_take_all_data_as_bytes(self.0.as_ptr()))
539 .ok_or_else(|| glib::bool_error!("Failed to take all data as bytes"))
540 }
541 }
542
543 #[doc(alias = "gst_harness_try_pull")]
544 pub fn try_pull(&mut self) -> Option<gst::Buffer> {
545 unsafe { from_glib_full(ffi::gst_harness_try_pull(self.0.as_ptr())) }
546 }
547
548 #[doc(alias = "gst_harness_try_pull_event")]
549 pub fn try_pull_event(&mut self) -> Option<gst::Event> {
550 unsafe { from_glib_full(ffi::gst_harness_try_pull_event(self.0.as_ptr())) }
551 }
552
553 #[doc(alias = "gst_harness_try_pull_upstream_event")]
554 pub fn try_pull_upstream_event(&mut self) -> Option<gst::Event> {
555 unsafe { from_glib_full(ffi::gst_harness_try_pull_upstream_event(self.0.as_ptr())) }
556 }
557
558 #[doc(alias = "gst_harness_upstream_events_in_queue")]
559 pub fn upstream_events_in_queue(&self) -> u32 {
560 unsafe { ffi::gst_harness_upstream_events_in_queue(self.0.as_ptr()) }
561 }
562
563 #[doc(alias = "gst_harness_upstream_events_received")]
564 pub fn upstream_events_received(&self) -> u32 {
565 unsafe { ffi::gst_harness_upstream_events_received(self.0.as_ptr()) }
566 }
567
568 #[doc(alias = "gst_harness_use_systemclock")]
569 pub fn use_systemclock(&mut self) {
570 unsafe {
571 ffi::gst_harness_use_systemclock(self.0.as_ptr());
572 }
573 }
574
575 #[doc(alias = "gst_harness_use_testclock")]
576 pub fn use_testclock(&mut self) {
577 unsafe {
578 ffi::gst_harness_use_testclock(self.0.as_ptr());
579 }
580 }
581
582 #[doc(alias = "gst_harness_wait_for_clock_id_waits")]
583 pub fn wait_for_clock_id_waits(
584 &mut self,
585 waits: u32,
586 timeout: u32,
587 ) -> Result<(), glib::BoolError> {
588 unsafe {
589 glib::result_from_gboolean!(
590 ffi::gst_harness_wait_for_clock_id_waits(self.0.as_ptr(), waits, timeout),
591 "Failed to wait for clock id waits",
592 )
593 }
594 }
595
596 #[inline]
597 unsafe fn from_glib_full(ptr: *mut ffi::GstHarness) -> Harness {
598 debug_assert!(!ptr.is_null());
599
600 Harness(ptr::NonNull::new_unchecked(ptr))
601 }
602
603 #[doc(alias = "gst_harness_new")]
604 pub fn new(element_name: &str) -> Harness {
605 assert_initialized_main_thread!();
606 unsafe { Self::from_glib_full(ffi::gst_harness_new(element_name.to_glib_none().0)) }
607 }
608
609 #[doc(alias = "gst_harness_new_empty")]
610 pub fn new_empty() -> Harness {
611 assert_initialized_main_thread!();
612 unsafe { Self::from_glib_full(ffi::gst_harness_new_empty()) }
613 }
614
615 #[doc(alias = "gst_harness_new_full")]
616 pub fn new_full<P: IsA<gst::Element>>(
617 element: &P,
618 hsrc: Option<&gst::StaticPadTemplate>,
619 element_sinkpad_name: Option<&str>,
620 hsink: Option<&gst::StaticPadTemplate>,
621 element_srcpad_name: Option<&str>,
622 ) -> Harness {
623 assert_initialized_main_thread!();
624 let element_sinkpad_name = element_sinkpad_name.to_glib_none();
625 let element_srcpad_name = element_srcpad_name.to_glib_none();
626 unsafe {
627 Self::from_glib_full(ffi::gst_harness_new_full(
628 element.as_ref().to_glib_none().0,
629 hsrc.to_glib_none().0 as *mut _,
630 element_sinkpad_name.0,
631 hsink.to_glib_none().0 as *mut _,
632 element_srcpad_name.0,
633 ))
634 }
635 }
636
637 #[doc(alias = "gst_harness_new_parse")]
638 pub fn new_parse(launchline: &str) -> Harness {
639 assert_initialized_main_thread!();
640 unsafe { Self::from_glib_full(ffi::gst_harness_new_parse(launchline.to_glib_none().0)) }
641 }
642
643 #[doc(alias = "gst_harness_new_with_element")]
644 pub fn with_element<P: IsA<gst::Element>>(
645 element: &P,
646 element_sinkpad_name: Option<&str>,
647 element_srcpad_name: Option<&str>,
648 ) -> Harness {
649 skip_assert_initialized!();
650 let element_sinkpad_name = element_sinkpad_name.to_glib_none();
651 let element_srcpad_name = element_srcpad_name.to_glib_none();
652 unsafe {
653 Self::from_glib_full(ffi::gst_harness_new_with_element(
654 element.as_ref().to_glib_none().0,
655 element_sinkpad_name.0,
656 element_srcpad_name.0,
657 ))
658 }
659 }
660
661 #[doc(alias = "gst_harness_new_with_padnames")]
662 pub fn with_padnames(
663 element_name: &str,
664 element_sinkpad_name: Option<&str>,
665 element_srcpad_name: Option<&str>,
666 ) -> Harness {
667 assert_initialized_main_thread!();
668 let element_sinkpad_name = element_sinkpad_name.to_glib_none();
669 let element_srcpad_name = element_srcpad_name.to_glib_none();
670 unsafe {
671 Self::from_glib_full(ffi::gst_harness_new_with_padnames(
672 element_name.to_glib_none().0,
673 element_sinkpad_name.0,
674 element_srcpad_name.0,
675 ))
676 }
677 }
678
679 #[doc(alias = "gst_harness_new_with_templates")]
680 pub fn with_templates(
681 element_name: &str,
682 hsrc: Option<&gst::StaticPadTemplate>,
683 hsink: Option<&gst::StaticPadTemplate>,
684 ) -> Harness {
685 assert_initialized_main_thread!();
686 unsafe {
687 Self::from_glib_full(ffi::gst_harness_new_with_templates(
688 element_name.to_glib_none().0,
689 hsrc.to_glib_none().0 as *mut _,
690 hsink.to_glib_none().0 as *mut _,
691 ))
692 }
693 }
694
695 #[doc(alias = "get_element")]
700 pub fn element(&self) -> Option<gst::Element> {
701 unsafe {
702 let ptr = (*self.0.as_ptr()).element;
704
705 if ptr.is_null() {
706 return None;
707 }
708
709 if glib::gobject_ffi::g_object_is_floating(ptr as *mut _) != glib::ffi::GFALSE {
711 glib::gobject_ffi::g_object_ref_sink(ptr as *mut _);
712 }
713
714 from_glib_none(ptr)
715 }
716 }
717
718 #[doc(alias = "get_sinkpad")]
719 pub fn sinkpad(&self) -> Option<gst::Pad> {
720 unsafe {
721 let ptr = (*self.0.as_ptr()).sinkpad;
723
724 if ptr.is_null() {
725 return None;
726 }
727
728 if glib::gobject_ffi::g_object_is_floating(ptr as *mut _) != glib::ffi::GFALSE {
730 glib::gobject_ffi::g_object_ref_sink(ptr as *mut _);
731 }
732
733 from_glib_none(ptr)
734 }
735 }
736
737 #[doc(alias = "get_srcpad")]
738 pub fn srcpad(&self) -> Option<gst::Pad> {
739 unsafe {
740 let ptr = (*self.0.as_ptr()).srcpad;
742
743 if ptr.is_null() {
744 return None;
745 }
746
747 if glib::gobject_ffi::g_object_is_floating(ptr as *mut _) != glib::ffi::GFALSE {
749 glib::gobject_ffi::g_object_ref_sink(ptr as *mut _);
750 }
751
752 from_glib_none(ptr)
753 }
754 }
755
756 #[doc(alias = "get_sink_harness")]
757 pub fn sink_harness(&self) -> Option<Ref<'_>> {
758 unsafe {
759 if (*self.0.as_ptr()).sink_harness.is_null() {
760 None
761 } else {
762 Some(Ref(
763 &*((&(*self.0.as_ptr()).sink_harness) as *const *mut ffi::GstHarness
764 as *const Harness),
765 ))
766 }
767 }
768 }
769
770 #[doc(alias = "get_src_harness")]
771 pub fn src_harness(&self) -> Option<Ref<'_>> {
772 unsafe {
773 if (*self.0.as_ptr()).src_harness.is_null() {
774 None
775 } else {
776 Some(Ref(
777 &*((&(*self.0.as_ptr()).src_harness) as *const *mut ffi::GstHarness
778 as *const Harness),
779 ))
780 }
781 }
782 }
783
784 #[doc(alias = "get_mut_sink_harness")]
785 pub fn sink_harness_mut(&mut self) -> Option<RefMut<'_>> {
786 unsafe {
787 if (*self.0.as_ptr()).sink_harness.is_null() {
788 None
789 } else {
790 Some(RefMut(
791 &mut *((&mut (*self.0.as_ptr()).sink_harness) as *mut *mut ffi::GstHarness
792 as *mut Harness),
793 ))
794 }
795 }
796 }
797
798 #[doc(alias = "get_mut_src_harness")]
799 pub fn src_harness_mut(&mut self) -> Option<RefMut<'_>> {
800 unsafe {
801 if (*self.0.as_ptr()).src_harness.is_null() {
802 None
803 } else {
804 Some(RefMut(
805 &mut *((&mut (*self.0.as_ptr()).src_harness) as *mut *mut ffi::GstHarness
806 as *mut Harness),
807 ))
808 }
809 }
810 }
811}
812
813#[derive(Debug)]
814pub struct Ref<'a>(&'a Harness);
815
816impl ops::Deref for Ref<'_> {
817 type Target = Harness;
818
819 #[inline]
820 fn deref(&self) -> &Harness {
821 self.0
822 }
823}
824
825#[derive(Debug)]
826pub struct RefMut<'a>(&'a mut Harness);
827
828impl ops::Deref for RefMut<'_> {
829 type Target = Harness;
830
831 #[inline]
832 fn deref(&self) -> &Harness {
833 self.0
834 }
835}
836
837impl ops::DerefMut for RefMut<'_> {
838 #[inline]
839 fn deref_mut(&mut self) -> &mut Harness {
840 self.0
841 }
842}
843
844#[cfg(test)]
845mod tests {
846 use super::*;
847
848 #[test]
849 fn test_identity_push_pull() {
850 gst::init().unwrap();
851
852 let mut h = Harness::new("identity");
853 h.set_src_caps_str("application/test");
854 let buf = gst::Buffer::new();
855 let buf = h.push_and_pull(buf);
856 assert!(buf.is_ok());
857 }
858}