<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <HTML ><HEAD ><TITLE >Property Probe Interface</TITLE ><META NAME="GENERATOR" CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK REL="HOME" TITLE="GStreamer Plugin Writer's Guide" HREF="index.html"><LINK REL="UP" TITLE="Interfaces" HREF="chapter-advanced-interfaces.html"><LINK REL="PREVIOUS" TITLE="Color Balance Interface" HREF="section-iface-colorbalance.html"><LINK REL="NEXT" TITLE="Profile Interface" HREF="section-iface-profile.html"></HEAD ><BODY CLASS="sect1" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#840084" ALINK="#0000FF" ><DIV CLASS="NAVHEADER" ><TABLE SUMMARY="Header navigation table" WIDTH="100%" BORDER="0" CELLPADDING="0" CELLSPACING="0" ><TR ><TH COLSPAN="3" ALIGN="center" ><SPAN CLASS="application" >GStreamer</SPAN > Plugin Writer's Guide</TH ></TR ><TR ><TD WIDTH="10%" ALIGN="left" VALIGN="bottom" ><A HREF="section-iface-colorbalance.html" ACCESSKEY="P" >Prev</A ></TD ><TD WIDTH="80%" ALIGN="center" VALIGN="bottom" >Chapter 18. Interfaces</TD ><TD WIDTH="10%" ALIGN="right" VALIGN="bottom" ><A HREF="section-iface-profile.html" ACCESSKEY="N" >Next</A ></TD ></TR ></TABLE ><HR ALIGN="LEFT" WIDTH="100%"></DIV ><DIV CLASS="sect1" ><H1 CLASS="sect1" ><A NAME="section-iface-propprobe" >18.5. Property Probe Interface</A ></H1 ><P > Property probing is a generic solution to the problem that properties' value lists in an enumeration are static. We've shown enumerations in <A HREF="chapter-building-args.html" >Adding Arguments</A >. 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. </P ><P > Property probing stores the list of allowed (or recommended) values in a <CODE CLASS="classname" >GValueArray</CODE > and returns that to the user. <CODE CLASS="classname" >NULL</CODE > 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 <CODE CLASS="classname" >GValueArray</CODE >, and one to retrieve the current <CODE CLASS="classname" >GValueArray</CODE >. 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 <CODE CLASS="classname" >GstPropertyProbe</CODE > interface. </P ><P > Below is a example of property probing for the audio filter element; it will probe for allowed values for the <SPAN CLASS="QUOTE" >"silent"</SPAN > property. Indeed, this value is a <CODE CLASS="classname" >gboolean</CODE > so it doesn't make much sense. Then again, it's only an example. </P ><PRE CLASS="programlisting" > #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; } </PRE ><P > You don't need to support any functions for getting or setting values. All that is handled via the standard <CODE CLASS="classname" >GObject</CODE > <CODE CLASS="function" >_set_property ()</CODE > and <CODE CLASS="function" >_get_property ()</CODE > functions. </P ></DIV ><DIV CLASS="NAVFOOTER" ><HR ALIGN="LEFT" WIDTH="100%"><TABLE SUMMARY="Footer navigation table" WIDTH="100%" BORDER="0" CELLPADDING="0" CELLSPACING="0" ><TR ><TD WIDTH="33%" ALIGN="left" VALIGN="top" ><A HREF="section-iface-colorbalance.html" ACCESSKEY="P" >Prev</A ></TD ><TD WIDTH="34%" ALIGN="center" VALIGN="top" ><A HREF="index.html" ACCESSKEY="H" >Home</A ></TD ><TD WIDTH="33%" ALIGN="right" VALIGN="top" ><A HREF="section-iface-profile.html" ACCESSKEY="N" >Next</A ></TD ></TR ><TR ><TD WIDTH="33%" ALIGN="left" VALIGN="top" >Color Balance Interface</TD ><TD WIDTH="34%" ALIGN="center" VALIGN="top" ><A HREF="chapter-advanced-interfaces.html" ACCESSKEY="U" >Up</A ></TD ><TD WIDTH="33%" ALIGN="right" VALIGN="top" >Profile Interface</TD ></TR ></TABLE ></DIV ></BODY ></HTML >