mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer-rs.git
synced 2024-12-23 08:36:31 +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