Skip to main content

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 {
82            &*(ffi::gst_video_converter_get_in_info(self.0.as_ptr()) as *const crate::VideoInfo)
83        }
84    }
85
86    #[cfg(feature = "v1_22")]
87    #[cfg_attr(docsrs, doc(cfg(feature = "v1_22")))]
88    #[doc(alias = "get_out_info")]
89    #[doc(alias = "gst_video_converter_get_out_info")]
90    pub fn out_info(&self) -> &crate::VideoInfo {
91        unsafe {
92            &*(ffi::gst_video_converter_get_out_info(self.0.as_ptr()) as *const crate::VideoInfo)
93        }
94    }
95
96    #[doc(alias = "gst_video_converter_frame")]
97    pub fn frame<T>(
98        &self,
99        src: &crate::VideoFrame<T>,
100        dest: &mut crate::VideoFrame<crate::video_frame::Writable>,
101    ) {
102        unsafe {
103            ffi::gst_video_converter_frame(self.0.as_ptr(), src.as_ptr(), dest.as_mut_ptr());
104        }
105    }
106
107    pub fn frame_ref<T>(
108        &self,
109        src: &crate::VideoFrameRef<T>,
110        dest: &mut crate::VideoFrameRef<&mut gst::BufferRef>,
111    ) {
112        unsafe {
113            ffi::gst_video_converter_frame(self.0.as_ptr(), src.as_ptr(), dest.as_mut_ptr());
114        }
115    }
116
117    #[cfg(feature = "v1_28")]
118    #[cfg_attr(docsrs, doc(cfg(feature = "v1_28")))]
119    #[doc(alias = "gst_video_converter_transform_metas")]
120    pub fn transform_metas(
121        &self,
122        src: &gst::BufferRef,
123        dest: &mut gst::BufferRef,
124    ) -> Result<(), glib::BoolError> {
125        unsafe {
126            let res = from_glib(ffi::gst_video_converter_transform_metas(
127                self.0.as_ptr(),
128                mut_override(src.as_ptr()),
129                dest.as_mut_ptr(),
130            ));
131            if res {
132                Ok(())
133            } else {
134                Err(glib::bool_error!("Couldn't transform metas"))
135            }
136        }
137    }
138}
139
140#[derive(Debug, Clone, PartialEq, Eq)]
141pub struct VideoConverterConfig(gst::Structure);
142
143impl ops::Deref for VideoConverterConfig {
144    type Target = gst::StructureRef;
145
146    #[inline]
147    fn deref(&self) -> &gst::StructureRef {
148        self.0.deref()
149    }
150}
151
152impl ops::DerefMut for VideoConverterConfig {
153    #[inline]
154    fn deref_mut(&mut self) -> &mut gst::StructureRef {
155        self.0.deref_mut()
156    }
157}
158
159impl AsRef<gst::StructureRef> for VideoConverterConfig {
160    #[inline]
161    fn as_ref(&self) -> &gst::StructureRef {
162        self.0.as_ref()
163    }
164}
165
166impl AsMut<gst::StructureRef> for VideoConverterConfig {
167    #[inline]
168    fn as_mut(&mut self) -> &mut gst::StructureRef {
169        self.0.as_mut()
170    }
171}
172
173impl Default for VideoConverterConfig {
174    fn default() -> Self {
175        Self::new()
176    }
177}
178
179impl TryFrom<gst::Structure> for VideoConverterConfig {
180    type Error = glib::BoolError;
181
182    fn try_from(v: gst::Structure) -> Result<Self, Self::Error> {
183        skip_assert_initialized!();
184        if v.name() == "GstVideoConverter" {
185            Ok(Self(v))
186        } else {
187            Err(glib::bool_error!("Structure is no VideoConverterConfig"))
188        }
189    }
190}
191
192impl<'a> TryFrom<&'a gst::StructureRef> for VideoConverterConfig {
193    type Error = glib::BoolError;
194
195    fn try_from(v: &'a gst::StructureRef) -> Result<Self, Self::Error> {
196        skip_assert_initialized!();
197        Self::try_from(v.to_owned())
198    }
199}
200
201impl From<VideoConverterConfig> for gst::Structure {
202    fn from(v: VideoConverterConfig) -> Self {
203        skip_assert_initialized!();
204        v.0
205    }
206}
207
208impl glib::value::ToValue for VideoConverterConfig {
209    fn to_value(&self) -> glib::Value {
210        self.0.to_value()
211    }
212
213    fn value_type(&self) -> glib::Type {
214        self.0.value_type()
215    }
216}
217
218impl glib::value::ToValueOptional for VideoConverterConfig {
219    fn to_value_optional(s: Option<&Self>) -> glib::Value {
220        skip_assert_initialized!();
221        s.map(|s| &s.0).to_value()
222    }
223}
224
225impl From<VideoConverterConfig> for glib::Value {
226    fn from(s: VideoConverterConfig) -> glib::Value {
227        skip_assert_initialized!();
228        s.0.into()
229    }
230}
231
232impl VideoConverterConfig {
233    pub fn new() -> Self {
234        Self(gst::Structure::new_empty("GstVideoConverter"))
235    }
236
237    pub fn set_resampler_method(&mut self, v: crate::VideoResamplerMethod) {
238        self.0
239            .set(glib::gstr!("GstVideoConverter.resampler-method"), v);
240    }
241
242    #[doc(alias = "get_resampler_method")]
243    pub fn resampler_method(&self) -> crate::VideoResamplerMethod {
244        self.0
245            .get_optional(glib::gstr!("GstVideoConverter.resampler-method"))
246            .expect("Wrong type")
247            .unwrap_or(crate::VideoResamplerMethod::Cubic)
248    }
249
250    pub fn set_chroma_resampler_method(&mut self, v: crate::VideoResamplerMethod) {
251        self.0
252            .set(glib::gstr!("GstVideoConverter.chroma-resampler-method"), v);
253    }
254
255    #[doc(alias = "get_chroma_resampler_method")]
256    pub fn chroma_resampler_method(&self) -> crate::VideoResamplerMethod {
257        self.0
258            .get_optional(glib::gstr!("GstVideoConverter.chroma-resampler-method"))
259            .expect("Wrong type")
260            .unwrap_or(crate::VideoResamplerMethod::Linear)
261    }
262
263    pub fn set_resampler_taps(&mut self, v: u32) {
264        self.0
265            .set(glib::gstr!("GstVideoConverter.resampler-taps"), v);
266    }
267
268    #[doc(alias = "get_resampler_taps")]
269    pub fn resampler_taps(&self) -> u32 {
270        self.0
271            .get_optional(glib::gstr!("GstVideoConverter.resampler-taps"))
272            .expect("Wrong type")
273            .unwrap_or(0)
274    }
275
276    pub fn set_dither_method(&mut self, v: crate::VideoDitherMethod) {
277        self.0
278            .set(glib::gstr!("GstVideoConverter.dither-method"), v);
279    }
280
281    #[doc(alias = "get_dither_method")]
282    pub fn dither_method(&self) -> crate::VideoDitherMethod {
283        self.0
284            .get_optional(glib::gstr!("GstVideoConverter.dither-method"))
285            .expect("Wrong type")
286            .unwrap_or(crate::VideoDitherMethod::Bayer)
287    }
288
289    pub fn set_dither_quantization(&mut self, v: u32) {
290        self.0
291            .set(glib::gstr!("GstVideoConverter.dither-quantization"), v);
292    }
293
294    #[doc(alias = "get_dither_quantization")]
295    pub fn dither_quantization(&self) -> u32 {
296        self.0
297            .get_optional(glib::gstr!("GstVideoConverter.dither-quantization"))
298            .expect("Wrong type")
299            .unwrap_or(1)
300    }
301
302    pub fn set_src_x(&mut self, v: i32) {
303        self.0.set(glib::gstr!("GstVideoConverter.src-x"), v);
304    }
305
306    #[doc(alias = "get_src_x")]
307    pub fn src_x(&self) -> i32 {
308        self.0
309            .get_optional(glib::gstr!("GstVideoConverter.src-x"))
310            .expect("Wrong type")
311            .unwrap_or(0)
312    }
313
314    pub fn set_src_y(&mut self, v: i32) {
315        self.0.set(glib::gstr!("GstVideoConverter.src-y"), v);
316    }
317
318    #[doc(alias = "get_src_y")]
319    pub fn src_y(&self) -> i32 {
320        self.0
321            .get_optional(glib::gstr!("GstVideoConverter.src-y"))
322            .expect("Wrong type")
323            .unwrap_or(0)
324    }
325
326    pub fn set_src_width(&mut self, v: Option<i32>) {
327        if let Some(v) = v {
328            self.0.set(glib::gstr!("GstVideoConverter.src-width"), v);
329        } else {
330            self.0
331                .remove_field(glib::gstr!("GstVideoConverter.src-width"));
332        }
333    }
334
335    #[doc(alias = "get_src_width")]
336    pub fn src_width(&self) -> Option<i32> {
337        self.0
338            .get_optional(glib::gstr!("GstVideoConverter.src-width"))
339            .expect("Wrong type")
340    }
341
342    pub fn set_src_height(&mut self, v: Option<i32>) {
343        if let Some(v) = v {
344            self.0.set(glib::gstr!("GstVideoConverter.src-height"), v);
345        } else {
346            self.0
347                .remove_field(glib::gstr!("GstVideoConverter.src-height"));
348        }
349    }
350
351    #[doc(alias = "get_src_height")]
352    pub fn src_height(&self) -> Option<i32> {
353        self.0
354            .get_optional(glib::gstr!("GstVideoConverter.src-height"))
355            .expect("Wrong type")
356    }
357
358    pub fn set_dest_x(&mut self, v: i32) {
359        self.0.set(glib::gstr!("GstVideoConverter.dest-x"), v);
360    }
361
362    #[doc(alias = "get_dest_x")]
363    pub fn dest_x(&self) -> i32 {
364        self.0
365            .get_optional(glib::gstr!("GstVideoConverter.dest-x"))
366            .expect("Wrong type")
367            .unwrap_or(0)
368    }
369
370    pub fn set_dest_y(&mut self, v: i32) {
371        self.0.set(glib::gstr!("GstVideoConverter.dest-y"), v);
372    }
373
374    #[doc(alias = "get_dest_y")]
375    pub fn dest_y(&self) -> i32 {
376        self.0
377            .get_optional(glib::gstr!("GstVideoConverter.dest-y"))
378            .expect("Wrong type")
379            .unwrap_or(0)
380    }
381
382    pub fn set_dest_width(&mut self, v: Option<i32>) {
383        if let Some(v) = v {
384            self.0.set(glib::gstr!("GstVideoConverter.dest-width"), v);
385        } else {
386            self.0
387                .remove_field(glib::gstr!("GstVideoConverter.dest-width"));
388        }
389    }
390
391    #[doc(alias = "get_dest_width")]
392    pub fn dest_width(&self) -> Option<i32> {
393        self.0
394            .get_optional(glib::gstr!("GstVideoConverter.dest-width"))
395            .expect("Wrong type")
396    }
397
398    pub fn set_dest_height(&mut self, v: Option<i32>) {
399        if let Some(v) = v {
400            self.0.set(glib::gstr!("GstVideoConverter.dest-height"), v);
401        } else {
402            self.0
403                .remove_field(glib::gstr!("GstVideoConverter.dest-height"));
404        }
405    }
406
407    #[doc(alias = "get_dest_height")]
408    pub fn dest_height(&self) -> Option<i32> {
409        self.0
410            .get_optional(glib::gstr!("GstVideoConverter.dest-height"))
411            .expect("Wrong type")
412    }
413
414    pub fn set_fill_border(&mut self, v: bool) {
415        self.0.set(glib::gstr!("GstVideoConverter.fill-border"), v);
416    }
417
418    #[doc(alias = "get_fill_border")]
419    pub fn fills_border(&self) -> bool {
420        self.0
421            .get_optional(glib::gstr!("GstVideoConverter.fill-border"))
422            .expect("Wrong type")
423            .unwrap_or(true)
424    }
425
426    pub fn set_alpha_value(&mut self, v: f64) {
427        self.0.set(glib::gstr!("GstVideoConverter.alpha-value"), v);
428    }
429
430    #[doc(alias = "get_alpha_value")]
431    pub fn alpha_value(&self) -> f64 {
432        self.0
433            .get_optional(glib::gstr!("GstVideoConverter.alpha-value"))
434            .expect("Wrong type")
435            .unwrap_or(1.0)
436    }
437
438    pub fn set_alpha_mode(&mut self, v: crate::VideoAlphaMode) {
439        self.0.set(glib::gstr!("GstVideoConverter.alpha-mode"), v);
440    }
441
442    #[doc(alias = "get_alpha_mode")]
443    pub fn alpha_mode(&self) -> crate::VideoAlphaMode {
444        self.0
445            .get_optional(glib::gstr!("GstVideoConverter.alpha-mode"))
446            .expect("Wrong type")
447            .unwrap_or(crate::VideoAlphaMode::Copy)
448    }
449
450    pub fn set_border_argb(&mut self, v: u32) {
451        self.0.set(glib::gstr!("GstVideoConverter.border-argb"), v);
452    }
453
454    #[doc(alias = "get_border_argb")]
455    pub fn border_argb(&self) -> u32 {
456        self.0
457            .get_optional(glib::gstr!("GstVideoConverter.border-argb"))
458            .expect("Wrong type")
459            .unwrap_or(0xff_00_00_00)
460    }
461
462    pub fn set_chroma_mode(&mut self, v: crate::VideoChromaMode) {
463        self.0.set(glib::gstr!("GstVideoConverter.chroma-mode"), v);
464    }
465
466    #[doc(alias = "get_chroma_mode")]
467    pub fn chroma_mode(&self) -> crate::VideoChromaMode {
468        self.0
469            .get_optional(glib::gstr!("GstVideoConverter.chroma-mode"))
470            .expect("Wrong type")
471            .unwrap_or(crate::VideoChromaMode::Full)
472    }
473
474    pub fn set_matrix_mode(&mut self, v: crate::VideoMatrixMode) {
475        self.0.set(glib::gstr!("GstVideoConverter.matrix-mode"), v);
476    }
477
478    #[doc(alias = "get_matrix_mode")]
479    pub fn matrix_mode(&self) -> crate::VideoMatrixMode {
480        self.0
481            .get_optional(glib::gstr!("GstVideoConverter.matrix-mode"))
482            .expect("Wrong type")
483            .unwrap_or(crate::VideoMatrixMode::Full)
484    }
485
486    pub fn set_gamma_mode(&mut self, v: crate::VideoGammaMode) {
487        self.0.set(glib::gstr!("GstVideoConverter.gamma-mode"), v);
488    }
489
490    #[doc(alias = "get_gamma_mode")]
491    pub fn gamma_mode(&self) -> crate::VideoGammaMode {
492        self.0
493            .get_optional(glib::gstr!("GstVideoConverter.gamma-mode"))
494            .expect("Wrong type")
495            .unwrap_or(crate::VideoGammaMode::None)
496    }
497
498    pub fn set_primaries_mode(&mut self, v: crate::VideoPrimariesMode) {
499        self.0
500            .set(glib::gstr!("GstVideoConverter.primaries-mode"), v);
501    }
502
503    #[doc(alias = "get_primaries_mode")]
504    pub fn primaries_mode(&self) -> crate::VideoPrimariesMode {
505        self.0
506            .get_optional(glib::gstr!("GstVideoConverter.primaries-mode"))
507            .expect("Wrong type")
508            .unwrap_or(crate::VideoPrimariesMode::None)
509    }
510
511    pub fn set_threads(&mut self, v: u32) {
512        self.0.set(glib::gstr!("GstVideoConverter.threads"), v);
513    }
514
515    #[doc(alias = "get_threads")]
516    pub fn threads(&self) -> u32 {
517        self.0
518            .get_optional(glib::gstr!("GstVideoConverter.threads"))
519            .expect("Wrong type")
520            .unwrap_or(1)
521    }
522}