1 | // Take a look at the license at the top of the repository in the LICENSE file. |
2 | |
3 | use std::{fmt, ptr}; |
4 | |
5 | use crate::ffi; |
6 | use glib::translate::*; |
7 | use gst::prelude::*; |
8 | |
9 | #[repr (transparent)] |
10 | #[doc (alias = "GstVideoMeta" )] |
11 | pub struct VideoMeta(ffi::GstVideoMeta); |
12 | |
13 | unsafe impl Send for VideoMeta {} |
14 | unsafe impl Sync for VideoMeta {} |
15 | |
16 | impl VideoMeta { |
17 | #[doc (alias = "gst_buffer_add_video_meta" )] |
18 | pub fn add( |
19 | buffer: &mut gst::BufferRef, |
20 | video_frame_flags: crate::VideoFrameFlags, |
21 | format: crate::VideoFormat, |
22 | width: u32, |
23 | height: u32, |
24 | ) -> Result<gst::MetaRefMut<Self, gst::meta::Standalone>, glib::BoolError> { |
25 | skip_assert_initialized!(); |
26 | |
27 | if format == crate::VideoFormat::Unknown || format == crate::VideoFormat::Encoded { |
28 | return Err(glib::bool_error!("Unsupported video format {}" , format)); |
29 | } |
30 | |
31 | let info = crate::VideoInfo::builder(format, width, height).build()?; |
32 | |
33 | if !info.is_valid() { |
34 | return Err(glib::bool_error!("Invalid video info" )); |
35 | } |
36 | |
37 | if buffer.size() < info.size() { |
38 | return Err(glib::bool_error!( |
39 | "Buffer smaller than required frame size ( {} < {})" , |
40 | buffer.size(), |
41 | info.size() |
42 | )); |
43 | } |
44 | |
45 | unsafe { |
46 | let meta = ffi::gst_buffer_add_video_meta( |
47 | buffer.as_mut_ptr(), |
48 | video_frame_flags.into_glib(), |
49 | format.into_glib(), |
50 | width, |
51 | height, |
52 | ); |
53 | |
54 | if meta.is_null() { |
55 | return Err(glib::bool_error!("Failed to add video meta" )); |
56 | } |
57 | |
58 | Ok(Self::from_mut_ptr(buffer, meta)) |
59 | } |
60 | } |
61 | |
62 | pub fn add_full<'a>( |
63 | buffer: &'a mut gst::BufferRef, |
64 | video_frame_flags: crate::VideoFrameFlags, |
65 | format: crate::VideoFormat, |
66 | width: u32, |
67 | height: u32, |
68 | offset: &[usize], |
69 | stride: &[i32], |
70 | ) -> Result<gst::MetaRefMut<'a, Self, gst::meta::Standalone>, glib::BoolError> { |
71 | skip_assert_initialized!(); |
72 | |
73 | if format == crate::VideoFormat::Unknown || format == crate::VideoFormat::Encoded { |
74 | return Err(glib::bool_error!("Unsupported video format {}" , format)); |
75 | } |
76 | |
77 | let n_planes = offset.len() as u32; |
78 | let info_builder = crate::VideoInfo::builder(format, width, height) |
79 | .offset(offset) |
80 | .stride(stride); |
81 | |
82 | #[cfg (feature = "v1_16" )] |
83 | let info_builder = info_builder.interlace_mode_if( |
84 | crate::VideoInterlaceMode::Alternate, |
85 | video_frame_flags.contains(crate::VideoFrameFlags::ONEFIELD), |
86 | ); |
87 | |
88 | let info = info_builder.build()?; |
89 | |
90 | if !info.is_valid() { |
91 | return Err(glib::bool_error!("Invalid video info" )); |
92 | } |
93 | |
94 | if buffer.size() < info.size() { |
95 | return Err(glib::bool_error!( |
96 | "Buffer smaller than required frame size ( {} < {})" , |
97 | buffer.size(), |
98 | info.size() |
99 | )); |
100 | } |
101 | |
102 | unsafe { |
103 | let meta = ffi::gst_buffer_add_video_meta_full( |
104 | buffer.as_mut_ptr(), |
105 | video_frame_flags.into_glib(), |
106 | format.into_glib(), |
107 | width, |
108 | height, |
109 | n_planes, |
110 | offset.as_ptr() as *mut _, |
111 | stride.as_ptr() as *mut _, |
112 | ); |
113 | |
114 | if meta.is_null() { |
115 | return Err(glib::bool_error!("Failed to add video meta" )); |
116 | } |
117 | |
118 | Ok(Self::from_mut_ptr(buffer, meta)) |
119 | } |
120 | } |
121 | |
122 | #[doc (alias = "get_flags" )] |
123 | #[inline ] |
124 | pub fn video_frame_flags(&self) -> crate::VideoFrameFlags { |
125 | unsafe { from_glib(self.0.flags) } |
126 | } |
127 | |
128 | #[doc (alias = "get_format" )] |
129 | #[inline ] |
130 | pub fn format(&self) -> crate::VideoFormat { |
131 | unsafe { from_glib(self.0.format) } |
132 | } |
133 | |
134 | #[doc (alias = "get_id" )] |
135 | #[inline ] |
136 | pub fn id(&self) -> i32 { |
137 | self.0.id |
138 | } |
139 | |
140 | #[doc (alias = "get_width" )] |
141 | #[inline ] |
142 | pub fn width(&self) -> u32 { |
143 | self.0.width |
144 | } |
145 | |
146 | #[doc (alias = "get_height" )] |
147 | #[inline ] |
148 | pub fn height(&self) -> u32 { |
149 | self.0.height |
150 | } |
151 | |
152 | #[doc (alias = "get_n_planes" )] |
153 | #[inline ] |
154 | pub fn n_planes(&self) -> u32 { |
155 | self.0.n_planes |
156 | } |
157 | |
158 | #[doc (alias = "get_offset" )] |
159 | #[inline ] |
160 | pub fn offset(&self) -> &[usize] { |
161 | &self.0.offset[0..(self.0.n_planes as usize)] |
162 | } |
163 | |
164 | #[doc (alias = "get_stride" )] |
165 | #[inline ] |
166 | pub fn stride(&self) -> &[i32] { |
167 | &self.0.stride[0..(self.0.n_planes as usize)] |
168 | } |
169 | |
170 | #[cfg (feature = "v1_18" )] |
171 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_18" )))] |
172 | #[doc (alias = "get_alignment" )] |
173 | #[inline ] |
174 | pub fn alignment(&self) -> crate::VideoAlignment { |
175 | crate::VideoAlignment::new( |
176 | self.0.alignment.padding_top, |
177 | self.0.alignment.padding_bottom, |
178 | self.0.alignment.padding_left, |
179 | self.0.alignment.padding_right, |
180 | &self.0.alignment.stride_align, |
181 | ) |
182 | } |
183 | |
184 | #[cfg (feature = "v1_18" )] |
185 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_18" )))] |
186 | #[doc (alias = "get_plane_size" )] |
187 | #[doc (alias = "gst_video_meta_get_plane_size" )] |
188 | pub fn plane_size(&self) -> Result<[usize; crate::VIDEO_MAX_PLANES], glib::BoolError> { |
189 | let mut plane_size = [0; crate::VIDEO_MAX_PLANES]; |
190 | |
191 | unsafe { |
192 | glib::result_from_gboolean!( |
193 | ffi::gst_video_meta_get_plane_size(mut_override(&self.0), &mut plane_size,), |
194 | "Failed to get plane size" |
195 | )?; |
196 | } |
197 | |
198 | Ok(plane_size) |
199 | } |
200 | |
201 | #[cfg (feature = "v1_18" )] |
202 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_18" )))] |
203 | #[doc (alias = "get_plane_height" )] |
204 | #[doc (alias = "gst_video_meta_get_plane_height" )] |
205 | pub fn plane_height(&self) -> Result<[u32; crate::VIDEO_MAX_PLANES], glib::BoolError> { |
206 | let mut plane_height = [0; crate::VIDEO_MAX_PLANES]; |
207 | |
208 | unsafe { |
209 | glib::result_from_gboolean!( |
210 | ffi::gst_video_meta_get_plane_height(mut_override(&self.0), &mut plane_height,), |
211 | "Failed to get plane height" |
212 | )?; |
213 | } |
214 | |
215 | Ok(plane_height) |
216 | } |
217 | |
218 | #[cfg (feature = "v1_18" )] |
219 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_18" )))] |
220 | #[doc (alias = "gst_video_meta_set_alignment" )] |
221 | pub fn set_alignment( |
222 | &mut self, |
223 | alignment: &crate::VideoAlignment, |
224 | ) -> Result<(), glib::BoolError> { |
225 | unsafe { |
226 | glib::result_from_gboolean!( |
227 | ffi::gst_video_meta_set_alignment(&mut self.0, alignment.0), |
228 | "Failed to set alignment on VideoMeta" |
229 | ) |
230 | } |
231 | } |
232 | } |
233 | |
234 | unsafe impl MetaAPI for VideoMeta { |
235 | type GstType = ffi::GstVideoMeta; |
236 | |
237 | #[doc (alias = "gst_video_meta_api_get_type" )] |
238 | #[inline ] |
239 | fn meta_api() -> glib::Type { |
240 | unsafe { from_glib(val:ffi::gst_video_meta_api_get_type()) } |
241 | } |
242 | } |
243 | |
244 | impl fmt::Debug for VideoMeta { |
245 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
246 | f&mut DebugStruct<'_, '_>.debug_struct("VideoMeta" ) |
247 | .field("id" , &self.id()) |
248 | .field("video_frame_flags" , &self.video_frame_flags()) |
249 | .field("format" , &self.format()) |
250 | .field("width" , &self.width()) |
251 | .field("height" , &self.height()) |
252 | .field("n_planes" , &self.n_planes()) |
253 | .field("offset" , &self.offset()) |
254 | .field(name:"stride" , &self.stride()) |
255 | .finish() |
256 | } |
257 | } |
258 | |
259 | #[repr (transparent)] |
260 | #[doc (alias = "GstVideoCropMeta" )] |
261 | pub struct VideoCropMeta(ffi::GstVideoCropMeta); |
262 | |
263 | unsafe impl Send for VideoCropMeta {} |
264 | unsafe impl Sync for VideoCropMeta {} |
265 | |
266 | impl VideoCropMeta { |
267 | #[doc (alias = "gst_buffer_add_meta" )] |
268 | pub fn add( |
269 | buffer: &mut gst::BufferRef, |
270 | rect: (u32, u32, u32, u32), |
271 | ) -> gst::MetaRefMut<Self, gst::meta::Standalone> { |
272 | skip_assert_initialized!(); |
273 | unsafe { |
274 | let meta = gst::ffi::gst_buffer_add_meta( |
275 | buffer.as_mut_ptr(), |
276 | ffi::gst_video_crop_meta_get_info(), |
277 | ptr::null_mut(), |
278 | ) as *mut ffi::GstVideoCropMeta; |
279 | |
280 | { |
281 | let meta = &mut *meta; |
282 | meta.x = rect.0; |
283 | meta.y = rect.1; |
284 | meta.width = rect.2; |
285 | meta.height = rect.3; |
286 | } |
287 | |
288 | Self::from_mut_ptr(buffer, meta) |
289 | } |
290 | } |
291 | |
292 | #[doc (alias = "get_rect" )] |
293 | #[inline ] |
294 | pub fn rect(&self) -> (u32, u32, u32, u32) { |
295 | (self.0.x, self.0.y, self.0.width, self.0.height) |
296 | } |
297 | |
298 | #[inline ] |
299 | pub fn set_rect(&mut self, rect: (u32, u32, u32, u32)) { |
300 | self.0.x = rect.0; |
301 | self.0.y = rect.1; |
302 | self.0.width = rect.2; |
303 | self.0.height = rect.3; |
304 | } |
305 | } |
306 | |
307 | unsafe impl MetaAPI for VideoCropMeta { |
308 | type GstType = ffi::GstVideoCropMeta; |
309 | |
310 | #[doc (alias = "gst_video_crop_meta_api_get_type" )] |
311 | #[inline ] |
312 | fn meta_api() -> glib::Type { |
313 | unsafe { from_glib(val:ffi::gst_video_crop_meta_api_get_type()) } |
314 | } |
315 | } |
316 | |
317 | impl fmt::Debug for VideoCropMeta { |
318 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
319 | f&mut DebugStruct<'_, '_>.debug_struct("VideoCropMeta" ) |
320 | .field(name:"rect" , &self.rect()) |
321 | .finish() |
322 | } |
323 | } |
324 | |
325 | #[repr (transparent)] |
326 | #[doc (alias = "GstVideoRegionOfInterestMeta" )] |
327 | pub struct VideoRegionOfInterestMeta(ffi::GstVideoRegionOfInterestMeta); |
328 | |
329 | unsafe impl Send for VideoRegionOfInterestMeta {} |
330 | unsafe impl Sync for VideoRegionOfInterestMeta {} |
331 | |
332 | impl VideoRegionOfInterestMeta { |
333 | #[doc (alias = "gst_buffer_add_video_region_of_interest_meta" )] |
334 | pub fn add<'a>( |
335 | buffer: &'a mut gst::BufferRef, |
336 | roi_type: &str, |
337 | rect: (u32, u32, u32, u32), |
338 | ) -> gst::MetaRefMut<'a, Self, gst::meta::Standalone> { |
339 | skip_assert_initialized!(); |
340 | unsafe { |
341 | let meta = ffi::gst_buffer_add_video_region_of_interest_meta( |
342 | buffer.as_mut_ptr(), |
343 | roi_type.to_glib_none().0, |
344 | rect.0, |
345 | rect.1, |
346 | rect.2, |
347 | rect.3, |
348 | ); |
349 | |
350 | Self::from_mut_ptr(buffer, meta) |
351 | } |
352 | } |
353 | |
354 | #[doc (alias = "get_rect" )] |
355 | #[inline ] |
356 | pub fn rect(&self) -> (u32, u32, u32, u32) { |
357 | (self.0.x, self.0.y, self.0.w, self.0.h) |
358 | } |
359 | |
360 | #[doc (alias = "get_id" )] |
361 | #[inline ] |
362 | pub fn id(&self) -> i32 { |
363 | self.0.id |
364 | } |
365 | |
366 | #[doc (alias = "get_parent_id" )] |
367 | #[inline ] |
368 | pub fn parent_id(&self) -> i32 { |
369 | self.0.parent_id |
370 | } |
371 | |
372 | #[doc (alias = "get_roi_type" )] |
373 | #[inline ] |
374 | pub fn roi_type<'a>(&self) -> &'a str { |
375 | unsafe { glib::Quark::from_glib(self.0.roi_type).as_str() } |
376 | } |
377 | |
378 | #[doc (alias = "get_params" )] |
379 | pub fn params(&self) -> ParamsIter { |
380 | ParamsIter { |
381 | _meta: self, |
382 | list: ptr::NonNull::new(self.0.params), |
383 | } |
384 | } |
385 | |
386 | #[doc (alias = "get_param" )] |
387 | #[inline ] |
388 | pub fn param<'b>(&'b self, name: &str) -> Option<&'b gst::StructureRef> { |
389 | self.params().find(|s| s.name() == name) |
390 | } |
391 | |
392 | #[inline ] |
393 | pub fn set_rect(&mut self, rect: (u32, u32, u32, u32)) { |
394 | self.0.x = rect.0; |
395 | self.0.y = rect.1; |
396 | self.0.w = rect.2; |
397 | self.0.h = rect.3; |
398 | } |
399 | |
400 | #[inline ] |
401 | pub fn set_id(&mut self, id: i32) { |
402 | self.0.id = id |
403 | } |
404 | |
405 | #[inline ] |
406 | pub fn set_parent_id(&mut self, id: i32) { |
407 | self.0.parent_id = id |
408 | } |
409 | |
410 | #[doc (alias = "gst_video_region_of_interest_meta_add_param" )] |
411 | pub fn add_param(&mut self, s: gst::Structure) { |
412 | unsafe { |
413 | ffi::gst_video_region_of_interest_meta_add_param(&mut self.0, s.into_glib_ptr()); |
414 | } |
415 | } |
416 | } |
417 | |
418 | pub struct ParamsIter<'a> { |
419 | _meta: &'a VideoRegionOfInterestMeta, |
420 | list: Option<ptr::NonNull<glib::ffi::GList>>, |
421 | } |
422 | |
423 | impl<'a> Iterator for ParamsIter<'a> { |
424 | type Item = &'a gst::StructureRef; |
425 | |
426 | fn next(&mut self) -> Option<&'a gst::StructureRef> { |
427 | match self.list { |
428 | None => None, |
429 | Some(list: NonNull) => unsafe { |
430 | self.list = ptr::NonNull::new(ptr:list.as_ref().next); |
431 | let data: *mut c_void = list.as_ref().data; |
432 | |
433 | let s: &StructureRef = gst::StructureRef::from_glib_borrow(ptr:data as *const gst::ffi::GstStructure); |
434 | |
435 | Some(s) |
436 | }, |
437 | } |
438 | } |
439 | } |
440 | |
441 | impl std::iter::FusedIterator for ParamsIter<'_> {} |
442 | |
443 | unsafe impl MetaAPI for VideoRegionOfInterestMeta { |
444 | type GstType = ffi::GstVideoRegionOfInterestMeta; |
445 | |
446 | #[doc (alias = "gst_video_region_of_interest_meta_api_get_type" )] |
447 | #[inline ] |
448 | fn meta_api() -> glib::Type { |
449 | unsafe { from_glib(val:ffi::gst_video_region_of_interest_meta_api_get_type()) } |
450 | } |
451 | } |
452 | |
453 | impl fmt::Debug for VideoRegionOfInterestMeta { |
454 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
455 | f&mut DebugStruct<'_, '_>.debug_struct("VideoRegionOfInterestMeta" ) |
456 | .field("roi_type" , &self.roi_type()) |
457 | .field("rect" , &self.rect()) |
458 | .field("id" , &self.id()) |
459 | .field("parent_id" , &self.parent_id()) |
460 | .field(name:"params" , &self.params().collect::<Vec<_>>()) |
461 | .finish() |
462 | } |
463 | } |
464 | |
465 | #[repr (transparent)] |
466 | #[doc (alias = "GstVideoAffineTransformationMeta" )] |
467 | pub struct VideoAffineTransformationMeta(ffi::GstVideoAffineTransformationMeta); |
468 | |
469 | unsafe impl Send for VideoAffineTransformationMeta {} |
470 | unsafe impl Sync for VideoAffineTransformationMeta {} |
471 | |
472 | impl VideoAffineTransformationMeta { |
473 | #[doc (alias = "gst_buffer_add_meta" )] |
474 | pub fn add<'a>( |
475 | buffer: &'a mut gst::BufferRef, |
476 | matrix: Option<&[[f32; 4]; 4]>, |
477 | ) -> gst::MetaRefMut<'a, Self, gst::meta::Standalone> { |
478 | skip_assert_initialized!(); |
479 | unsafe { |
480 | let meta = gst::ffi::gst_buffer_add_meta( |
481 | buffer.as_mut_ptr(), |
482 | ffi::gst_video_affine_transformation_meta_get_info(), |
483 | ptr::null_mut(), |
484 | ) as *mut ffi::GstVideoAffineTransformationMeta; |
485 | |
486 | if let Some(matrix) = matrix { |
487 | let meta = &mut *meta; |
488 | for (i, o) in Iterator::zip(matrix.iter().flatten(), meta.matrix.iter_mut()) { |
489 | *o = *i; |
490 | } |
491 | } |
492 | |
493 | Self::from_mut_ptr(buffer, meta) |
494 | } |
495 | } |
496 | |
497 | #[doc (alias = "get_matrix" )] |
498 | #[inline ] |
499 | pub fn matrix(&self) -> &[[f32; 4]; 4] { |
500 | unsafe { &*(&self.0.matrix as *const [f32; 16] as *const [[f32; 4]; 4]) } |
501 | } |
502 | |
503 | #[inline ] |
504 | pub fn set_matrix(&mut self, matrix: &[[f32; 4]; 4]) { |
505 | for (i, o) in Iterator::zip(matrix.iter().flatten(), self.0.matrix.iter_mut()) { |
506 | *o = *i; |
507 | } |
508 | } |
509 | |
510 | #[doc (alias = "gst_video_affine_transformation_meta_apply_matrix" )] |
511 | pub fn apply_matrix(&mut self, matrix: &[[f32; 4]; 4]) { |
512 | unsafe { |
513 | ffi::gst_video_affine_transformation_meta_apply_matrix( |
514 | &mut self.0, |
515 | matrix as *const [[f32; 4]; 4] as *const [f32; 16], |
516 | ); |
517 | } |
518 | } |
519 | } |
520 | |
521 | unsafe impl MetaAPI for VideoAffineTransformationMeta { |
522 | type GstType = ffi::GstVideoAffineTransformationMeta; |
523 | |
524 | #[doc (alias = "gst_video_affine_transformation_meta_api_get_type" )] |
525 | #[inline ] |
526 | fn meta_api() -> glib::Type { |
527 | unsafe { from_glib(val:ffi::gst_video_affine_transformation_meta_api_get_type()) } |
528 | } |
529 | } |
530 | |
531 | impl fmt::Debug for VideoAffineTransformationMeta { |
532 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
533 | f&mut DebugStruct<'_, '_>.debug_struct("VideoAffineTransformationMeta" ) |
534 | .field(name:"matrix" , &self.matrix()) |
535 | .finish() |
536 | } |
537 | } |
538 | |
539 | #[repr (transparent)] |
540 | #[doc (alias = "GstVideoOverlayCompositionMeta" )] |
541 | pub struct VideoOverlayCompositionMeta(ffi::GstVideoOverlayCompositionMeta); |
542 | |
543 | unsafe impl Send for VideoOverlayCompositionMeta {} |
544 | unsafe impl Sync for VideoOverlayCompositionMeta {} |
545 | |
546 | impl VideoOverlayCompositionMeta { |
547 | #[doc (alias = "gst_buffer_add_video_overlay_composition_meta" )] |
548 | pub fn add<'a>( |
549 | buffer: &'a mut gst::BufferRef, |
550 | overlay: &crate::VideoOverlayComposition, |
551 | ) -> gst::MetaRefMut<'a, Self, gst::meta::Standalone> { |
552 | skip_assert_initialized!(); |
553 | unsafe { |
554 | let meta = ffi::gst_buffer_add_video_overlay_composition_meta( |
555 | buffer.as_mut_ptr(), |
556 | overlay.as_mut_ptr(), |
557 | ); |
558 | |
559 | Self::from_mut_ptr(buffer, meta) |
560 | } |
561 | } |
562 | |
563 | #[doc (alias = "get_overlay" )] |
564 | #[inline ] |
565 | pub fn overlay(&self) -> &crate::VideoOverlayCompositionRef { |
566 | unsafe { crate::VideoOverlayCompositionRef::from_ptr(self.0.overlay) } |
567 | } |
568 | |
569 | #[doc (alias = "get_overlay_owned" )] |
570 | #[inline ] |
571 | pub fn overlay_owned(&self) -> crate::VideoOverlayComposition { |
572 | unsafe { from_glib_none(self.overlay().as_ptr()) } |
573 | } |
574 | |
575 | #[inline ] |
576 | pub fn set_overlay(&mut self, overlay: &crate::VideoOverlayComposition) { |
577 | #![allow (clippy::cast_ptr_alignment)] |
578 | unsafe { |
579 | gst::ffi::gst_mini_object_unref(self.0.overlay as *mut _); |
580 | self.0.overlay = |
581 | gst::ffi::gst_mini_object_ref(overlay.as_mut_ptr() as *mut _) as *mut _; |
582 | } |
583 | } |
584 | } |
585 | |
586 | unsafe impl MetaAPI for VideoOverlayCompositionMeta { |
587 | type GstType = ffi::GstVideoOverlayCompositionMeta; |
588 | |
589 | #[doc (alias = "gst_video_overlay_composition_meta_api_get_type" )] |
590 | #[inline ] |
591 | fn meta_api() -> glib::Type { |
592 | unsafe { from_glib(val:ffi::gst_video_overlay_composition_meta_api_get_type()) } |
593 | } |
594 | } |
595 | |
596 | impl fmt::Debug for VideoOverlayCompositionMeta { |
597 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
598 | f&mut DebugStruct<'_, '_>.debug_struct("VideoOverlayCompositionMeta" ) |
599 | .field(name:"overlay" , &self.overlay()) |
600 | .finish() |
601 | } |
602 | } |
603 | |
604 | #[cfg (feature = "v1_16" )] |
605 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_16" )))] |
606 | #[repr (transparent)] |
607 | #[doc (alias = "GstVideoCaptionMeta" )] |
608 | pub struct VideoCaptionMeta(ffi::GstVideoCaptionMeta); |
609 | |
610 | #[cfg (feature = "v1_16" )] |
611 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_16" )))] |
612 | unsafe impl Send for VideoCaptionMeta {} |
613 | #[cfg (feature = "v1_16" )] |
614 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_16" )))] |
615 | unsafe impl Sync for VideoCaptionMeta {} |
616 | |
617 | #[cfg (feature = "v1_16" )] |
618 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_16" )))] |
619 | impl VideoCaptionMeta { |
620 | #[doc (alias = "gst_buffer_add_video_caption_meta" )] |
621 | pub fn add<'a>( |
622 | buffer: &'a mut gst::BufferRef, |
623 | caption_type: crate::VideoCaptionType, |
624 | data: &[u8], |
625 | ) -> gst::MetaRefMut<'a, Self, gst::meta::Standalone> { |
626 | skip_assert_initialized!(); |
627 | assert!(!data.is_empty()); |
628 | unsafe { |
629 | let meta = ffi::gst_buffer_add_video_caption_meta( |
630 | buffer.as_mut_ptr(), |
631 | caption_type.into_glib(), |
632 | data.as_ptr(), |
633 | data.len(), |
634 | ); |
635 | |
636 | Self::from_mut_ptr(buffer, meta) |
637 | } |
638 | } |
639 | |
640 | #[doc (alias = "get_caption_type" )] |
641 | #[inline ] |
642 | pub fn caption_type(&self) -> crate::VideoCaptionType { |
643 | unsafe { from_glib(self.0.caption_type) } |
644 | } |
645 | |
646 | #[doc (alias = "get_data" )] |
647 | #[inline ] |
648 | pub fn data(&self) -> &[u8] { |
649 | if self.0.size == 0 { |
650 | return &[]; |
651 | } |
652 | unsafe { |
653 | use std::slice; |
654 | |
655 | slice::from_raw_parts(self.0.data, self.0.size) |
656 | } |
657 | } |
658 | } |
659 | |
660 | #[cfg (feature = "v1_16" )] |
661 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_16" )))] |
662 | unsafe impl MetaAPI for VideoCaptionMeta { |
663 | type GstType = ffi::GstVideoCaptionMeta; |
664 | |
665 | #[doc (alias = "gst_video_caption_meta_api_get_type" )] |
666 | #[inline ] |
667 | fn meta_api() -> glib::Type { |
668 | unsafe { from_glib(ffi::gst_video_caption_meta_api_get_type()) } |
669 | } |
670 | } |
671 | |
672 | #[cfg (feature = "v1_16" )] |
673 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_16" )))] |
674 | impl fmt::Debug for VideoCaptionMeta { |
675 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
676 | f.debug_struct("VideoCaptionMeta" ) |
677 | .field("caption_type" , &self.caption_type()) |
678 | .field("data" , &self.data()) |
679 | .finish() |
680 | } |
681 | } |
682 | |
683 | #[cfg (feature = "v1_18" )] |
684 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_18" )))] |
685 | #[repr (transparent)] |
686 | #[doc (alias = "GstVideoAFDMeta" )] |
687 | pub struct VideoAFDMeta(ffi::GstVideoAFDMeta); |
688 | |
689 | #[cfg (feature = "v1_18" )] |
690 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_18" )))] |
691 | unsafe impl Send for VideoAFDMeta {} |
692 | #[cfg (feature = "v1_18" )] |
693 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_18" )))] |
694 | unsafe impl Sync for VideoAFDMeta {} |
695 | |
696 | #[cfg (feature = "v1_18" )] |
697 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_18" )))] |
698 | impl VideoAFDMeta { |
699 | #[doc (alias = "gst_buffer_add_video_afd_meta" )] |
700 | pub fn add( |
701 | buffer: &mut gst::BufferRef, |
702 | field: u8, |
703 | spec: crate::VideoAFDSpec, |
704 | afd: crate::VideoAFDValue, |
705 | ) -> gst::MetaRefMut<Self, gst::meta::Standalone> { |
706 | skip_assert_initialized!(); |
707 | |
708 | unsafe { |
709 | let meta = ffi::gst_buffer_add_video_afd_meta( |
710 | buffer.as_mut_ptr(), |
711 | field, |
712 | spec.into_glib(), |
713 | afd.into_glib(), |
714 | ); |
715 | |
716 | Self::from_mut_ptr(buffer, meta) |
717 | } |
718 | } |
719 | |
720 | #[doc (alias = "get_field" )] |
721 | #[inline ] |
722 | pub fn field(&self) -> u8 { |
723 | self.0.field |
724 | } |
725 | |
726 | #[doc (alias = "get_spec" )] |
727 | #[inline ] |
728 | pub fn spec(&self) -> crate::VideoAFDSpec { |
729 | unsafe { from_glib(self.0.spec) } |
730 | } |
731 | |
732 | #[doc (alias = "get_afd" )] |
733 | #[inline ] |
734 | pub fn afd(&self) -> crate::VideoAFDValue { |
735 | unsafe { from_glib(self.0.afd) } |
736 | } |
737 | } |
738 | |
739 | #[cfg (feature = "v1_18" )] |
740 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_18" )))] |
741 | unsafe impl MetaAPI for VideoAFDMeta { |
742 | type GstType = ffi::GstVideoAFDMeta; |
743 | |
744 | #[doc (alias = "gst_video_afd_meta_api_get_type" )] |
745 | #[inline ] |
746 | fn meta_api() -> glib::Type { |
747 | unsafe { from_glib(ffi::gst_video_afd_meta_api_get_type()) } |
748 | } |
749 | } |
750 | |
751 | #[cfg (feature = "v1_18" )] |
752 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_18" )))] |
753 | impl fmt::Debug for VideoAFDMeta { |
754 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
755 | f.debug_struct("VideoAFDMeta" ) |
756 | .field("field" , &self.field()) |
757 | .field("spec" , &self.spec()) |
758 | .field("afd" , &self.afd()) |
759 | .finish() |
760 | } |
761 | } |
762 | |
763 | #[cfg (feature = "v1_18" )] |
764 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_18" )))] |
765 | #[repr (transparent)] |
766 | #[doc (alias = "GstVideoBarMeta" )] |
767 | pub struct VideoBarMeta(ffi::GstVideoBarMeta); |
768 | |
769 | #[cfg (feature = "v1_18" )] |
770 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_18" )))] |
771 | unsafe impl Send for VideoBarMeta {} |
772 | #[cfg (feature = "v1_18" )] |
773 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_18" )))] |
774 | unsafe impl Sync for VideoBarMeta {} |
775 | |
776 | #[cfg (feature = "v1_18" )] |
777 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_18" )))] |
778 | impl VideoBarMeta { |
779 | #[doc (alias = "gst_buffer_add_video_bar_meta" )] |
780 | pub fn add( |
781 | buffer: &mut gst::BufferRef, |
782 | field: u8, |
783 | is_letterbox: bool, |
784 | bar_data1: u32, |
785 | bar_data2: u32, |
786 | ) -> gst::MetaRefMut<Self, gst::meta::Standalone> { |
787 | skip_assert_initialized!(); |
788 | |
789 | unsafe { |
790 | let meta = ffi::gst_buffer_add_video_bar_meta( |
791 | buffer.as_mut_ptr(), |
792 | field, |
793 | is_letterbox.into_glib(), |
794 | bar_data1, |
795 | bar_data2, |
796 | ); |
797 | |
798 | Self::from_mut_ptr(buffer, meta) |
799 | } |
800 | } |
801 | |
802 | #[doc (alias = "get_field" )] |
803 | #[inline ] |
804 | pub fn field(&self) -> u8 { |
805 | self.0.field |
806 | } |
807 | |
808 | #[inline ] |
809 | pub fn is_letterbox(&self) -> bool { |
810 | unsafe { from_glib(self.0.is_letterbox) } |
811 | } |
812 | |
813 | #[doc (alias = "get_bar_data1" )] |
814 | #[inline ] |
815 | pub fn bar_data1(&self) -> u32 { |
816 | self.0.bar_data1 |
817 | } |
818 | |
819 | #[doc (alias = "get_bar_data2" )] |
820 | #[inline ] |
821 | pub fn bar_data2(&self) -> u32 { |
822 | self.0.bar_data2 |
823 | } |
824 | } |
825 | |
826 | #[cfg (feature = "v1_18" )] |
827 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_18" )))] |
828 | unsafe impl MetaAPI for VideoBarMeta { |
829 | type GstType = ffi::GstVideoBarMeta; |
830 | |
831 | #[doc (alias = "gst_video_bar_meta_api_get_type" )] |
832 | #[inline ] |
833 | fn meta_api() -> glib::Type { |
834 | unsafe { from_glib(ffi::gst_video_bar_meta_api_get_type()) } |
835 | } |
836 | } |
837 | |
838 | #[cfg (feature = "v1_18" )] |
839 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_18" )))] |
840 | impl fmt::Debug for VideoBarMeta { |
841 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
842 | f.debug_struct("VideoBarMeta" ) |
843 | .field("field" , &self.field()) |
844 | .field("is_letterbox" , &self.is_letterbox()) |
845 | .field("bar_data1" , &self.bar_data1()) |
846 | .field("bar_data2" , &self.bar_data2()) |
847 | .finish() |
848 | } |
849 | } |
850 | |
851 | #[cfg (feature = "v1_20" )] |
852 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_20" )))] |
853 | #[repr (transparent)] |
854 | #[doc (alias = "GstVideoCodecAlphaMeta" )] |
855 | pub struct VideoCodecAlphaMeta(ffi::GstVideoCodecAlphaMeta); |
856 | |
857 | #[cfg (feature = "v1_20" )] |
858 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_20" )))] |
859 | unsafe impl Send for VideoCodecAlphaMeta {} |
860 | #[cfg (feature = "v1_20" )] |
861 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_20" )))] |
862 | unsafe impl Sync for VideoCodecAlphaMeta {} |
863 | |
864 | #[cfg (feature = "v1_20" )] |
865 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_20" )))] |
866 | impl VideoCodecAlphaMeta { |
867 | #[doc (alias = "gst_buffer_add_video_codec_alpha_meta" )] |
868 | pub fn add( |
869 | buffer: &mut gst::BufferRef, |
870 | alpha_buffer: gst::Buffer, |
871 | ) -> gst::MetaRefMut<Self, gst::meta::Standalone> { |
872 | skip_assert_initialized!(); |
873 | unsafe { |
874 | let meta = ffi::gst_buffer_add_video_codec_alpha_meta( |
875 | buffer.as_mut_ptr(), |
876 | alpha_buffer.to_glib_none().0, |
877 | ); |
878 | |
879 | Self::from_mut_ptr(buffer, meta) |
880 | } |
881 | } |
882 | |
883 | #[inline ] |
884 | pub fn alpha_buffer(&self) -> &gst::BufferRef { |
885 | unsafe { gst::BufferRef::from_ptr(self.0.buffer) } |
886 | } |
887 | |
888 | #[inline ] |
889 | pub fn alpha_buffer_owned(&self) -> gst::Buffer { |
890 | unsafe { from_glib_none(self.0.buffer) } |
891 | } |
892 | } |
893 | |
894 | #[cfg (feature = "v1_20" )] |
895 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_20" )))] |
896 | unsafe impl MetaAPI for VideoCodecAlphaMeta { |
897 | type GstType = ffi::GstVideoCodecAlphaMeta; |
898 | |
899 | #[doc (alias = "gst_video_codec_alpha_meta_api_get_type" )] |
900 | #[inline ] |
901 | fn meta_api() -> glib::Type { |
902 | unsafe { from_glib(ffi::gst_video_codec_alpha_meta_api_get_type()) } |
903 | } |
904 | } |
905 | |
906 | #[cfg (feature = "v1_20" )] |
907 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_20" )))] |
908 | impl fmt::Debug for VideoCodecAlphaMeta { |
909 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
910 | f.debug_struct("VideoCodecAlphaMeta" ) |
911 | .field("buffer" , &self.alpha_buffer()) |
912 | .finish() |
913 | } |
914 | } |
915 | |
916 | #[cfg (feature = "v1_22" )] |
917 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_22" )))] |
918 | #[repr (transparent)] |
919 | #[doc (alias = "GstVideoSEIUserDataUnregisteredMeta" )] |
920 | pub struct VideoSeiUserDataUnregisteredMeta(ffi::GstVideoSEIUserDataUnregisteredMeta); |
921 | |
922 | #[cfg (feature = "v1_22" )] |
923 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_22" )))] |
924 | unsafe impl Send for VideoSeiUserDataUnregisteredMeta {} |
925 | #[cfg (feature = "v1_22" )] |
926 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_22" )))] |
927 | unsafe impl Sync for VideoSeiUserDataUnregisteredMeta {} |
928 | |
929 | #[cfg (feature = "v1_22" )] |
930 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_22" )))] |
931 | impl VideoSeiUserDataUnregisteredMeta { |
932 | #[doc (alias = "gst_buffer_add_video_sei_user_data_unregistered_meta" )] |
933 | pub fn add<'a>( |
934 | buffer: &'a mut gst::BufferRef, |
935 | uuid: &[u8; 16], |
936 | data: &[u8], |
937 | ) -> gst::MetaRefMut<'a, Self, gst::meta::Standalone> { |
938 | skip_assert_initialized!(); |
939 | assert!(!data.is_empty()); |
940 | unsafe { |
941 | let meta = ffi::gst_buffer_add_video_sei_user_data_unregistered_meta( |
942 | buffer.as_mut_ptr(), |
943 | mut_override(uuid.as_ptr()), |
944 | mut_override(data.as_ptr()), |
945 | data.len(), |
946 | ); |
947 | |
948 | Self::from_mut_ptr(buffer, meta) |
949 | } |
950 | } |
951 | |
952 | #[doc (alias = "get_data" )] |
953 | #[inline ] |
954 | pub fn data(&self) -> &[u8] { |
955 | if self.0.size == 0 { |
956 | return &[]; |
957 | } |
958 | // SAFETY: In the C API we have a pointer data and a size variable |
959 | // indicating the length of the data. Here we convert it to a size, |
960 | // making sure we read the size specified in the C API. |
961 | unsafe { |
962 | use std::slice; |
963 | slice::from_raw_parts(self.0.data, self.0.size) |
964 | } |
965 | } |
966 | |
967 | #[doc (alias = "get_uuid" )] |
968 | #[inline ] |
969 | pub fn uuid(&self) -> [u8; 16] { |
970 | self.0.uuid |
971 | } |
972 | } |
973 | |
974 | #[cfg (feature = "v1_22" )] |
975 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_22" )))] |
976 | impl fmt::Debug for VideoSeiUserDataUnregisteredMeta { |
977 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
978 | f.debug_struct("VideoSeiUserDataUnregisteredMeta" ) |
979 | .field( |
980 | "uuid" , |
981 | &format!("0x{:032X}" , u128::from_be_bytes(self.uuid())), |
982 | ) |
983 | .field("data" , &self.data()) |
984 | .finish() |
985 | } |
986 | } |
987 | |
988 | #[cfg (feature = "v1_22" )] |
989 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_22" )))] |
990 | unsafe impl MetaAPI for VideoSeiUserDataUnregisteredMeta { |
991 | type GstType = ffi::GstVideoSEIUserDataUnregisteredMeta; |
992 | |
993 | #[doc (alias = "gst_video_sei_user_data_unregistered_meta_api_get_type" )] |
994 | fn meta_api() -> glib::Type { |
995 | unsafe { |
996 | glib::translate::from_glib(ffi::gst_video_sei_user_data_unregistered_meta_api_get_type()) |
997 | } |
998 | } |
999 | } |
1000 | |
1001 | #[cfg (feature = "v1_24" )] |
1002 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_24" )))] |
1003 | #[repr (transparent)] |
1004 | #[doc (alias = "GstAncillaryMeta" )] |
1005 | pub struct AncillaryMeta(ffi::GstAncillaryMeta); |
1006 | |
1007 | #[cfg (feature = "v1_24" )] |
1008 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_24" )))] |
1009 | unsafe impl Send for AncillaryMeta {} |
1010 | #[cfg (feature = "v1_24" )] |
1011 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_24" )))] |
1012 | unsafe impl Sync for AncillaryMeta {} |
1013 | |
1014 | #[cfg (feature = "v1_24" )] |
1015 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_24" )))] |
1016 | impl AncillaryMeta { |
1017 | #[doc (alias = "gst_buffer_add_ancillary_meta" )] |
1018 | pub fn add(buffer: &mut gst::BufferRef) -> gst::MetaRefMut<Self, gst::meta::Standalone> { |
1019 | skip_assert_initialized!(); |
1020 | unsafe { |
1021 | let meta = ffi::gst_buffer_add_ancillary_meta(buffer.as_mut_ptr()); |
1022 | |
1023 | Self::from_mut_ptr(buffer, meta) |
1024 | } |
1025 | } |
1026 | |
1027 | #[inline ] |
1028 | pub fn field(&self) -> crate::AncillaryMetaField { |
1029 | unsafe { from_glib(self.0.field) } |
1030 | } |
1031 | |
1032 | #[inline ] |
1033 | pub fn set_field(&mut self, field: crate::AncillaryMetaField) { |
1034 | self.0.field = field.into_glib(); |
1035 | } |
1036 | |
1037 | #[inline ] |
1038 | pub fn c_not_y_channel(&self) -> bool { |
1039 | unsafe { from_glib(self.0.c_not_y_channel) } |
1040 | } |
1041 | |
1042 | #[inline ] |
1043 | pub fn set_c_not_y_channel(&mut self, c_not_y_channel: bool) { |
1044 | self.0.c_not_y_channel = c_not_y_channel.into_glib(); |
1045 | } |
1046 | |
1047 | #[inline ] |
1048 | pub fn line(&self) -> u16 { |
1049 | self.0.line |
1050 | } |
1051 | |
1052 | #[inline ] |
1053 | pub fn set_line(&mut self, line: u16) { |
1054 | self.0.line = line; |
1055 | } |
1056 | |
1057 | #[inline ] |
1058 | pub fn offset(&self) -> u16 { |
1059 | self.0.offset |
1060 | } |
1061 | |
1062 | #[inline ] |
1063 | pub fn set_offset(&mut self, offset: u16) { |
1064 | self.0.offset = offset; |
1065 | } |
1066 | |
1067 | #[inline ] |
1068 | pub fn did(&self) -> u16 { |
1069 | self.0.DID |
1070 | } |
1071 | |
1072 | #[inline ] |
1073 | pub fn set_did(&mut self, did: u16) { |
1074 | self.0.DID = did; |
1075 | } |
1076 | |
1077 | #[inline ] |
1078 | pub fn sdid_block_number(&self) -> u16 { |
1079 | self.0.SDID_block_number |
1080 | } |
1081 | |
1082 | #[inline ] |
1083 | pub fn set_sdid_block_number(&mut self, sdid_block_number: u16) { |
1084 | self.0.SDID_block_number = sdid_block_number; |
1085 | } |
1086 | |
1087 | #[inline ] |
1088 | pub fn data_count(&self) -> u16 { |
1089 | self.0.data_count |
1090 | } |
1091 | |
1092 | #[inline ] |
1093 | pub fn checksum(&self) -> u16 { |
1094 | self.0.checksum |
1095 | } |
1096 | |
1097 | #[inline ] |
1098 | pub fn set_checksum(&mut self, checksum: u16) { |
1099 | self.0.checksum = checksum; |
1100 | } |
1101 | |
1102 | #[inline ] |
1103 | pub fn data(&self) -> &[u16] { |
1104 | if self.0.data_count & 0xff == 0 { |
1105 | return &[]; |
1106 | } |
1107 | unsafe { |
1108 | use std::slice; |
1109 | |
1110 | slice::from_raw_parts(self.0.data, (self.0.data_count & 0xff) as usize) |
1111 | } |
1112 | } |
1113 | |
1114 | #[inline ] |
1115 | pub fn data_mut(&mut self) -> &mut [u16] { |
1116 | if self.0.data_count & 0xff == 0 { |
1117 | return &mut []; |
1118 | } |
1119 | unsafe { |
1120 | use std::slice; |
1121 | |
1122 | slice::from_raw_parts_mut(self.0.data, (self.0.data_count & 0xff) as usize) |
1123 | } |
1124 | } |
1125 | |
1126 | #[inline ] |
1127 | pub fn set_data(&mut self, data: glib::Slice<u16>) { |
1128 | unsafe { |
1129 | assert!(data.len() < 256); |
1130 | self.0.data_count = data.len() as u16; |
1131 | self.0.data = data.into_glib_ptr(); |
1132 | } |
1133 | } |
1134 | |
1135 | #[inline ] |
1136 | pub fn set_data_count_upper_two_bits(&mut self, upper_two_bits: u8) { |
1137 | assert!(upper_two_bits & !0x03 == 0); |
1138 | self.0.data_count = ((upper_two_bits as u16) << 8) | self.0.data_count & 0xff; |
1139 | } |
1140 | } |
1141 | |
1142 | #[cfg (feature = "v1_24" )] |
1143 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_24" )))] |
1144 | unsafe impl MetaAPI for AncillaryMeta { |
1145 | type GstType = ffi::GstAncillaryMeta; |
1146 | |
1147 | #[doc (alias = "gst_ancillary_meta_api_get_type" )] |
1148 | #[inline ] |
1149 | fn meta_api() -> glib::Type { |
1150 | unsafe { from_glib(ffi::gst_ancillary_meta_api_get_type()) } |
1151 | } |
1152 | } |
1153 | |
1154 | #[cfg (feature = "v1_24" )] |
1155 | #[cfg_attr (docsrs, doc(cfg(feature = "v1_24" )))] |
1156 | impl fmt::Debug for AncillaryMeta { |
1157 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
1158 | f.debug_struct("AncillaryMeta" ) |
1159 | .field("field" , &self.field()) |
1160 | .field("c_not_y_channel" , &self.c_not_y_channel()) |
1161 | .field("line" , &self.line()) |
1162 | .field("offset" , &self.offset()) |
1163 | .field("did" , &self.did()) |
1164 | .field("sdid_block_number" , &self.sdid_block_number()) |
1165 | .field("data_count" , &self.data_count()) |
1166 | .field("data" , &self.data()) |
1167 | .field("checksum" , &self.checksum()) |
1168 | .finish() |
1169 | } |
1170 | } |
1171 | |
1172 | pub mod tags { |
1173 | gst::impl_meta_tag!(Video, crate::ffi::GST_META_TAG_VIDEO_STR); |
1174 | gst::impl_meta_tag!(Size, crate::ffi::GST_META_TAG_VIDEO_SIZE_STR); |
1175 | gst::impl_meta_tag!(Orientation, crate::ffi::GST_META_TAG_VIDEO_ORIENTATION_STR); |
1176 | gst::impl_meta_tag!(Colorspace, crate::ffi::GST_META_TAG_VIDEO_COLORSPACE_STR); |
1177 | } |
1178 | |
1179 | #[derive (Debug, Clone, PartialEq, Eq)] |
1180 | pub struct VideoMetaTransformScale<'a> { |
1181 | in_info: &'a crate::VideoInfo, |
1182 | out_info: &'a crate::VideoInfo, |
1183 | } |
1184 | |
1185 | impl<'a> VideoMetaTransformScale<'a> { |
1186 | pub fn new(in_info: &'a crate::VideoInfo, out_info: &'a crate::VideoInfo) -> Self { |
1187 | skip_assert_initialized!(); |
1188 | VideoMetaTransformScale { in_info, out_info } |
1189 | } |
1190 | } |
1191 | |
1192 | unsafe impl<'a> gst::meta::MetaTransform<'a> for VideoMetaTransformScale<'a> { |
1193 | type GLibType = ffi::GstVideoMetaTransform; |
1194 | |
1195 | #[doc (alias = "gst_video_meta_transform_scale_get_quark" )] |
1196 | fn quark() -> glib::Quark { |
1197 | unsafe { from_glib(val:ffi::gst_video_meta_transform_scale_get_quark()) } |
1198 | } |
1199 | |
1200 | fn to_raw<T: MetaAPI>( |
1201 | &self, |
1202 | _meta: &gst::MetaRef<T>, |
1203 | ) -> Result<ffi::GstVideoMetaTransform, glib::BoolError> { |
1204 | Ok(ffi::GstVideoMetaTransform { |
1205 | in_info: mut_override(self.in_info.to_glib_none().0), |
1206 | out_info: mut_override(self.out_info.to_glib_none().0), |
1207 | }) |
1208 | } |
1209 | } |
1210 | |
1211 | #[cfg (test)] |
1212 | mod tests { |
1213 | use super::*; |
1214 | |
1215 | #[test ] |
1216 | fn test_add_get_meta() { |
1217 | gst::init().unwrap(); |
1218 | |
1219 | let mut buffer = gst::Buffer::with_size(320 * 240 * 4).unwrap(); |
1220 | { |
1221 | let meta = VideoMeta::add( |
1222 | buffer.get_mut().unwrap(), |
1223 | crate::VideoFrameFlags::empty(), |
1224 | crate::VideoFormat::Argb, |
1225 | 320, |
1226 | 240, |
1227 | ) |
1228 | .unwrap(); |
1229 | assert_eq!(meta.id(), 0); |
1230 | assert_eq!(meta.video_frame_flags(), crate::VideoFrameFlags::empty()); |
1231 | assert_eq!(meta.format(), crate::VideoFormat::Argb); |
1232 | assert_eq!(meta.width(), 320); |
1233 | assert_eq!(meta.height(), 240); |
1234 | assert_eq!(meta.n_planes(), 1); |
1235 | assert_eq!(meta.offset(), &[0]); |
1236 | assert_eq!(meta.stride(), &[320 * 4]); |
1237 | assert!(meta.has_tag::<gst::meta::tags::Memory>()); |
1238 | assert!(meta.has_tag::<tags::Video>()); |
1239 | assert!(meta.has_tag::<tags::Colorspace>()); |
1240 | assert!(meta.has_tag::<tags::Size>()); |
1241 | } |
1242 | |
1243 | { |
1244 | let meta = buffer.meta::<VideoMeta>().unwrap(); |
1245 | assert_eq!(meta.id(), 0); |
1246 | assert_eq!(meta.video_frame_flags(), crate::VideoFrameFlags::empty()); |
1247 | assert_eq!(meta.format(), crate::VideoFormat::Argb); |
1248 | assert_eq!(meta.width(), 320); |
1249 | assert_eq!(meta.height(), 240); |
1250 | assert_eq!(meta.n_planes(), 1); |
1251 | assert_eq!(meta.offset(), &[0]); |
1252 | assert_eq!(meta.stride(), &[320 * 4]); |
1253 | } |
1254 | } |
1255 | |
1256 | #[test ] |
1257 | fn test_add_full_get_meta() { |
1258 | gst::init().unwrap(); |
1259 | |
1260 | let mut buffer = gst::Buffer::with_size(320 * 240 * 4).unwrap(); |
1261 | { |
1262 | let meta = VideoMeta::add_full( |
1263 | buffer.get_mut().unwrap(), |
1264 | crate::VideoFrameFlags::empty(), |
1265 | crate::VideoFormat::Argb, |
1266 | 320, |
1267 | 240, |
1268 | &[0], |
1269 | &[320 * 4], |
1270 | ) |
1271 | .unwrap(); |
1272 | assert_eq!(meta.id(), 0); |
1273 | assert_eq!(meta.video_frame_flags(), crate::VideoFrameFlags::empty()); |
1274 | assert_eq!(meta.format(), crate::VideoFormat::Argb); |
1275 | assert_eq!(meta.width(), 320); |
1276 | assert_eq!(meta.height(), 240); |
1277 | assert_eq!(meta.n_planes(), 1); |
1278 | assert_eq!(meta.offset(), &[0]); |
1279 | assert_eq!(meta.stride(), &[320 * 4]); |
1280 | } |
1281 | |
1282 | { |
1283 | let meta = buffer.meta::<VideoMeta>().unwrap(); |
1284 | assert_eq!(meta.id(), 0); |
1285 | assert_eq!(meta.video_frame_flags(), crate::VideoFrameFlags::empty()); |
1286 | assert_eq!(meta.format(), crate::VideoFormat::Argb); |
1287 | assert_eq!(meta.width(), 320); |
1288 | assert_eq!(meta.height(), 240); |
1289 | assert_eq!(meta.n_planes(), 1); |
1290 | assert_eq!(meta.offset(), &[0]); |
1291 | assert_eq!(meta.stride(), &[320 * 4]); |
1292 | } |
1293 | } |
1294 | |
1295 | #[test ] |
1296 | #[cfg (feature = "v1_16" )] |
1297 | fn test_add_full_alternate_interlacing() { |
1298 | gst::init().unwrap(); |
1299 | let mut buffer = gst::Buffer::with_size(320 * 120 * 4).unwrap(); |
1300 | VideoMeta::add_full( |
1301 | buffer.get_mut().unwrap(), |
1302 | crate::VideoFrameFlags::TOP_FIELD, |
1303 | crate::VideoFormat::Argb, |
1304 | 320, |
1305 | 240, |
1306 | &[0], |
1307 | &[320 * 4], |
1308 | ) |
1309 | .unwrap(); |
1310 | } |
1311 | |
1312 | #[test ] |
1313 | #[cfg (feature = "v1_18" )] |
1314 | fn test_video_meta_alignment() { |
1315 | gst::init().unwrap(); |
1316 | |
1317 | let mut buffer = gst::Buffer::with_size(115200).unwrap(); |
1318 | let meta = VideoMeta::add( |
1319 | buffer.get_mut().unwrap(), |
1320 | crate::VideoFrameFlags::empty(), |
1321 | crate::VideoFormat::Nv12, |
1322 | 320, |
1323 | 240, |
1324 | ) |
1325 | .unwrap(); |
1326 | |
1327 | let alig = meta.alignment(); |
1328 | assert_eq!(alig, crate::VideoAlignment::new(0, 0, 0, 0, &[0, 0, 0, 0])); |
1329 | |
1330 | assert_eq!(meta.plane_size().unwrap(), [76800, 38400, 0, 0]); |
1331 | assert_eq!(meta.plane_height().unwrap(), [240, 120, 0, 0]); |
1332 | |
1333 | /* horizontal padding */ |
1334 | let mut info = crate::VideoInfo::builder(crate::VideoFormat::Nv12, 320, 240) |
1335 | .build() |
1336 | .expect("Failed to create VideoInfo" ); |
1337 | let mut alig = crate::VideoAlignment::new(0, 0, 2, 6, &[0, 0, 0, 0]); |
1338 | info.align(&mut alig).unwrap(); |
1339 | |
1340 | let mut meta = VideoMeta::add_full( |
1341 | buffer.get_mut().unwrap(), |
1342 | crate::VideoFrameFlags::empty(), |
1343 | crate::VideoFormat::Nv12, |
1344 | info.width(), |
1345 | info.height(), |
1346 | info.offset(), |
1347 | info.stride(), |
1348 | ) |
1349 | .unwrap(); |
1350 | meta.set_alignment(&alig).unwrap(); |
1351 | |
1352 | let alig = meta.alignment(); |
1353 | assert_eq!(alig, crate::VideoAlignment::new(0, 0, 2, 6, &[0, 0, 0, 0])); |
1354 | |
1355 | assert_eq!(meta.plane_size().unwrap(), [78720, 39360, 0, 0]); |
1356 | assert_eq!(meta.plane_height().unwrap(), [240, 120, 0, 0]); |
1357 | |
1358 | /* vertical alignment */ |
1359 | let mut info = crate::VideoInfo::builder(crate::VideoFormat::Nv12, 320, 240) |
1360 | .build() |
1361 | .expect("Failed to create VideoInfo" ); |
1362 | let mut alig = crate::VideoAlignment::new(2, 6, 0, 0, &[0, 0, 0, 0]); |
1363 | info.align(&mut alig).unwrap(); |
1364 | |
1365 | let mut meta = VideoMeta::add_full( |
1366 | buffer.get_mut().unwrap(), |
1367 | crate::VideoFrameFlags::empty(), |
1368 | crate::VideoFormat::Nv12, |
1369 | info.width(), |
1370 | info.height(), |
1371 | info.offset(), |
1372 | info.stride(), |
1373 | ) |
1374 | .unwrap(); |
1375 | meta.set_alignment(&alig).unwrap(); |
1376 | |
1377 | let alig = meta.alignment(); |
1378 | assert_eq!(alig, crate::VideoAlignment::new(2, 6, 0, 0, &[0, 0, 0, 0])); |
1379 | |
1380 | assert_eq!(meta.plane_size().unwrap(), [79360, 39680, 0, 0]); |
1381 | assert_eq!(meta.plane_height().unwrap(), [248, 124, 0, 0]); |
1382 | } |
1383 | |
1384 | #[test ] |
1385 | #[cfg (feature = "v1_22" )] |
1386 | fn test_get_video_sei_user_data_unregistered_meta() { |
1387 | gst::init().unwrap(); |
1388 | |
1389 | const META_UUID: &[u8; 16] = &[ |
1390 | 0x4D, 0x49, 0x53, 0x50, 0x6D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x65, 0x63, 0x74, 0x69, |
1391 | 0x6D, 0x65, |
1392 | ]; |
1393 | |
1394 | const META_DATA: &[u8] = &[ |
1395 | 0x1f, 0x00, 0x05, 0xff, 0x21, 0x7e, 0xff, 0x29, 0xb5, 0xff, 0xdc, 0x13, |
1396 | ]; |
1397 | |
1398 | let buffer_data = &[ |
1399 | &[0x00, 0x00, 0x00, 0x20, 0x06, 0x05, 0x1c], |
1400 | META_UUID as &[u8], |
1401 | META_DATA, |
1402 | &[ |
1403 | 0x80, 0x00, 0x00, 0x00, 0x14, 0x65, 0x88, 0x84, 0x00, 0x10, 0xff, 0xfe, 0xf6, 0xf0, |
1404 | 0xfe, 0x05, 0x36, 0x56, 0x04, 0x50, 0x96, 0x7b, 0x3f, 0x53, 0xe1, |
1405 | ], |
1406 | ] |
1407 | .concat(); |
1408 | |
1409 | let mut harness = gst_check::Harness::new("h264parse" ); |
1410 | harness.set_src_caps_str(r#" |
1411 | video/x-h264, stream-format=(string)avc, |
1412 | width=(int)1920, height=(int)1080, framerate=(fraction)25/1, |
1413 | bit-depth-chroma=(uint)8, parsed=(boolean)true, |
1414 | alignment=(string)au, profile=(string)high, level=(string)4, |
1415 | codec_data=(buffer)01640028ffe1001a67640028acb200f0044fcb080000030008000003019478c1924001000568ebccb22c |
1416 | "# ); |
1417 | let buffer = gst::Buffer::from_slice(buffer_data.clone()); |
1418 | let buffer = harness.push_and_pull(buffer).unwrap(); |
1419 | |
1420 | let meta = buffer.meta::<VideoSeiUserDataUnregisteredMeta>().unwrap(); |
1421 | assert_eq!(meta.uuid(), *META_UUID); |
1422 | assert_eq!(meta.data(), META_DATA); |
1423 | assert_eq!(meta.data().len(), META_DATA.len()); |
1424 | } |
1425 | |
1426 | #[test ] |
1427 | fn test_meta_video_transform() { |
1428 | gst::init().unwrap(); |
1429 | |
1430 | let mut buffer = gst::Buffer::with_size(320 * 240 * 4).unwrap(); |
1431 | let meta = VideoCropMeta::add(buffer.get_mut().unwrap(), (10, 10, 20, 20)); |
1432 | |
1433 | let mut buffer2 = gst::Buffer::with_size(640 * 480 * 4).unwrap(); |
1434 | |
1435 | let in_video_info = crate::VideoInfo::builder(crate::VideoFormat::Rgba, 320, 240) |
1436 | .build() |
1437 | .unwrap(); |
1438 | let out_video_info = crate::VideoInfo::builder(crate::VideoFormat::Rgba, 640, 480) |
1439 | .build() |
1440 | .unwrap(); |
1441 | |
1442 | meta.transform( |
1443 | buffer2.get_mut().unwrap(), |
1444 | &VideoMetaTransformScale::new(&in_video_info, &out_video_info), |
1445 | ) |
1446 | .unwrap(); |
1447 | |
1448 | let meta2 = buffer2.meta::<VideoCropMeta>().unwrap(); |
1449 | |
1450 | assert_eq!(meta2.rect(), (20, 20, 40, 40)); |
1451 | } |
1452 | } |
1453 | |