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