1use glib::translate::*;
4use gst::subclass::prelude::*;
5
6use crate::{
7 VideoCodecFrame, VideoDecoder, ffi,
8 prelude::*,
9 video_codec_state::{Readable, VideoCodecState},
10};
11
12pub trait VideoDecoderImpl: ElementImpl + ObjectSubclass<Type: IsA<VideoDecoder>> {
13 fn open(&self) -> Result<(), gst::ErrorMessage> {
17 self.parent_open()
18 }
19
20 fn close(&self) -> Result<(), gst::ErrorMessage> {
24 self.parent_close()
25 }
26
27 fn start(&self) -> Result<(), gst::ErrorMessage> {
31 self.parent_start()
32 }
33
34 fn stop(&self) -> Result<(), gst::ErrorMessage> {
38 self.parent_stop()
39 }
40
41 fn finish(&self) -> Result<gst::FlowSuccess, gst::FlowError> {
45 self.parent_finish()
46 }
47
48 fn drain(&self) -> Result<gst::FlowSuccess, gst::FlowError> {
54 self.parent_drain()
55 }
56
57 fn set_format(
59 &self,
60 state: &VideoCodecState<'static, Readable>,
61 ) -> Result<(), gst::LoggableError> {
62 self.parent_set_format(state)
63 }
64
65 fn parse(
69 &self,
70 frame: &VideoCodecFrame,
71 adapter: &gst_base::Adapter,
72 at_eos: bool,
73 ) -> Result<gst::FlowSuccess, gst::FlowError> {
74 self.parent_parse(frame, adapter, at_eos)
75 }
76
77 fn handle_frame(&self, frame: VideoCodecFrame) -> Result<gst::FlowSuccess, gst::FlowError> {
80 self.parent_handle_frame(frame)
81 }
82
83 fn flush(&self) -> bool {
87 self.parent_flush()
88 }
89
90 fn negotiate(&self) -> Result<(), gst::LoggableError> {
98 self.parent_negotiate()
99 }
100
101 fn caps(&self, filter: Option<&gst::Caps>) -> gst::Caps {
102 self.parent_caps(filter)
103 }
104
105 fn sink_event(&self, event: gst::Event) -> bool {
112 self.parent_sink_event(event)
113 }
114
115 fn sink_query(&self, query: &mut gst::QueryRef) -> bool {
121 self.parent_sink_query(query)
122 }
123
124 fn src_event(&self, event: gst::Event) -> bool {
131 self.parent_src_event(event)
132 }
133
134 fn src_query(&self, query: &mut gst::QueryRef) -> bool {
140 self.parent_src_query(query)
141 }
142
143 fn propose_allocation(
148 &self,
149 query: &mut gst::query::Allocation,
150 ) -> Result<(), gst::LoggableError> {
151 self.parent_propose_allocation(query)
152 }
153
154 fn decide_allocation(
161 &self,
162 query: &mut gst::query::Allocation,
163 ) -> Result<(), gst::LoggableError> {
164 self.parent_decide_allocation(query)
165 }
166
167 #[cfg(feature = "v1_20")]
176 #[cfg_attr(docsrs, doc(cfg(feature = "v1_20")))]
177 fn handle_missing_data(
178 &self,
179 timestamp: gst::ClockTime,
180 duration: Option<gst::ClockTime>,
181 ) -> bool {
182 self.parent_handle_missing_data(timestamp, duration)
183 }
184}
185
186pub trait VideoDecoderImplExt: VideoDecoderImpl {
187 fn parent_open(&self) -> Result<(), gst::ErrorMessage> {
188 unsafe {
189 let data = Self::type_data();
190 let parent_class = data.as_ref().parent_class() as *mut ffi::GstVideoDecoderClass;
191 (*parent_class)
192 .open
193 .map(|f| {
194 if from_glib(f(self
195 .obj()
196 .unsafe_cast_ref::<VideoDecoder>()
197 .to_glib_none()
198 .0))
199 {
200 Ok(())
201 } else {
202 Err(gst::error_msg!(
203 gst::CoreError::StateChange,
204 ["Parent function `open` failed"]
205 ))
206 }
207 })
208 .unwrap_or(Ok(()))
209 }
210 }
211
212 fn parent_close(&self) -> Result<(), gst::ErrorMessage> {
213 unsafe {
214 let data = Self::type_data();
215 let parent_class = data.as_ref().parent_class() as *mut ffi::GstVideoDecoderClass;
216 (*parent_class)
217 .close
218 .map(|f| {
219 if from_glib(f(self
220 .obj()
221 .unsafe_cast_ref::<VideoDecoder>()
222 .to_glib_none()
223 .0))
224 {
225 Ok(())
226 } else {
227 Err(gst::error_msg!(
228 gst::CoreError::StateChange,
229 ["Parent function `close` failed"]
230 ))
231 }
232 })
233 .unwrap_or(Ok(()))
234 }
235 }
236
237 fn parent_start(&self) -> Result<(), gst::ErrorMessage> {
238 unsafe {
239 let data = Self::type_data();
240 let parent_class = data.as_ref().parent_class() as *mut ffi::GstVideoDecoderClass;
241 (*parent_class)
242 .start
243 .map(|f| {
244 if from_glib(f(self
245 .obj()
246 .unsafe_cast_ref::<VideoDecoder>()
247 .to_glib_none()
248 .0))
249 {
250 Ok(())
251 } else {
252 Err(gst::error_msg!(
253 gst::CoreError::StateChange,
254 ["Parent function `start` failed"]
255 ))
256 }
257 })
258 .unwrap_or(Ok(()))
259 }
260 }
261
262 fn parent_stop(&self) -> Result<(), gst::ErrorMessage> {
263 unsafe {
264 let data = Self::type_data();
265 let parent_class = data.as_ref().parent_class() as *mut ffi::GstVideoDecoderClass;
266 (*parent_class)
267 .stop
268 .map(|f| {
269 if from_glib(f(self
270 .obj()
271 .unsafe_cast_ref::<VideoDecoder>()
272 .to_glib_none()
273 .0))
274 {
275 Ok(())
276 } else {
277 Err(gst::error_msg!(
278 gst::CoreError::StateChange,
279 ["Parent function `stop` failed"]
280 ))
281 }
282 })
283 .unwrap_or(Ok(()))
284 }
285 }
286
287 fn parent_finish(&self) -> Result<gst::FlowSuccess, gst::FlowError> {
288 unsafe {
289 let data = Self::type_data();
290 let parent_class = data.as_ref().parent_class() as *mut ffi::GstVideoDecoderClass;
291 (*parent_class)
292 .finish
293 .map(|f| {
294 try_from_glib(f(self
295 .obj()
296 .unsafe_cast_ref::<VideoDecoder>()
297 .to_glib_none()
298 .0))
299 })
300 .unwrap_or(Ok(gst::FlowSuccess::Ok))
301 }
302 }
303
304 fn parent_drain(&self) -> Result<gst::FlowSuccess, gst::FlowError> {
305 unsafe {
306 let data = Self::type_data();
307 let parent_class = data.as_ref().parent_class() as *mut ffi::GstVideoDecoderClass;
308 (*parent_class)
309 .drain
310 .map(|f| {
311 try_from_glib(f(self
312 .obj()
313 .unsafe_cast_ref::<VideoDecoder>()
314 .to_glib_none()
315 .0))
316 })
317 .unwrap_or(Ok(gst::FlowSuccess::Ok))
318 }
319 }
320
321 fn parent_set_format(
322 &self,
323 state: &VideoCodecState<'static, Readable>,
324 ) -> Result<(), gst::LoggableError> {
325 unsafe {
326 let data = Self::type_data();
327 let parent_class = data.as_ref().parent_class() as *mut ffi::GstVideoDecoderClass;
328 (*parent_class)
329 .set_format
330 .map(|f| {
331 gst::result_from_gboolean!(
332 f(
333 self.obj()
334 .unsafe_cast_ref::<VideoDecoder>()
335 .to_glib_none()
336 .0,
337 state.as_mut_ptr()
338 ),
339 gst::CAT_RUST,
340 "parent function `set_format` failed"
341 )
342 })
343 .unwrap_or(Ok(()))
344 }
345 }
346
347 fn parent_parse(
348 &self,
349 frame: &VideoCodecFrame,
350 adapter: &gst_base::Adapter,
351 at_eos: bool,
352 ) -> Result<gst::FlowSuccess, gst::FlowError> {
353 unsafe {
354 let data = Self::type_data();
355 let parent_class = data.as_ref().parent_class() as *mut ffi::GstVideoDecoderClass;
356 (*parent_class)
357 .parse
358 .map(|f| {
359 try_from_glib(f(
360 self.obj()
361 .unsafe_cast_ref::<VideoDecoder>()
362 .to_glib_none()
363 .0,
364 frame.to_glib_none().0,
365 adapter.to_glib_none().0,
366 at_eos.into_glib(),
367 ))
368 })
369 .unwrap_or(Ok(gst::FlowSuccess::Ok))
370 }
371 }
372
373 fn parent_handle_frame(
374 &self,
375 frame: VideoCodecFrame,
376 ) -> Result<gst::FlowSuccess, gst::FlowError> {
377 unsafe {
378 let data = Self::type_data();
379 let parent_class = data.as_ref().parent_class() as *mut ffi::GstVideoDecoderClass;
380 (*parent_class)
381 .handle_frame
382 .map(|f| {
383 try_from_glib(f(
384 self.obj()
385 .unsafe_cast_ref::<VideoDecoder>()
386 .to_glib_none()
387 .0,
388 frame.to_glib_none().0,
389 ))
390 })
391 .unwrap_or(Err(gst::FlowError::Error))
392 }
393 }
394
395 fn parent_flush(&self) -> bool {
396 unsafe {
397 let data = Self::type_data();
398 let parent_class = data.as_ref().parent_class() as *mut ffi::GstVideoDecoderClass;
399 (*parent_class)
400 .flush
401 .map(|f| {
402 from_glib(f(self
403 .obj()
404 .unsafe_cast_ref::<VideoDecoder>()
405 .to_glib_none()
406 .0))
407 })
408 .unwrap_or(false)
409 }
410 }
411
412 fn parent_negotiate(&self) -> Result<(), gst::LoggableError> {
413 unsafe {
414 let data = Self::type_data();
415 let parent_class = data.as_ref().parent_class() as *mut ffi::GstVideoDecoderClass;
416 (*parent_class)
417 .negotiate
418 .map(|f| {
419 gst::result_from_gboolean!(
420 f(self
421 .obj()
422 .unsafe_cast_ref::<VideoDecoder>()
423 .to_glib_none()
424 .0),
425 gst::CAT_RUST,
426 "Parent function `negotiate` failed"
427 )
428 })
429 .unwrap_or(Ok(()))
430 }
431 }
432
433 fn parent_caps(&self, filter: Option<&gst::Caps>) -> gst::Caps {
434 unsafe {
435 let data = Self::type_data();
436 let parent_class = data.as_ref().parent_class() as *mut ffi::GstVideoDecoderClass;
437 (*parent_class)
438 .getcaps
439 .map(|f| {
440 from_glib_full(f(
441 self.obj()
442 .unsafe_cast_ref::<VideoDecoder>()
443 .to_glib_none()
444 .0,
445 filter.to_glib_none().0,
446 ))
447 })
448 .unwrap_or_else(|| {
449 self.obj()
450 .unsafe_cast_ref::<VideoDecoder>()
451 .proxy_getcaps(None, filter)
452 })
453 }
454 }
455
456 fn parent_sink_event(&self, event: gst::Event) -> bool {
457 unsafe {
458 let data = Self::type_data();
459 let parent_class = data.as_ref().parent_class() as *mut ffi::GstVideoDecoderClass;
460 let f = (*parent_class)
461 .sink_event
462 .expect("Missing parent function `sink_event`");
463 from_glib(f(
464 self.obj()
465 .unsafe_cast_ref::<VideoDecoder>()
466 .to_glib_none()
467 .0,
468 event.into_glib_ptr(),
469 ))
470 }
471 }
472
473 fn parent_sink_query(&self, query: &mut gst::QueryRef) -> bool {
474 unsafe {
475 let data = Self::type_data();
476 let parent_class = data.as_ref().parent_class() as *mut ffi::GstVideoDecoderClass;
477 let f = (*parent_class)
478 .sink_query
479 .expect("Missing parent function `sink_query`");
480 from_glib(f(
481 self.obj()
482 .unsafe_cast_ref::<VideoDecoder>()
483 .to_glib_none()
484 .0,
485 query.as_mut_ptr(),
486 ))
487 }
488 }
489
490 fn parent_src_event(&self, event: gst::Event) -> bool {
491 unsafe {
492 let data = Self::type_data();
493 let parent_class = data.as_ref().parent_class() as *mut ffi::GstVideoDecoderClass;
494 let f = (*parent_class)
495 .src_event
496 .expect("Missing parent function `src_event`");
497 from_glib(f(
498 self.obj()
499 .unsafe_cast_ref::<VideoDecoder>()
500 .to_glib_none()
501 .0,
502 event.into_glib_ptr(),
503 ))
504 }
505 }
506
507 fn parent_src_query(&self, query: &mut gst::QueryRef) -> bool {
508 unsafe {
509 let data = Self::type_data();
510 let parent_class = data.as_ref().parent_class() as *mut ffi::GstVideoDecoderClass;
511 let f = (*parent_class)
512 .src_query
513 .expect("Missing parent function `src_query`");
514 from_glib(f(
515 self.obj()
516 .unsafe_cast_ref::<VideoDecoder>()
517 .to_glib_none()
518 .0,
519 query.as_mut_ptr(),
520 ))
521 }
522 }
523
524 fn parent_propose_allocation(
525 &self,
526 query: &mut gst::query::Allocation,
527 ) -> Result<(), gst::LoggableError> {
528 unsafe {
529 let data = Self::type_data();
530 let parent_class = data.as_ref().parent_class() as *mut ffi::GstVideoDecoderClass;
531 (*parent_class)
532 .propose_allocation
533 .map(|f| {
534 gst::result_from_gboolean!(
535 f(
536 self.obj()
537 .unsafe_cast_ref::<VideoDecoder>()
538 .to_glib_none()
539 .0,
540 query.as_mut_ptr(),
541 ),
542 gst::CAT_RUST,
543 "Parent function `propose_allocation` failed",
544 )
545 })
546 .unwrap_or(Ok(()))
547 }
548 }
549
550 fn parent_decide_allocation(
551 &self,
552 query: &mut gst::query::Allocation,
553 ) -> Result<(), gst::LoggableError> {
554 unsafe {
555 let data = Self::type_data();
556 let parent_class = data.as_ref().parent_class() as *mut ffi::GstVideoDecoderClass;
557 (*parent_class)
558 .decide_allocation
559 .map(|f| {
560 gst::result_from_gboolean!(
561 f(
562 self.obj()
563 .unsafe_cast_ref::<VideoDecoder>()
564 .to_glib_none()
565 .0,
566 query.as_mut_ptr(),
567 ),
568 gst::CAT_RUST,
569 "Parent function `decide_allocation` failed",
570 )
571 })
572 .unwrap_or(Ok(()))
573 }
574 }
575
576 #[cfg(feature = "v1_20")]
577 #[cfg_attr(docsrs, doc(cfg(feature = "v1_20")))]
578 fn parent_handle_missing_data(
579 &self,
580 timestamp: gst::ClockTime,
581 duration: Option<gst::ClockTime>,
582 ) -> bool {
583 unsafe {
584 let data = Self::type_data();
585 let parent_class = data.as_ref().parent_class() as *mut ffi::GstVideoDecoderClass;
586 (*parent_class)
587 .handle_missing_data
588 .map(|f| {
589 from_glib(f(
590 self.obj()
591 .unsafe_cast_ref::<VideoDecoder>()
592 .to_glib_none()
593 .0,
594 timestamp.into_glib(),
595 duration.into_glib(),
596 ))
597 })
598 .unwrap_or(true)
599 }
600 }
601}
602
603impl<T: VideoDecoderImpl> VideoDecoderImplExt for T {}
604
605unsafe impl<T: VideoDecoderImpl> IsSubclassable<T> for VideoDecoder {
606 fn class_init(klass: &mut glib::Class<Self>) {
607 Self::parent_class_init::<T>(klass);
608 let klass = klass.as_mut();
609 klass.open = Some(video_decoder_open::<T>);
610 klass.close = Some(video_decoder_close::<T>);
611 klass.start = Some(video_decoder_start::<T>);
612 klass.stop = Some(video_decoder_stop::<T>);
613 klass.finish = Some(video_decoder_finish::<T>);
614 klass.drain = Some(video_decoder_drain::<T>);
615 klass.set_format = Some(video_decoder_set_format::<T>);
616 klass.parse = Some(video_decoder_parse::<T>);
617 klass.handle_frame = Some(video_decoder_handle_frame::<T>);
618 klass.flush = Some(video_decoder_flush::<T>);
619 klass.negotiate = Some(video_decoder_negotiate::<T>);
620 klass.getcaps = Some(video_decoder_getcaps::<T>);
621 klass.sink_event = Some(video_decoder_sink_event::<T>);
622 klass.src_event = Some(video_decoder_src_event::<T>);
623 klass.sink_query = Some(video_decoder_sink_query::<T>);
624 klass.src_query = Some(video_decoder_src_query::<T>);
625 klass.propose_allocation = Some(video_decoder_propose_allocation::<T>);
626 klass.decide_allocation = Some(video_decoder_decide_allocation::<T>);
627 #[cfg(feature = "v1_20")]
628 {
629 klass.handle_missing_data = Some(video_decoder_handle_missing_data::<T>);
630 }
631 }
632}
633
634unsafe extern "C" fn video_decoder_open<T: VideoDecoderImpl>(
635 ptr: *mut ffi::GstVideoDecoder,
636) -> glib::ffi::gboolean {
637 unsafe {
638 let instance = &*(ptr as *mut T::Instance);
639 let imp = instance.imp();
640
641 gst::element_panic_to_error!(imp, false, {
642 match imp.open() {
643 Ok(()) => true,
644 Err(err) => {
645 imp.post_error_message(err);
646 false
647 }
648 }
649 })
650 .into_glib()
651 }
652}
653
654unsafe extern "C" fn video_decoder_close<T: VideoDecoderImpl>(
655 ptr: *mut ffi::GstVideoDecoder,
656) -> glib::ffi::gboolean {
657 unsafe {
658 let instance = &*(ptr as *mut T::Instance);
659 let imp = instance.imp();
660
661 gst::element_panic_to_error!(imp, false, {
662 match imp.close() {
663 Ok(()) => true,
664 Err(err) => {
665 imp.post_error_message(err);
666 false
667 }
668 }
669 })
670 .into_glib()
671 }
672}
673
674unsafe extern "C" fn video_decoder_start<T: VideoDecoderImpl>(
675 ptr: *mut ffi::GstVideoDecoder,
676) -> glib::ffi::gboolean {
677 unsafe {
678 let instance = &*(ptr as *mut T::Instance);
679 let imp = instance.imp();
680
681 gst::element_panic_to_error!(imp, false, {
682 match imp.start() {
683 Ok(()) => true,
684 Err(err) => {
685 imp.post_error_message(err);
686 false
687 }
688 }
689 })
690 .into_glib()
691 }
692}
693
694unsafe extern "C" fn video_decoder_stop<T: VideoDecoderImpl>(
695 ptr: *mut ffi::GstVideoDecoder,
696) -> glib::ffi::gboolean {
697 unsafe {
698 let instance = &*(ptr as *mut T::Instance);
699 let imp = instance.imp();
700
701 gst::element_panic_to_error!(imp, false, {
702 match imp.stop() {
703 Ok(()) => true,
704 Err(err) => {
705 imp.post_error_message(err);
706 false
707 }
708 }
709 })
710 .into_glib()
711 }
712}
713
714unsafe extern "C" fn video_decoder_finish<T: VideoDecoderImpl>(
715 ptr: *mut ffi::GstVideoDecoder,
716) -> gst::ffi::GstFlowReturn {
717 unsafe {
718 let instance = &*(ptr as *mut T::Instance);
719 let imp = instance.imp();
720
721 gst::element_panic_to_error!(imp, gst::FlowReturn::Error, { imp.finish().into() })
722 .into_glib()
723 }
724}
725
726unsafe extern "C" fn video_decoder_drain<T: VideoDecoderImpl>(
727 ptr: *mut ffi::GstVideoDecoder,
728) -> gst::ffi::GstFlowReturn {
729 unsafe {
730 let instance = &*(ptr as *mut T::Instance);
731 let imp = instance.imp();
732
733 gst::element_panic_to_error!(imp, gst::FlowReturn::Error, { imp.drain().into() })
734 .into_glib()
735 }
736}
737
738unsafe extern "C" fn video_decoder_set_format<T: VideoDecoderImpl>(
739 ptr: *mut ffi::GstVideoDecoder,
740 state: *mut ffi::GstVideoCodecState,
741) -> glib::ffi::gboolean {
742 unsafe {
743 let instance = &*(ptr as *mut T::Instance);
744 let imp = instance.imp();
745 ffi::gst_video_codec_state_ref(state);
746 let wrap_state = VideoCodecState::<Readable>::new(state);
747
748 gst::element_panic_to_error!(imp, false, {
749 match imp.set_format(&wrap_state) {
750 Ok(()) => true,
751 Err(err) => {
752 err.log_with_imp(imp);
753 false
754 }
755 }
756 })
757 .into_glib()
758 }
759}
760
761unsafe extern "C" fn video_decoder_parse<T: VideoDecoderImpl>(
762 ptr: *mut ffi::GstVideoDecoder,
763 frame: *mut ffi::GstVideoCodecFrame,
764 adapter: *mut gst_base::ffi::GstAdapter,
765 at_eos: glib::ffi::gboolean,
766) -> gst::ffi::GstFlowReturn {
767 unsafe {
768 let instance = &*(ptr as *mut T::Instance);
769 let imp = instance.imp();
770 ffi::gst_video_codec_frame_ref(frame);
771 let instance = imp.obj();
772 let instance = instance.unsafe_cast_ref::<VideoDecoder>();
773 let wrap_frame = VideoCodecFrame::new(frame, instance);
774 let wrap_adapter: Borrowed<gst_base::Adapter> = from_glib_borrow(adapter);
775 let at_eos: bool = from_glib(at_eos);
776
777 gst::element_panic_to_error!(imp, gst::FlowReturn::Error, {
778 imp.parse(&wrap_frame, &wrap_adapter, at_eos).into()
779 })
780 .into_glib()
781 }
782}
783
784unsafe extern "C" fn video_decoder_handle_frame<T: VideoDecoderImpl>(
785 ptr: *mut ffi::GstVideoDecoder,
786 frame: *mut ffi::GstVideoCodecFrame,
787) -> gst::ffi::GstFlowReturn {
788 unsafe {
789 let instance = &*(ptr as *mut T::Instance);
790 let imp = instance.imp();
791 let instance = imp.obj();
792 let instance = instance.unsafe_cast_ref::<VideoDecoder>();
793 let wrap_frame = VideoCodecFrame::new(frame, instance);
794
795 gst::element_panic_to_error!(imp, gst::FlowReturn::Error, {
796 imp.handle_frame(wrap_frame).into()
797 })
798 .into_glib()
799 }
800}
801
802unsafe extern "C" fn video_decoder_flush<T: VideoDecoderImpl>(
803 ptr: *mut ffi::GstVideoDecoder,
804) -> glib::ffi::gboolean {
805 unsafe {
806 let instance = &*(ptr as *mut T::Instance);
807 let imp = instance.imp();
808
809 gst::element_panic_to_error!(imp, false, { VideoDecoderImpl::flush(imp) }).into_glib()
810 }
811}
812
813unsafe extern "C" fn video_decoder_negotiate<T: VideoDecoderImpl>(
814 ptr: *mut ffi::GstVideoDecoder,
815) -> glib::ffi::gboolean {
816 unsafe {
817 let instance = &*(ptr as *mut T::Instance);
818 let imp = instance.imp();
819
820 gst::element_panic_to_error!(imp, false, {
821 match imp.negotiate() {
822 Ok(()) => true,
823 Err(err) => {
824 err.log_with_imp(imp);
825 false
826 }
827 }
828 })
829 .into_glib()
830 }
831}
832
833unsafe extern "C" fn video_decoder_getcaps<T: VideoDecoderImpl>(
834 ptr: *mut ffi::GstVideoDecoder,
835 filter: *mut gst::ffi::GstCaps,
836) -> *mut gst::ffi::GstCaps {
837 unsafe {
838 let instance = &*(ptr as *mut T::Instance);
839 let imp = instance.imp();
840
841 gst::element_panic_to_error!(imp, gst::Caps::new_empty(), {
842 VideoDecoderImpl::caps(
843 imp,
844 Option::<gst::Caps>::from_glib_borrow(filter)
845 .as_ref()
846 .as_ref(),
847 )
848 })
849 .into_glib_ptr()
850 }
851}
852
853unsafe extern "C" fn video_decoder_sink_event<T: VideoDecoderImpl>(
854 ptr: *mut ffi::GstVideoDecoder,
855 event: *mut gst::ffi::GstEvent,
856) -> glib::ffi::gboolean {
857 unsafe {
858 let instance = &*(ptr as *mut T::Instance);
859 let imp = instance.imp();
860
861 gst::element_panic_to_error!(imp, false, { imp.sink_event(from_glib_full(event)) })
862 .into_glib()
863 }
864}
865
866unsafe extern "C" fn video_decoder_sink_query<T: VideoDecoderImpl>(
867 ptr: *mut ffi::GstVideoDecoder,
868 query: *mut gst::ffi::GstQuery,
869) -> glib::ffi::gboolean {
870 unsafe {
871 let instance = &*(ptr as *mut T::Instance);
872 let imp = instance.imp();
873
874 gst::element_panic_to_error!(imp, false, {
875 imp.sink_query(gst::QueryRef::from_mut_ptr(query))
876 })
877 .into_glib()
878 }
879}
880
881unsafe extern "C" fn video_decoder_src_event<T: VideoDecoderImpl>(
882 ptr: *mut ffi::GstVideoDecoder,
883 event: *mut gst::ffi::GstEvent,
884) -> glib::ffi::gboolean {
885 unsafe {
886 let instance = &*(ptr as *mut T::Instance);
887 let imp = instance.imp();
888
889 gst::element_panic_to_error!(imp, false, { imp.src_event(from_glib_full(event)) })
890 .into_glib()
891 }
892}
893
894unsafe extern "C" fn video_decoder_src_query<T: VideoDecoderImpl>(
895 ptr: *mut ffi::GstVideoDecoder,
896 query: *mut gst::ffi::GstQuery,
897) -> glib::ffi::gboolean {
898 unsafe {
899 let instance = &*(ptr as *mut T::Instance);
900 let imp = instance.imp();
901
902 gst::element_panic_to_error!(imp, false, {
903 imp.src_query(gst::QueryRef::from_mut_ptr(query))
904 })
905 .into_glib()
906 }
907}
908
909unsafe extern "C" fn video_decoder_propose_allocation<T: VideoDecoderImpl>(
910 ptr: *mut ffi::GstVideoDecoder,
911 query: *mut gst::ffi::GstQuery,
912) -> glib::ffi::gboolean {
913 unsafe {
914 let instance = &*(ptr as *mut T::Instance);
915 let imp = instance.imp();
916 let query = match gst::QueryRef::from_mut_ptr(query).view_mut() {
917 gst::QueryViewMut::Allocation(allocation) => allocation,
918 _ => unreachable!(),
919 };
920
921 gst::element_panic_to_error!(imp, false, {
922 match imp.propose_allocation(query) {
923 Ok(()) => true,
924 Err(err) => {
925 err.log_with_imp(imp);
926 false
927 }
928 }
929 })
930 .into_glib()
931 }
932}
933
934unsafe extern "C" fn video_decoder_decide_allocation<T: VideoDecoderImpl>(
935 ptr: *mut ffi::GstVideoDecoder,
936 query: *mut gst::ffi::GstQuery,
937) -> glib::ffi::gboolean {
938 unsafe {
939 let instance = &*(ptr as *mut T::Instance);
940 let imp = instance.imp();
941 let query = match gst::QueryRef::from_mut_ptr(query).view_mut() {
942 gst::QueryViewMut::Allocation(allocation) => allocation,
943 _ => unreachable!(),
944 };
945
946 gst::element_panic_to_error!(imp, false, {
947 match imp.decide_allocation(query) {
948 Ok(()) => true,
949 Err(err) => {
950 err.log_with_imp(imp);
951 false
952 }
953 }
954 })
955 .into_glib()
956 }
957}
958
959#[cfg(feature = "v1_20")]
960unsafe extern "C" fn video_decoder_handle_missing_data<T: VideoDecoderImpl>(
961 ptr: *mut ffi::GstVideoDecoder,
962 timestamp: gst::ffi::GstClockTime,
963 duration: gst::ffi::GstClockTime,
964) -> glib::ffi::gboolean {
965 unsafe {
966 let instance = &*(ptr as *mut T::Instance);
967 let imp = instance.imp();
968
969 gst::element_panic_to_error!(imp, true, {
970 imp.handle_missing_data(
971 Option::<gst::ClockTime>::from_glib(timestamp).unwrap(),
972 from_glib(duration),
973 )
974 })
975 .into_glib()
976 }
977}