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