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