gstreamer_video/
video_converter.rs1use 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}