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,19 +1,9 @@
use crate::{playback::Playbin3, priv_prelude::*};
use gstreamer::State;
#[repr(transparent)]
pub struct Pipeline {
inner: gstreamer::Pipeline,
}
impl core::fmt::Debug for Pipeline {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("Pipeline")
.field("pipeline", &self.inner)
// .field("state", &self.pipeline.state(gstreamer::ClockTime::NONE))
.finish()
}
}
wrap_gst!(Pipeline);
parent_child!(Element, Pipeline);
parent_child!(Bin, Pipeline);
impl Drop for Pipeline {
fn drop(&mut self) {
@@ -41,55 +31,56 @@ impl Pipeline {
Ok(current)
}
pub fn wait_non_null_sync(&self) -> Result<()> {
if 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(core::time::Duration::from_secs(1)) {
let view = message.view();
dbg!(&view);
if let gstreamer::MessageView::StateChanged(change) = view
&& change.current() != State::Null
{
break;
}
}
Ok(())
}
}
// 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(())
}
}
// 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
@@ -111,14 +102,11 @@ impl Pipeline {
self.inner
.set_state(gstreamer::State::Ready)
.change_context(Error)
.attach("Failed to set pipeline to Paused state")?;
.attach("Failed to set pipeline to Ready state")?;
Ok(())
}
pub unsafe fn set_state(
&self,
state: gstreamer::State,
) -> Result<gstreamer::StateChangeSuccess> {
pub fn set_state(&self, state: gstreamer::State) -> Result<gstreamer::StateChangeSuccess> {
let result = self
.inner
.set_state(state)
@@ -127,15 +115,3 @@ impl Pipeline {
Ok(result)
}
}
impl core::ops::Deref for Playbin3 {
type Target = Pipeline;
fn deref(&self) -> &Self::Target {
let gp = self
.inner
.downcast_ref::<gstreamer::Pipeline>()
.expect("BUG: Playbin3 must be a pipeline");
unsafe { &*(gp as *const _ as *const Pipeline) }
}
}