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