1use std::mem;
10use std::ptr;
11
12use glib_ffi;
13use gobject_ffi;
14use gst_base_ffi;
15use gst_ffi;
16
17use glib;
18use glib::translate::*;
19use gst;
20use gst::prelude::*;
21use gst_base;
22
23use gobject_subclass::anyimpl::*;
24use gobject_subclass::object::*;
25
26use element::*;
27use object::*;
28
29pub trait BaseSrcImpl<T: BaseSrcBase>:
30 AnyImpl + ObjectImpl<T> + ElementImpl<T> + Send + Sync + 'static
31where
32 T::InstanceStructType: PanicPoison,
33{
34 fn start(&self, _element: &T) -> bool {
35 true
36 }
37
38 fn stop(&self, _element: &T) -> bool {
39 true
40 }
41
42 fn is_seekable(&self, _element: &T) -> bool {
43 false
44 }
45
46 fn get_size(&self, _element: &T) -> Option<u64> {
47 None
48 }
49
50 fn fill(
51 &self,
52 _element: &T,
53 _offset: u64,
54 _length: u32,
55 _buffer: &mut gst::BufferRef,
56 ) -> gst::FlowReturn {
57 unimplemented!()
58 }
59
60 fn create(
61 &self,
62 element: &T,
63 offset: u64,
64 length: u32,
65 ) -> Result<gst::Buffer, gst::FlowReturn> {
66 element.parent_create(offset, length)
67 }
68
69 fn do_seek(&self, element: &T, segment: &mut gst::Segment) -> bool {
70 element.parent_do_seek(segment)
71 }
72
73 fn query(&self, element: &T, query: &mut gst::QueryRef) -> bool {
74 element.parent_query(query)
75 }
76
77 fn event(&self, element: &T, event: &gst::Event) -> bool {
78 element.parent_event(event)
79 }
80
81 fn get_caps(&self, element: &T, filter: Option<&gst::CapsRef>) -> Option<gst::Caps> {
82 element.parent_get_caps(filter)
83 }
84
85 fn negotiate(&self, element: &T) -> bool {
86 element.parent_negotiate()
87 }
88
89 fn set_caps(&self, element: &T, caps: &gst::CapsRef) -> bool {
90 element.parent_set_caps(caps)
91 }
92
93 fn fixate(&self, element: &T, caps: gst::Caps) -> gst::Caps {
94 element.parent_fixate(caps)
95 }
96
97 fn unlock(&self, _element: &T) -> bool {
98 true
99 }
100
101 fn unlock_stop(&self, _element: &T) -> bool {
102 true
103 }
104}
105
106any_impl!(BaseSrcBase, BaseSrcImpl, PanicPoison);
107
108pub unsafe trait BaseSrcBase:
109 IsA<gst::Element> + IsA<gst_base::BaseSrc> + ObjectType
110{
111 fn parent_create(&self, offset: u64, length: u32) -> Result<gst::Buffer, gst::FlowReturn> {
112 unsafe {
113 let klass = self.get_class();
114 let parent_klass = (*klass).get_parent_class() as *const gst_base_ffi::GstBaseSrcClass;
115 (*parent_klass)
116 .create
117 .map(|f| {
118 let mut buffer: *mut gst_ffi::GstBuffer = ptr::null_mut();
119 let buffer_ref = &mut buffer as *mut _ as *mut gst_ffi::GstBuffer;
122 match from_glib(f(self.to_glib_none().0, offset, length, buffer_ref)) {
123 gst::FlowReturn::Ok => Ok(from_glib_full(buffer)),
124 ret => Err(ret),
125 }
126 })
127 .unwrap_or(Err(gst::FlowReturn::Error))
128 }
129 }
130
131 fn parent_do_seek(&self, segment: &mut gst::Segment) -> bool {
132 unsafe {
133 let klass = self.get_class();
134 let parent_klass = (*klass).get_parent_class() as *const gst_base_ffi::GstBaseSrcClass;
135 (*parent_klass)
136 .do_seek
137 .map(|f| from_glib(f(self.to_glib_none().0, segment.to_glib_none_mut().0)))
138 .unwrap_or(false)
139 }
140 }
141
142 fn parent_query(&self, query: &mut gst::QueryRef) -> bool {
143 unsafe {
144 let klass = self.get_class();
145 let parent_klass = (*klass).get_parent_class() as *const gst_base_ffi::GstBaseSrcClass;
146 (*parent_klass)
147 .query
148 .map(|f| from_glib(f(self.to_glib_none().0, query.as_mut_ptr())))
149 .unwrap_or(false)
150 }
151 }
152
153 fn parent_event(&self, event: &gst::Event) -> bool {
154 unsafe {
155 let klass = self.get_class();
156 let parent_klass = (*klass).get_parent_class() as *const gst_base_ffi::GstBaseSrcClass;
157 (*parent_klass)
158 .event
159 .map(|f| from_glib(f(self.to_glib_none().0, event.to_glib_none().0)))
160 .unwrap_or(false)
161 }
162 }
163
164 fn parent_get_caps(&self, filter: Option<&gst::CapsRef>) -> Option<gst::Caps> {
165 unsafe {
166 let klass = self.get_class();
167 let parent_klass = (*klass).get_parent_class() as *const gst_base_ffi::GstBaseSrcClass;
168 let filter_ptr = if let Some(filter) = filter {
169 filter.as_mut_ptr()
170 } else {
171 ptr::null_mut()
172 };
173
174 (*parent_klass)
175 .get_caps
176 .map(|f| from_glib_full(f(self.to_glib_none().0, filter_ptr)))
177 .unwrap_or(None)
178 }
179 }
180
181 fn parent_negotiate(&self) -> bool {
182 unsafe {
183 let klass = self.get_class();
184 let parent_klass = (*klass).get_parent_class() as *const gst_base_ffi::GstBaseSrcClass;
185 (*parent_klass)
186 .negotiate
187 .map(|f| from_glib(f(self.to_glib_none().0)))
188 .unwrap_or(false)
189 }
190 }
191
192 fn parent_set_caps(&self, caps: &gst::CapsRef) -> bool {
193 unsafe {
194 let klass = self.get_class();
195 let parent_klass = (*klass).get_parent_class() as *const gst_base_ffi::GstBaseSrcClass;
196 (*parent_klass)
197 .set_caps
198 .map(|f| from_glib(f(self.to_glib_none().0, caps.as_mut_ptr())))
199 .unwrap_or(true)
200 }
201 }
202
203 fn parent_fixate(&self, caps: gst::Caps) -> gst::Caps {
204 unsafe {
205 let klass = self.get_class();
206 let parent_klass = (*klass).get_parent_class() as *const gst_base_ffi::GstBaseSrcClass;
207
208 match (*parent_klass).fixate {
209 Some(fixate) => from_glib_full(fixate(self.to_glib_none().0, caps.into_ptr())),
210 None => caps,
211 }
212 }
213 }
214}
215
216pub unsafe trait BaseSrcClassExt<T: BaseSrcBase>
217where
218 T::ImplType: BaseSrcImpl<T>,
219 T::InstanceStructType: PanicPoison,
220{
221 fn override_vfuncs(&mut self, _: &ClassInitToken) {
222 unsafe {
223 let klass = &mut *(self as *const Self as *mut gst_base_ffi::GstBaseSrcClass);
224 klass.start = Some(base_src_start::<T>);
225 klass.stop = Some(base_src_stop::<T>);
226 klass.is_seekable = Some(base_src_is_seekable::<T>);
227 klass.get_size = Some(base_src_get_size::<T>);
228 klass.fill = Some(base_src_fill::<T>);
229 klass.create = Some(base_src_create::<T>);
230 klass.do_seek = Some(base_src_do_seek::<T>);
231 klass.query = Some(base_src_query::<T>);
232 klass.event = Some(base_src_event::<T>);
233 klass.get_caps = Some(base_src_get_caps::<T>);
234 klass.negotiate = Some(base_src_negotiate::<T>);
235 klass.set_caps = Some(base_src_set_caps::<T>);
236 klass.fixate = Some(base_src_fixate::<T>);
237 klass.unlock = Some(base_src_unlock::<T>);
238 klass.unlock_stop = Some(base_src_unlock_stop::<T>);
239 }
240 }
241}
242
243glib_wrapper! {
244 pub struct BaseSrc(Object<ElementInstanceStruct<BaseSrc>>):
245 [gst_base::BaseSrc => gst_base_ffi::GstBaseSrc,
246 gst::Element => gst_ffi::GstElement,
247 gst::Object => gst_ffi::GstObject];
248
249 match fn {
250 get_type => || get_type::<BaseSrc>(),
251 }
252}
253
254unsafe impl<T: IsA<gst::Element> + IsA<gst_base::BaseSrc> + ObjectType> BaseSrcBase for T {}
255pub type BaseSrcClass = ClassStruct<BaseSrc>;
256
257unsafe impl BaseSrcClassExt<BaseSrc> for BaseSrcClass {}
259unsafe impl ElementClassExt<BaseSrc> for BaseSrcClass {}
260unsafe impl ObjectClassExt<BaseSrc> for BaseSrcClass {}
261
262unsafe impl Send for BaseSrc {}
263unsafe impl Sync for BaseSrc {}
264
265#[macro_export]
266macro_rules! box_base_src_impl(
267 ($name:ident) => {
268 box_element_impl!($name);
269
270 impl<T: BaseSrcBase> BaseSrcImpl<T> for Box<$name<T>>
271 where
272 T::InstanceStructType: PanicPoison
273 {
274 fn start(&self, element: &T) -> bool {
275 let imp: &$name<T> = self.as_ref();
276 imp.start(element)
277 }
278
279 fn stop(&self, element: &T) -> bool {
280 let imp: &$name<T> = self.as_ref();
281 imp.stop(element)
282 }
283
284 fn is_seekable(&self, element: &T) -> bool {
285 let imp: &$name<T> = self.as_ref();
286 imp.is_seekable(element)
287 }
288
289 fn get_size(&self, element: &T) -> Option<u64> {
290 let imp: &$name<T> = self.as_ref();
291 imp.get_size(element)
292 }
293
294 fn fill(
295 &self,
296 element: &T,
297 offset: u64,
298 length: u32,
299 buffer: &mut gst::BufferRef,
300 ) -> gst::FlowReturn {
301 let imp: &$name<T> = self.as_ref();
302 imp.fill(element, offset, length, buffer)
303 }
304
305 fn create(
306 &self,
307 element: &T,
308 offset: u64,
309 length: u32,
310 ) -> Result<gst::Buffer, gst::FlowReturn> {
311 let imp: &$name<T> = self.as_ref();
312 imp.create(element, offset, length)
313 }
314
315 fn do_seek(&self, element: &T, segment: &mut gst::Segment) -> bool {
316 let imp: &$name<T> = self.as_ref();
317 imp.do_seek(element, segment)
318 }
319
320 fn query(&self, element: &T, query: &mut gst::QueryRef) -> bool {
321 let imp: &$name<T> = self.as_ref();
322 BaseSrcImpl::query(imp, element, query)
323 }
324
325 fn event(&self, element: &T, event: &gst::Event) -> bool {
326 let imp: &$name<T> = self.as_ref();
327 imp.event(element, event)
328 }
329
330 fn get_caps(&self, element: &T, filter: Option<&gst::CapsRef>) -> Option<gst::Caps> {
331 let imp: &$name<T> = self.as_ref();
332 imp.get_caps(element, filter)
333 }
334
335 fn negotiate(&self, element: &T) -> bool {
336 let imp: &$name<T> = self.as_ref();
337 imp.negotiate(element)
338 }
339
340 fn set_caps(&self, element: &T, caps: &gst::CapsRef) -> bool {
341 let imp: &$name<T> = self.as_ref();
342 imp.set_caps(element, caps)
343 }
344
345 fn fixate(&self, element: &T, caps: gst::Caps) -> gst::Caps {
346 let imp: &$name<T> = self.as_ref();
347 imp.fixate(element, caps)
348 }
349
350 fn unlock(&self, element: &T) -> bool {
351 let imp: &$name<T> = self.as_ref();
352 imp.unlock(element)
353 }
354
355 fn unlock_stop(&self, element: &T) -> bool {
356 let imp: &$name<T> = self.as_ref();
357 imp.unlock_stop(element)
358 }
359 }
360 };
361);
362box_base_src_impl!(BaseSrcImpl);
363
364impl ObjectType for BaseSrc {
365 const NAME: &'static str = "RsBaseSrc";
366 type ParentType = gst_base::BaseSrc;
367 type ImplType = Box<BaseSrcImpl<Self>>;
368 type InstanceStructType = ElementInstanceStruct<Self>;
369
370 fn class_init(token: &ClassInitToken, klass: &mut BaseSrcClass) {
371 ObjectClassExt::override_vfuncs(klass, token);
372 ElementClassExt::override_vfuncs(klass, token);
373 BaseSrcClassExt::override_vfuncs(klass, token);
374 }
375
376 object_type_fns!();
377}
378
379unsafe extern "C" fn base_src_start<T: BaseSrcBase>(
380 ptr: *mut gst_base_ffi::GstBaseSrc,
381) -> glib_ffi::gboolean
382where
383 T::ImplType: BaseSrcImpl<T>,
384 T::InstanceStructType: PanicPoison,
385{
386 floating_reference_guard!(ptr);
387 let element = &*(ptr as *mut T::InstanceStructType);
388 let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType);
389 let imp = element.get_impl();
390
391 panic_to_error!(&wrap, &element.panicked(), false, { imp.start(&wrap) }).to_glib()
392}
393
394unsafe extern "C" fn base_src_stop<T: BaseSrcBase>(
395 ptr: *mut gst_base_ffi::GstBaseSrc,
396) -> glib_ffi::gboolean
397where
398 T::ImplType: BaseSrcImpl<T>,
399 T::InstanceStructType: PanicPoison,
400{
401 floating_reference_guard!(ptr);
402 let element = &*(ptr as *mut T::InstanceStructType);
403 let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType);
404 let imp = element.get_impl();
405
406 panic_to_error!(&wrap, &element.panicked(), false, { imp.stop(&wrap) }).to_glib()
407}
408
409unsafe extern "C" fn base_src_is_seekable<T: BaseSrcBase>(
410 ptr: *mut gst_base_ffi::GstBaseSrc,
411) -> glib_ffi::gboolean
412where
413 T::ImplType: BaseSrcImpl<T>,
414 T::InstanceStructType: PanicPoison,
415{
416 floating_reference_guard!(ptr);
417 let element = &*(ptr as *mut T::InstanceStructType);
418 let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType);
419 let imp = element.get_impl();
420
421 panic_to_error!(&wrap, &element.panicked(), false, {
422 imp.is_seekable(&wrap)
423 })
424 .to_glib()
425}
426
427unsafe extern "C" fn base_src_get_size<T: BaseSrcBase>(
428 ptr: *mut gst_base_ffi::GstBaseSrc,
429 size: *mut u64,
430) -> glib_ffi::gboolean
431where
432 T::ImplType: BaseSrcImpl<T>,
433 T::InstanceStructType: PanicPoison,
434{
435 floating_reference_guard!(ptr);
436 let element = &*(ptr as *mut T::InstanceStructType);
437 let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType);
438 let imp = element.get_impl();
439
440 panic_to_error!(&wrap, &element.panicked(), false, {
441 match imp.get_size(&wrap) {
442 Some(s) => {
443 *size = s;
444 true
445 }
446 None => false,
447 }
448 })
449 .to_glib()
450}
451
452unsafe extern "C" fn base_src_fill<T: BaseSrcBase>(
453 ptr: *mut gst_base_ffi::GstBaseSrc,
454 offset: u64,
455 length: u32,
456 buffer: *mut gst_ffi::GstBuffer,
457) -> gst_ffi::GstFlowReturn
458where
459 T::ImplType: BaseSrcImpl<T>,
460 T::InstanceStructType: PanicPoison,
461{
462 floating_reference_guard!(ptr);
463 let element = &*(ptr as *mut T::InstanceStructType);
464 let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType);
465 let imp = element.get_impl();
466 let buffer = gst::BufferRef::from_mut_ptr(buffer);
467
468 panic_to_error!(&wrap, &element.panicked(), gst::FlowReturn::Error, {
469 imp.fill(&wrap, offset, length, buffer)
470 })
471 .to_glib()
472}
473
474unsafe extern "C" fn base_src_create<T: BaseSrcBase>(
475 ptr: *mut gst_base_ffi::GstBaseSrc,
476 offset: u64,
477 length: u32,
478 buffer_ptr: *mut gst_ffi::GstBuffer,
479) -> gst_ffi::GstFlowReturn
480where
481 T::ImplType: BaseSrcImpl<T>,
482 T::InstanceStructType: PanicPoison,
483{
484 floating_reference_guard!(ptr);
485 let element = &*(ptr as *mut T::InstanceStructType);
486 let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType);
487 let imp = element.get_impl();
488 let buffer_ptr = buffer_ptr as *mut *mut gst_ffi::GstBuffer;
491
492 panic_to_error!(&wrap, &element.panicked(), gst::FlowReturn::Error, {
493 match imp.create(&wrap, offset, length) {
494 Ok(buffer) => {
495 *buffer_ptr = buffer.into_ptr();
496 gst::FlowReturn::Ok
497 }
498 Err(err) => err,
499 }
500 })
501 .to_glib()
502}
503
504unsafe extern "C" fn base_src_do_seek<T: BaseSrcBase>(
505 ptr: *mut gst_base_ffi::GstBaseSrc,
506 segment: *mut gst_ffi::GstSegment,
507) -> glib_ffi::gboolean
508where
509 T::ImplType: BaseSrcImpl<T>,
510 T::InstanceStructType: PanicPoison,
511{
512 floating_reference_guard!(ptr);
513 let element = &*(ptr as *mut T::InstanceStructType);
514 let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType);
515 let imp = element.get_impl();
516
517 panic_to_error!(&wrap, &element.panicked(), false, {
518 imp.do_seek(&wrap, &mut from_glib_borrow(segment))
519 })
520 .to_glib()
521}
522
523unsafe extern "C" fn base_src_query<T: BaseSrcBase>(
524 ptr: *mut gst_base_ffi::GstBaseSrc,
525 query_ptr: *mut gst_ffi::GstQuery,
526) -> glib_ffi::gboolean
527where
528 T::ImplType: BaseSrcImpl<T>,
529 T::InstanceStructType: PanicPoison,
530{
531 floating_reference_guard!(ptr);
532 let element = &*(ptr as *mut T::InstanceStructType);
533 let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType);
534 let imp = element.get_impl();
535 let query = gst::QueryRef::from_mut_ptr(query_ptr);
536
537 panic_to_error!(&wrap, &element.panicked(), false, {
538 BaseSrcImpl::query(imp, &wrap, query)
539 })
540 .to_glib()
541}
542
543unsafe extern "C" fn base_src_event<T: BaseSrcBase>(
544 ptr: *mut gst_base_ffi::GstBaseSrc,
545 event_ptr: *mut gst_ffi::GstEvent,
546) -> glib_ffi::gboolean
547where
548 T::ImplType: BaseSrcImpl<T>,
549 T::InstanceStructType: PanicPoison,
550{
551 floating_reference_guard!(ptr);
552 let element = &*(ptr as *mut T::InstanceStructType);
553 let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType);
554 let imp = element.get_impl();
555
556 panic_to_error!(&wrap, &element.panicked(), false, {
557 imp.event(&wrap, &from_glib_borrow(event_ptr))
558 })
559 .to_glib()
560}
561
562unsafe extern "C" fn base_src_get_caps<T: BaseSrcBase>(
563 ptr: *mut gst_base_ffi::GstBaseSrc,
564 filter: *mut gst_ffi::GstCaps,
565) -> *mut gst_ffi::GstCaps
566where
567 T::ImplType: BaseSrcImpl<T>,
568 T::InstanceStructType: PanicPoison,
569{
570 floating_reference_guard!(ptr);
571 let element = &*(ptr as *mut T::InstanceStructType);
572 let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType);
573 let imp = element.get_impl();
574 let filter = if filter.is_null() {
575 None
576 } else {
577 Some(gst::CapsRef::from_ptr(filter))
578 };
579
580 panic_to_error!(&wrap, &element.panicked(), None, {
581 imp.get_caps(&wrap, filter)
582 })
583 .map(|caps| caps.into_ptr())
584 .unwrap_or(ptr::null_mut())
585}
586
587unsafe extern "C" fn base_src_negotiate<T: BaseSrcBase>(
588 ptr: *mut gst_base_ffi::GstBaseSrc,
589) -> glib_ffi::gboolean
590where
591 T::ImplType: BaseSrcImpl<T>,
592 T::InstanceStructType: PanicPoison,
593{
594 floating_reference_guard!(ptr);
595 let element = &*(ptr as *mut T::InstanceStructType);
596 let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType);
597 let imp = element.get_impl();
598
599 panic_to_error!(&wrap, &element.panicked(), false, { imp.negotiate(&wrap) }).to_glib()
600}
601
602unsafe extern "C" fn base_src_set_caps<T: BaseSrcBase>(
603 ptr: *mut gst_base_ffi::GstBaseSrc,
604 caps: *mut gst_ffi::GstCaps,
605) -> glib_ffi::gboolean
606where
607 T::ImplType: BaseSrcImpl<T>,
608 T::InstanceStructType: PanicPoison,
609{
610 floating_reference_guard!(ptr);
611 let element = &*(ptr as *mut T::InstanceStructType);
612 let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType);
613 let imp = element.get_impl();
614 let caps = gst::CapsRef::from_ptr(caps);
615
616 panic_to_error!(&wrap, &element.panicked(), false, {
617 imp.set_caps(&wrap, caps)
618 })
619 .to_glib()
620}
621
622unsafe extern "C" fn base_src_fixate<T: BaseSrcBase>(
623 ptr: *mut gst_base_ffi::GstBaseSrc,
624 caps: *mut gst_ffi::GstCaps,
625) -> *mut gst_ffi::GstCaps
626where
627 T::ImplType: BaseSrcImpl<T>,
628 T::InstanceStructType: PanicPoison,
629{
630 floating_reference_guard!(ptr);
631 let element = &*(ptr as *mut T::InstanceStructType);
632 let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType);
633 let imp = element.get_impl();
634 let caps = from_glib_full(caps);
635
636 panic_to_error!(&wrap, &element.panicked(), gst::Caps::new_empty(), {
637 imp.fixate(&wrap, caps)
638 })
639 .into_ptr()
640}
641
642unsafe extern "C" fn base_src_unlock<T: BaseSrcBase>(
643 ptr: *mut gst_base_ffi::GstBaseSrc,
644) -> glib_ffi::gboolean
645where
646 T::ImplType: BaseSrcImpl<T>,
647 T::InstanceStructType: PanicPoison,
648{
649 floating_reference_guard!(ptr);
650 let element = &*(ptr as *mut T::InstanceStructType);
651 let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType);
652 let imp = element.get_impl();
653
654 panic_to_error!(&wrap, &element.panicked(), false, { imp.unlock(&wrap) }).to_glib()
655}
656
657unsafe extern "C" fn base_src_unlock_stop<T: BaseSrcBase>(
658 ptr: *mut gst_base_ffi::GstBaseSrc,
659) -> glib_ffi::gboolean
660where
661 T::ImplType: BaseSrcImpl<T>,
662 T::InstanceStructType: PanicPoison,
663{
664 floating_reference_guard!(ptr);
665 let element = &*(ptr as *mut T::InstanceStructType);
666 let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType);
667 let imp = element.get_impl();
668
669 panic_to_error!(&wrap, &element.panicked(), false, {
670 imp.unlock_stop(&wrap)
671 })
672 .to_glib()
673}