gstreamer_video/subclass/
video_decoder.rs

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 = &*(ptr as *mut T::Instance);
566    let imp = instance.imp();
567
568    gst::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 = &*(ptr as *mut T::Instance);
584    let imp = instance.imp();
585
586    gst::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 = &*(ptr as *mut T::Instance);
602    let imp = instance.imp();
603
604    gst::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 = &*(ptr as *mut T::Instance);
620    let imp = instance.imp();
621
622    gst::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 = &*(ptr as *mut T::Instance);
638    let imp = 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 = &*(ptr as *mut T::Instance);
647    let imp = 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 = &*(ptr as *mut T::Instance);
657    let imp = instance.imp();
658    ffi::gst_video_codec_state_ref(state);
659    let wrap_state = VideoCodecState::<Readable>::new(state);
660
661    gst::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 = &*(ptr as *mut T::Instance);
680    let imp = instance.imp();
681    ffi::gst_video_codec_frame_ref(frame);
682    let instance = imp.obj();
683    let instance = instance.unsafe_cast_ref::<VideoDecoder>();
684    let wrap_frame = VideoCodecFrame::new(frame, instance);
685    let wrap_adapter: Borrowed<gst_base::Adapter> = from_glib_borrow(adapter);
686    let at_eos: bool = from_glib(at_eos);
687
688    gst::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 = &*(ptr as *mut T::Instance);
699    let imp = instance.imp();
700    let instance = imp.obj();
701    let instance = instance.unsafe_cast_ref::<VideoDecoder>();
702    let wrap_frame = VideoCodecFrame::new(frame, instance);
703
704    gst::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 = &*(ptr as *mut T::Instance);
714    let imp = 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 = &*(ptr as *mut T::Instance);
723    let imp = instance.imp();
724
725    gst::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 = &*(ptr as *mut T::Instance);
742    let imp = instance.imp();
743
744    gst::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 = &*(ptr as *mut T::Instance);
760    let imp = 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 = &*(ptr as *mut T::Instance);
770    let imp = instance.imp();
771
772    gst::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 = &*(ptr as *mut T::Instance);
783    let imp = 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 = &*(ptr as *mut T::Instance);
793    let imp = instance.imp();
794
795    gst::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 = &*(ptr as *mut T::Instance);
806    let imp = instance.imp();
807    let query = match gst::QueryRef::from_mut_ptr(query).view_mut() {
808        gst::QueryViewMut::Allocation(allocation) => allocation,
809        _ => unreachable!(),
810    };
811
812    gst::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 = &*(ptr as *mut T::Instance);
829    let imp = instance.imp();
830    let query = match gst::QueryRef::from_mut_ptr(query).view_mut() {
831        gst::QueryViewMut::Allocation(allocation) => allocation,
832        _ => unreachable!(),
833    };
834
835    gst::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}