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::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::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::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::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::panic_to_error!(imp, gst::FlowReturn::Error, { imp.finish().into() }).into_glib()
722 }
723}
724
725unsafe extern "C" fn video_decoder_drain<T: VideoDecoderImpl>(
726 ptr: *mut ffi::GstVideoDecoder,
727) -> gst::ffi::GstFlowReturn {
728 unsafe {
729 let instance = &*(ptr as *mut T::Instance);
730 let imp = instance.imp();
731
732 gst::panic_to_error!(imp, gst::FlowReturn::Error, { imp.drain().into() }).into_glib()
733 }
734}
735
736unsafe extern "C" fn video_decoder_set_format<T: VideoDecoderImpl>(
737 ptr: *mut ffi::GstVideoDecoder,
738 state: *mut ffi::GstVideoCodecState,
739) -> glib::ffi::gboolean {
740 unsafe {
741 let instance = &*(ptr as *mut T::Instance);
742 let imp = instance.imp();
743 ffi::gst_video_codec_state_ref(state);
744 let wrap_state = VideoCodecState::<Readable>::new(state);
745
746 gst::panic_to_error!(imp, false, {
747 match imp.set_format(&wrap_state) {
748 Ok(()) => true,
749 Err(err) => {
750 err.log_with_imp(imp);
751 false
752 }
753 }
754 })
755 .into_glib()
756 }
757}
758
759unsafe extern "C" fn video_decoder_parse<T: VideoDecoderImpl>(
760 ptr: *mut ffi::GstVideoDecoder,
761 frame: *mut ffi::GstVideoCodecFrame,
762 adapter: *mut gst_base::ffi::GstAdapter,
763 at_eos: glib::ffi::gboolean,
764) -> gst::ffi::GstFlowReturn {
765 unsafe {
766 let instance = &*(ptr as *mut T::Instance);
767 let imp = instance.imp();
768 ffi::gst_video_codec_frame_ref(frame);
769 let instance = imp.obj();
770 let instance = instance.unsafe_cast_ref::<VideoDecoder>();
771 let wrap_frame = VideoCodecFrame::new(frame, instance);
772 let wrap_adapter: Borrowed<gst_base::Adapter> = from_glib_borrow(adapter);
773 let at_eos: bool = from_glib(at_eos);
774
775 gst::panic_to_error!(imp, gst::FlowReturn::Error, {
776 imp.parse(&wrap_frame, &wrap_adapter, at_eos).into()
777 })
778 .into_glib()
779 }
780}
781
782unsafe extern "C" fn video_decoder_handle_frame<T: VideoDecoderImpl>(
783 ptr: *mut ffi::GstVideoDecoder,
784 frame: *mut ffi::GstVideoCodecFrame,
785) -> gst::ffi::GstFlowReturn {
786 unsafe {
787 let instance = &*(ptr as *mut T::Instance);
788 let imp = instance.imp();
789 let instance = imp.obj();
790 let instance = instance.unsafe_cast_ref::<VideoDecoder>();
791 let wrap_frame = VideoCodecFrame::new(frame, instance);
792
793 gst::panic_to_error!(imp, gst::FlowReturn::Error, {
794 imp.handle_frame(wrap_frame).into()
795 })
796 .into_glib()
797 }
798}
799
800unsafe extern "C" fn video_decoder_flush<T: VideoDecoderImpl>(
801 ptr: *mut ffi::GstVideoDecoder,
802) -> glib::ffi::gboolean {
803 unsafe {
804 let instance = &*(ptr as *mut T::Instance);
805 let imp = instance.imp();
806
807 gst::panic_to_error!(imp, false, { VideoDecoderImpl::flush(imp) }).into_glib()
808 }
809}
810
811unsafe extern "C" fn video_decoder_negotiate<T: VideoDecoderImpl>(
812 ptr: *mut ffi::GstVideoDecoder,
813) -> glib::ffi::gboolean {
814 unsafe {
815 let instance = &*(ptr as *mut T::Instance);
816 let imp = instance.imp();
817
818 gst::panic_to_error!(imp, false, {
819 match imp.negotiate() {
820 Ok(()) => true,
821 Err(err) => {
822 err.log_with_imp(imp);
823 false
824 }
825 }
826 })
827 .into_glib()
828 }
829}
830
831unsafe extern "C" fn video_decoder_getcaps<T: VideoDecoderImpl>(
832 ptr: *mut ffi::GstVideoDecoder,
833 filter: *mut gst::ffi::GstCaps,
834) -> *mut gst::ffi::GstCaps {
835 unsafe {
836 let instance = &*(ptr as *mut T::Instance);
837 let imp = instance.imp();
838
839 gst::panic_to_error!(imp, gst::Caps::new_empty(), {
840 VideoDecoderImpl::caps(
841 imp,
842 Option::<gst::Caps>::from_glib_borrow(filter)
843 .as_ref()
844 .as_ref(),
845 )
846 })
847 .into_glib_ptr()
848 }
849}
850
851unsafe extern "C" fn video_decoder_sink_event<T: VideoDecoderImpl>(
852 ptr: *mut ffi::GstVideoDecoder,
853 event: *mut gst::ffi::GstEvent,
854) -> glib::ffi::gboolean {
855 unsafe {
856 let instance = &*(ptr as *mut T::Instance);
857 let imp = instance.imp();
858
859 gst::panic_to_error!(imp, false, { imp.sink_event(from_glib_full(event)) }).into_glib()
860 }
861}
862
863unsafe extern "C" fn video_decoder_sink_query<T: VideoDecoderImpl>(
864 ptr: *mut ffi::GstVideoDecoder,
865 query: *mut gst::ffi::GstQuery,
866) -> glib::ffi::gboolean {
867 unsafe {
868 let instance = &*(ptr as *mut T::Instance);
869 let imp = instance.imp();
870
871 gst::panic_to_error!(imp, false, {
872 imp.sink_query(gst::QueryRef::from_mut_ptr(query))
873 })
874 .into_glib()
875 }
876}
877
878unsafe extern "C" fn video_decoder_src_event<T: VideoDecoderImpl>(
879 ptr: *mut ffi::GstVideoDecoder,
880 event: *mut gst::ffi::GstEvent,
881) -> glib::ffi::gboolean {
882 unsafe {
883 let instance = &*(ptr as *mut T::Instance);
884 let imp = instance.imp();
885
886 gst::panic_to_error!(imp, false, { imp.src_event(from_glib_full(event)) }).into_glib()
887 }
888}
889
890unsafe extern "C" fn video_decoder_src_query<T: VideoDecoderImpl>(
891 ptr: *mut ffi::GstVideoDecoder,
892 query: *mut gst::ffi::GstQuery,
893) -> glib::ffi::gboolean {
894 unsafe {
895 let instance = &*(ptr as *mut T::Instance);
896 let imp = instance.imp();
897
898 gst::panic_to_error!(imp, false, {
899 imp.src_query(gst::QueryRef::from_mut_ptr(query))
900 })
901 .into_glib()
902 }
903}
904
905unsafe extern "C" fn video_decoder_propose_allocation<T: VideoDecoderImpl>(
906 ptr: *mut ffi::GstVideoDecoder,
907 query: *mut gst::ffi::GstQuery,
908) -> glib::ffi::gboolean {
909 unsafe {
910 let instance = &*(ptr as *mut T::Instance);
911 let imp = instance.imp();
912 let query = match gst::QueryRef::from_mut_ptr(query).view_mut() {
913 gst::QueryViewMut::Allocation(allocation) => allocation,
914 _ => unreachable!(),
915 };
916
917 gst::panic_to_error!(imp, false, {
918 match imp.propose_allocation(query) {
919 Ok(()) => true,
920 Err(err) => {
921 err.log_with_imp(imp);
922 false
923 }
924 }
925 })
926 .into_glib()
927 }
928}
929
930unsafe extern "C" fn video_decoder_decide_allocation<T: VideoDecoderImpl>(
931 ptr: *mut ffi::GstVideoDecoder,
932 query: *mut gst::ffi::GstQuery,
933) -> glib::ffi::gboolean {
934 unsafe {
935 let instance = &*(ptr as *mut T::Instance);
936 let imp = instance.imp();
937 let query = match gst::QueryRef::from_mut_ptr(query).view_mut() {
938 gst::QueryViewMut::Allocation(allocation) => allocation,
939 _ => unreachable!(),
940 };
941
942 gst::panic_to_error!(imp, false, {
943 match imp.decide_allocation(query) {
944 Ok(()) => true,
945 Err(err) => {
946 err.log_with_imp(imp);
947 false
948 }
949 }
950 })
951 .into_glib()
952 }
953}
954
955#[cfg(feature = "v1_20")]
956unsafe extern "C" fn video_decoder_handle_missing_data<T: VideoDecoderImpl>(
957 ptr: *mut ffi::GstVideoDecoder,
958 timestamp: gst::ffi::GstClockTime,
959 duration: gst::ffi::GstClockTime,
960) -> glib::ffi::gboolean {
961 unsafe {
962 let instance = &*(ptr as *mut T::Instance);
963 let imp = instance.imp();
964
965 gst::panic_to_error!(imp, true, {
966 imp.handle_missing_data(
967 Option::<gst::ClockTime>::from_glib(timestamp).unwrap(),
968 from_glib(duration),
969 )
970 })
971 .into_glib()
972 }
973}