| GStreamer Plugin Writer's Guide (0.8.7) | ||
|---|---|---|
| <<< Previous | Interfaces | Next >>> |
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.
| <<< Previous | Home | Next >>> |
| Color Balance Interface | Up | Profile Interface |