134 lines
4.0 KiB
Rust
134 lines
4.0 KiB
Rust
use crate::priv_prelude::*;
|
|
use crate::wrap_gst;
|
|
|
|
wrap_gst!(Element, gstreamer::Element);
|
|
|
|
// pub trait IsElement {
|
|
// fn upcast_ref(&self) -> ∈
|
|
// fn into_element(self) -> Element;
|
|
// fn pad(&self, name: &str) -> Option<Pad> {
|
|
// use gstreamer::prelude::*;
|
|
// self.upcast_ref().inner.static_pad(name).map(Pad::from)
|
|
// }
|
|
// }
|
|
|
|
// impl IsElement for Element {
|
|
// fn upcast_ref(&self) -> &Element {
|
|
// self
|
|
// }
|
|
//
|
|
// fn into_element(self) -> Element {
|
|
// self
|
|
// }
|
|
// }
|
|
|
|
impl Element {
|
|
pub fn pad(&self, name: impl AsRef<str>) -> Option<Pad> {
|
|
use gstreamer::prelude::*;
|
|
self.inner.static_pad(name.as_ref()).map(Pad::from)
|
|
}
|
|
|
|
pub fn bus(&self) -> Result<Bus> {
|
|
use gstreamer::prelude::*;
|
|
self.inner
|
|
.bus()
|
|
.map(Bus::from)
|
|
.ok_or(Error)
|
|
.attach_with(|| format!("Failed to get bus from Element: {}", self.inner.name()))
|
|
}
|
|
}
|
|
|
|
pub trait Sink: ChildOf<Element> {
|
|
fn sink(&self, name: impl AsRef<str>) -> Pad {
|
|
self.upcast_ref()
|
|
.pad(name)
|
|
.expect("Sink element has no sink pad")
|
|
}
|
|
}
|
|
pub trait Source: ChildOf<Element> {
|
|
fn source(&self, name: impl AsRef<str>) -> Pad {
|
|
self.upcast_ref()
|
|
.pad(name)
|
|
.expect("Source element has no src pad")
|
|
}
|
|
|
|
fn link<S: Sink>(&self, sink: &S) -> Result<Bin>
|
|
where
|
|
Self: Sized,
|
|
{
|
|
use gstreamer::prelude::*;
|
|
if let Ok(bin) = self.upcast_ref().inner.clone().downcast::<gstreamer::Bin>() {
|
|
bin.add(&sink.upcast_ref().inner)
|
|
.change_context(Error)
|
|
.attach("Failed to add sink to bin")?;
|
|
self.upcast_ref()
|
|
.inner
|
|
.link(&sink.upcast_ref().inner)
|
|
.change_context(Error)
|
|
.attach("Failed to link elements")?;
|
|
Ok(Bin::from(bin))
|
|
} else {
|
|
let bin = gstreamer::Bin::builder()
|
|
.name(format!(
|
|
"{}-link-{}",
|
|
self.upcast_ref().inner.name(),
|
|
sink.upcast_ref().inner.name()
|
|
))
|
|
.build();
|
|
bin.add(&self.upcast_ref().inner)
|
|
.change_context(Error)
|
|
.attach("Failed to add source to bin")?;
|
|
bin.add(&sink.upcast_ref().inner)
|
|
.change_context(Error)
|
|
.attach("Failed to add sink to bin")?;
|
|
self.upcast_ref()
|
|
.inner
|
|
.link(&sink.upcast_ref().inner)
|
|
.change_context(Error)
|
|
.attach("Failed to link elements")?;
|
|
if let Some(sink_pad) = self.upcast_ref().pad("sink") {
|
|
let ghost_pad = Pad::ghost(&sink_pad)?;
|
|
bin.add_pad(&ghost_pad.inner)
|
|
.change_context(Error)
|
|
.attach("Failed to add src pad to bin")?;
|
|
ghost_pad.activate(true)?;
|
|
}
|
|
Ok(From::from(bin))
|
|
}
|
|
}
|
|
|
|
// fn link_pad<S: Sink>(&self, sink: &S, src_pad_name: &str, sink_pad_name: &str) -> Result<()> {
|
|
// use gstreamer::prelude::*;
|
|
// let src_pad = self
|
|
// .upcast_ref()
|
|
// .pad(src_pad_name)
|
|
// .ok_or(Error)
|
|
// .attach("Source pad not found")?;
|
|
// let sink_pad = sink
|
|
// .upcast_ref()
|
|
// .pad(sink_pad_name)
|
|
// .ok_or(Error)
|
|
// .attach("Sink pad not found")?;
|
|
// src_pad
|
|
// .inner
|
|
// .link(&sink_pad.inner)
|
|
// .change_context(Error)
|
|
// .attach("Failed to link source pad to sink pad")?;
|
|
// Ok(())
|
|
// }
|
|
}
|
|
|
|
pub trait ElementExt: ChildOf<Element> + Sync {
|
|
#[track_caller]
|
|
fn bus(&self) -> Result<Bus> {
|
|
self.upcast_ref().bus()
|
|
}
|
|
|
|
#[track_caller]
|
|
fn pad(&self, name: impl AsRef<str>) -> Option<Pad> {
|
|
self.upcast_ref().pad(name)
|
|
}
|
|
}
|
|
|
|
impl<T: ChildOf<Element> + Sync> ElementExt for T {}
|