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