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