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