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