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