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