mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer-rs.git
synced 2024-05-31 22:58:33 +00:00
wip: print properties
This commit is contained in:
parent
15d17ded1a
commit
62025d5e56
|
@ -20,6 +20,7 @@
|
|||
// DEALINGS IN THE SOFTWARE.
|
||||
use ansi_term::Color;
|
||||
use clap::{Arg, Command};
|
||||
use gst::glib;
|
||||
use gst::prelude::*;
|
||||
|
||||
const BRBLUE: Color = Color::RGB(97, 127, 166);
|
||||
|
@ -35,7 +36,9 @@ const STRUCT_NAME_COLOR: Color = Color::Yellow;
|
|||
const CAPS_FEATURE_COLOR: Color = Color::Green;
|
||||
const FIELD_VALUE_COLOR: Color = BRBLUE;
|
||||
const FIELD_NAME_COLOR: Color = Color::Cyan;
|
||||
const PROP_ATTR_NAME_COLOR: Color = Color::Yellow;
|
||||
const PROP_ATTR_VALUE_COLOR: Color = Color::Cyan;
|
||||
const DATATYPE_COLOR: Color = Color::Green;
|
||||
|
||||
fn print_element_list() {
|
||||
let registry = gst::Registry::get();
|
||||
|
@ -107,9 +110,9 @@ fn print_plugin_info(plugin: &gst::Plugin) {
|
|||
println!();
|
||||
}
|
||||
|
||||
fn hierarchy_foreach<F>(type_: gst::glib::Type, foreach_func: &mut F)
|
||||
fn hierarchy_foreach<F>(type_: glib::Type, foreach_func: &mut F)
|
||||
where
|
||||
F: FnMut(gst::glib::Type),
|
||||
F: FnMut(glib::Type),
|
||||
{
|
||||
if let Some(parent) = type_.parent() {
|
||||
hierarchy_foreach(parent, foreach_func);
|
||||
|
@ -118,9 +121,9 @@ where
|
|||
foreach_func(type_);
|
||||
}
|
||||
|
||||
fn print_hierarchy(type_: gst::glib::Type) {
|
||||
fn print_hierarchy(type_: glib::Type) {
|
||||
let mut level = 0;
|
||||
let mut func = |cur_type: gst::glib::Type| {
|
||||
let mut func = |cur_type: glib::Type| {
|
||||
if level > 0 {
|
||||
print!("{}", " ".repeat(level - 1));
|
||||
print!(" {}", CHILD_LINK_COLOR.paint("+----"));
|
||||
|
@ -133,7 +136,7 @@ fn print_hierarchy(type_: gst::glib::Type) {
|
|||
println!();
|
||||
}
|
||||
|
||||
fn print_interfaces(type_: gst::glib::Type) {
|
||||
fn print_interfaces(type_: glib::Type) {
|
||||
let interfaces = type_.interfaces();
|
||||
if interfaces.is_empty() {
|
||||
return;
|
||||
|
@ -316,6 +319,177 @@ fn print_pad_info(element: &gst::Element) {
|
|||
}
|
||||
}
|
||||
|
||||
fn print_pspec_flags(pspec: &glib::ParamSpec, indent: usize) {
|
||||
let flags_to_string = [
|
||||
(glib::ParamFlags::READABLE, "writable"),
|
||||
(glib::ParamFlags::WRITABLE, "readable"),
|
||||
(glib::ParamFlags::DEPRECATED, "deprecated"),
|
||||
(gst::PARAM_FLAG_CONTROLLABLE, "controllable"),
|
||||
(gst::PARAM_FLAG_CONDITIONALLY_AVAILABLE, "conditionally available"),
|
||||
(gst::PARAM_FLAG_MUTABLE_PLAYING, "changeable in NULL, READY, PAUSED or PLAYING state"),
|
||||
(gst::PARAM_FLAG_MUTABLE_PAUSED, "changeable only in NULL, READY or PAUSED state"),
|
||||
(gst::PARAM_FLAG_MUTABLE_READY, "changeable only in NULL or READY state"),
|
||||
// TODO: ~KNOWN_PARAM_FLAGS
|
||||
];
|
||||
let flags = pspec.flags();
|
||||
|
||||
print!("{:indent$}{}: ", "", PROP_ATTR_NAME_COLOR.paint("flags"), indent = indent);
|
||||
|
||||
let mut first_flag = true;
|
||||
for (flag, string) in flags_to_string.iter() {
|
||||
if !flags.contains(*flag) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if !first_flag {
|
||||
print!(", ")
|
||||
}
|
||||
print!("{}", PROP_ATTR_VALUE_COLOR.paint(*string));
|
||||
first_flag = false;
|
||||
}
|
||||
println!();
|
||||
}
|
||||
|
||||
fn print_default_prop(title: &str, range: Option<(String, String)>, default: &str, indent: usize) {
|
||||
print!("{:indent$}: ", "", indent = indent);
|
||||
print!("{}.", DATATYPE_COLOR.paint(title));
|
||||
|
||||
if let Some((min, max)) = range {
|
||||
print!("{}: {} - {}",
|
||||
PROP_ATTR_NAME_COLOR.paint("Range"),
|
||||
PROP_ATTR_VALUE_COLOR.paint(min.to_string()),
|
||||
PROP_ATTR_VALUE_COLOR.paint(max.to_string()),
|
||||
);
|
||||
}
|
||||
print!(" ");
|
||||
print!("{}: {}", PROP_ATTR_NAME_COLOR.paint("Default"),
|
||||
PROP_ATTR_VALUE_COLOR.paint(default.to_string()));
|
||||
}
|
||||
|
||||
fn print_default_property_value(element: &gst::Element, pspec: &glib::ParamSpec, readable: bool, indent: usize) {
|
||||
let value : glib::Value = if readable {
|
||||
element.property::<glib::Value>(&pspec.name())
|
||||
} else {
|
||||
pspec.default_value().clone()
|
||||
};
|
||||
|
||||
match value.type_() {
|
||||
glib::types::Type::STRING => {
|
||||
let default = match value.get::<Option<&str>>() {
|
||||
Ok(Some(val)) => format!("\"{}\"", val),
|
||||
_ => "null".to_string(),
|
||||
};
|
||||
print_default_prop("String", None, &default, indent);
|
||||
},
|
||||
glib::types::Type::BOOL => {
|
||||
let default = value.get::<bool>().unwrap().to_string();
|
||||
print_default_prop("Boolean", None, &default, indent);
|
||||
},
|
||||
glib::types::Type::I_LONG => {
|
||||
let default = value.get::<i64>().unwrap().to_string();
|
||||
let pspec = pspec.downcast_ref::<glib::ParamSpecLong>().unwrap();
|
||||
let range = Some((pspec.minimum().to_string(), pspec.maximum().to_string()));
|
||||
print_default_prop("Long", range, &default, indent);
|
||||
},
|
||||
glib::types::Type::U_LONG => {
|
||||
let default = value.get::<u64>().unwrap().to_string();
|
||||
let pspec = pspec.downcast_ref::<glib::ParamSpecULong>().unwrap();
|
||||
let range = Some((pspec.minimum().to_string(), pspec.maximum().to_string()));
|
||||
print_default_prop("Unsigned Long", range, &default, indent);
|
||||
},
|
||||
glib::types::Type::U32 => {
|
||||
let default = value.get::<u32>().unwrap().to_string();
|
||||
let pspec = pspec.downcast_ref::<glib::ParamSpecUInt>().unwrap();
|
||||
let range = Some((pspec.minimum().to_string(), pspec.maximum().to_string()));
|
||||
print_default_prop("Unsigned Integer", range, &default, indent);
|
||||
},
|
||||
glib::types::Type::I32 => {
|
||||
let default = value.get::<i32>().unwrap().to_string();
|
||||
let pspec = pspec.downcast_ref::<glib::ParamSpecInt>().unwrap();
|
||||
let range = Some((pspec.minimum().to_string(), pspec.maximum().to_string()));
|
||||
print_default_prop("Integer", range, &default, indent);
|
||||
},
|
||||
glib::types::Type::U64 => {
|
||||
let default = value.get::<u64>().unwrap().to_string();
|
||||
let pspec = pspec.downcast_ref::<glib::ParamSpecUInt64>().unwrap();
|
||||
let range = Some((pspec.minimum().to_string(), pspec.maximum().to_string()));
|
||||
print_default_prop("Unsigned Integer64", range, &default, indent);
|
||||
},
|
||||
glib::types::Type::I64 => {
|
||||
let default = value.get::<i64>().unwrap().to_string();
|
||||
let pspec = pspec.downcast_ref::<glib::ParamSpecInt64>().unwrap();
|
||||
let range = Some((pspec.minimum().to_string(), pspec.maximum().to_string()));
|
||||
print_default_prop("Integer64", range, &default, indent);
|
||||
},
|
||||
glib::types::Type::F32 => {
|
||||
let default = value.get::<f32>().unwrap().to_string();
|
||||
let pspec = pspec.downcast_ref::<glib::ParamSpecFloat>().unwrap();
|
||||
let range = Some((pspec.minimum().to_string(), pspec.maximum().to_string()));
|
||||
print_default_prop("Float", range, &default, indent);
|
||||
},
|
||||
glib::types::Type::F64 => {
|
||||
let default = value.get::<f64>().unwrap().to_string();
|
||||
let pspec = pspec.downcast_ref::<glib::ParamSpecDouble>().unwrap();
|
||||
let range = Some((pspec.minimum().to_string(), pspec.maximum().to_string()));
|
||||
print_default_prop("Double", range, &default, indent);
|
||||
},
|
||||
typ if typ.is_a(glib::types::Type::ENUM) => {
|
||||
let val = value.get::<&glib::EnumValue>().unwrap();
|
||||
let pspec = pspec.downcast_ref::<glib::ParamSpecEnum>().unwrap();
|
||||
let default = format!("{}, \"{}\"", val.value(), val.nick());
|
||||
let title = format!("Enum \"{}\"", value.type_().name());
|
||||
|
||||
print_default_prop(&title, None, &default, indent);
|
||||
for (i, enum_val) in pspec.enum_class().to_owned().values().iter().enumerate() {
|
||||
println!();
|
||||
print!("{}", " ".repeat(2 + 20 + 1 + 1));
|
||||
print!("{}: {} - {}",
|
||||
PROP_ATTR_NAME_COLOR.paint(&format!("({})", i)),
|
||||
PROP_ATTR_VALUE_COLOR.paint(&format!("{:<16}", enum_val.nick())),
|
||||
enum_val.name()
|
||||
);
|
||||
}
|
||||
},
|
||||
typ if typ.is_a(glib::types::Type::FLAGS) => {
|
||||
// TODO
|
||||
},
|
||||
typ if typ.is_a(gst::Caps::static_type()) => {
|
||||
match value.get::<Option<&gst::Caps>>() {
|
||||
Ok(Some(val)) => print_caps(val), // test with uridecodebin, "caps" property.
|
||||
_ => println!("Caps (NULL)"),
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
||||
println!()
|
||||
}
|
||||
|
||||
fn print_element_properties(element: &gst::Element) {
|
||||
let mut property_specs = element.list_properties();
|
||||
property_specs.sort_by_key(|pspec| pspec.name());
|
||||
|
||||
println!("{}:", HEADING_COLOR.paint("Element Properties"));
|
||||
println!();
|
||||
|
||||
for pspec in property_specs {
|
||||
let owner_type = pspec.owner_type();
|
||||
|
||||
if owner_type == glib::types::Type::OBJECT
|
||||
|| owner_type == gst::Object::static_type()
|
||||
|| owner_type == gst::Pad::static_type()
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
print_property(pspec.name(), &pspec.blurb().unwrap(), 20, 2, true);
|
||||
print_pspec_flags(&pspec, 2 + 20 + 1 + 1);
|
||||
|
||||
let readable = pspec.flags().contains(glib::ParamFlags::READABLE);
|
||||
print_default_property_value(element, &pspec, readable, 20 + 1 + 1);
|
||||
}
|
||||
}
|
||||
|
||||
fn print_element_info(feature: &gst::PluginFeature) -> Result<(), String> {
|
||||
let Ok(factory) = feature.load() else {
|
||||
return Err(format!("element factory '{}' couldn't be loaded", feature.name()));
|
||||
|
@ -341,6 +515,7 @@ fn print_element_info(feature: &gst::PluginFeature) -> Result<(), String> {
|
|||
print_clocking_info(&element);
|
||||
print_uri_handler_info(&element);
|
||||
print_pad_info(&element);
|
||||
print_element_properties(&element);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue