feat: Restructure the gst parent<->child relations

This commit is contained in:
uttarayan21
2025-12-23 01:09:01 +05:30
parent 043d1e99f0
commit 8d46bd2b85
11 changed files with 274 additions and 343 deletions

View File

@@ -1,43 +1,45 @@
use crate::{Bin, Error, Pad, Result, ResultExt};
#[repr(transparent)]
pub struct Element {
pub(crate) inner: gstreamer::Element,
}
use crate::priv_prelude::*;
use crate::wrap_gst;
pub trait IsElement {
fn as_element(&self) -> &Element;
fn into_element(self) -> Element;
fn pad(&self, name: &str) -> Option<Pad> {
wrap_gst!(Element, gstreamer::Element);
// pub trait IsElement {
// fn upcast_ref(&self) -> &Element;
// 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.as_element().inner.static_pad(name).map(Pad::from)
self.inner.static_pad(name.as_ref()).map(Pad::from)
}
}
impl IsElement for Element {
fn as_element(&self) -> &Element {
self
}
fn into_element(self) -> Element {
self
}
}
pub trait Sink: IsElement {
pub trait Sink: ChildOf<Element> {
fn sink(&self, name: impl AsRef<str>) -> Pad {
use gstreamer::prelude::*;
self.as_element()
.pad(name.as_ref())
.map(From::from)
self.upcast_ref()
.pad(name)
.expect("Sink element has no sink pad")
}
}
pub trait Source: IsElement {
pub trait Source: ChildOf<Element> {
fn source(&self, name: impl AsRef<str>) -> Pad {
use gstreamer::prelude::*;
self.as_element()
.pad(name.as_ref())
.map(From::from)
self.upcast_ref()
.pad(name)
.expect("Source element has no src pad")
}
@@ -46,13 +48,13 @@ pub trait Source: IsElement {
Self: Sized,
{
use gstreamer::prelude::*;
if let Ok(bin) = self.as_element().inner.clone().downcast::<gstreamer::Bin>() {
bin.add(&sink.as_element().inner)
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.as_element()
self.upcast_ref()
.inner
.link(&sink.as_element().inner)
.link(&sink.upcast_ref().inner)
.change_context(Error)
.attach("Failed to link elements")?;
Ok(Bin::from(bin))
@@ -60,22 +62,22 @@ pub trait Source: IsElement {
let bin = gstreamer::Bin::builder()
.name(format!(
"{}-link-{}",
self.as_element().inner.name(),
sink.as_element().inner.name()
self.upcast_ref().inner.name(),
sink.upcast_ref().inner.name()
))
.build();
bin.add(&self.as_element().inner)
bin.add(&self.upcast_ref().inner)
.change_context(Error)
.attach("Failed to add source to bin")?;
bin.add(&sink.as_element().inner)
bin.add(&sink.upcast_ref().inner)
.change_context(Error)
.attach("Failed to add sink to bin")?;
self.as_element()
self.upcast_ref()
.inner
.link(&sink.as_element().inner)
.link(&sink.upcast_ref().inner)
.change_context(Error)
.attach("Failed to link elements")?;
if let Some(sink_pad) = self.as_element().pad("sink") {
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)
@@ -89,12 +91,12 @@ pub trait Source: IsElement {
// fn link_pad<S: Sink>(&self, sink: &S, src_pad_name: &str, sink_pad_name: &str) -> Result<()> {
// use gstreamer::prelude::*;
// let src_pad = self
// .as_element()
// .upcast_ref()
// .pad(src_pad_name)
// .ok_or(Error)
// .attach("Source pad not found")?;
// let sink_pad = sink
// .as_element()
// .upcast_ref()
// .pad(sink_pad_name)
// .ok_or(Error)
// .attach("Sink pad not found")?;