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")]
158 #[cfg_attr(docsrs, doc(cfg(feature = "v1_30")))]
159 fn prepare_allocator(&self, caps: Option<&gst::Caps>) -> Result<(), gst::LoggableError> {
160 self.parent_prepare_allocator(caps)
161 }
162}
163
164pub trait VideoEncoderImplExt: VideoEncoderImpl {
165 fn parent_open(&self) -> Result<(), gst::ErrorMessage> {
166 unsafe {
167 let data = Self::type_data();
168 let parent_class = data.as_ref().parent_class() as *mut ffi::GstVideoEncoderClass;
169 (*parent_class)
170 .open
171 .map(|f| {
172 if from_glib(f(self
173 .obj()
174 .unsafe_cast_ref::<VideoEncoder>()
175 .to_glib_none()
176 .0))
177 {
178 Ok(())
179 } else {
180 Err(gst::error_msg!(
181 gst::CoreError::StateChange,
182 ["Parent function `open` failed"]
183 ))
184 }
185 })
186 .unwrap_or(Ok(()))
187 }
188 }
189
190 fn parent_close(&self) -> Result<(), gst::ErrorMessage> {
191 unsafe {
192 let data = Self::type_data();
193 let parent_class = data.as_ref().parent_class() as *mut ffi::GstVideoEncoderClass;
194 (*parent_class)
195 .close
196 .map(|f| {
197 if from_glib(f(self
198 .obj()
199 .unsafe_cast_ref::<VideoEncoder>()
200 .to_glib_none()
201 .0))
202 {
203 Ok(())
204 } else {
205 Err(gst::error_msg!(
206 gst::CoreError::StateChange,
207 ["Parent function `close` failed"]
208 ))
209 }
210 })
211 .unwrap_or(Ok(()))
212 }
213 }
214
215 fn parent_start(&self) -> Result<(), gst::ErrorMessage> {
216 unsafe {
217 let data = Self::type_data();
218 let parent_class = data.as_ref().parent_class() as *mut ffi::GstVideoEncoderClass;
219 (*parent_class)
220 .start
221 .map(|f| {
222 if from_glib(f(self
223 .obj()
224 .unsafe_cast_ref::<VideoEncoder>()
225 .to_glib_none()
226 .0))
227 {
228 Ok(())
229 } else {
230 Err(gst::error_msg!(
231 gst::CoreError::StateChange,
232 ["Parent function `start` failed"]
233 ))
234 }
235 })
236 .unwrap_or(Ok(()))
237 }
238 }
239
240 fn parent_stop(&self) -> Result<(), gst::ErrorMessage> {
241 unsafe {
242 let data = Self::type_data();
243 let parent_class = data.as_ref().parent_class() as *mut ffi::GstVideoEncoderClass;
244 (*parent_class)
245 .stop
246 .map(|f| {
247 if from_glib(f(self
248 .obj()
249 .unsafe_cast_ref::<VideoEncoder>()
250 .to_glib_none()
251 .0))
252 {
253 Ok(())
254 } else {
255 Err(gst::error_msg!(
256 gst::CoreError::StateChange,
257 ["Parent function `stop` failed"]
258 ))
259 }
260 })
261 .unwrap_or(Ok(()))
262 }
263 }
264
265 fn parent_finish(&self) -> Result<gst::FlowSuccess, gst::FlowError> {
266 unsafe {
267 let data = Self::type_data();
268 let parent_class = data.as_ref().parent_class() as *mut ffi::GstVideoEncoderClass;
269 (*parent_class)
270 .finish
271 .map(|f| {
272 try_from_glib(f(self
273 .obj()
274 .unsafe_cast_ref::<VideoEncoder>()
275 .to_glib_none()
276 .0))
277 })
278 .unwrap_or(Ok(gst::FlowSuccess::Ok))
279 }
280 }
281
282 fn parent_set_format(
283 &self,
284 state: &VideoCodecState<'static, Readable>,
285 ) -> Result<(), gst::LoggableError> {
286 unsafe {
287 let data = Self::type_data();
288 let parent_class = data.as_ref().parent_class() as *mut ffi::GstVideoEncoderClass;
289 (*parent_class)
290 .set_format
291 .map(|f| {
292 gst::result_from_gboolean!(
293 f(
294 self.obj()
295 .unsafe_cast_ref::<VideoEncoder>()
296 .to_glib_none()
297 .0,
298 state.as_mut_ptr()
299 ),
300 gst::CAT_RUST,
301 "parent function `set_format` failed"
302 )
303 })
304 .unwrap_or(Ok(()))
305 }
306 }
307
308 fn parent_handle_frame(
309 &self,
310 frame: VideoCodecFrame,
311 ) -> Result<gst::FlowSuccess, gst::FlowError> {
312 unsafe {
313 let data = Self::type_data();
314 let parent_class = data.as_ref().parent_class() as *mut ffi::GstVideoEncoderClass;
315 (*parent_class)
316 .handle_frame
317 .map(|f| {
318 try_from_glib(f(
319 self.obj()
320 .unsafe_cast_ref::<VideoEncoder>()
321 .to_glib_none()
322 .0,
323 frame.to_glib_none().0,
324 ))
325 })
326 .unwrap_or(Err(gst::FlowError::Error))
327 }
328 }
329
330 fn parent_flush(&self) -> bool {
331 unsafe {
332 let data = Self::type_data();
333 let parent_class = data.as_ref().parent_class() as *mut ffi::GstVideoEncoderClass;
334 (*parent_class)
335 .flush
336 .map(|f| {
337 from_glib(f(self
338 .obj()
339 .unsafe_cast_ref::<VideoEncoder>()
340 .to_glib_none()
341 .0))
342 })
343 .unwrap_or(false)
344 }
345 }
346
347 fn parent_negotiate(&self) -> Result<(), gst::LoggableError> {
348 unsafe {
349 let data = Self::type_data();
350 let parent_class = data.as_ref().parent_class() as *mut ffi::GstVideoEncoderClass;
351 (*parent_class)
352 .negotiate
353 .map(|f| {
354 gst::result_from_gboolean!(
355 f(self
356 .obj()
357 .unsafe_cast_ref::<VideoEncoder>()
358 .to_glib_none()
359 .0),
360 gst::CAT_RUST,
361 "Parent function `negotiate` failed"
362 )
363 })
364 .unwrap_or(Ok(()))
365 }
366 }
367
368 fn parent_caps(&self, filter: Option<&gst::Caps>) -> gst::Caps {
369 unsafe {
370 let data = Self::type_data();
371 let parent_class = data.as_ref().parent_class() as *mut ffi::GstVideoEncoderClass;
372 (*parent_class)
373 .getcaps
374 .map(|f| {
375 from_glib_full(f(
376 self.obj()
377 .unsafe_cast_ref::<VideoEncoder>()
378 .to_glib_none()
379 .0,
380 filter.to_glib_none().0,
381 ))
382 })
383 .unwrap_or_else(|| {
384 self.obj()
385 .unsafe_cast_ref::<VideoEncoder>()
386 .proxy_getcaps(None, filter)
387 })
388 }
389 }
390
391 fn parent_sink_event(&self, event: gst::Event) -> bool {
392 unsafe {
393 let data = Self::type_data();
394 let parent_class = data.as_ref().parent_class() as *mut ffi::GstVideoEncoderClass;
395 let f = (*parent_class)
396 .sink_event
397 .expect("Missing parent function `sink_event`");
398 from_glib(f(
399 self.obj()
400 .unsafe_cast_ref::<VideoEncoder>()
401 .to_glib_none()
402 .0,
403 event.into_glib_ptr(),
404 ))
405 }
406 }
407
408 fn parent_sink_query(&self, query: &mut gst::QueryRef) -> bool {
409 unsafe {
410 let data = Self::type_data();
411 let parent_class = data.as_ref().parent_class() as *mut ffi::GstVideoEncoderClass;
412 let f = (*parent_class)
413 .sink_query
414 .expect("Missing parent function `sink_query`");
415 from_glib(f(
416 self.obj()
417 .unsafe_cast_ref::<VideoEncoder>()
418 .to_glib_none()
419 .0,
420 query.as_mut_ptr(),
421 ))
422 }
423 }
424
425 fn parent_src_event(&self, event: gst::Event) -> bool {
426 unsafe {
427 let data = Self::type_data();
428 let parent_class = data.as_ref().parent_class() as *mut ffi::GstVideoEncoderClass;
429 let f = (*parent_class)
430 .src_event
431 .expect("Missing parent function `src_event`");
432 from_glib(f(
433 self.obj()
434 .unsafe_cast_ref::<VideoEncoder>()
435 .to_glib_none()
436 .0,
437 event.into_glib_ptr(),
438 ))
439 }
440 }
441
442 fn parent_src_query(&self, query: &mut gst::QueryRef) -> bool {
443 unsafe {
444 let data = Self::type_data();
445 let parent_class = data.as_ref().parent_class() as *mut ffi::GstVideoEncoderClass;
446 let f = (*parent_class)
447 .src_query
448 .expect("Missing parent function `src_query`");
449 from_glib(f(
450 self.obj()
451 .unsafe_cast_ref::<VideoEncoder>()
452 .to_glib_none()
453 .0,
454 query.as_mut_ptr(),
455 ))
456 }
457 }
458
459 fn parent_propose_allocation(
460 &self,
461 query: &mut gst::query::Allocation,
462 ) -> Result<(), gst::LoggableError> {
463 unsafe {
464 let data = Self::type_data();
465 let parent_class = data.as_ref().parent_class() as *mut ffi::GstVideoEncoderClass;
466 (*parent_class)
467 .propose_allocation
468 .map(|f| {
469 gst::result_from_gboolean!(
470 f(
471 self.obj()
472 .unsafe_cast_ref::<VideoEncoder>()
473 .to_glib_none()
474 .0,
475 query.as_mut_ptr(),
476 ),
477 gst::CAT_RUST,
478 "Parent function `propose_allocation` failed",
479 )
480 })
481 .unwrap_or(Ok(()))
482 }
483 }
484
485 fn parent_decide_allocation(
486 &self,
487 query: &mut gst::query::Allocation,
488 ) -> Result<(), gst::LoggableError> {
489 unsafe {
490 let data = Self::type_data();
491 let parent_class = data.as_ref().parent_class() as *mut ffi::GstVideoEncoderClass;
492 (*parent_class)
493 .decide_allocation
494 .map(|f| {
495 gst::result_from_gboolean!(
496 f(
497 self.obj()
498 .unsafe_cast_ref::<VideoEncoder>()
499 .to_glib_none()
500 .0,
501 query.as_mut_ptr(),
502 ),
503 gst::CAT_RUST,
504 "Parent function `decide_allocation` failed",
505 )
506 })
507 .unwrap_or(Ok(()))
508 }
509 }
510
511 #[cfg(feature = "v1_30")]
512 #[cfg_attr(docsrs, doc(cfg(feature = "v1_30")))]
513 fn parent_prepare_allocator(&self, caps: Option<&gst::Caps>) -> Result<(), gst::LoggableError> {
514 unsafe {
515 let data = Self::type_data();
516 let parent_class = data.as_ref().parent_class() as *mut ffi::GstVideoEncoderClass;
517 (*parent_class)
518 .prepare_allocator
519 .map(|f| {
520 gst::result_from_gboolean!(
521 f(
522 self.obj()
523 .unsafe_cast_ref::<VideoEncoder>()
524 .to_glib_none()
525 .0,
526 caps.to_glib_none().0
527 ),
528 gst::CAT_RUST,
529 "Parent function `prepare_allocator` failed",
530 )
531 })
532 .unwrap_or(Ok(()))
533 }
534 }
535}
536
537impl<T: VideoEncoderImpl> VideoEncoderImplExt for T {}
538
539unsafe impl<T: VideoEncoderImpl> IsSubclassable<T> for VideoEncoder {
540 fn class_init(klass: &mut glib::Class<Self>) {
541 Self::parent_class_init::<T>(klass);
542 let klass = klass.as_mut();
543 klass.open = Some(video_encoder_open::<T>);
544 klass.close = Some(video_encoder_close::<T>);
545 klass.start = Some(video_encoder_start::<T>);
546 klass.stop = Some(video_encoder_stop::<T>);
547 klass.finish = Some(video_encoder_finish::<T>);
548 klass.set_format = Some(video_encoder_set_format::<T>);
549 klass.handle_frame = Some(video_encoder_handle_frame::<T>);
550 klass.flush = Some(video_encoder_flush::<T>);
551 klass.negotiate = Some(video_encoder_negotiate::<T>);
552 klass.getcaps = Some(video_encoder_getcaps::<T>);
553 klass.sink_event = Some(video_encoder_sink_event::<T>);
554 klass.src_event = Some(video_encoder_src_event::<T>);
555 klass.sink_query = Some(video_encoder_sink_query::<T>);
556 klass.src_query = Some(video_encoder_src_query::<T>);
557 klass.propose_allocation = Some(video_encoder_propose_allocation::<T>);
558 klass.decide_allocation = Some(video_encoder_decide_allocation::<T>);
559 #[cfg(feature = "v1_30")]
560 {
561 klass.prepare_allocator = Some(video_encoder_prepare_allocator::<T>);
562 }
563 }
564}
565
566unsafe extern "C" fn video_encoder_open<T: VideoEncoderImpl>(
567 ptr: *mut ffi::GstVideoEncoder,
568) -> glib::ffi::gboolean {
569 unsafe {
570 let instance = &*(ptr as *mut T::Instance);
571 let imp = instance.imp();
572
573 gst::panic_to_error!(imp, false, {
574 match imp.open() {
575 Ok(()) => true,
576 Err(err) => {
577 imp.post_error_message(err);
578 false
579 }
580 }
581 })
582 .into_glib()
583 }
584}
585
586unsafe extern "C" fn video_encoder_close<T: VideoEncoderImpl>(
587 ptr: *mut ffi::GstVideoEncoder,
588) -> glib::ffi::gboolean {
589 unsafe {
590 let instance = &*(ptr as *mut T::Instance);
591 let imp = instance.imp();
592
593 gst::panic_to_error!(imp, false, {
594 match imp.close() {
595 Ok(()) => true,
596 Err(err) => {
597 imp.post_error_message(err);
598 false
599 }
600 }
601 })
602 .into_glib()
603 }
604}
605
606unsafe extern "C" fn video_encoder_start<T: VideoEncoderImpl>(
607 ptr: *mut ffi::GstVideoEncoder,
608) -> glib::ffi::gboolean {
609 unsafe {
610 let instance = &*(ptr as *mut T::Instance);
611 let imp = instance.imp();
612
613 gst::panic_to_error!(imp, false, {
614 match imp.start() {
615 Ok(()) => true,
616 Err(err) => {
617 imp.post_error_message(err);
618 false
619 }
620 }
621 })
622 .into_glib()
623 }
624}
625
626unsafe extern "C" fn video_encoder_stop<T: VideoEncoderImpl>(
627 ptr: *mut ffi::GstVideoEncoder,
628) -> glib::ffi::gboolean {
629 unsafe {
630 let instance = &*(ptr as *mut T::Instance);
631 let imp = instance.imp();
632
633 gst::panic_to_error!(imp, false, {
634 match imp.stop() {
635 Ok(()) => true,
636 Err(err) => {
637 imp.post_error_message(err);
638 false
639 }
640 }
641 })
642 .into_glib()
643 }
644}
645
646unsafe extern "C" fn video_encoder_finish<T: VideoEncoderImpl>(
647 ptr: *mut ffi::GstVideoEncoder,
648) -> gst::ffi::GstFlowReturn {
649 unsafe {
650 let instance = &*(ptr as *mut T::Instance);
651 let imp = instance.imp();
652
653 gst::panic_to_error!(imp, gst::FlowReturn::Error, { imp.finish().into() }).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::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::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::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::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::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::panic_to_error!(imp, false, { imp.sink_event(from_glib_full(event)) }).into_glib()
758 }
759}
760
761unsafe extern "C" fn video_encoder_sink_query<T: VideoEncoderImpl>(
762 ptr: *mut ffi::GstVideoEncoder,
763 query: *mut gst::ffi::GstQuery,
764) -> glib::ffi::gboolean {
765 unsafe {
766 let instance = &*(ptr as *mut T::Instance);
767 let imp = instance.imp();
768
769 gst::panic_to_error!(imp, false, {
770 imp.sink_query(gst::QueryRef::from_mut_ptr(query))
771 })
772 .into_glib()
773 }
774}
775
776unsafe extern "C" fn video_encoder_src_event<T: VideoEncoderImpl>(
777 ptr: *mut ffi::GstVideoEncoder,
778 event: *mut gst::ffi::GstEvent,
779) -> glib::ffi::gboolean {
780 unsafe {
781 let instance = &*(ptr as *mut T::Instance);
782 let imp = instance.imp();
783
784 gst::panic_to_error!(imp, false, { imp.src_event(from_glib_full(event)) }).into_glib()
785 }
786}
787
788unsafe extern "C" fn video_encoder_src_query<T: VideoEncoderImpl>(
789 ptr: *mut ffi::GstVideoEncoder,
790 query: *mut gst::ffi::GstQuery,
791) -> glib::ffi::gboolean {
792 unsafe {
793 let instance = &*(ptr as *mut T::Instance);
794 let imp = instance.imp();
795
796 gst::panic_to_error!(imp, false, {
797 imp.src_query(gst::QueryRef::from_mut_ptr(query))
798 })
799 .into_glib()
800 }
801}
802
803unsafe extern "C" fn video_encoder_propose_allocation<T: VideoEncoderImpl>(
804 ptr: *mut ffi::GstVideoEncoder,
805 query: *mut gst::ffi::GstQuery,
806) -> glib::ffi::gboolean {
807 unsafe {
808 let instance = &*(ptr as *mut T::Instance);
809 let imp = instance.imp();
810 let query = match gst::QueryRef::from_mut_ptr(query).view_mut() {
811 gst::QueryViewMut::Allocation(allocation) => allocation,
812 _ => unreachable!(),
813 };
814
815 gst::panic_to_error!(imp, false, {
816 match imp.propose_allocation(query) {
817 Ok(()) => true,
818 Err(err) => {
819 err.log_with_imp(imp);
820 false
821 }
822 }
823 })
824 .into_glib()
825 }
826}
827
828unsafe extern "C" fn video_encoder_decide_allocation<T: VideoEncoderImpl>(
829 ptr: *mut ffi::GstVideoEncoder,
830 query: *mut gst::ffi::GstQuery,
831) -> glib::ffi::gboolean {
832 unsafe {
833 let instance = &*(ptr as *mut T::Instance);
834 let imp = instance.imp();
835 let query = match gst::QueryRef::from_mut_ptr(query).view_mut() {
836 gst::QueryViewMut::Allocation(allocation) => allocation,
837 _ => unreachable!(),
838 };
839
840 gst::panic_to_error!(imp, false, {
841 match imp.decide_allocation(query) {
842 Ok(()) => true,
843 Err(err) => {
844 err.log_with_imp(imp);
845 false
846 }
847 }
848 })
849 .into_glib()
850 }
851}
852
853#[cfg(feature = "v1_30")]
854#[cfg_attr(docsrs, doc(cfg(feature = "v1_30")))]
855unsafe extern "C" fn video_encoder_prepare_allocator<T: VideoEncoderImpl>(
856 ptr: *mut ffi::GstVideoEncoder,
857 caps: *mut gst::ffi::GstCaps,
858) -> glib::ffi::gboolean {
859 unsafe {
860 let instance = &*(ptr as *mut T::Instance);
861 let imp = instance.imp();
862 let caps = Option::<gst::Caps>::from_glib_none(caps);
863
864 gst::panic_to_error!(imp, false, {
865 match imp.prepare_allocator(caps.as_ref()) {
866 Ok(()) => true,
867 Err(err) => {
868 err.log_with_imp(imp);
869 false
870 }
871 }
872 })
873 .into_glib()
874 }
875}