2020-12-15 10:53:31 +00:00
|
|
|
// Take a look at the license at the top of the repository in the LICENSE file.
|
2018-09-28 14:36:50 +00:00
|
|
|
|
|
|
|
use std::fmt;
|
2019-07-11 12:34:28 +00:00
|
|
|
use std::mem;
|
2018-09-28 14:36:50 +00:00
|
|
|
|
2021-04-27 15:15:46 +00:00
|
|
|
use glib::translate::{from_glib, from_glib_full, from_glib_none, IntoGlib, ToGlibPtr};
|
2018-09-28 14:36:50 +00:00
|
|
|
|
2020-12-20 15:09:22 +00:00
|
|
|
gst::mini_object_wrapper!(
|
2018-09-28 14:36:50 +00:00
|
|
|
VideoOverlayRectangle,
|
|
|
|
VideoOverlayRectangleRef,
|
2020-11-22 09:53:17 +00:00
|
|
|
ffi::GstVideoOverlayRectangle,
|
|
|
|
|| ffi::gst_video_overlay_rectangle_get_type()
|
2018-09-28 14:36:50 +00:00
|
|
|
);
|
|
|
|
|
2020-06-29 21:12:46 +00:00
|
|
|
impl fmt::Debug for VideoOverlayRectangle {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
VideoOverlayRectangleRef::fmt(self, f)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-28 14:36:50 +00:00
|
|
|
impl fmt::Debug for VideoOverlayRectangleRef {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
f.debug_struct("VideoOverlayRectangle")
|
2021-04-11 19:39:50 +00:00
|
|
|
.field("flags", &self.flags())
|
|
|
|
.field("global_alpha", &self.global_alpha())
|
|
|
|
.field("render_rectangle", &self.render_rectangle())
|
2018-09-28 14:36:50 +00:00
|
|
|
.finish()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl VideoOverlayRectangle {
|
|
|
|
pub fn new_raw(
|
2019-05-23 11:28:09 +00:00
|
|
|
buffer: &gst::Buffer,
|
2018-09-28 14:36:50 +00:00
|
|
|
render_x: i32,
|
|
|
|
render_y: i32,
|
|
|
|
render_width: u32,
|
|
|
|
render_height: u32,
|
2020-11-22 09:53:17 +00:00
|
|
|
flags: crate::VideoOverlayFormatFlags,
|
2018-09-28 14:36:50 +00:00
|
|
|
) -> Self {
|
2020-03-22 14:18:47 +00:00
|
|
|
assert_initialized_main_thread!();
|
2021-04-20 10:24:17 +00:00
|
|
|
assert!(buffer.meta::<crate::VideoMeta>().is_some());
|
2018-09-28 14:36:50 +00:00
|
|
|
unsafe {
|
2020-11-22 09:53:17 +00:00
|
|
|
from_glib_full(ffi::gst_video_overlay_rectangle_new_raw(
|
2019-05-23 11:28:09 +00:00
|
|
|
buffer.to_glib_none().0,
|
2018-09-28 14:36:50 +00:00
|
|
|
render_x,
|
|
|
|
render_y,
|
|
|
|
render_width,
|
|
|
|
render_height,
|
2021-04-27 15:15:46 +00:00
|
|
|
flags.into_glib(),
|
2018-09-28 14:36:50 +00:00
|
|
|
))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl VideoOverlayRectangleRef {
|
2021-04-11 19:39:50 +00:00
|
|
|
pub fn flags(&self) -> crate::VideoOverlayFormatFlags {
|
2018-09-28 14:36:50 +00:00
|
|
|
unsafe {
|
2020-11-22 09:53:17 +00:00
|
|
|
from_glib(ffi::gst_video_overlay_rectangle_get_flags(
|
2018-09-28 14:36:50 +00:00
|
|
|
self.as_mut_ptr(),
|
|
|
|
))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-11 19:39:50 +00:00
|
|
|
pub fn global_alpha(&self) -> f32 {
|
2020-11-22 09:53:17 +00:00
|
|
|
unsafe { ffi::gst_video_overlay_rectangle_get_global_alpha(self.as_mut_ptr()) }
|
2018-09-28 14:36:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn set_global_alpha(&mut self, alpha: f32) {
|
2020-11-22 09:53:17 +00:00
|
|
|
unsafe { ffi::gst_video_overlay_rectangle_set_global_alpha(self.as_mut_ptr(), alpha) }
|
2018-09-28 14:36:50 +00:00
|
|
|
}
|
|
|
|
|
2021-04-11 19:39:50 +00:00
|
|
|
pub fn seqnum(&self) -> u32 {
|
2020-11-22 09:53:17 +00:00
|
|
|
unsafe { ffi::gst_video_overlay_rectangle_get_seqnum(self.as_mut_ptr()) }
|
2018-09-28 14:36:50 +00:00
|
|
|
}
|
|
|
|
|
2021-04-11 19:39:50 +00:00
|
|
|
pub fn render_rectangle(&self) -> (i32, i32, u32, u32) {
|
2018-09-28 14:36:50 +00:00
|
|
|
unsafe {
|
2019-07-11 12:34:28 +00:00
|
|
|
let mut render_x = mem::MaybeUninit::uninit();
|
|
|
|
let mut render_y = mem::MaybeUninit::uninit();
|
|
|
|
let mut render_width = mem::MaybeUninit::uninit();
|
|
|
|
let mut render_height = mem::MaybeUninit::uninit();
|
2018-09-28 14:36:50 +00:00
|
|
|
|
2020-11-22 09:53:17 +00:00
|
|
|
ffi::gst_video_overlay_rectangle_get_render_rectangle(
|
2018-09-28 14:36:50 +00:00
|
|
|
self.as_mut_ptr(),
|
2019-07-11 12:34:28 +00:00
|
|
|
render_x.as_mut_ptr(),
|
|
|
|
render_y.as_mut_ptr(),
|
|
|
|
render_width.as_mut_ptr(),
|
|
|
|
render_height.as_mut_ptr(),
|
2018-09-28 14:36:50 +00:00
|
|
|
);
|
|
|
|
|
2019-07-11 12:34:28 +00:00
|
|
|
(
|
|
|
|
render_x.assume_init(),
|
|
|
|
render_y.assume_init(),
|
|
|
|
render_width.assume_init(),
|
|
|
|
render_height.assume_init(),
|
|
|
|
)
|
2018-09-28 14:36:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn set_render_rectangle(
|
|
|
|
&mut self,
|
|
|
|
render_x: i32,
|
|
|
|
render_y: i32,
|
|
|
|
render_width: u32,
|
|
|
|
render_height: u32,
|
|
|
|
) {
|
|
|
|
unsafe {
|
2020-11-22 09:53:17 +00:00
|
|
|
ffi::gst_video_overlay_rectangle_set_render_rectangle(
|
2018-09-28 14:36:50 +00:00
|
|
|
self.as_mut_ptr(),
|
|
|
|
render_x,
|
|
|
|
render_y,
|
|
|
|
render_width,
|
|
|
|
render_height,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-20 10:23:24 +00:00
|
|
|
pub fn pixels_unscaled_raw(&self, flags: crate::VideoOverlayFormatFlags) -> gst::Buffer {
|
2018-09-28 14:36:50 +00:00
|
|
|
unsafe {
|
2020-11-22 09:53:17 +00:00
|
|
|
from_glib_none(ffi::gst_video_overlay_rectangle_get_pixels_unscaled_raw(
|
|
|
|
self.as_mut_ptr(),
|
2021-04-27 15:15:46 +00:00
|
|
|
flags.into_glib(),
|
2020-11-22 09:53:17 +00:00
|
|
|
))
|
2018-09-28 14:36:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-20 10:23:24 +00:00
|
|
|
pub fn pixels_unscaled_ayuv(&self, flags: crate::VideoOverlayFormatFlags) -> gst::Buffer {
|
2018-09-28 14:36:50 +00:00
|
|
|
unsafe {
|
2020-11-22 09:53:17 +00:00
|
|
|
from_glib_none(ffi::gst_video_overlay_rectangle_get_pixels_unscaled_ayuv(
|
|
|
|
self.as_mut_ptr(),
|
2021-04-27 15:15:46 +00:00
|
|
|
flags.into_glib(),
|
2020-11-22 09:53:17 +00:00
|
|
|
))
|
2018-09-28 14:36:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-20 10:23:24 +00:00
|
|
|
pub fn pixels_unscaled_argb(&self, flags: crate::VideoOverlayFormatFlags) -> gst::Buffer {
|
2018-09-28 14:36:50 +00:00
|
|
|
unsafe {
|
2020-11-22 09:53:17 +00:00
|
|
|
from_glib_none(ffi::gst_video_overlay_rectangle_get_pixels_unscaled_argb(
|
|
|
|
self.as_mut_ptr(),
|
2021-04-27 15:15:46 +00:00
|
|
|
flags.into_glib(),
|
2020-11-22 09:53:17 +00:00
|
|
|
))
|
2018-09-28 14:36:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-20 10:23:24 +00:00
|
|
|
pub fn pixels_raw(&self, flags: crate::VideoOverlayFormatFlags) -> gst::Buffer {
|
2018-09-28 14:36:50 +00:00
|
|
|
unsafe {
|
2020-11-22 09:53:17 +00:00
|
|
|
from_glib_none(ffi::gst_video_overlay_rectangle_get_pixels_raw(
|
2018-09-28 14:36:50 +00:00
|
|
|
self.as_mut_ptr(),
|
2021-04-27 15:15:46 +00:00
|
|
|
flags.into_glib(),
|
2018-09-28 14:36:50 +00:00
|
|
|
))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-20 10:23:24 +00:00
|
|
|
pub fn pixels_ayuv(&self, flags: crate::VideoOverlayFormatFlags) -> gst::Buffer {
|
2018-09-28 14:36:50 +00:00
|
|
|
unsafe {
|
2020-11-22 09:53:17 +00:00
|
|
|
from_glib_none(ffi::gst_video_overlay_rectangle_get_pixels_ayuv(
|
2018-09-28 14:36:50 +00:00
|
|
|
self.as_mut_ptr(),
|
2021-04-27 15:15:46 +00:00
|
|
|
flags.into_glib(),
|
2018-09-28 14:36:50 +00:00
|
|
|
))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-20 10:23:24 +00:00
|
|
|
pub fn pixels_argb(&self, flags: crate::VideoOverlayFormatFlags) -> gst::Buffer {
|
2018-09-28 14:36:50 +00:00
|
|
|
unsafe {
|
2020-11-22 09:53:17 +00:00
|
|
|
from_glib_none(ffi::gst_video_overlay_rectangle_get_pixels_argb(
|
2018-09-28 14:36:50 +00:00
|
|
|
self.as_mut_ptr(),
|
2021-04-27 15:15:46 +00:00
|
|
|
flags.into_glib(),
|
2018-09-28 14:36:50 +00:00
|
|
|
))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-20 15:09:22 +00:00
|
|
|
gst::mini_object_wrapper!(
|
2018-09-28 14:36:50 +00:00
|
|
|
VideoOverlayComposition,
|
|
|
|
VideoOverlayCompositionRef,
|
2020-11-22 09:53:17 +00:00
|
|
|
ffi::GstVideoOverlayComposition,
|
|
|
|
|| ffi::gst_video_overlay_composition_get_type()
|
2018-09-28 14:36:50 +00:00
|
|
|
);
|
|
|
|
|
2020-06-29 21:12:46 +00:00
|
|
|
impl fmt::Debug for VideoOverlayComposition {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
VideoOverlayCompositionRef::fmt(self, f)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-28 14:36:50 +00:00
|
|
|
impl fmt::Debug for VideoOverlayCompositionRef {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
f.debug_struct("VideoOverlayComposition").finish()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl VideoOverlayComposition {
|
2019-12-17 08:41:51 +00:00
|
|
|
pub fn new<'a, T: IntoIterator<Item = &'a VideoOverlayRectangle>>(
|
|
|
|
rects: T,
|
|
|
|
) -> Result<Self, glib::error::BoolError> {
|
2020-03-22 14:18:47 +00:00
|
|
|
assert_initialized_main_thread!();
|
2018-09-28 14:36:50 +00:00
|
|
|
unsafe {
|
2018-10-01 11:52:31 +00:00
|
|
|
let mut iter = rects.into_iter();
|
|
|
|
|
|
|
|
let first = match iter.next() {
|
2020-11-22 09:53:17 +00:00
|
|
|
None => {
|
2020-12-17 22:38:06 +00:00
|
|
|
return Err(glib::bool_error!(
|
2020-11-22 09:53:17 +00:00
|
|
|
"Failed to create VideoOverlayComposition"
|
|
|
|
))
|
|
|
|
}
|
2018-10-01 11:52:31 +00:00
|
|
|
Some(first) => first,
|
|
|
|
};
|
|
|
|
|
2020-11-22 09:53:17 +00:00
|
|
|
let composition =
|
|
|
|
Self::from_glib_full(ffi::gst_video_overlay_composition_new(first.as_mut_ptr()));
|
2018-10-01 11:52:31 +00:00
|
|
|
|
|
|
|
for rect in iter {
|
2020-11-22 09:53:17 +00:00
|
|
|
ffi::gst_video_overlay_composition_add_rectangle(
|
2018-10-01 11:52:31 +00:00
|
|
|
composition.as_mut_ptr(),
|
|
|
|
rect.as_mut_ptr(),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2019-12-17 08:41:51 +00:00
|
|
|
Ok(composition)
|
2018-09-28 14:36:50 +00:00
|
|
|
}
|
|
|
|
}
|
2018-10-01 11:52:31 +00:00
|
|
|
}
|
2018-09-28 14:36:50 +00:00
|
|
|
|
2018-10-01 11:52:31 +00:00
|
|
|
impl VideoOverlayCompositionRef {
|
2018-09-28 14:36:50 +00:00
|
|
|
pub fn n_rectangles(&self) -> u32 {
|
2020-11-22 09:53:17 +00:00
|
|
|
unsafe { ffi::gst_video_overlay_composition_n_rectangles(self.as_mut_ptr()) }
|
2018-09-28 14:36:50 +00:00
|
|
|
}
|
|
|
|
|
2021-04-20 10:23:24 +00:00
|
|
|
pub fn rectangle(&self, idx: u32) -> Result<VideoOverlayRectangle, glib::error::BoolError> {
|
2018-09-28 14:36:50 +00:00
|
|
|
if idx >= self.n_rectangles() {
|
2020-12-17 22:38:06 +00:00
|
|
|
return Err(glib::bool_error!("Invalid index"));
|
2018-09-28 14:36:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
unsafe {
|
2020-11-22 09:53:17 +00:00
|
|
|
match from_glib_none(ffi::gst_video_overlay_composition_get_rectangle(
|
2018-09-28 14:36:50 +00:00
|
|
|
self.as_mut_ptr(),
|
|
|
|
idx,
|
2019-12-17 08:41:51 +00:00
|
|
|
)) {
|
|
|
|
Some(r) => Ok(r),
|
2020-12-17 22:38:06 +00:00
|
|
|
None => Err(glib::bool_error!("Failed to get rectangle")),
|
2019-12-17 08:41:51 +00:00
|
|
|
}
|
2018-09-28 14:36:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-11 19:39:50 +00:00
|
|
|
pub fn seqnum(&self) -> u32 {
|
2020-11-22 09:53:17 +00:00
|
|
|
unsafe { ffi::gst_video_overlay_composition_get_seqnum(self.as_mut_ptr()) }
|
2018-09-28 14:36:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn blend(
|
|
|
|
&self,
|
2020-11-22 09:53:17 +00:00
|
|
|
frame: &mut crate::VideoFrameRef<&mut gst::BufferRef>,
|
2018-09-28 14:36:50 +00:00
|
|
|
) -> Result<(), glib::BoolError> {
|
|
|
|
unsafe {
|
2020-12-17 22:38:06 +00:00
|
|
|
glib::result_from_gboolean!(
|
2020-11-22 09:53:17 +00:00
|
|
|
ffi::gst_video_overlay_composition_blend(self.as_mut_ptr(), frame.as_mut_ptr()),
|
2018-09-28 14:36:50 +00:00
|
|
|
"Failed to blend overlay composition",
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|