Property probing is a generic solution to the problem that properties' value lists in an enumeration are static. We've shown enumerations in Adding Arguments. Property probing tries to accomplish a goal similar to enumeration lists: to have a limited, explicit list of allowed values for a property. There are two differences between enumeration lists and probing. Firstly, enumerations only allow strings as values; property probing works for any value type. Secondly, the contents of a probed list of allowed values may change during the life of an element. The contents of a enumeraiton list are static. Crrently, property probing is being used for detection of devices (e.g. for OSS elements, Video4linux elements, etc.). It could - in theory - be used for any property, though.
Property probing stores the list of allowed (or recommended) values in a
GValueArray
and returns that to the user.
NULL
is a valid return value, too. The process of
property probing is separated over two virtual functions: one for probing
the property to create a GValueArray
, and one to
retrieve the current GValueArray
. Those two are
separated because probing might take a long time (several seconds). Also,
this simpliies interface implementation in elements. For the application,
there are functions that wrap those two. For more information on this,
have a look at the API reference for the
GstPropertyProbe
interface.
Below is a example of property probing for the audio filter element; it will probe for allowed values for the "silent" property. Indeed, this value is a gboolean so it doesn't make much sense. Then again, it's only an example.
#include <gst/propertyprobe/propertyprobe.h> static void gst_my_filter_probe_interface_init (GstPropertyProbeInterface *iface); GType gst_my_filter_get_type (void) { [..] static const GInterfaceInfo probe_interface_info = { (GInterfaceInitFunc) gst_my_filter_probe_interface_init, NULL, NULL }; [..] g_type_add_interface_static (my_filter_type, GST_TYPE_PROPERTY_PROBE, &probe_interface_info); [..] } static const GList * gst_my_filter_probe_get_properties (GstPropertyProbe *probe) { GObjectClass *klass = G_OBJECT_GET_CLASS (probe); static GList *props = NULL; if (!props) { GParamSpec *pspec; pspec = g_object_class_find_property (klass, "silent"); props = g_list_append (props, pspec); } return props; } static gboolean gst_my_filter_probe_needs_probe (GstPropertyProbe *probe, guint prop_id, const GParamSpec *pspec) { gboolean res = FALSE; switch (prop_id) { case ARG_SILENT: res = FALSE; break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec); break; } return res; } static void gst_my_filter_probe_probe_property (GstPropertyProbe *probe, guint prop_id, const GParamSpec *pspec) { switch (prop_id) { case ARG_SILENT: /* don't need to do much here... */ break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec); break; } } static GValueArray * gst_my_filter_get_silent_values (GstMyFilter *filter) { GValueArray *array = g_value_array_new (2); GValue value = { 0 }; g_value_init (&value, G_TYPE_BOOLEAN); /* add TRUE */ g_value_set_boolean (&value, TRUE); g_value_array_append (array, &value); /* add FALSE */ g_value_set_boolean (&value, FALSE); g_value_array_append (array, &value); g_value_unset (&value); return array; } static GValueArray * gst_my_filter_probe_get_values (GstPropertyProbe *probe, guint prop_id, const GParamSpec *pspec) { GstMyFilter *filter = GST_MY_FILTER (probe); GValueArray *array = NULL; switch (prop_id) { case ARG_SILENT: array = gst_my_filter_get_silent_values (filter); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (probe, prop_id, pspec); break; } return array; } static void gst_my_filter_probe_interface_init (GstPropertyProbeInterface *iface) { iface->get_properties = gst_my_filter_probe_get_properties; iface->needs_probe = gst_my_filter_probe_needs_probe; iface->probe_property = gst_my_filter_probe_probe_property; iface->get_values = gst_my_filter_probe_get_values; }
You don't need to support any functions for getting or setting values.
All that is handled via the standard GObject
_set_property ()
and _get_property ()
functions.