feat: Modify gst crate to add lot of more granularity

This commit is contained in:
uttarayan21
2025-12-22 13:27:30 +05:30
parent d42ef3b550
commit 043d1e99f0
23 changed files with 947 additions and 392 deletions

View File

@@ -1,4 +1,4 @@
use crate::{Error, Pad, Result, ResultExt};
use crate::{Bin, Error, Pad, Result, ResultExt};
#[repr(transparent)]
pub struct Element {
pub(crate) inner: gstreamer::Element,
@@ -24,29 +24,85 @@ impl IsElement for Element {
}
pub trait Sink: IsElement {
fn sink_pad(&self) -> Pad {
fn sink(&self, name: impl AsRef<str>) -> Pad {
use gstreamer::prelude::*;
self.as_element()
.pad("sink")
.pad(name.as_ref())
.map(From::from)
.expect("Sink element has no sink pad")
}
}
pub trait Source: IsElement {
fn source_pad(&self) -> Pad {
fn source(&self, name: impl AsRef<str>) -> Pad {
use gstreamer::prelude::*;
self.as_element()
.pad("src")
.pad(name.as_ref())
.map(From::from)
.expect("Source element has no src pad")
}
fn link<S: Sink>(&self, sink: &S) -> Result<()> {
fn link<S: Sink>(&self, sink: &S) -> Result<Bin>
where
Self: Sized,
{
use gstreamer::prelude::*;
self.as_element()
.inner
.link(&sink.as_element().inner)
.change_context(Error)
.attach("Failed to link source to sink")
if let Ok(bin) = self.as_element().inner.clone().downcast::<gstreamer::Bin>() {
bin.add(&sink.as_element().inner)
.change_context(Error)
.attach("Failed to add sink to bin")?;
self.as_element()
.inner
.link(&sink.as_element().inner)
.change_context(Error)
.attach("Failed to link elements")?;
Ok(Bin::from(bin))
} else {
let bin = gstreamer::Bin::builder()
.name(format!(
"{}-link-{}",
self.as_element().inner.name(),
sink.as_element().inner.name()
))
.build();
bin.add(&self.as_element().inner)
.change_context(Error)
.attach("Failed to add source to bin")?;
bin.add(&sink.as_element().inner)
.change_context(Error)
.attach("Failed to add sink to bin")?;
self.as_element()
.inner
.link(&sink.as_element().inner)
.change_context(Error)
.attach("Failed to link elements")?;
if let Some(sink_pad) = self.as_element().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
// .as_element()
// .pad(src_pad_name)
// .ok_or(Error)
// .attach("Source pad not found")?;
// let sink_pad = sink
// .as_element()
// .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(())
// }
}