mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer-rs.git
synced 2025-01-25 16:38:20 +00:00
Add basic-tutorial-6 from the GStreamer tutorials
https://cgit.freedesktop.org/gstreamer/gst-docs/tree/examples/tutorials/basic-tutorial-6.c Fixes https://github.com/sdroege/gstreamer-rs/pull/43
This commit is contained in:
parent
e1d134c4be
commit
b24f628772
1 changed files with 164 additions and 0 deletions
164
tutorials/src/bin/basic-tutorial-6.rs
Normal file
164
tutorials/src/bin/basic-tutorial-6.rs
Normal file
|
@ -0,0 +1,164 @@
|
||||||
|
extern crate gstreamer as gst;
|
||||||
|
use gst::prelude::*;
|
||||||
|
use gst::MessageView;
|
||||||
|
|
||||||
|
|
||||||
|
fn print_caps(caps: gst::Caps, prefix: &str) {
|
||||||
|
if caps.is_any() {
|
||||||
|
println!("{}ANY", prefix);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if caps.is_empty() {
|
||||||
|
println!("{}EMPTY", prefix);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for structure in caps.iter() {
|
||||||
|
println!("{}{}", prefix, structure.get_name());
|
||||||
|
for (field, value) in structure.iter() {
|
||||||
|
println!("{} {}:{:?}", prefix, field, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prints information about a Pad Template, including its Capabilitites
|
||||||
|
fn print_pad_template_information(factory: &gst::ElementFactory) {
|
||||||
|
let long_name = factory
|
||||||
|
.get_metadata("long-name")
|
||||||
|
.expect("Failed to get long-name of element factory.");
|
||||||
|
println!("Pad Template for {}:", long_name);
|
||||||
|
|
||||||
|
if factory.get_num_pad_templates() == 0u32 {
|
||||||
|
println!(" None");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for pad_template in factory.get_static_pad_templates() {
|
||||||
|
if pad_template.direction() == gst::PadDirection::Src {
|
||||||
|
println!(" SRC template: '{}'", pad_template.name_template());
|
||||||
|
} else if pad_template.direction() == gst::PadDirection::Sink {
|
||||||
|
println!(" SINK template: '{}'", pad_template.name_template());
|
||||||
|
} else {
|
||||||
|
println!(" UNKNOWN!!! template: '{}'", pad_template.name_template());
|
||||||
|
}
|
||||||
|
|
||||||
|
if pad_template.presence() == gst::PadPresence::Always {
|
||||||
|
println!(" Availability: Always");
|
||||||
|
} else if pad_template.presence() == gst::PadPresence::Sometimes {
|
||||||
|
println!(" Availability: Sometimes");
|
||||||
|
} else if pad_template.presence() == gst::PadPresence::Request {
|
||||||
|
println!(" Availability: On request");
|
||||||
|
} else {
|
||||||
|
println!(" Availability: UNKNOWN!!!");
|
||||||
|
}
|
||||||
|
|
||||||
|
let caps = pad_template.get_caps();
|
||||||
|
println!(" Capabilities:");
|
||||||
|
print_caps(caps, " ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_pad_capabilities(element: &gst::Element, pad_name: &str) {
|
||||||
|
let pad = element
|
||||||
|
.get_static_pad(pad_name)
|
||||||
|
.expect("Could not retrieve pad");
|
||||||
|
|
||||||
|
println!("Caps for the {} pad:", pad_name);
|
||||||
|
match pad.get_current_caps() {
|
||||||
|
Some(caps) => {
|
||||||
|
print_caps(caps, " ");
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
let caps = pad.query_caps(None).expect("Failed to query caps on pad");
|
||||||
|
print_caps(caps, " ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// Initialize GStreamer
|
||||||
|
gst::init().unwrap();
|
||||||
|
|
||||||
|
// Create the element factories
|
||||||
|
let source_factory =
|
||||||
|
gst::ElementFactory::find("audiotestsrc").expect("Failed to create audiotestsrc factory.");
|
||||||
|
let sink_factory = gst::ElementFactory::find("autoaudiosink")
|
||||||
|
.expect("Failed to create autoaudiosink factory.");
|
||||||
|
|
||||||
|
// Print information about the pad templates of these factories
|
||||||
|
print_pad_template_information(&source_factory);
|
||||||
|
print_pad_template_information(&sink_factory);
|
||||||
|
|
||||||
|
// Ask the factories to instantiate actual elements
|
||||||
|
let source = source_factory
|
||||||
|
.create("source")
|
||||||
|
.expect("Failed to create source element");
|
||||||
|
let sink = sink_factory
|
||||||
|
.create("sink")
|
||||||
|
.expect("Failed to create sink element");
|
||||||
|
|
||||||
|
// Create the empty pipeline
|
||||||
|
let pipeline = gst::Pipeline::new("test-pipeline");
|
||||||
|
|
||||||
|
pipeline.add_many(&[&source, &sink]).unwrap();
|
||||||
|
source.link(&sink).expect("Elements could not be linked.");
|
||||||
|
|
||||||
|
// Print initial negotiated caps (in NULL state)
|
||||||
|
println!("In NULL state:");
|
||||||
|
print_pad_capabilities(&sink, "sink");
|
||||||
|
|
||||||
|
// Start playing
|
||||||
|
let ret = pipeline.set_state(gst::State::Playing);
|
||||||
|
if ret == gst::StateChangeReturn::Failure {
|
||||||
|
eprintln!(
|
||||||
|
"Unable to set the pipeline to the playing state (check the bus for error messages)."
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait until error, EOS or State Change
|
||||||
|
let bus = pipeline.get_bus().unwrap();
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let msg = bus.timed_pop(gst::CLOCK_TIME_NONE);
|
||||||
|
|
||||||
|
match msg {
|
||||||
|
Some(msg) => {
|
||||||
|
match msg.view() {
|
||||||
|
MessageView::Error(err) => {
|
||||||
|
println!(
|
||||||
|
"Error received from element {}: {} ({:?})",
|
||||||
|
msg.get_src().get_path_string(),
|
||||||
|
err.get_error(),
|
||||||
|
err.get_debug()
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
MessageView::Eos(..) => {
|
||||||
|
println!("End-Of-Stream reached.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
MessageView::StateChanged(state) =>
|
||||||
|
// We are only interested in state-changed messages from the pipeline
|
||||||
|
if msg.get_src() == pipeline {
|
||||||
|
let new_state = state.get_current();
|
||||||
|
let old_state = state.get_old();
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"Pipeline state changed from {:?} to {:?}",
|
||||||
|
old_state,
|
||||||
|
new_state
|
||||||
|
);
|
||||||
|
print_pad_capabilities(&sink, "sink");
|
||||||
|
},
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shutdown pipeline
|
||||||
|
let ret = pipeline.set_state(gst::State::Null);
|
||||||
|
assert_ne!(ret, gst::StateChangeReturn::Failure);
|
||||||
|
}
|
Loading…
Reference in a new issue