gst-plugins-rs/generic/inter/examples/basic.rs
Mathieu Duponchelle e905299eba generic: expose inter plugin
This new plugin exposes two elements, intersink and intersrc. These act
as wormholes for data in the same process and can be used to forward
data from one pipeline to another.

The implementation makes use of gstreamer-utils' StreamProducer, and
supports dynamically adding and removing consumers, before and after
producers, and changing producer names while PLAYING, both on the sink
and the src.

This initial implementation comes with a small demo, and a few tests.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1257>
2023-08-14 08:13:12 +00:00

75 lines
2.2 KiB
Rust

use anyhow::Error;
use futures::prelude::*;
use futures::stream::select_all;
use gst::prelude::*;
fn toplevel(obj: &gst::Object) -> gst::Object {
if let Some(parent) = obj.parent() {
toplevel(&parent)
} else {
obj.clone()
}
}
#[tokio::main]
async fn main() -> Result<(), Error> {
gst::init()?;
let src_pipeline = gst::parse_launch("videotestsrc is-live=true ! intersink")?;
let sink_pipeline = gst::parse_launch("intersrc ! videoconvert ! autovideosink")?;
let mut stream = select_all([
src_pipeline.bus().unwrap().stream(),
sink_pipeline.bus().unwrap().stream(),
]);
let base_time = gst::SystemClock::obtain().time().unwrap();
src_pipeline.set_clock(Some(&gst::SystemClock::obtain()))?;
src_pipeline.set_start_time(gst::ClockTime::NONE);
src_pipeline.set_base_time(base_time);
sink_pipeline.set_clock(Some(&gst::SystemClock::obtain()))?;
sink_pipeline.set_start_time(gst::ClockTime::NONE);
sink_pipeline.set_base_time(base_time);
src_pipeline.set_state(gst::State::Playing)?;
sink_pipeline.set_state(gst::State::Playing)?;
while let Some(msg) = stream.next().await {
use gst::MessageView;
match msg.view() {
MessageView::Latency(..) => {
if let Some(o) = msg.src() {
if let Ok(pipeline) = toplevel(o).downcast::<gst::Pipeline>() {
eprintln!("Recalculating latency {:?}", pipeline);
let _ = pipeline.recalculate_latency();
}
}
}
MessageView::Eos(..) => {
eprintln!("Unexpected EOS");
break;
}
MessageView::Error(err) => {
eprintln!(
"Got error from {}: {} ({})",
msg.src()
.map(|s| String::from(s.path_string()))
.unwrap_or_else(|| "None".into()),
err.error(),
err.debug().unwrap_or_else(|| "".into()),
);
break;
}
_ => (),
}
}
src_pipeline.set_state(gst::State::Null)?;
sink_pipeline.set_state(gst::State::Null)?;
Ok(())
}