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