diff --git a/gst/src/bus.rs b/gst/src/bus.rs index bc4bb61..196b773 100644 --- a/gst/src/bus.rs +++ b/gst/src/bus.rs @@ -1,8 +1,6 @@ -#[derive(Debug, Clone)] -#[repr(transparent)] -pub struct Bus { - pub(crate) bus: gstreamer::Bus, -} +use crate::priv_prelude::*; + +wrap_gst!(Bus); impl Bus { pub fn iter_timed( @@ -13,14 +11,10 @@ impl Bus { Some(dur) => gstreamer::ClockTime::try_from(dur).ok(), None => gstreamer::ClockTime::NONE, }; - self.bus.iter_timed(clocktime) + self.inner.iter_timed(clocktime) } pub fn stream(&self) -> gstreamer::bus::BusStream { - self.bus.stream() - } - - pub fn into_inner(self) -> gstreamer::Bus { - self.bus + self.inner.stream() } } diff --git a/gst/src/pad.rs b/gst/src/pad.rs index 91d658a..316d172 100644 --- a/gst/src/pad.rs +++ b/gst/src/pad.rs @@ -1,37 +1,6 @@ use crate::priv_prelude::*; - -#[derive(Debug)] -#[repr(transparent)] -pub struct Pad { - pub(crate) inner: gstreamer::Pad, -} -impl From for Pad { - fn from(inner: gstreamer::Pad) -> Self { - Self { inner } - } -} -impl From for gstreamer::Pad { - fn from(wrapper: Pad) -> Self { - wrapper.inner - } -} -impl Pad { - pub fn into_inner(self) -> gstreamer::Pad { - self.inner - } -} -impl GstWrapper for Pad { - type GstType = gstreamer::Pad; - fn from_gst(gst: Self::GstType) -> Self { - Self { inner: gst } - } - fn into_gst(self) -> Self::GstType { - self.inner - } - fn as_gst_ref(&self) -> &Self::GstType { - &self.inner - } -} +/// Pads are link points between elements +wrap_gst!(Pad, gstreamer::Pad); impl Pad { pub fn ghost(target: &Pad) -> Result { diff --git a/gst/src/pipeline.rs b/gst/src/pipeline.rs index 43d9ee1..9eb299b 100644 --- a/gst/src/pipeline.rs +++ b/gst/src/pipeline.rs @@ -18,7 +18,7 @@ impl Pipeline { .bus() .ok_or(Error) .attach("Failed to get bus from pipeline")?; - Ok(Bus { bus }) + Ok(Bus::from_gst(bus)) } /// Get the state @@ -31,57 +31,6 @@ impl Pipeline { Ok(current) } - // pub fn wait_non_null_sync(&self) -> Result<()> { - // if dbg!( - // self.state(core::time::Duration::ZERO) - // .change_context(Error) - // .attach("Failed to get video context") - // )? != gstreamer::State::Null - // { - // Ok(()) - // } else { - // let bus = self.bus()?; - // for message in bus.iter_timed(None) { - // let view = message.view(); - // dbg!(&view); - // panic!(); - // if let gstreamer::MessageView::StateChanged(change) = view - // && change.current() != State::Null - // { - // break; - // } - // } - // Ok(()) - // } - // } - - // Waits for the pipeline to be ready - // pub async fn wait_non_null(&self) -> Result<()> { - // if self - // .state(None) - // .change_context(Error) - // .attach("Failed to get video context")? - // != gstreamer::State::Null - // { - // Ok(()) - // } else { - // use futures::StreamExt; - // self.bus()? - // .stream() - // .filter(|message: &gstreamer::Message| { - // let view = message.view(); - // if let gstreamer::MessageView::StateChanged(change) = view { - // core::future::ready(change.current() != gstreamer::State::Null) - // } else { - // core::future::ready(false) - // } - // }) - // .next() - // .await; - // Ok(()) - // } - // } - pub fn play(&self) -> Result<()> { self.inner .set_state(gstreamer::State::Playing) @@ -115,3 +64,36 @@ impl Pipeline { Ok(result) } } + +pub trait PipelineExt { + fn bus(&self) -> Result; + fn play(&self) -> Result<()>; + fn pause(&self) -> Result<()>; + fn ready(&self) -> Result<()>; + fn set_state(&self, state: gstreamer::State) -> Result; + fn state(&self, timeout: impl Into>) -> Result; +} + +impl PipelineExt for T +where + T: ChildOf, +{ + fn bus(&self) -> Result { + self.upcast_ref().bus() + } + fn play(&self) -> Result<()> { + self.upcast_ref().play() + } + fn pause(&self) -> Result<()> { + self.upcast_ref().pause() + } + fn ready(&self) -> Result<()> { + self.upcast_ref().ready() + } + fn set_state(&self, state: gstreamer::State) -> Result { + self.upcast_ref().set_state(state) + } + fn state(&self, timeout: impl Into>) -> Result { + self.upcast_ref().state(timeout) + } +} diff --git a/gst/src/plugins/app/appsink.rs b/gst/src/plugins/app/appsink.rs index 84c5a02..a534504 100644 --- a/gst/src/plugins/app/appsink.rs +++ b/gst/src/plugins/app/appsink.rs @@ -23,7 +23,6 @@ impl AppSink { } pub fn with_caps(mut self, caps: Caps) -> Self { - use gstreamer::prelude::*; self.inner.set_property("caps", caps.inner); self } @@ -34,7 +33,6 @@ impl AppSink { } pub fn pull_sample(&self) -> Result { - use gstreamer::prelude::*; self.appsink() .pull_sample() .change_context(Error) @@ -45,7 +43,6 @@ impl AppSink { &self, timeout: impl Into>, ) -> Result> { - use gstreamer::prelude::*; Ok(self .appsink() .try_pull_sample(duration_to_clocktime(timeout)?) @@ -53,7 +50,6 @@ impl AppSink { } pub fn pull_preroll(&self) -> Result { - use gstreamer::prelude::*; self.appsink() .pull_preroll() .change_context(Error) @@ -65,7 +61,6 @@ impl AppSink { &self, timeout: impl Into>, ) -> Result> { - use gstreamer::prelude::*; Ok(self .appsink() .try_pull_preroll(duration_to_clocktime(timeout)?) diff --git a/gst/src/plugins/playback/playbin3.rs b/gst/src/plugins/playback/playbin3.rs index 348f7ed..4da2f10 100644 --- a/gst/src/plugins/playback/playbin3.rs +++ b/gst/src/plugins/playback/playbin3.rs @@ -13,7 +13,6 @@ impl Drop for Playbin3 { impl Playbin3 { pub fn new(name: impl AsRef) -> Result { - use gstreamer::prelude::*; gstreamer::ElementFactory::make("playbin3") .name(name.as_ref()) .build() @@ -22,51 +21,33 @@ impl Playbin3 { } pub fn with_uri(self, uri: impl AsRef) -> Self { - use gstreamer::prelude::*; self.inner.set_property("uri", uri.as_ref()); self } pub fn with_video_sink(self, video_sink: &impl ChildOf) -> Self { - use gstreamer::prelude::*; self.inner .set_property("video-sink", &video_sink.upcast_ref().inner); self } pub fn with_text_sink(self, text_sink: &impl ChildOf) -> Self { - use gstreamer::prelude::*; self.inner .set_property("text-sink", &text_sink.upcast_ref().inner); self } pub fn with_audio_sink(self, audio_sink: &impl ChildOf) -> Self { - use gstreamer::prelude::*; self.inner .set_property("audio-sink", &audio_sink.upcast_ref().inner); self } pub fn set_volume(&self, volume: f64) { - use gstreamer::prelude::*; self.inner.set_property("volume", volume.clamp(1.0, 100.0)) } pub fn get_volume(&self) -> f64 { - use gstreamer::prelude::*; self.inner.property::("volume") } } - -impl core::ops::Deref for Playbin3 { - type Target = Pipeline; - - fn deref(&self) -> &Self::Target { - let gp = self - .inner - .downcast_ref::() - .expect("BUG: Playbin3 must be a pipeline"); - unsafe { &*(gp as *const _ as *const Pipeline) } - } -} diff --git a/gst/src/wrapper.rs b/gst/src/wrapper.rs index 6228767..aa6c988 100644 --- a/gst/src/wrapper.rs +++ b/gst/src/wrapper.rs @@ -1,32 +1,35 @@ pub trait GstWrapper { type GstType: glib::prelude::ObjectType; fn from_gst(gst: Self::GstType) -> Self; - fn into_gst(self) -> Self::GstType; + // fn into_gst(self) -> Self::GstType; fn as_gst_ref(&self) -> &Self::GstType; } #[macro_export] macro_rules! wrap_gst { ($name:ident) => { - wrap_gst!($name, gstreamer::$name); + $crate::wrap_gst!($name, gstreamer::$name); }; ($name:ident, $inner:ty) => { + $crate::wrap_gst!(core $name, $inner); + $crate::wrap_gst!($name, $inner, into_inner); + }; + ($name:ident, $inner:ty, skip_inner) => { + $crate::wrap_gst!(core $name, $inner); + }; + + (core $name:ident, $inner:ty) => { #[derive(Debug, Clone)] #[repr(transparent)] pub struct $name { pub(crate) inner: $inner, } - impl From<$inner> for $name { - fn from(inner: $inner) -> Self { - Self { inner } - } - } - impl From<$name> for $inner { - fn from(wrapper: $name) -> Self { - wrapper.into_inner() - } - } + // impl From<$name> for $inner { + // fn from(wrapper: $name) -> Self { + // wrapper.into_inner() + // } + // } impl $name { pub fn into_inner(self) -> $inner { @@ -41,9 +44,9 @@ macro_rules! wrap_gst { Self { inner: gst } } - fn into_gst(self) -> Self::GstType { - self.inner.clone() - } + // fn into_gst(self) -> Self::GstType { + // self.inner.clone() + // } fn as_gst_ref(&self) -> &Self::GstType { &self.inner @@ -56,6 +59,13 @@ macro_rules! wrap_gst { } } }; + ($name:ident, $inner:ty, into_inner) => { + impl From<$inner> for $name { + fn from(inner: $inner) -> Self { + Self { inner } + } + } + }; } /// A trait for types that can be upcasted to type T. @@ -93,5 +103,31 @@ macro_rules! parent_child { } } } - }; + }; // ($parent:ty, $child:ty, deref) => { + // $crate::parent_child!($parent, $child); + // $crate::parent_child!($parent, $child, __deref); + // }; + // + // ($parent:ty, $child:ty, downcast, deref) => { + // $crate::parent_child!($parent, $child, downcast); + // $crate::parent_child!($parent, $child, __deref); + // }; + // ($parent:ty, $child:ty, deref, downcast) => { + // $crate::parent_child!($parent, $child, downcast); + // $crate::parent_child!($parent, $child, __deref); + // }; + // + // ($parent:ty, $child:ty, __deref) => { + // impl core::ops::Deref for $child + // where + // $child: GstWrapper, + // $parent: GstWrapper, + // { + // type Target = $parent; + // + // fn deref(&self) -> &Self::Target { + // self.upcast_ref() + // } + // } + // }; }