gstreamer_video/
video_converter.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use std::{ops, ptr};
4
5use crate::{ffi, prelude::*};
6use glib::{prelude::*, translate::*};
7
8#[derive(Debug)]
9#[doc(alias = "GstVideoConverter")]
10pub struct VideoConverter(ptr::NonNull<ffi::GstVideoConverter>);
11
12impl Drop for VideoConverter {
13    #[inline]
14    fn drop(&mut self) {
15        unsafe {
16            ffi::gst_video_converter_free(self.0.as_ptr());
17        }
18    }
19}
20
21unsafe impl Send for VideoConverter {}
22unsafe impl Sync for VideoConverter {}
23
24impl VideoConverter {
25    #[doc(alias = "gst_video_converter_new")]
26    pub fn new(
27        in_info: &crate::VideoInfo,
28        out_info: &crate::VideoInfo,
29        config: Option<VideoConverterConfig>,
30    ) -> Result<Self, glib::BoolError> {
31        skip_assert_initialized!();
32        if in_info.fps() != out_info.fps() {
33            return Err(glib::bool_error!("Can't do framerate conversion"));
34        }
35
36        if in_info.interlace_mode() != out_info.interlace_mode() {
37            return Err(glib::bool_error!("Can't do interlacing conversion"));
38        }
39
40        unsafe {
41            let ptr = ffi::gst_video_converter_new(
42                in_info.to_glib_none().0 as *mut _,
43                out_info.to_glib_none().0 as *mut _,
44                config
45                    .map(|s| s.0.into_glib_ptr())
46                    .unwrap_or(ptr::null_mut()),
47            );
48            if ptr.is_null() {
49                Err(glib::bool_error!("Failed to create video converter"))
50            } else {
51                Ok(Self(ptr::NonNull::new_unchecked(ptr)))
52            }
53        }
54    }
55
56    #[doc(alias = "get_config")]
57    #[doc(alias = "gst_video_converter_get_config")]
58    pub fn config(&self) -> VideoConverterConfig {
59        unsafe {
60            VideoConverterConfig(
61                gst::StructureRef::from_glib_borrow(ffi::gst_video_converter_get_config(
62                    self.0.as_ptr(),
63                ))
64                .to_owned(),
65            )
66        }
67    }
68
69    #[doc(alias = "gst_video_converter_set_config")]
70    pub fn set_config(&mut self, config: VideoConverterConfig) {
71        unsafe {
72            ffi::gst_video_converter_set_config(self.0.as_ptr(), config.0.into_glib_ptr());
73        }
74    }
75
76    #[cfg(feature = "v1_22")]
77    #[cfg_attr(docsrs, doc(cfg(feature = "v1_22")))]
78    #[doc(alias = "get_in_info")]
79    #[doc(alias = "gst_video_converter_get_in_info")]
80    pub fn in_info(&self) -> crate::VideoInfo {
81        unsafe { from_glib_none(ffi::gst_video_converter_get_in_info(self.0.as_ptr())) }
82    }
83
84    #[cfg(feature = "v1_22")]
85    #[cfg_attr(docsrs, doc(cfg(feature = "v1_22")))]
86    #[doc(alias = "get_out_info")]
87    #[doc(alias = "gst_video_converter_get_out_info")]
88    pub fn out_info(&self) -> crate::VideoInfo {
89        unsafe { from_glib_none(ffi::gst_video_converter_get_out_info(self.0.as_ptr())) }
90    }
91
92    #[doc(alias = "gst_video_converter_frame")]
93    pub fn frame<T>(
94        &self,
95        src: &crate::VideoFrame<T>,
96        dest: &mut crate::VideoFrame<crate::video_frame::Writable>,
97    ) {
98        unsafe {
99            ffi::gst_video_converter_frame(self.0.as_ptr(), src.as_ptr(), dest.as_mut_ptr());
100        }
101    }
102
103    pub fn frame_ref<T>(
104        &self,
105        src: &crate::VideoFrameRef<T>,
106        dest: &mut crate::VideoFrameRef<&mut gst::BufferRef>,
107    ) {
108        unsafe {
109            ffi::gst_video_converter_frame(self.0.as_ptr(), src.as_ptr(), dest.as_mut_ptr());
110        }
111    }
112}
113
114#[derive(Debug, Clone, PartialEq, Eq)]
115pub struct VideoConverterConfig(gst::Structure);
116
117impl ops::Deref for VideoConverterConfig {
118    type Target = gst::StructureRef;
119
120    #[inline]
121    fn deref(&self) -> &gst::StructureRef {
122        self.0.deref()
123    }
124}
125
126impl ops::DerefMut for VideoConverterConfig {
127    #[inline]
128    fn deref_mut(&mut self) -> &mut gst::StructureRef {
129        self.0.deref_mut()
130    }
131}
132
133impl AsRef<gst::StructureRef> for VideoConverterConfig {
134    #[inline]
135    fn as_ref(&self) -> &gst::StructureRef {
136        self.0.as_ref()
137    }
138}
139
140impl AsMut<gst::StructureRef> for VideoConverterConfig {
141    #[inline]
142    fn as_mut(&mut self) -> &mut gst::StructureRef {
143        self.0.as_mut()
144    }
145}
146
147impl Default for VideoConverterConfig {
148    fn default() -> Self {
149        Self::new()
150    }
151}
152
153impl TryFrom<gst::Structure> for VideoConverterConfig {
154    type Error = glib::BoolError;
155
156    fn try_from(v: gst::Structure) -> Result<Self, Self::Error> {
157        skip_assert_initialized!();
158        if v.name() == "GstVideoConverter" {
159            Ok(Self(v))
160        } else {
161            Err(glib::bool_error!("Structure is no VideoConverterConfig"))
162        }
163    }
164}
165
166impl<'a> TryFrom<&'a gst::StructureRef> for VideoConverterConfig {
167    type Error = glib::BoolError;
168
169    fn try_from(v: &'a gst::StructureRef) -> Result<Self, Self::Error> {
170        skip_assert_initialized!();
171        Self::try_from(v.to_owned())
172    }
173}
174
175impl From<VideoConverterConfig> for gst::Structure {
176    fn from(v: VideoConverterConfig) -> Self {
177        skip_assert_initialized!();
178        v.0
179    }
180}
181
182impl glib::value::ToValue for VideoConverterConfig {
183    fn to_value(&self) -> glib::Value {
184        self.0.to_value()
185    }
186
187    fn value_type(&self) -> glib::Type {
188        self.0.value_type()
189    }
190}
191
192impl glib::value::ToValueOptional for VideoConverterConfig {
193    fn to_value_optional(s: Option<&Self>) -> glib::Value {
194        skip_assert_initialized!();
195        s.map(|s| &s.0).to_value()
196    }
197}
198
199impl From<VideoConverterConfig> for glib::Value {
200    fn from(s: VideoConverterConfig) -> glib::Value {
201        skip_assert_initialized!();
202        s.0.into()
203    }
204}
205
206impl VideoConverterConfig {
207    pub fn new() -> Self {
208        Self(gst::Structure::new_empty("GstVideoConverter"))
209    }
210
211    pub fn set_resampler_method(&mut self, v: crate::VideoResamplerMethod) {
212        self.0
213            .set(glib::gstr!("GstVideoConverter.resampler-method"), v);
214    }
215
216    #[doc(alias = "get_resampler_method")]
217    pub fn resampler_method(&self) -> crate::VideoResamplerMethod {
218        self.0
219            .get_optional(glib::gstr!("GstVideoConverter.resampler-method"))
220            .expect("Wrong type")
221            .unwrap_or(crate::VideoResamplerMethod::Cubic)
222    }
223
224    pub fn set_chroma_resampler_method(&mut self, v: crate::VideoResamplerMethod) {
225        self.0
226            .set(glib::gstr!("GstVideoConverter.chroma-resampler-method"), v);
227    }
228
229    #[doc(alias = "get_chroma_resampler_method")]
230    pub fn chroma_resampler_method(&self) -> crate::VideoResamplerMethod {
231        self.0
232            .get_optional(glib::gstr!("GstVideoConverter.chroma-resampler-method"))
233            .expect("Wrong type")
234            .unwrap_or(crate::VideoResamplerMethod::Linear)
235    }
236
237    pub fn set_resampler_taps(&mut self, v: u32) {
238        self.0
239            .set(glib::gstr!("GstVideoConverter.resampler-taps"), v);
240    }
241
242    #[doc(alias = "get_resampler_taps")]
243    pub fn resampler_taps(&self) -> u32 {
244        self.0
245            .get_optional(glib::gstr!("GstVideoConverter.resampler-taps"))
246            .expect("Wrong type")
247            .unwrap_or(0)
248    }
249
250    pub fn set_dither_method(&mut self, v: crate::VideoDitherMethod) {
251        self.0
252            .set(glib::gstr!("GstVideoConverter.dither-method"), v);
253    }
254
255    #[doc(alias = "get_dither_method")]
256    pub fn dither_method(&self) -> crate::VideoDitherMethod {
257        self.0
258            .get_optional(glib::gstr!("GstVideoConverter.dither-method"))
259            .expect("Wrong type")
260            .unwrap_or(crate::VideoDitherMethod::Bayer)
261    }
262
263    pub fn set_dither_quantization(&mut self, v: u32) {
264        self.0
265            .set(glib::gstr!("GstVideoConverter.dither-quantization"), v);
266    }
267
268    #[doc(alias = "get_dither_quantization")]
269    pub fn dither_quantization(&self) -> u32 {
270        self.0
271            .get_optional(glib::gstr!("GstVideoConverter.dither-quantization"))
272            .expect("Wrong type")
273            .unwrap_or(1)
274    }
275
276    pub fn set_src_x(&mut self, v: i32) {
277        self.0.set(glib::gstr!("GstVideoConverter.src-x"), v);
278    }
279
280    #[doc(alias = "get_src_x")]
281    pub fn src_x(&self) -> i32 {
282        self.0
283            .get_optional(glib::gstr!("GstVideoConverter.src-x"))
284            .expect("Wrong type")
285            .unwrap_or(0)
286    }
287
288    pub fn set_src_y(&mut self, v: i32) {
289        self.0.set(glib::gstr!("GstVideoConverter.src-y"), v);
290    }
291
292    #[doc(alias = "get_src_y")]
293    pub fn src_y(&self) -> i32 {
294        self.0
295            .get_optional(glib::gstr!("GstVideoConverter.src-y"))
296            .expect("Wrong type")
297            .unwrap_or(0)
298    }
299
300    pub fn set_src_width(&mut self, v: Option<i32>) {
301        if let Some(v) = v {
302            self.0.set(glib::gstr!("GstVideoConverter.src-width"), v);
303        } else {
304            self.0
305                .remove_field(glib::gstr!("GstVideoConverter.src-width"));
306        }
307    }
308
309    #[doc(alias = "get_src_width")]
310    pub fn src_width(&self) -> Option<i32> {
311        self.0
312            .get_optional(glib::gstr!("GstVideoConverter.src-width"))
313            .expect("Wrong type")
314    }
315
316    pub fn set_src_height(&mut self, v: Option<i32>) {
317        if let Some(v) = v {
318            self.0.set(glib::gstr!("GstVideoConverter.src-height"), v);
319        } else {
320            self.0
321                .remove_field(glib::gstr!("GstVideoConverter.src-height"));
322        }
323    }
324
325    #[doc(alias = "get_src_height")]
326    pub fn src_height(&self) -> Option<i32> {
327        self.0
328            .get_optional(glib::gstr!("GstVideoConverter.src-height"))
329            .expect("Wrong type")
330    }
331
332    pub fn set_dest_x(&mut self, v: i32) {
333        self.0.set(glib::gstr!("GstVideoConverter.dest-x"), v);
334    }
335
336    #[doc(alias = "get_dest_x")]
337    pub fn dest_x(&self) -> i32 {
338        self.0
339            .get_optional(glib::gstr!("GstVideoConverter.dest-x"))
340            .expect("Wrong type")
341            .unwrap_or(0)
342    }
343
344    pub fn set_dest_y(&mut self, v: i32) {
345        self.0.set(glib::gstr!("GstVideoConverter.dest-y"), v);
346    }
347
348    #[doc(alias = "get_dest_y")]
349    pub fn dest_y(&self) -> i32 {
350        self.0
351            .get_optional(glib::gstr!("GstVideoConverter.dest-y"))
352            .expect("Wrong type")
353            .unwrap_or(0)
354    }
355
356    pub fn set_dest_width(&mut self, v: Option<i32>) {
357        if let Some(v) = v {
358            self.0.set(glib::gstr!("GstVideoConverter.dest-width"), v);
359        } else {
360            self.0
361                .remove_field(glib::gstr!("GstVideoConverter.dest-width"));
362        }
363    }
364
365    #[doc(alias = "get_dest_width")]
366    pub fn dest_width(&self) -> Option<i32> {
367        self.0
368            .get_optional(glib::gstr!("GstVideoConverter.dest-width"))
369            .expect("Wrong type")
370    }
371
372    pub fn set_dest_height(&mut self, v: Option<i32>) {
373        if let Some(v) = v {
374            self.0.set(glib::gstr!("GstVideoConverter.dest-height"), v);
375        } else {
376            self.0
377                .remove_field(glib::gstr!("GstVideoConverter.dest-height"));
378        }
379    }
380
381    #[doc(alias = "get_dest_height")]
382    pub fn dest_height(&self) -> Option<i32> {
383        self.0
384            .get_optional(glib::gstr!("GstVideoConverter.dest-height"))
385            .expect("Wrong type")
386    }
387
388    pub fn set_fill_border(&mut self, v: bool) {
389        self.0.set(glib::gstr!("GstVideoConverter.fill-border"), v);
390    }
391
392    #[doc(alias = "get_fill_border")]
393    pub fn fills_border(&self) -> bool {
394        self.0
395            .get_optional(glib::gstr!("GstVideoConverter.fill-border"))
396            .expect("Wrong type")
397            .unwrap_or(true)
398    }
399
400    pub fn set_alpha_value(&mut self, v: f64) {
401        self.0.set(glib::gstr!("GstVideoConverter.alpha-value"), v);
402    }
403
404    #[doc(alias = "get_alpha_value")]
405    pub fn alpha_value(&self) -> f64 {
406        self.0
407            .get_optional(glib::gstr!("GstVideoConverter.alpha-value"))
408            .expect("Wrong type")
409            .unwrap_or(1.0)
410    }
411
412    pub fn set_alpha_mode(&mut self, v: crate::VideoAlphaMode) {
413        self.0.set(glib::gstr!("GstVideoConverter.alpha-mode"), v);
414    }
415
416    #[doc(alias = "get_alpha_mode")]
417    pub fn alpha_mode(&self) -> crate::VideoAlphaMode {
418        self.0
419            .get_optional(glib::gstr!("GstVideoConverter.alpha-mode"))
420            .expect("Wrong type")
421            .unwrap_or(crate::VideoAlphaMode::Copy)
422    }
423
424    pub fn set_border_argb(&mut self, v: u32) {
425        self.0.set(glib::gstr!("GstVideoConverter.border-argb"), v);
426    }
427
428    #[doc(alias = "get_border_argb")]
429    pub fn border_argb(&self) -> u32 {
430        self.0
431            .get_optional(glib::gstr!("GstVideoConverter.border-argb"))
432            .expect("Wrong type")
433            .unwrap_or(0xff_00_00_00)
434    }
435
436    pub fn set_chroma_mode(&mut self, v: crate::VideoChromaMode) {
437        self.0.set(glib::gstr!("GstVideoConverter.chroma-mode"), v);
438    }
439
440    #[doc(alias = "get_chroma_mode")]
441    pub fn chroma_mode(&self) -> crate::VideoChromaMode {
442        self.0
443            .get_optional(glib::gstr!("GstVideoConverter.chroma-mode"))
444            .expect("Wrong type")
445            .unwrap_or(crate::VideoChromaMode::Full)
446    }
447
448    pub fn set_matrix_mode(&mut self, v: crate::VideoMatrixMode) {
449        self.0.set(glib::gstr!("GstVideoConverter.matrix-mode"), v);
450    }
451
452    #[doc(alias = "get_matrix_mode")]
453    pub fn matrix_mode(&self) -> crate::VideoMatrixMode {
454        self.0
455            .get_optional(glib::gstr!("GstVideoConverter.matrix-mode"))
456            .expect("Wrong type")
457            .unwrap_or(crate::VideoMatrixMode::Full)
458    }
459
460    pub fn set_gamma_mode(&mut self, v: crate::VideoGammaMode) {
461        self.0.set(glib::gstr!("GstVideoConverter.gamma-mode"), v);
462    }
463
464    #[doc(alias = "get_gamma_mode")]
465    pub fn gamma_mode(&self) -> crate::VideoGammaMode {
466        self.0
467            .get_optional(glib::gstr!("GstVideoConverter.gamma-mode"))
468            .expect("Wrong type")
469            .unwrap_or(crate::VideoGammaMode::None)
470    }
471
472    pub fn set_primaries_mode(&mut self, v: crate::VideoPrimariesMode) {
473        self.0
474            .set(glib::gstr!("GstVideoConverter.primaries-mode"), v);
475    }
476
477    #[doc(alias = "get_primaries_mode")]
478    pub fn primaries_mode(&self) -> crate::VideoPrimariesMode {
479        self.0
480            .get_optional(glib::gstr!("GstVideoConverter.primaries-mode"))
481            .expect("Wrong type")
482            .unwrap_or(crate::VideoPrimariesMode::None)
483    }
484
485    pub fn set_threads(&mut self, v: u32) {
486        self.0.set(glib::gstr!("GstVideoConverter.threads"), v);
487    }
488
489    #[doc(alias = "get_threads")]
490    pub fn threads(&self) -> u32 {
491        self.0
492            .get_optional(glib::gstr!("GstVideoConverter.threads"))
493            .expect("Wrong type")
494            .unwrap_or(1)
495    }
496}