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