mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer-rs.git
synced 2024-12-01 14:01:32 +00:00
206 lines
6 KiB
Rust
206 lines
6 KiB
Rust
// Take a look at the license at the top of the repository in the LICENSE file.
|
|
|
|
use crate::NavigationMessageType;
|
|
use glib::translate::{from_glib, from_glib_full, IntoGlib, ToGlibPtr};
|
|
use glib::ToSendValue;
|
|
use gst::ffi as gst_ffi;
|
|
use gst::{prelude::*, Message, Object, Seqnum};
|
|
use std::ptr;
|
|
|
|
macro_rules! message_builder_generic_impl {
|
|
($new_fn:expr) => {
|
|
#[allow(clippy::needless_update)]
|
|
pub fn src<O: IsA<Object> + Cast + Clone>(self, src: &O) -> Self {
|
|
Self {
|
|
builder: self.builder.src(src),
|
|
..self
|
|
}
|
|
}
|
|
|
|
#[doc(alias = "gst_message_set_seqnum")]
|
|
#[allow(clippy::needless_update)]
|
|
pub fn seqnum(self, seqnum: Seqnum) -> Self {
|
|
Self {
|
|
builder: self.builder.seqnum(seqnum),
|
|
..self
|
|
}
|
|
}
|
|
|
|
#[allow(clippy::needless_update)]
|
|
pub fn other_fields(
|
|
self,
|
|
other_fields: &[(&'a str, &'a (dyn ToSendValue + Sync))],
|
|
) -> Self {
|
|
Self {
|
|
builder: self.builder.other_fields(other_fields),
|
|
..self
|
|
}
|
|
}
|
|
|
|
#[must_use = "Building the message without using it has no effect"]
|
|
pub fn build(mut self) -> Message {
|
|
assert_initialized_main_thread!();
|
|
unsafe {
|
|
let src = self.builder.src.to_glib_none().0;
|
|
let msg = $new_fn(&mut self, src);
|
|
if let Some(seqnum) = self.builder.seqnum {
|
|
gst_ffi::gst_message_set_seqnum(msg, seqnum.into_glib());
|
|
}
|
|
|
|
if !self.builder.other_fields.is_empty() {
|
|
let structure = gst_ffi::gst_message_writable_structure(msg);
|
|
|
|
if !structure.is_null() {
|
|
let structure =
|
|
gst::StructureRef::from_glib_borrow_mut(structure as *mut _);
|
|
|
|
for (k, v) in self.builder.other_fields {
|
|
structure.set_value(k, v.to_send_value());
|
|
}
|
|
}
|
|
}
|
|
|
|
from_glib_full(msg)
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
struct MessageBuilder<'a> {
|
|
pub src: Option<Object>,
|
|
pub seqnum: Option<Seqnum>,
|
|
#[allow(unused)]
|
|
pub other_fields: Vec<(&'a str, &'a (dyn ToSendValue + Sync))>,
|
|
}
|
|
|
|
impl<'a> MessageBuilder<'a> {
|
|
pub fn new() -> Self {
|
|
assert_initialized_main_thread!();
|
|
Self {
|
|
src: None,
|
|
seqnum: None,
|
|
other_fields: Vec::new(),
|
|
}
|
|
}
|
|
|
|
pub fn src<O: IsA<Object> + Cast + Clone>(self, src: &O) -> Self {
|
|
Self {
|
|
src: Some(src.clone().upcast::<Object>()),
|
|
..self
|
|
}
|
|
}
|
|
|
|
pub fn seqnum(self, seqnum: Seqnum) -> Self {
|
|
Self {
|
|
seqnum: Some(seqnum),
|
|
..self
|
|
}
|
|
}
|
|
|
|
pub fn other_fields(self, other_fields: &[(&'a str, &'a (dyn ToSendValue + Sync))]) -> Self {
|
|
Self {
|
|
other_fields: self
|
|
.other_fields
|
|
.iter()
|
|
.cloned()
|
|
.chain(other_fields.iter().cloned())
|
|
.collect(),
|
|
..self
|
|
}
|
|
}
|
|
}
|
|
|
|
#[must_use = "The builder must be built to be used"]
|
|
pub struct NavigationEventMessageBuilder<'a> {
|
|
builder: MessageBuilder<'a>,
|
|
event: gst::Event,
|
|
}
|
|
|
|
impl<'a> NavigationEventMessageBuilder<'a> {
|
|
fn new(event: gst::Event) -> Self {
|
|
skip_assert_initialized!();
|
|
Self {
|
|
builder: MessageBuilder::new(),
|
|
event,
|
|
}
|
|
}
|
|
|
|
message_builder_generic_impl!(|s: &Self, src| ffi::gst_navigation_message_new_event(
|
|
src,
|
|
s.event.to_glib_none().0
|
|
));
|
|
}
|
|
|
|
#[derive(Clone, Debug)]
|
|
pub struct NavigationEventMessage {
|
|
pub event: gst::Event,
|
|
}
|
|
|
|
impl PartialEq for NavigationEventMessage {
|
|
fn eq(&self, other: &Self) -> bool {
|
|
unsafe { self.event.as_ptr() == other.event.as_ptr() }
|
|
}
|
|
}
|
|
|
|
impl Eq for NavigationEventMessage {}
|
|
|
|
impl NavigationEventMessage {
|
|
#[doc(alias = "gst_navigation_message_new_event")]
|
|
#[allow(clippy::new_ret_no_self)]
|
|
pub fn new(event: gst::Event) -> gst::Message {
|
|
assert_initialized_main_thread!();
|
|
NavigationEventMessageBuilder::new(event).build()
|
|
}
|
|
|
|
pub fn builder<'a>(event: gst::Event) -> NavigationEventMessageBuilder<'a> {
|
|
assert_initialized_main_thread!();
|
|
NavigationEventMessageBuilder::new(event)
|
|
}
|
|
|
|
#[doc(alias = "gst_navigation_message_parse_event")]
|
|
pub fn parse(msg: &gst::MessageRef) -> Result<Self, glib::error::BoolError> {
|
|
assert_initialized_main_thread!();
|
|
unsafe {
|
|
let mut event = ptr::null_mut();
|
|
let ret = from_glib(ffi::gst_navigation_message_parse_event(
|
|
msg.as_mut_ptr(),
|
|
&mut event,
|
|
));
|
|
if ret {
|
|
Ok(Self {
|
|
event: from_glib_full(event),
|
|
})
|
|
} else {
|
|
Err(glib::bool_error!("Invalid navigation event msg"))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, PartialEq, Eq, Debug)]
|
|
pub enum NavigationMessage {
|
|
Event(NavigationEventMessage),
|
|
}
|
|
|
|
impl NavigationMessage {
|
|
#[doc(alias = "gst_navigation_message_get_type")]
|
|
pub fn type_(msg: &gst::MessageRef) -> NavigationMessageType {
|
|
assert_initialized_main_thread!();
|
|
unsafe { from_glib(ffi::gst_navigation_message_get_type(msg.as_mut_ptr())) }
|
|
}
|
|
|
|
#[doc(alias = "gst_navigation_message_parse_event")]
|
|
pub fn parse(msg: &gst::MessageRef) -> Result<Self, glib::error::BoolError> {
|
|
skip_assert_initialized!();
|
|
|
|
let event_type: NavigationMessageType = Self::type_(msg);
|
|
|
|
match event_type {
|
|
NavigationMessageType::Event => NavigationEventMessage::parse(msg).map(Self::Event),
|
|
_ => Err(glib::bool_error!(
|
|
"Unsupported navigation msg {:?}",
|
|
event_type
|
|
)),
|
|
}
|
|
}
|
|
}
|