| 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 | |