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 | ffi, |
8 | prelude::*, |
9 | video_codec_state::{Readable, VideoCodecState}, |
10 | VideoCodecFrame, VideoEncoder, |
11 | }; |
12 | |
13 | pub trait VideoEncoderImpl: VideoEncoderImplExt + ElementImpl { |
14 | fn open(&self) -> Result<(), gst::ErrorMessage> { |
15 | self.parent_open() |
16 | } |
17 | |
18 | fn close(&self) -> Result<(), gst::ErrorMessage> { |
19 | self.parent_close() |
20 | } |
21 | |
22 | fn start(&self) -> Result<(), gst::ErrorMessage> { |
23 | self.parent_start() |
24 | } |
25 | |
26 | fn stop(&self) -> Result<(), gst::ErrorMessage> { |
27 | self.parent_stop() |
28 | } |
29 | |
30 | fn finish(&self) -> Result<gst::FlowSuccess, gst::FlowError> { |
31 | self.parent_finish() |
32 | } |
33 | |
34 | fn set_format( |
35 | &self, |
36 | state: &VideoCodecState<'static, Readable>, |
37 | ) -> Result<(), gst::LoggableError> { |
38 | self.parent_set_format(state) |
39 | } |
40 | |
41 | fn handle_frame(&self, frame: VideoCodecFrame) -> Result<gst::FlowSuccess, gst::FlowError> { |
42 | self.parent_handle_frame(frame) |
43 | } |
44 | |
45 | fn flush(&self) -> bool { |
46 | self.parent_flush() |
47 | } |
48 | |
49 | fn negotiate(&self) -> Result<(), gst::LoggableError> { |
50 | self.parent_negotiate() |
51 | } |
52 | |
53 | fn caps(&self, filter: Option<&gst::Caps>) -> gst::Caps { |
54 | self.parent_caps(filter) |
55 | } |
56 | |
57 | fn sink_event(&self, event: gst::Event) -> bool { |
58 | self.parent_sink_event(event) |
59 | } |
60 | |
61 | fn sink_query(&self, query: &mut gst::QueryRef) -> bool { |
62 | self.parent_sink_query(query) |
63 | } |
64 | |
65 | fn src_event(&self, event: gst::Event) -> bool { |
66 | self.parent_src_event(event) |
67 | } |
68 | |
69 | fn src_query(&self, query: &mut gst::QueryRef) -> bool { |
70 | self.parent_src_query(query) |
71 | } |
72 | |
73 | fn propose_allocation( |
74 | &self, |
75 | query: &mut gst::query::Allocation, |
76 | ) -> Result<(), gst::LoggableError> { |
77 | self.parent_propose_allocation(query) |
78 | } |
79 | |
80 | fn decide_allocation( |
81 | &self, |
82 | query: &mut gst::query::Allocation, |
83 | ) -> Result<(), gst::LoggableError> { |
84 | self.parent_decide_allocation(query) |
85 | } |
86 | } |
87 | |
88 | mod sealed { |
89 | pub trait Sealed {} |
90 | impl<T: super::VideoEncoderImplExt> Sealed for T {} |
91 | } |
92 | |
93 | pub trait VideoEncoderImplExt: sealed::Sealed + ObjectSubclass { |
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 | |
441 | impl<T: VideoEncoderImpl> VideoEncoderImplExt for T {} |
442 | |
443 | unsafe impl<T: VideoEncoderImpl> IsSubclassable<T> for VideoEncoder { |
444 | fn class_init(klass: &mut glib::Class<Self>) { |
445 | Self::parent_class_init::<T>(class:klass); |
446 | let klass: &mut GstVideoEncoderClass = klass.as_mut(); |
447 | klass.open = Some(video_encoder_open::<T>); |
448 | klass.close = Some(video_encoder_close::<T>); |
449 | klass.start = Some(video_encoder_start::<T>); |
450 | klass.stop = Some(video_encoder_stop::<T>); |
451 | klass.finish = Some(video_encoder_finish::<T>); |
452 | klass.set_format = Some(video_encoder_set_format::<T>); |
453 | klass.handle_frame = Some(video_encoder_handle_frame::<T>); |
454 | klass.flush = Some(video_encoder_flush::<T>); |
455 | klass.negotiate = Some(video_encoder_negotiate::<T>); |
456 | klass.getcaps = Some(video_encoder_getcaps::<T>); |
457 | klass.sink_event = Some(video_encoder_sink_event::<T>); |
458 | klass.src_event = Some(video_encoder_src_event::<T>); |
459 | klass.sink_query = Some(video_encoder_sink_query::<T>); |
460 | klass.src_query = Some(video_encoder_src_query::<T>); |
461 | klass.propose_allocation = Some(video_encoder_propose_allocation::<T>); |
462 | klass.decide_allocation = Some(video_encoder_decide_allocation::<T>); |
463 | } |
464 | } |
465 | |
466 | unsafe extern "C" fn video_encoder_open<T: VideoEncoderImpl>( |
467 | ptr: *mut ffi::GstVideoEncoder, |
468 | ) -> glib::ffi::gboolean { |
469 | let instance: &::Instance = &*(ptr as *mut T::Instance); |
470 | let imp: &T = instance.imp(); |
471 | |
472 | gstbool::panic_to_error!(imp, false, { |
473 | match imp.open() { |
474 | Ok(()) => true, |
475 | Err(err) => { |
476 | imp.post_error_message(err); |
477 | false |
478 | } |
479 | } |
480 | }) |
481 | .into_glib() |
482 | } |
483 | |
484 | unsafe extern "C" fn video_encoder_close<T: VideoEncoderImpl>( |
485 | ptr: *mut ffi::GstVideoEncoder, |
486 | ) -> glib::ffi::gboolean { |
487 | let instance: &::Instance = &*(ptr as *mut T::Instance); |
488 | let imp: &T = instance.imp(); |
489 | |
490 | gstbool::panic_to_error!(imp, false, { |
491 | match imp.close() { |
492 | Ok(()) => true, |
493 | Err(err) => { |
494 | imp.post_error_message(err); |
495 | false |
496 | } |
497 | } |
498 | }) |
499 | .into_glib() |
500 | } |
501 | |
502 | unsafe extern "C" fn video_encoder_start<T: VideoEncoderImpl>( |
503 | ptr: *mut ffi::GstVideoEncoder, |
504 | ) -> glib::ffi::gboolean { |
505 | let instance: &::Instance = &*(ptr as *mut T::Instance); |
506 | let imp: &T = instance.imp(); |
507 | |
508 | gstbool::panic_to_error!(imp, false, { |
509 | match imp.start() { |
510 | Ok(()) => true, |
511 | Err(err) => { |
512 | imp.post_error_message(err); |
513 | false |
514 | } |
515 | } |
516 | }) |
517 | .into_glib() |
518 | } |
519 | |
520 | unsafe extern "C" fn video_encoder_stop<T: VideoEncoderImpl>( |
521 | ptr: *mut ffi::GstVideoEncoder, |
522 | ) -> glib::ffi::gboolean { |
523 | let instance: &::Instance = &*(ptr as *mut T::Instance); |
524 | let imp: &T = instance.imp(); |
525 | |
526 | gstbool::panic_to_error!(imp, false, { |
527 | match imp.stop() { |
528 | Ok(()) => true, |
529 | Err(err) => { |
530 | imp.post_error_message(err); |
531 | false |
532 | } |
533 | } |
534 | }) |
535 | .into_glib() |
536 | } |
537 | |
538 | unsafe extern "C" fn video_encoder_finish<T: VideoEncoderImpl>( |
539 | ptr: *mut ffi::GstVideoEncoder, |
540 | ) -> gst::ffi::GstFlowReturn { |
541 | let instance: &::Instance = &*(ptr as *mut T::Instance); |
542 | let imp: &T = instance.imp(); |
543 | |
544 | gst::panic_to_error!(imp, gst::FlowReturn::Error, { imp.finish().into() }).into_glib() |
545 | } |
546 | |
547 | unsafe extern "C" fn video_encoder_set_format<T: VideoEncoderImpl>( |
548 | ptr: *mut ffi::GstVideoEncoder, |
549 | state: *mut ffi::GstVideoCodecState, |
550 | ) -> glib::ffi::gboolean { |
551 | let instance: &::Instance = &*(ptr as *mut T::Instance); |
552 | let imp: &T = instance.imp(); |
553 | ffi::gst_video_codec_state_ref(state); |
554 | let wrap_state: VideoCodecState<'_, Readable> = VideoCodecState::<Readable>::new(state); |
555 | |
556 | gstbool::panic_to_error!(imp, false, { |
557 | match imp.set_format(&wrap_state) { |
558 | Ok(()) => true, |
559 | Err(err) => { |
560 | err.log_with_imp(imp); |
561 | false |
562 | } |
563 | } |
564 | }) |
565 | .into_glib() |
566 | } |
567 | |
568 | unsafe extern "C" fn video_encoder_handle_frame<T: VideoEncoderImpl>( |
569 | ptr: *mut ffi::GstVideoEncoder, |
570 | frame: *mut ffi::GstVideoCodecFrame, |
571 | ) -> gst::ffi::GstFlowReturn { |
572 | let instance: &::Instance = &*(ptr as *mut T::Instance); |
573 | let imp: &T = instance.imp(); |
574 | let instance: BorrowedObject<'_, ::Type> = imp.obj(); |
575 | let instance: &VideoEncoder = instance.unsafe_cast_ref::<VideoEncoder>(); |
576 | let wrap_frame: VideoCodecFrame<'_> = VideoCodecFrame::new(frame, element:instance); |
577 | |
578 | gstFlowReturn::panic_to_error!(imp, gst::FlowReturn::Error, { |
579 | imp.handle_frame(wrap_frame).into() |
580 | }) |
581 | .into_glib() |
582 | } |
583 | |
584 | unsafe extern "C" fn video_encoder_flush<T: VideoEncoderImpl>( |
585 | ptr: *mut ffi::GstVideoEncoder, |
586 | ) -> glib::ffi::gboolean { |
587 | let instance: &::Instance = &*(ptr as *mut T::Instance); |
588 | let imp: &T = instance.imp(); |
589 | |
590 | gst::panic_to_error!(imp, false, { VideoEncoderImpl::flush(imp) }).into_glib() |
591 | } |
592 | |
593 | unsafe extern "C" fn video_encoder_negotiate<T: VideoEncoderImpl>( |
594 | ptr: *mut ffi::GstVideoEncoder, |
595 | ) -> glib::ffi::gboolean { |
596 | let instance: &::Instance = &*(ptr as *mut T::Instance); |
597 | let imp: &T = instance.imp(); |
598 | |
599 | gstbool::panic_to_error!(imp, false, { |
600 | match imp.negotiate() { |
601 | Ok(()) => true, |
602 | Err(err) => { |
603 | err.log_with_imp(imp); |
604 | false |
605 | } |
606 | } |
607 | }) |
608 | .into_glib() |
609 | } |
610 | |
611 | unsafe extern "C" fn video_encoder_getcaps<T: VideoEncoderImpl>( |
612 | ptr: *mut ffi::GstVideoEncoder, |
613 | filter: *mut gst::ffi::GstCaps, |
614 | ) -> *mut gst::ffi::GstCaps { |
615 | let instance: &::Instance = &*(ptr as *mut T::Instance); |
616 | let imp: &T = instance.imp(); |
617 | |
618 | gstCaps::panic_to_error!(imp, gst::Caps::new_empty(), { |
619 | VideoEncoderImpl::caps( |
620 | imp, |
621 | Option::<gst::Caps>::from_glib_borrow(filter) |
622 | .as_ref() |
623 | .as_ref(), |
624 | ) |
625 | }) |
626 | .into_glib_ptr() |
627 | } |
628 | |
629 | unsafe extern "C" fn video_encoder_sink_event<T: VideoEncoderImpl>( |
630 | ptr: *mut ffi::GstVideoEncoder, |
631 | event: *mut gst::ffi::GstEvent, |
632 | ) -> glib::ffi::gboolean { |
633 | let instance: &::Instance = &*(ptr as *mut T::Instance); |
634 | let imp: &T = instance.imp(); |
635 | |
636 | gst::panic_to_error!(imp, false, { imp.sink_event(from_glib_full(event)) }).into_glib() |
637 | } |
638 | |
639 | unsafe extern "C" fn video_encoder_sink_query<T: VideoEncoderImpl>( |
640 | ptr: *mut ffi::GstVideoEncoder, |
641 | query: *mut gst::ffi::GstQuery, |
642 | ) -> glib::ffi::gboolean { |
643 | let instance: &::Instance = &*(ptr as *mut T::Instance); |
644 | let imp: &T = instance.imp(); |
645 | |
646 | gstbool::panic_to_error!(imp, false, { |
647 | imp.sink_query(gst::QueryRef::from_mut_ptr(query)) |
648 | }) |
649 | .into_glib() |
650 | } |
651 | |
652 | unsafe extern "C" fn video_encoder_src_event<T: VideoEncoderImpl>( |
653 | ptr: *mut ffi::GstVideoEncoder, |
654 | event: *mut gst::ffi::GstEvent, |
655 | ) -> glib::ffi::gboolean { |
656 | let instance: &::Instance = &*(ptr as *mut T::Instance); |
657 | let imp: &T = instance.imp(); |
658 | |
659 | gst::panic_to_error!(imp, false, { imp.src_event(from_glib_full(event)) }).into_glib() |
660 | } |
661 | |
662 | unsafe extern "C" fn video_encoder_src_query<T: VideoEncoderImpl>( |
663 | ptr: *mut ffi::GstVideoEncoder, |
664 | query: *mut gst::ffi::GstQuery, |
665 | ) -> glib::ffi::gboolean { |
666 | let instance: &::Instance = &*(ptr as *mut T::Instance); |
667 | let imp: &T = instance.imp(); |
668 | |
669 | gstbool::panic_to_error!(imp, false, { |
670 | imp.src_query(gst::QueryRef::from_mut_ptr(query)) |
671 | }) |
672 | .into_glib() |
673 | } |
674 | |
675 | unsafe extern "C" fn video_encoder_propose_allocation<T: VideoEncoderImpl>( |
676 | ptr: *mut ffi::GstVideoEncoder, |
677 | query: *mut gst::ffi::GstQuery, |
678 | ) -> glib::ffi::gboolean { |
679 | let instance: &::Instance = &*(ptr as *mut T::Instance); |
680 | let imp: &T = instance.imp(); |
681 | let query: &mut Allocation = match gst::QueryRef::from_mut_ptr(query).view_mut() { |
682 | gst::QueryViewMut::Allocation(allocation: &mut Allocation) => allocation, |
683 | _ => unreachable!(), |
684 | }; |
685 | |
686 | gstbool::panic_to_error!(imp, false, { |
687 | match imp.propose_allocation(query) { |
688 | Ok(()) => true, |
689 | Err(err) => { |
690 | err.log_with_imp(imp); |
691 | false |
692 | } |
693 | } |
694 | }) |
695 | .into_glib() |
696 | } |
697 | |
698 | unsafe extern "C" fn video_encoder_decide_allocation<T: VideoEncoderImpl>( |
699 | ptr: *mut ffi::GstVideoEncoder, |
700 | query: *mut gst::ffi::GstQuery, |
701 | ) -> glib::ffi::gboolean { |
702 | let instance: &::Instance = &*(ptr as *mut T::Instance); |
703 | let imp: &T = instance.imp(); |
704 | let query: &mut Allocation = match gst::QueryRef::from_mut_ptr(query).view_mut() { |
705 | gst::QueryViewMut::Allocation(allocation: &mut Allocation) => allocation, |
706 | _ => unreachable!(), |
707 | }; |
708 | |
709 | gstbool::panic_to_error!(imp, false, { |
710 | match imp.decide_allocation(query) { |
711 | Ok(()) => true, |
712 | Err(err) => { |
713 | err.log_with_imp(imp); |
714 | false |
715 | } |
716 | } |
717 | }) |
718 | .into_glib() |
719 | } |
720 | |