2018-09-29 09:01:26 +00:00
|
|
|
// Copyright (C) 2018 Sebastian Dröge <sebastian@centricular.com>
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
|
|
|
use std::fmt;
|
2020-06-02 08:18:42 +00:00
|
|
|
use std::ptr;
|
2018-09-29 09:01:26 +00:00
|
|
|
|
|
|
|
use glib;
|
2020-06-02 08:18:42 +00:00
|
|
|
use glib::translate::{from_glib, from_glib_none, FromGlib, ToGlib, ToGlibPtr};
|
2018-09-29 09:01:26 +00:00
|
|
|
use gst;
|
|
|
|
use gst::prelude::*;
|
2019-03-19 07:58:20 +00:00
|
|
|
use gst_sys;
|
|
|
|
use gst_video_sys;
|
2018-09-29 09:01:26 +00:00
|
|
|
|
|
|
|
#[repr(C)]
|
2019-03-19 07:58:20 +00:00
|
|
|
pub struct VideoMeta(gst_video_sys::GstVideoMeta);
|
2018-09-29 09:01:26 +00:00
|
|
|
|
2019-12-18 15:04:42 +00:00
|
|
|
unsafe impl Send for VideoMeta {}
|
|
|
|
unsafe impl Sync for VideoMeta {}
|
|
|
|
|
2018-09-29 22:17:12 +00:00
|
|
|
impl VideoMeta {
|
2018-10-11 08:40:00 +00:00
|
|
|
pub fn add(
|
|
|
|
buffer: &mut gst::BufferRef,
|
2018-09-29 09:01:26 +00:00
|
|
|
flags: ::VideoFrameFlags,
|
|
|
|
format: ::VideoFormat,
|
|
|
|
width: u32,
|
|
|
|
height: u32,
|
2018-10-11 08:40:00 +00:00
|
|
|
) -> gst::MetaRefMut<Self, gst::meta::Standalone> {
|
2020-03-22 14:18:47 +00:00
|
|
|
skip_assert_initialized!();
|
|
|
|
|
2018-09-29 09:01:26 +00:00
|
|
|
let info = ::VideoInfo::new(format, width, height).build().unwrap();
|
|
|
|
assert!(buffer.get_size() >= info.size());
|
|
|
|
|
|
|
|
unsafe {
|
2019-03-19 07:58:20 +00:00
|
|
|
let meta = gst_video_sys::gst_buffer_add_video_meta(
|
2018-09-29 09:01:26 +00:00
|
|
|
buffer.as_mut_ptr(),
|
|
|
|
flags.to_glib(),
|
|
|
|
format.to_glib(),
|
|
|
|
width,
|
|
|
|
height,
|
|
|
|
);
|
|
|
|
|
2018-09-29 22:17:12 +00:00
|
|
|
Self::from_mut_ptr(buffer, meta)
|
2018-09-29 09:01:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-29 22:17:12 +00:00
|
|
|
pub fn add_full<'a>(
|
2018-09-29 09:01:26 +00:00
|
|
|
buffer: &'a mut gst::BufferRef,
|
|
|
|
flags: ::VideoFrameFlags,
|
|
|
|
format: ::VideoFormat,
|
|
|
|
width: u32,
|
|
|
|
height: u32,
|
2019-11-17 12:55:04 +00:00
|
|
|
offset: &[usize],
|
|
|
|
stride: &[i32],
|
2018-09-29 09:01:26 +00:00
|
|
|
) -> gst::MetaRefMut<'a, Self, gst::meta::Standalone> {
|
2020-03-22 14:18:47 +00:00
|
|
|
skip_assert_initialized!();
|
|
|
|
|
2019-11-17 12:55:04 +00:00
|
|
|
let n_planes = offset.len() as u32;
|
2018-09-29 09:01:26 +00:00
|
|
|
let info = ::VideoInfo::new(format, width, height)
|
2018-10-11 08:40:00 +00:00
|
|
|
.offset(offset)
|
|
|
|
.stride(stride)
|
2018-09-29 09:01:26 +00:00
|
|
|
.build()
|
2019-11-17 12:55:04 +00:00
|
|
|
.expect("Unable to build VideoInfo for given format, offsets and strides");
|
2018-09-29 09:01:26 +00:00
|
|
|
assert!(buffer.get_size() >= info.size());
|
|
|
|
|
|
|
|
unsafe {
|
2019-03-19 07:58:20 +00:00
|
|
|
let meta = gst_video_sys::gst_buffer_add_video_meta_full(
|
2018-09-29 09:01:26 +00:00
|
|
|
buffer.as_mut_ptr(),
|
|
|
|
flags.to_glib(),
|
|
|
|
format.to_glib(),
|
|
|
|
width,
|
|
|
|
height,
|
|
|
|
n_planes,
|
|
|
|
offset.as_ptr() as *mut _,
|
|
|
|
stride.as_ptr() as *mut _,
|
|
|
|
);
|
|
|
|
|
2018-09-29 22:17:12 +00:00
|
|
|
Self::from_mut_ptr(buffer, meta)
|
2018-09-29 09:01:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_flags(&self) -> ::VideoFrameFlags {
|
|
|
|
from_glib(self.0.flags)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_format(&self) -> ::VideoFormat {
|
|
|
|
from_glib(self.0.format)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_id(&self) -> i32 {
|
|
|
|
self.0.id
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_width(&self) -> u32 {
|
|
|
|
self.0.width
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_height(&self) -> u32 {
|
|
|
|
self.0.height
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_n_planes(&self) -> u32 {
|
|
|
|
self.0.n_planes
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_offset(&self) -> &[usize] {
|
|
|
|
&self.0.offset[0..(self.0.n_planes as usize)]
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_stride(&self) -> &[i32] {
|
|
|
|
&self.0.stride[0..(self.0.n_planes as usize)]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-29 22:17:12 +00:00
|
|
|
unsafe impl MetaAPI for VideoMeta {
|
2019-03-19 07:58:20 +00:00
|
|
|
type GstType = gst_video_sys::GstVideoMeta;
|
2018-09-29 09:01:26 +00:00
|
|
|
|
|
|
|
fn get_meta_api() -> glib::Type {
|
2019-03-19 07:58:20 +00:00
|
|
|
unsafe { from_glib(gst_video_sys::gst_video_meta_api_get_type()) }
|
2018-09-29 09:01:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-29 22:17:12 +00:00
|
|
|
impl fmt::Debug for VideoMeta {
|
2018-09-29 09:01:26 +00:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
f.debug_struct("VideoMeta")
|
|
|
|
.field("id", &self.get_id())
|
|
|
|
.field("flags", &self.get_flags())
|
|
|
|
.field("format", &self.get_format())
|
|
|
|
.field("width", &self.get_width())
|
|
|
|
.field("height", &self.get_height())
|
|
|
|
.field("n_planes", &self.get_n_planes())
|
|
|
|
.field("offset", &self.get_offset())
|
|
|
|
.field("stride", &self.get_stride())
|
|
|
|
.finish()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-02 08:18:42 +00:00
|
|
|
#[repr(C)]
|
|
|
|
pub struct VideoCropMeta(gst_video_sys::GstVideoCropMeta);
|
|
|
|
|
|
|
|
unsafe impl Send for VideoCropMeta {}
|
|
|
|
unsafe impl Sync for VideoCropMeta {}
|
|
|
|
|
|
|
|
impl VideoCropMeta {
|
|
|
|
pub fn add(
|
|
|
|
buffer: &mut gst::BufferRef,
|
|
|
|
rect: (u32, u32, u32, u32),
|
|
|
|
) -> gst::MetaRefMut<Self, gst::meta::Standalone> {
|
|
|
|
skip_assert_initialized!();
|
|
|
|
unsafe {
|
|
|
|
let meta = gst_sys::gst_buffer_add_meta(
|
|
|
|
buffer.as_mut_ptr(),
|
|
|
|
gst_video_sys::gst_video_crop_meta_get_info(),
|
|
|
|
ptr::null_mut(),
|
|
|
|
) as *mut gst_video_sys::GstVideoCropMeta;
|
|
|
|
|
|
|
|
{
|
|
|
|
let meta = &mut *meta;
|
|
|
|
meta.x = rect.0;
|
|
|
|
meta.y = rect.1;
|
|
|
|
meta.width = rect.2;
|
|
|
|
meta.height = rect.3;
|
|
|
|
}
|
|
|
|
|
|
|
|
Self::from_mut_ptr(buffer, meta)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_rect(&self) -> (u32, u32, u32, u32) {
|
|
|
|
(self.0.x, self.0.y, self.0.width, self.0.height)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn set_rect(&mut self, rect: (u32, u32, u32, u32)) {
|
|
|
|
self.0.x = rect.0;
|
|
|
|
self.0.y = rect.1;
|
|
|
|
self.0.width = rect.2;
|
|
|
|
self.0.height = rect.3;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
unsafe impl MetaAPI for VideoCropMeta {
|
|
|
|
type GstType = gst_video_sys::GstVideoCropMeta;
|
|
|
|
|
|
|
|
fn get_meta_api() -> glib::Type {
|
|
|
|
unsafe { from_glib(gst_video_sys::gst_video_crop_meta_api_get_type()) }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Debug for VideoCropMeta {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
f.debug_struct("VideoCropMeta")
|
|
|
|
.field("rect", &self.get_rect())
|
|
|
|
.finish()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[repr(C)]
|
|
|
|
pub struct VideoRegionOfInterestMeta(gst_video_sys::GstVideoRegionOfInterestMeta);
|
|
|
|
|
|
|
|
unsafe impl Send for VideoRegionOfInterestMeta {}
|
|
|
|
unsafe impl Sync for VideoRegionOfInterestMeta {}
|
|
|
|
|
|
|
|
impl VideoRegionOfInterestMeta {
|
|
|
|
pub fn add<'a>(
|
|
|
|
buffer: &'a mut gst::BufferRef,
|
|
|
|
roi_type: &str,
|
|
|
|
rect: (u32, u32, u32, u32),
|
|
|
|
) -> gst::MetaRefMut<'a, Self, gst::meta::Standalone> {
|
|
|
|
skip_assert_initialized!();
|
|
|
|
unsafe {
|
|
|
|
let meta = gst_video_sys::gst_buffer_add_video_region_of_interest_meta(
|
|
|
|
buffer.as_mut_ptr(),
|
|
|
|
roi_type.to_glib_none().0,
|
|
|
|
rect.0,
|
|
|
|
rect.1,
|
|
|
|
rect.2,
|
|
|
|
rect.3,
|
|
|
|
);
|
|
|
|
|
|
|
|
Self::from_mut_ptr(buffer, meta)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_rect(&self) -> (u32, u32, u32, u32) {
|
|
|
|
(self.0.x, self.0.y, self.0.w, self.0.h)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_id(&self) -> i32 {
|
|
|
|
self.0.id
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_parent_id(&self) -> i32 {
|
|
|
|
self.0.parent_id
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_roi_type<'a>(&self) -> &'a str {
|
|
|
|
glib::Quark::from_glib(self.0.roi_type).to_string()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(feature = "v1_14")]
|
|
|
|
pub fn get_params(&self) -> ParamsIter {
|
|
|
|
ParamsIter {
|
|
|
|
_meta: self,
|
|
|
|
list: self.0.params,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(feature = "v1_14")]
|
|
|
|
pub fn get_param<'b>(&self, name: &'b str) -> Option<&gst::StructureRef> {
|
|
|
|
self.get_params().find(|s| s.get_name() == name)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn set_rect(&mut self, rect: (u32, u32, u32, u32)) {
|
|
|
|
self.0.x = rect.0;
|
|
|
|
self.0.y = rect.1;
|
|
|
|
self.0.w = rect.2;
|
|
|
|
self.0.h = rect.3;
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn set_id(&mut self, id: i32) {
|
|
|
|
self.0.id = id
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn set_parent_id(&mut self, id: i32) {
|
|
|
|
self.0.parent_id = id
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(feature = "v1_14")]
|
|
|
|
pub fn add_param(&mut self, s: gst::Structure) {
|
|
|
|
unsafe {
|
|
|
|
gst_video_sys::gst_video_region_of_interest_meta_add_param(&mut self.0, s.into_ptr());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(feature = "v1_14")]
|
|
|
|
pub struct ParamsIter<'a> {
|
|
|
|
_meta: &'a VideoRegionOfInterestMeta,
|
|
|
|
list: *const glib_sys::GList,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(feature = "v1_14")]
|
|
|
|
impl<'a> Iterator for ParamsIter<'a> {
|
|
|
|
type Item = &'a gst::StructureRef;
|
|
|
|
|
|
|
|
fn next(&mut self) -> Option<&'a gst::StructureRef> {
|
|
|
|
if self.list.is_null() {
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsafe {
|
|
|
|
let data = (*self.list).data;
|
|
|
|
assert!(!data.is_null());
|
|
|
|
self.list = (*self.list).next;
|
|
|
|
|
|
|
|
let s = gst::StructureRef::from_glib_borrow(data as *const gst_sys::GstStructure);
|
|
|
|
|
|
|
|
Some(s)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
unsafe impl MetaAPI for VideoRegionOfInterestMeta {
|
|
|
|
type GstType = gst_video_sys::GstVideoRegionOfInterestMeta;
|
|
|
|
|
|
|
|
fn get_meta_api() -> glib::Type {
|
|
|
|
unsafe { from_glib(gst_video_sys::gst_video_region_of_interest_meta_api_get_type()) }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Debug for VideoRegionOfInterestMeta {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
let mut f = f.debug_struct("VideoRegionOfInterestMeta");
|
|
|
|
|
|
|
|
f.field("roi_type", &self.get_roi_type())
|
|
|
|
.field("rect", &self.get_rect())
|
|
|
|
.field("id", &self.get_id())
|
|
|
|
.field("parent_id", &self.get_parent_id());
|
|
|
|
|
|
|
|
#[cfg(feature = "v1_14")]
|
|
|
|
{
|
|
|
|
f.field("params", &self.get_params().collect::<Vec<_>>());
|
|
|
|
}
|
|
|
|
|
|
|
|
f.finish()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[repr(C)]
|
|
|
|
pub struct VideoAffineTransformationMeta(gst_video_sys::GstVideoAffineTransformationMeta);
|
|
|
|
|
|
|
|
unsafe impl Send for VideoAffineTransformationMeta {}
|
|
|
|
unsafe impl Sync for VideoAffineTransformationMeta {}
|
|
|
|
|
|
|
|
impl VideoAffineTransformationMeta {
|
|
|
|
pub fn add<'a>(
|
|
|
|
buffer: &'a mut gst::BufferRef,
|
|
|
|
matrix: Option<&[f32; 16]>,
|
|
|
|
) -> gst::MetaRefMut<'a, Self, gst::meta::Standalone> {
|
|
|
|
skip_assert_initialized!();
|
|
|
|
unsafe {
|
|
|
|
let meta = gst_sys::gst_buffer_add_meta(
|
|
|
|
buffer.as_mut_ptr(),
|
|
|
|
gst_video_sys::gst_video_affine_transformation_meta_get_info(),
|
|
|
|
ptr::null_mut(),
|
|
|
|
) as *mut gst_video_sys::GstVideoAffineTransformationMeta;
|
|
|
|
|
|
|
|
if let Some(matrix) = matrix {
|
|
|
|
let meta = &mut *meta;
|
|
|
|
meta.matrix.copy_from_slice(matrix);
|
|
|
|
}
|
|
|
|
|
|
|
|
Self::from_mut_ptr(buffer, meta)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_matrix(&self) -> &[f32; 16] {
|
|
|
|
&self.0.matrix
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn set_matrix(&mut self, matrix: &[f32; 16]) {
|
|
|
|
self.0.matrix.copy_from_slice(matrix);
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn apply_matrix(&mut self, matrix: &[f32; 16]) {
|
|
|
|
unsafe {
|
|
|
|
gst_video_sys::gst_video_affine_transformation_meta_apply_matrix(&mut self.0, matrix);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
unsafe impl MetaAPI for VideoAffineTransformationMeta {
|
|
|
|
type GstType = gst_video_sys::GstVideoAffineTransformationMeta;
|
|
|
|
|
|
|
|
fn get_meta_api() -> glib::Type {
|
|
|
|
unsafe { from_glib(gst_video_sys::gst_video_affine_transformation_meta_api_get_type()) }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl fmt::Debug for VideoAffineTransformationMeta {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
f.debug_struct("VideoAffineTransformationMeta")
|
|
|
|
.field("matrix", &self.get_matrix())
|
|
|
|
.finish()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-29 09:01:26 +00:00
|
|
|
#[repr(C)]
|
2019-03-19 07:58:20 +00:00
|
|
|
pub struct VideoOverlayCompositionMeta(gst_video_sys::GstVideoOverlayCompositionMeta);
|
2018-09-29 09:01:26 +00:00
|
|
|
|
2019-12-18 15:04:42 +00:00
|
|
|
unsafe impl Send for VideoOverlayCompositionMeta {}
|
|
|
|
unsafe impl Sync for VideoOverlayCompositionMeta {}
|
|
|
|
|
2018-09-29 22:17:12 +00:00
|
|
|
impl VideoOverlayCompositionMeta {
|
|
|
|
pub fn add<'a>(
|
2018-09-29 09:01:26 +00:00
|
|
|
buffer: &'a mut gst::BufferRef,
|
2018-10-11 08:40:00 +00:00
|
|
|
overlay: &::VideoOverlayComposition,
|
2018-09-29 09:01:26 +00:00
|
|
|
) -> gst::MetaRefMut<'a, Self, gst::meta::Standalone> {
|
2020-03-22 14:18:47 +00:00
|
|
|
skip_assert_initialized!();
|
2018-09-29 09:01:26 +00:00
|
|
|
unsafe {
|
2019-03-19 07:58:20 +00:00
|
|
|
let meta = gst_video_sys::gst_buffer_add_video_overlay_composition_meta(
|
2018-09-29 09:01:26 +00:00
|
|
|
buffer.as_mut_ptr(),
|
|
|
|
overlay.as_mut_ptr(),
|
|
|
|
);
|
|
|
|
|
2018-09-29 22:17:12 +00:00
|
|
|
Self::from_mut_ptr(buffer, meta)
|
2018-09-29 09:01:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_overlay(&self) -> &::VideoOverlayCompositionRef {
|
|
|
|
unsafe { ::VideoOverlayCompositionRef::from_ptr(self.0.overlay) }
|
|
|
|
}
|
|
|
|
|
2019-05-23 11:28:09 +00:00
|
|
|
pub fn get_overlay_owned(&self) -> ::VideoOverlayComposition {
|
|
|
|
unsafe { from_glib_none(self.get_overlay().as_ptr()) }
|
|
|
|
}
|
|
|
|
|
2018-10-11 08:40:00 +00:00
|
|
|
pub fn set_overlay(&mut self, overlay: &::VideoOverlayComposition) {
|
2019-02-28 08:32:13 +00:00
|
|
|
#![allow(clippy::cast_ptr_alignment)]
|
2018-09-29 09:01:26 +00:00
|
|
|
unsafe {
|
2019-03-19 07:58:20 +00:00
|
|
|
gst_sys::gst_mini_object_unref(self.0.overlay as *mut _);
|
|
|
|
self.0.overlay = gst_sys::gst_mini_object_ref(overlay.as_mut_ptr() as *mut _) as *mut _;
|
2018-09-29 09:01:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-29 22:17:12 +00:00
|
|
|
unsafe impl MetaAPI for VideoOverlayCompositionMeta {
|
2019-03-19 07:58:20 +00:00
|
|
|
type GstType = gst_video_sys::GstVideoOverlayCompositionMeta;
|
2018-09-29 09:01:26 +00:00
|
|
|
|
|
|
|
fn get_meta_api() -> glib::Type {
|
2019-03-19 07:58:20 +00:00
|
|
|
unsafe { from_glib(gst_video_sys::gst_video_overlay_composition_meta_api_get_type()) }
|
2018-09-29 09:01:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-29 22:17:12 +00:00
|
|
|
impl fmt::Debug for VideoOverlayCompositionMeta {
|
2018-09-29 09:01:26 +00:00
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
f.debug_struct("VideoOverlayCompositionMeta")
|
|
|
|
.field("overlay", &self.get_overlay())
|
|
|
|
.finish()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-15 21:35:19 +00:00
|
|
|
#[cfg(any(feature = "v1_16", feature = "dox"))]
|
|
|
|
#[repr(C)]
|
|
|
|
pub struct VideoCaptionMeta(gst_video_sys::GstVideoCaptionMeta);
|
|
|
|
|
2019-12-18 15:04:42 +00:00
|
|
|
#[cfg(any(feature = "v1_16", feature = "dox"))]
|
|
|
|
unsafe impl Send for VideoCaptionMeta {}
|
|
|
|
#[cfg(any(feature = "v1_16", feature = "dox"))]
|
|
|
|
unsafe impl Sync for VideoCaptionMeta {}
|
|
|
|
|
2019-05-15 21:35:19 +00:00
|
|
|
#[cfg(any(feature = "v1_16", feature = "dox"))]
|
|
|
|
impl VideoCaptionMeta {
|
|
|
|
pub fn add<'a>(
|
|
|
|
buffer: &'a mut gst::BufferRef,
|
|
|
|
caption_type: ::VideoCaptionType,
|
|
|
|
data: &[u8],
|
|
|
|
) -> gst::MetaRefMut<'a, Self, gst::meta::Standalone> {
|
2020-03-22 14:18:47 +00:00
|
|
|
skip_assert_initialized!();
|
2020-04-22 18:42:39 +00:00
|
|
|
assert!(!data.is_empty());
|
2019-05-15 21:35:19 +00:00
|
|
|
unsafe {
|
|
|
|
let meta = gst_video_sys::gst_buffer_add_video_caption_meta(
|
|
|
|
buffer.as_mut_ptr(),
|
|
|
|
caption_type.to_glib(),
|
|
|
|
data.as_ptr(),
|
|
|
|
data.len(),
|
|
|
|
);
|
|
|
|
|
|
|
|
Self::from_mut_ptr(buffer, meta)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_caption_type(&self) -> ::VideoCaptionType {
|
|
|
|
from_glib(self.0.caption_type)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_data(&self) -> &[u8] {
|
|
|
|
unsafe {
|
|
|
|
use std::slice;
|
|
|
|
|
|
|
|
slice::from_raw_parts(self.0.data, self.0.size)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(any(feature = "v1_16", feature = "dox"))]
|
|
|
|
unsafe impl MetaAPI for VideoCaptionMeta {
|
|
|
|
type GstType = gst_video_sys::GstVideoCaptionMeta;
|
|
|
|
|
|
|
|
fn get_meta_api() -> glib::Type {
|
|
|
|
unsafe { from_glib(gst_video_sys::gst_video_caption_meta_api_get_type()) }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(any(feature = "v1_16", feature = "dox"))]
|
|
|
|
impl fmt::Debug for VideoCaptionMeta {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
f.debug_struct("VideoCaptionMeta")
|
|
|
|
.field("caption_type", &self.get_caption_type())
|
|
|
|
.field("data", &self.get_data())
|
|
|
|
.finish()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-15 23:18:26 +00:00
|
|
|
#[cfg(any(feature = "v1_18", feature = "dox"))]
|
|
|
|
#[repr(C)]
|
|
|
|
pub struct VideoAFDMeta(gst_video_sys::GstVideoAFDMeta);
|
|
|
|
|
|
|
|
#[cfg(any(feature = "v1_18", feature = "dox"))]
|
|
|
|
unsafe impl Send for VideoAFDMeta {}
|
|
|
|
#[cfg(any(feature = "v1_18", feature = "dox"))]
|
|
|
|
unsafe impl Sync for VideoAFDMeta {}
|
|
|
|
|
|
|
|
#[cfg(any(feature = "v1_18", feature = "dox"))]
|
|
|
|
impl VideoAFDMeta {
|
|
|
|
pub fn add(
|
|
|
|
buffer: &mut gst::BufferRef,
|
|
|
|
field: u8,
|
|
|
|
spec: ::VideoAFDSpec,
|
|
|
|
afd: ::VideoAFDValue,
|
|
|
|
) -> gst::MetaRefMut<Self, gst::meta::Standalone> {
|
|
|
|
skip_assert_initialized!();
|
|
|
|
|
|
|
|
unsafe {
|
|
|
|
let meta = gst_video_sys::gst_buffer_add_video_afd_meta(
|
|
|
|
buffer.as_mut_ptr(),
|
|
|
|
field,
|
|
|
|
spec.to_glib(),
|
|
|
|
afd.to_glib(),
|
|
|
|
);
|
|
|
|
|
|
|
|
Self::from_mut_ptr(buffer, meta)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_field(&self) -> u8 {
|
|
|
|
self.0.field
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_spec(&self) -> ::VideoAFDSpec {
|
|
|
|
from_glib(self.0.spec)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_afd(&self) -> ::VideoAFDValue {
|
|
|
|
from_glib(self.0.afd)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(any(feature = "v1_18", feature = "dox"))]
|
|
|
|
unsafe impl MetaAPI for VideoAFDMeta {
|
|
|
|
type GstType = gst_video_sys::GstVideoAFDMeta;
|
|
|
|
|
|
|
|
fn get_meta_api() -> glib::Type {
|
|
|
|
unsafe { from_glib(gst_video_sys::gst_video_afd_meta_api_get_type()) }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(any(feature = "v1_18", feature = "dox"))]
|
|
|
|
impl fmt::Debug for VideoAFDMeta {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
f.debug_struct("VideoAFDMeta")
|
|
|
|
.field("field", &self.get_field())
|
|
|
|
.field("spec", &self.get_spec())
|
|
|
|
.field("afd", &self.get_afd())
|
|
|
|
.finish()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(any(feature = "v1_18", feature = "dox"))]
|
|
|
|
#[repr(C)]
|
|
|
|
pub struct VideoBarMeta(gst_video_sys::GstVideoBarMeta);
|
|
|
|
|
|
|
|
#[cfg(any(feature = "v1_18", feature = "dox"))]
|
|
|
|
unsafe impl Send for VideoBarMeta {}
|
|
|
|
#[cfg(any(feature = "v1_18", feature = "dox"))]
|
|
|
|
unsafe impl Sync for VideoBarMeta {}
|
|
|
|
|
|
|
|
#[cfg(any(feature = "v1_18", feature = "dox"))]
|
|
|
|
impl VideoBarMeta {
|
|
|
|
pub fn add(
|
|
|
|
buffer: &mut gst::BufferRef,
|
|
|
|
field: u8,
|
|
|
|
is_letterbox: bool,
|
|
|
|
bar_data1: u32,
|
|
|
|
bar_data2: u32,
|
|
|
|
) -> gst::MetaRefMut<Self, gst::meta::Standalone> {
|
|
|
|
skip_assert_initialized!();
|
|
|
|
|
|
|
|
unsafe {
|
|
|
|
let meta = gst_video_sys::gst_buffer_add_video_bar_meta(
|
|
|
|
buffer.as_mut_ptr(),
|
|
|
|
field,
|
|
|
|
is_letterbox.to_glib(),
|
|
|
|
bar_data1,
|
|
|
|
bar_data2,
|
|
|
|
);
|
|
|
|
|
|
|
|
Self::from_mut_ptr(buffer, meta)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_field(&self) -> u8 {
|
|
|
|
self.0.field
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn is_letterbox(&self) -> bool {
|
|
|
|
from_glib(self.0.is_letterbox)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_bar_data1(&self) -> u32 {
|
|
|
|
self.0.bar_data1
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_bar_data2(&self) -> u32 {
|
|
|
|
self.0.bar_data2
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(any(feature = "v1_18", feature = "dox"))]
|
|
|
|
unsafe impl MetaAPI for VideoBarMeta {
|
|
|
|
type GstType = gst_video_sys::GstVideoBarMeta;
|
|
|
|
|
|
|
|
fn get_meta_api() -> glib::Type {
|
|
|
|
unsafe { from_glib(gst_video_sys::gst_video_bar_meta_api_get_type()) }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(any(feature = "v1_18", feature = "dox"))]
|
|
|
|
impl fmt::Debug for VideoBarMeta {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
f.debug_struct("VideoBarMeta")
|
|
|
|
.field("field", &self.get_field())
|
|
|
|
.field("is_letterbox", &self.is_letterbox())
|
|
|
|
.field("bar_data1", &self.get_bar_data1())
|
|
|
|
.field("bar_data2", &self.get_bar_data2())
|
|
|
|
.finish()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-29 09:01:26 +00:00
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_add_get_meta() {
|
|
|
|
gst::init().unwrap();
|
|
|
|
|
|
|
|
let mut buffer = gst::Buffer::with_size(320 * 240 * 4).unwrap();
|
|
|
|
{
|
|
|
|
let meta = VideoMeta::add(
|
|
|
|
buffer.get_mut().unwrap(),
|
|
|
|
::VideoFrameFlags::NONE,
|
|
|
|
::VideoFormat::Argb,
|
|
|
|
320,
|
|
|
|
240,
|
|
|
|
);
|
|
|
|
assert_eq!(meta.get_id(), 0);
|
|
|
|
assert_eq!(meta.get_flags(), ::VideoFrameFlags::NONE);
|
|
|
|
assert_eq!(meta.get_format(), ::VideoFormat::Argb);
|
|
|
|
assert_eq!(meta.get_width(), 320);
|
|
|
|
assert_eq!(meta.get_height(), 240);
|
|
|
|
assert_eq!(meta.get_n_planes(), 1);
|
|
|
|
assert_eq!(meta.get_offset(), &[0]);
|
|
|
|
assert_eq!(meta.get_stride(), &[320 * 4]);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
let meta = buffer.get_meta::<VideoMeta>().unwrap();
|
|
|
|
assert_eq!(meta.get_id(), 0);
|
|
|
|
assert_eq!(meta.get_flags(), ::VideoFrameFlags::NONE);
|
|
|
|
assert_eq!(meta.get_format(), ::VideoFormat::Argb);
|
|
|
|
assert_eq!(meta.get_width(), 320);
|
|
|
|
assert_eq!(meta.get_height(), 240);
|
|
|
|
assert_eq!(meta.get_n_planes(), 1);
|
|
|
|
assert_eq!(meta.get_offset(), &[0]);
|
|
|
|
assert_eq!(meta.get_stride(), &[320 * 4]);
|
|
|
|
}
|
|
|
|
}
|
2019-11-17 12:55:04 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_add_full_get_meta() {
|
|
|
|
gst::init().unwrap();
|
|
|
|
|
|
|
|
let mut buffer = gst::Buffer::with_size(320 * 240 * 4).unwrap();
|
|
|
|
{
|
|
|
|
let meta = VideoMeta::add_full(
|
|
|
|
buffer.get_mut().unwrap(),
|
|
|
|
::VideoFrameFlags::NONE,
|
|
|
|
::VideoFormat::Argb,
|
|
|
|
320,
|
|
|
|
240,
|
|
|
|
&[0],
|
|
|
|
&[320 * 4],
|
|
|
|
);
|
|
|
|
assert_eq!(meta.get_id(), 0);
|
|
|
|
assert_eq!(meta.get_flags(), ::VideoFrameFlags::NONE);
|
|
|
|
assert_eq!(meta.get_format(), ::VideoFormat::Argb);
|
|
|
|
assert_eq!(meta.get_width(), 320);
|
|
|
|
assert_eq!(meta.get_height(), 240);
|
|
|
|
assert_eq!(meta.get_n_planes(), 1);
|
|
|
|
assert_eq!(meta.get_offset(), &[0]);
|
|
|
|
assert_eq!(meta.get_stride(), &[320 * 4]);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
let meta = buffer.get_meta::<VideoMeta>().unwrap();
|
|
|
|
assert_eq!(meta.get_id(), 0);
|
|
|
|
assert_eq!(meta.get_flags(), ::VideoFrameFlags::NONE);
|
|
|
|
assert_eq!(meta.get_format(), ::VideoFormat::Argb);
|
|
|
|
assert_eq!(meta.get_width(), 320);
|
|
|
|
assert_eq!(meta.get_height(), 240);
|
|
|
|
assert_eq!(meta.get_n_planes(), 1);
|
|
|
|
assert_eq!(meta.get_offset(), &[0]);
|
|
|
|
assert_eq!(meta.get_stride(), &[320 * 4]);
|
|
|
|
}
|
|
|
|
}
|
2018-09-29 09:01:26 +00:00
|
|
|
}
|