1 | // Take a look at the license at the top of the repository in the LICENSE file. |
2 | |
3 | use glib::translate::*; |
4 | use gst::subclass::prelude::*; |
5 | |
6 | use crate::{ |
7 | prelude::*, |
8 | video_codec_state::{Readable, VideoCodecState}, |
9 | VideoCodecFrame, VideoEncoder, |
10 | }; |
11 | |
12 | pub trait VideoEncoderImpl: VideoEncoderImplExt + ElementImpl { |
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 | |
87 | mod sealed { |
88 | pub trait Sealed {} |
89 | impl<T: super::VideoEncoderImplExt> Sealed for T {} |
90 | } |
91 | |
92 | pub trait VideoEncoderImplExt: sealed::Sealed + ObjectSubclass { |
93 | fn parent_open(&self) -> Result<(), gst::ErrorMessage> { |
94 | unsafe { |
95 | let data = Self::type_data(); |
96 | let parent_class = data.as_ref().parent_class() as *mut ffi::GstVideoEncoderClass; |
97 | (*parent_class) |
98 | .open |
99 | .map(|f| { |
100 | if from_glib(f(self |
101 | .obj() |
102 | .unsafe_cast_ref::<VideoEncoder>() |
103 | .to_glib_none() |
104 | .0)) |
105 | { |
106 | Ok(()) |
107 | } else { |
108 | Err(gst::error_msg!( |
109 | gst::CoreError::StateChange, |
110 | ["Parent function `open` failed" ] |
111 | )) |
112 | } |
113 | }) |
114 | .unwrap_or(Ok(())) |
115 | } |
116 | } |
117 | |
118 | fn parent_close(&self) -> Result<(), gst::ErrorMessage> { |
119 | unsafe { |
120 | let data = Self::type_data(); |
121 | let parent_class = data.as_ref().parent_class() as *mut ffi::GstVideoEncoderClass; |
122 | (*parent_class) |
123 | .close |
124 | .map(|f| { |
125 | if from_glib(f(self |
126 | .obj() |
127 | .unsafe_cast_ref::<VideoEncoder>() |
128 | .to_glib_none() |
129 | .0)) |
130 | { |
131 | Ok(()) |
132 | } else { |
133 | Err(gst::error_msg!( |
134 | gst::CoreError::StateChange, |
135 | ["Parent function `close` failed" ] |
136 | )) |
137 | } |
138 | }) |
139 | .unwrap_or(Ok(())) |
140 | } |
141 | } |
142 | |
143 | fn parent_start(&self) -> Result<(), gst::ErrorMessage> { |
144 | unsafe { |
145 | let data = Self::type_data(); |
146 | let parent_class = data.as_ref().parent_class() as *mut ffi::GstVideoEncoderClass; |
147 | (*parent_class) |
148 | .start |
149 | .map(|f| { |
150 | if from_glib(f(self |
151 | .obj() |
152 | .unsafe_cast_ref::<VideoEncoder>() |
153 | .to_glib_none() |
154 | .0)) |
155 | { |
156 | Ok(()) |
157 | } else { |
158 | Err(gst::error_msg!( |
159 | gst::CoreError::StateChange, |
160 | ["Parent function `start` failed" ] |
161 | )) |
162 | } |
163 | }) |
164 | .unwrap_or(Ok(())) |
165 | } |
166 | } |
167 | |
168 | fn parent_stop(&self) -> Result<(), gst::ErrorMessage> { |
169 | unsafe { |
170 | let data = Self::type_data(); |
171 | let parent_class = data.as_ref().parent_class() as *mut ffi::GstVideoEncoderClass; |
172 | (*parent_class) |
173 | .stop |
174 | .map(|f| { |
175 | if from_glib(f(self |
176 | .obj() |
177 | .unsafe_cast_ref::<VideoEncoder>() |
178 | .to_glib_none() |
179 | .0)) |
180 | { |
181 | Ok(()) |
182 | } else { |
183 | Err(gst::error_msg!( |
184 | gst::CoreError::StateChange, |
185 | ["Parent function `stop` failed" ] |
186 | )) |
187 | } |
188 | }) |
189 | .unwrap_or(Ok(())) |
190 | } |
191 | } |
192 | |
193 | fn parent_finish(&self) -> Result<gst::FlowSuccess, gst::FlowError> { |
194 | unsafe { |
195 | let data = Self::type_data(); |
196 | let parent_class = data.as_ref().parent_class() as *mut ffi::GstVideoEncoderClass; |
197 | (*parent_class) |
198 | .finish |
199 | .map(|f| { |
200 | try_from_glib(f(self |
201 | .obj() |
202 | .unsafe_cast_ref::<VideoEncoder>() |
203 | .to_glib_none() |
204 | .0)) |
205 | }) |
206 | .unwrap_or(Ok(gst::FlowSuccess::Ok)) |
207 | } |
208 | } |
209 | |
210 | fn parent_set_format( |
211 | &self, |
212 | state: &VideoCodecState<'static, Readable>, |
213 | ) -> Result<(), gst::LoggableError> { |
214 | unsafe { |
215 | let data = Self::type_data(); |
216 | let parent_class = data.as_ref().parent_class() as *mut ffi::GstVideoEncoderClass; |
217 | (*parent_class) |
218 | .set_format |
219 | .map(|f| { |
220 | gst::result_from_gboolean!( |
221 | f( |
222 | self.obj() |
223 | .unsafe_cast_ref::<VideoEncoder>() |
224 | .to_glib_none() |
225 | .0, |
226 | state.as_mut_ptr() |
227 | ), |
228 | gst::CAT_RUST, |
229 | "parent function `set_format` failed" |
230 | ) |
231 | }) |
232 | .unwrap_or(Ok(())) |
233 | } |
234 | } |
235 | |
236 | fn parent_handle_frame( |
237 | &self, |
238 | frame: VideoCodecFrame, |
239 | ) -> Result<gst::FlowSuccess, gst::FlowError> { |
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 | .handle_frame |
245 | .map(|f| { |
246 | try_from_glib(f( |
247 | self.obj() |
248 | .unsafe_cast_ref::<VideoEncoder>() |
249 | .to_glib_none() |
250 | .0, |
251 | frame.to_glib_none().0, |
252 | )) |
253 | }) |
254 | .unwrap_or(Err(gst::FlowError::Error)) |
255 | } |
256 | } |
257 | |
258 | fn parent_flush(&self) -> bool { |
259 | unsafe { |
260 | let data = Self::type_data(); |
261 | let parent_class = data.as_ref().parent_class() as *mut ffi::GstVideoEncoderClass; |
262 | (*parent_class) |
263 | .flush |
264 | .map(|f| { |
265 | from_glib(f(self |
266 | .obj() |
267 | .unsafe_cast_ref::<VideoEncoder>() |
268 | .to_glib_none() |
269 | .0)) |
270 | }) |
271 | .unwrap_or(false) |
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::GstVideoEncoderClass; |
279 | (*parent_class) |
280 | .negotiate |
281 | .map(|f| { |
282 | gst::result_from_gboolean!( |
283 | f(self |
284 | .obj() |
285 | .unsafe_cast_ref::<VideoEncoder>() |
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::GstVideoEncoderClass; |
300 | (*parent_class) |
301 | .getcaps |
302 | .map(|f| { |
303 | from_glib_full(f( |
304 | self.obj() |
305 | .unsafe_cast_ref::<VideoEncoder>() |
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::<VideoEncoder>() |
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::GstVideoEncoderClass; |
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::<VideoEncoder>() |
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::GstVideoEncoderClass; |
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::<VideoEncoder>() |
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::GstVideoEncoderClass; |
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::<VideoEncoder>() |
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::GstVideoEncoderClass; |
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::<VideoEncoder>() |
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::GstVideoEncoderClass; |
394 | (*parent_class) |
395 | .propose_allocation |
396 | .map(|f| { |
397 | gst::result_from_gboolean!( |
398 | f( |
399 | self.obj() |
400 | .unsafe_cast_ref::<VideoEncoder>() |
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::GstVideoEncoderClass; |
420 | (*parent_class) |
421 | .decide_allocation |
422 | .map(|f| { |
423 | gst::result_from_gboolean!( |
424 | f( |
425 | self.obj() |
426 | .unsafe_cast_ref::<VideoEncoder>() |
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: VideoEncoderImpl> VideoEncoderImplExt for T {} |
441 | |
442 | unsafe impl<T: VideoEncoderImpl> IsSubclassable<T> for VideoEncoder { |
443 | fn class_init(klass: &mut glib::Class<Self>) { |
444 | Self::parent_class_init::<T>(class:klass); |
445 | let klass: &mut GstVideoEncoderClass = klass.as_mut(); |
446 | klass.open = Some(video_encoder_open::<T>); |
447 | klass.close = Some(video_encoder_close::<T>); |
448 | klass.start = Some(video_encoder_start::<T>); |
449 | klass.stop = Some(video_encoder_stop::<T>); |
450 | klass.finish = Some(video_encoder_finish::<T>); |
451 | klass.set_format = Some(video_encoder_set_format::<T>); |
452 | klass.handle_frame = Some(video_encoder_handle_frame::<T>); |
453 | klass.flush = Some(video_encoder_flush::<T>); |
454 | klass.negotiate = Some(video_encoder_negotiate::<T>); |
455 | klass.getcaps = Some(video_encoder_getcaps::<T>); |
456 | klass.sink_event = Some(video_encoder_sink_event::<T>); |
457 | klass.src_event = Some(video_encoder_src_event::<T>); |
458 | klass.sink_query = Some(video_encoder_sink_query::<T>); |
459 | klass.src_query = Some(video_encoder_src_query::<T>); |
460 | klass.propose_allocation = Some(video_encoder_propose_allocation::<T>); |
461 | klass.decide_allocation = Some(video_encoder_decide_allocation::<T>); |
462 | } |
463 | } |
464 | |
465 | unsafe extern "C" fn video_encoder_open<T: VideoEncoderImpl>( |
466 | ptr: *mut ffi::GstVideoEncoder, |
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 video_encoder_close<T: VideoEncoderImpl>( |
484 | ptr: *mut ffi::GstVideoEncoder, |
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 video_encoder_start<T: VideoEncoderImpl>( |
502 | ptr: *mut ffi::GstVideoEncoder, |
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 video_encoder_stop<T: VideoEncoderImpl>( |
520 | ptr: *mut ffi::GstVideoEncoder, |
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 video_encoder_finish<T: VideoEncoderImpl>( |
538 | ptr: *mut ffi::GstVideoEncoder, |
539 | ) -> gst::ffi::GstFlowReturn { |
540 | let instance: &::Instance = &*(ptr as *mut T::Instance); |
541 | let imp: &T = instance.imp(); |
542 | |
543 | gst::panic_to_error!(imp, gst::FlowReturn::Error, { imp.finish().into() }).into_glib() |
544 | } |
545 | |
546 | unsafe extern "C" fn video_encoder_set_format<T: VideoEncoderImpl>( |
547 | ptr: *mut ffi::GstVideoEncoder, |
548 | state: *mut ffi::GstVideoCodecState, |
549 | ) -> glib::ffi::gboolean { |
550 | let instance: &::Instance = &*(ptr as *mut T::Instance); |
551 | let imp: &T = instance.imp(); |
552 | ffi::gst_video_codec_state_ref(state); |
553 | let wrap_state: VideoCodecState<'_, Readable> = VideoCodecState::<Readable>::new(state); |
554 | |
555 | gstbool::panic_to_error!(imp, false, { |
556 | match imp.set_format(&wrap_state) { |
557 | Ok(()) => true, |
558 | Err(err) => { |
559 | err.log_with_imp(imp); |
560 | false |
561 | } |
562 | } |
563 | }) |
564 | .into_glib() |
565 | } |
566 | |
567 | unsafe extern "C" fn video_encoder_handle_frame<T: VideoEncoderImpl>( |
568 | ptr: *mut ffi::GstVideoEncoder, |
569 | frame: *mut ffi::GstVideoCodecFrame, |
570 | ) -> gst::ffi::GstFlowReturn { |
571 | let instance: &::Instance = &*(ptr as *mut T::Instance); |
572 | let imp: &T = instance.imp(); |
573 | let instance: BorrowedObject<'_, ::Type> = imp.obj(); |
574 | let instance: &VideoEncoder = instance.unsafe_cast_ref::<VideoEncoder>(); |
575 | let wrap_frame: VideoCodecFrame<'_> = VideoCodecFrame::new(frame, element:instance); |
576 | |
577 | gstFlowReturn::panic_to_error!(imp, gst::FlowReturn::Error, { |
578 | imp.handle_frame(wrap_frame).into() |
579 | }) |
580 | .into_glib() |
581 | } |
582 | |
583 | unsafe extern "C" fn video_encoder_flush<T: VideoEncoderImpl>( |
584 | ptr: *mut ffi::GstVideoEncoder, |
585 | ) -> glib::ffi::gboolean { |
586 | let instance: &::Instance = &*(ptr as *mut T::Instance); |
587 | let imp: &T = instance.imp(); |
588 | |
589 | gst::panic_to_error!(imp, false, { VideoEncoderImpl::flush(imp) }).into_glib() |
590 | } |
591 | |
592 | unsafe extern "C" fn video_encoder_negotiate<T: VideoEncoderImpl>( |
593 | ptr: *mut ffi::GstVideoEncoder, |
594 | ) -> glib::ffi::gboolean { |
595 | let instance: &::Instance = &*(ptr as *mut T::Instance); |
596 | let imp: &T = instance.imp(); |
597 | |
598 | gstbool::panic_to_error!(imp, false, { |
599 | match imp.negotiate() { |
600 | Ok(()) => true, |
601 | Err(err) => { |
602 | err.log_with_imp(imp); |
603 | false |
604 | } |
605 | } |
606 | }) |
607 | .into_glib() |
608 | } |
609 | |
610 | unsafe extern "C" fn video_encoder_getcaps<T: VideoEncoderImpl>( |
611 | ptr: *mut ffi::GstVideoEncoder, |
612 | filter: *mut gst::ffi::GstCaps, |
613 | ) -> *mut gst::ffi::GstCaps { |
614 | let instance: &::Instance = &*(ptr as *mut T::Instance); |
615 | let imp: &T = instance.imp(); |
616 | |
617 | gstCaps::panic_to_error!(imp, gst::Caps::new_empty(), { |
618 | VideoEncoderImpl::caps( |
619 | imp, |
620 | Option::<gst::Caps>::from_glib_borrow(filter) |
621 | .as_ref() |
622 | .as_ref(), |
623 | ) |
624 | }) |
625 | .into_glib_ptr() |
626 | } |
627 | |
628 | unsafe extern "C" fn video_encoder_sink_event<T: VideoEncoderImpl>( |
629 | ptr: *mut ffi::GstVideoEncoder, |
630 | event: *mut gst::ffi::GstEvent, |
631 | ) -> glib::ffi::gboolean { |
632 | let instance: &::Instance = &*(ptr as *mut T::Instance); |
633 | let imp: &T = instance.imp(); |
634 | |
635 | gst::panic_to_error!(imp, false, { imp.sink_event(from_glib_full(event)) }).into_glib() |
636 | } |
637 | |
638 | unsafe extern "C" fn video_encoder_sink_query<T: VideoEncoderImpl>( |
639 | ptr: *mut ffi::GstVideoEncoder, |
640 | query: *mut gst::ffi::GstQuery, |
641 | ) -> glib::ffi::gboolean { |
642 | let instance: &::Instance = &*(ptr as *mut T::Instance); |
643 | let imp: &T = instance.imp(); |
644 | |
645 | gstbool::panic_to_error!(imp, false, { |
646 | imp.sink_query(gst::QueryRef::from_mut_ptr(query)) |
647 | }) |
648 | .into_glib() |
649 | } |
650 | |
651 | unsafe extern "C" fn video_encoder_src_event<T: VideoEncoderImpl>( |
652 | ptr: *mut ffi::GstVideoEncoder, |
653 | event: *mut gst::ffi::GstEvent, |
654 | ) -> glib::ffi::gboolean { |
655 | let instance: &::Instance = &*(ptr as *mut T::Instance); |
656 | let imp: &T = instance.imp(); |
657 | |
658 | gst::panic_to_error!(imp, false, { imp.src_event(from_glib_full(event)) }).into_glib() |
659 | } |
660 | |
661 | unsafe extern "C" fn video_encoder_src_query<T: VideoEncoderImpl>( |
662 | ptr: *mut ffi::GstVideoEncoder, |
663 | query: *mut gst::ffi::GstQuery, |
664 | ) -> glib::ffi::gboolean { |
665 | let instance: &::Instance = &*(ptr as *mut T::Instance); |
666 | let imp: &T = instance.imp(); |
667 | |
668 | gstbool::panic_to_error!(imp, false, { |
669 | imp.src_query(gst::QueryRef::from_mut_ptr(query)) |
670 | }) |
671 | .into_glib() |
672 | } |
673 | |
674 | unsafe extern "C" fn video_encoder_propose_allocation<T: VideoEncoderImpl>( |
675 | ptr: *mut ffi::GstVideoEncoder, |
676 | query: *mut gst::ffi::GstQuery, |
677 | ) -> glib::ffi::gboolean { |
678 | let instance: &::Instance = &*(ptr as *mut T::Instance); |
679 | let imp: &T = instance.imp(); |
680 | let query: &mut Allocation = match gst::QueryRef::from_mut_ptr(query).view_mut() { |
681 | gst::QueryViewMut::Allocation(allocation: &mut Allocation) => allocation, |
682 | _ => unreachable!(), |
683 | }; |
684 | |
685 | gstbool::panic_to_error!(imp, false, { |
686 | match imp.propose_allocation(query) { |
687 | Ok(()) => true, |
688 | Err(err) => { |
689 | err.log_with_imp(imp); |
690 | false |
691 | } |
692 | } |
693 | }) |
694 | .into_glib() |
695 | } |
696 | |
697 | unsafe extern "C" fn video_encoder_decide_allocation<T: VideoEncoderImpl>( |
698 | ptr: *mut ffi::GstVideoEncoder, |
699 | query: *mut gst::ffi::GstQuery, |
700 | ) -> glib::ffi::gboolean { |
701 | let instance: &::Instance = &*(ptr as *mut T::Instance); |
702 | let imp: &T = instance.imp(); |
703 | let query: &mut Allocation = match gst::QueryRef::from_mut_ptr(query).view_mut() { |
704 | gst::QueryViewMut::Allocation(allocation: &mut Allocation) => allocation, |
705 | _ => unreachable!(), |
706 | }; |
707 | |
708 | gstbool::panic_to_error!(imp, false, { |
709 | match imp.decide_allocation(query) { |
710 | Ok(()) => true, |
711 | Err(err) => { |
712 | err.log_with_imp(imp); |
713 | false |
714 | } |
715 | } |
716 | }) |
717 | .into_glib() |
718 | } |
719 | |