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