1 | // Take a look at the license at the top of the repository in the LICENSE file. |
2 | |
3 | use std::{ops, ptr}; |
4 | |
5 | use crate::{ffi, prelude::*}; |
6 | use glib::{prelude::*, translate::*}; |
7 | |
8 | #[derive (Debug)] |
9 | #[doc (alias = "GstVideoConverter" )] |
10 | pub struct VideoConverter(ptr::NonNull<ffi::GstVideoConverter>); |
11 | |
12 | impl 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 | |
21 | unsafe impl Send for VideoConverter {} |
22 | unsafe impl Sync for VideoConverter {} |
23 | |
24 | impl 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)] |
115 | pub struct VideoConverterConfig(gst::Structure); |
116 | |
117 | impl 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 | |
126 | impl ops::DerefMut for VideoConverterConfig { |
127 | #[inline ] |
128 | fn deref_mut(&mut self) -> &mut gst::StructureRef { |
129 | self.0.deref_mut() |
130 | } |
131 | } |
132 | |
133 | impl AsRef<gst::StructureRef> for VideoConverterConfig { |
134 | #[inline ] |
135 | fn as_ref(&self) -> &gst::StructureRef { |
136 | self.0.as_ref() |
137 | } |
138 | } |
139 | |
140 | impl AsMut<gst::StructureRef> for VideoConverterConfig { |
141 | #[inline ] |
142 | fn as_mut(&mut self) -> &mut gst::StructureRef { |
143 | self.0.as_mut() |
144 | } |
145 | } |
146 | |
147 | impl Default for VideoConverterConfig { |
148 | fn default() -> Self { |
149 | Self::new() |
150 | } |
151 | } |
152 | |
153 | impl 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 | |
166 | impl<'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 | |
175 | impl From<VideoConverterConfig> for gst::Structure { |
176 | fn from(v: VideoConverterConfig) -> Self { |
177 | skip_assert_initialized!(); |
178 | v.0 |
179 | } |
180 | } |
181 | |
182 | impl 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 | |
192 | impl glib::value::ToValueOptional for VideoConverterConfig { |
193 | fn to_value_optional(s: Option<&Self>) -> glib::Value { |
194 | skip_assert_initialized!(); |
195 | s.map(|s: &VideoConverterConfig| &s.0).to_value() |
196 | } |
197 | } |
198 | |
199 | impl From<VideoConverterConfig> for glib::Value { |
200 | fn from(s: VideoConverterConfig) -> glib::Value { |
201 | skip_assert_initialized!(); |
202 | s.0.into() |
203 | } |
204 | } |
205 | |
206 | impl 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 | } |
497 | |