Reputation: 1380
I'm writing a rust
application with a simple gstreamer pipeline. I would like to print the stats property of the appsink
element in a human readable format.
With this code:
let stats = appsink.get_property("stats").unwrap();
println!("stats: {:?}", stats);
I get:
stats: Value(GString(Foreign(0x7f9c008f00, 101)))
Since that isn't human readable, I tried:
let stats = appsink.get_property("stats").unwrap().get::<GString>();
println!("stats: {:?}", stats);
but got:
stats: Err(GetError { actual: GstStructure, requested: gchararray })
I'm not sure how to interpret the output.
I've looked at this post: gstreamer rust get human readable output for bitrate set on x264enc but it doesn't show how to approach a GString
.
Upvotes: 0
Views: 798
Reputation: 2143
Close to what transistor wrote, the correct way of doing this would be
let stats = appsink.get_property("stats").unwrap();
println!("stats: {:?}", stats.get::<gst::Structure>().expect("not a structure").expect("structure was None"));
You don't have to transform the glib::Value
to a String
, but you can directly get a gst::Structure
from the glib::Value
and work on that. Among other things it provides a Debug
impl that allows direct printing of it, and various API for accessing the fields, etc. See https://gstreamer.pages.freedesktop.org/gstreamer-rs/gstreamer/structure/struct.StructureRef.htm
Upvotes: 1
Reputation: 1660
I was able to sort of reproduce this using the following example:
use gstreamer::prelude::*;
fn main() {
gstreamer::init().unwrap();
let source = gstreamer::ElementFactory::make("videotestsrc", Some("source")).expect("Could not create source element.");
let val = source.get_property("pattern").unwrap();
println!("{:?}", val);
}
This will attempt to get the pattern
property on a generic VideoTestSrc element, and it will print out the string address instead of the actual string. Adding .get::<GString>()
to the let val
statement will produce a runtime error:
Err(GetError { actual: GstVideoTestSrcPattern, requested: gchararray })
which is telling us that it tried to cast to gchararray but the actual data type of the property is a custom type, GstVideoTestSrcPattern, which is not a string. In your example, the property value has the type GstStructure
. It might be possible to use .get::<GstVideoTestSrcPattern>()
to get the value of the pattern
property and manipulate it as such, but since we want a string here, there's another way using the .transform() method defined on a glib::Value:
let val = source.get_property("pattern").unwrap().transform::<String>().unwrap().get::<String>().unwrap().unwrap();
This is rather unwieldy and it would be advised to do a lot more error checking on the values returned here (for example using the ?
operator instead of the .unwrap()
s).
The .transform::<String>()
call will try to give us a String representation of the property's value, but it gives us a Option<Value>
which we must unwrap and convert into an actual String using .get::<String>()
, which gives us a Result<Option<String>, GetError>
(the inner option is because the string could be NULL). Unwrapping those values gives us a printable string.
There might be a simpler way, but this at least gives you the result. There is more documentation on how to deal with glib Value types here: https://gstreamer.pages.freedesktop.org/gstreamer-rs/glib/value/struct.Value.html But unfortunately it's not very easy to read and doesn't have examples. It might be possible to glean more info from the rust port of the gstreamer tutorials: https://gitlab.freedesktop.org/gstreamer/gstreamer-rs/tree/master/tutorials
Upvotes: 1