mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-07 06:52:41 +00:00
pwg: more updates for 1.0
This commit is contained in:
parent
b527b0b498
commit
bc76088811
3 changed files with 47 additions and 39 deletions
|
@ -1,7 +1,7 @@
|
||||||
<!-- ############ chapter ############# -->
|
<!-- ############ chapter ############# -->
|
||||||
|
|
||||||
<chapter id="chapter-building-args" xreflabel="Adding Arguments">
|
<chapter id="chapter-building-args" xreflabel="Adding Properties">
|
||||||
<title>Adding Arguments</title>
|
<title>Adding Properties</title>
|
||||||
<para>
|
<para>
|
||||||
The primary and most important way of controlling how an element behaves,
|
The primary and most important way of controlling how an element behaves,
|
||||||
is through GObject properties. GObject properties are defined in the
|
is through GObject properties. GObject properties are defined in the
|
||||||
|
@ -12,6 +12,14 @@
|
||||||
and can then fill in the value or take action required for that property
|
and can then fill in the value or take action required for that property
|
||||||
to change value internally.
|
to change value internally.
|
||||||
</para>
|
</para>
|
||||||
|
<para>
|
||||||
|
You probably also want to keep an instance variable around
|
||||||
|
with the currently configured value of the property that you use in the
|
||||||
|
get and set functions.
|
||||||
|
Note that <classname>GObject</classname> will not automatically set your
|
||||||
|
instance variable to the default value, you will have to do that in the
|
||||||
|
<function>_init ()</function> function of your element.
|
||||||
|
</para>
|
||||||
<programlisting><!-- example-begin properties.c a --><!--
|
<programlisting><!-- example-begin properties.c a --><!--
|
||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
GST_BOILERPLATE (GstMyFilter, gst_my_filter, GstElement, GST_TYPE_ELEMENT);
|
GST_BOILERPLATE (GstMyFilter, gst_my_filter, GstElement, GST_TYPE_ELEMENT);
|
||||||
|
@ -27,8 +35,8 @@ gst_my_filter_init (GstMyFilter * filter)
|
||||||
<!-- example-begin properties.c b -->
|
<!-- example-begin properties.c b -->
|
||||||
/* properties */
|
/* properties */
|
||||||
enum {
|
enum {
|
||||||
ARG_0,
|
PROP_0,
|
||||||
ARG_SILENT
|
PROP_SILENT
|
||||||
/* FILL ME */
|
/* FILL ME */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -46,15 +54,15 @@ gst_my_filter_class_init (GstMyFilterClass *klass)
|
||||||
{
|
{
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||||
|
|
||||||
/* define properties */
|
|
||||||
g_object_class_install_property (object_class, ARG_SILENT,
|
|
||||||
g_param_spec_boolean ("silent", "Silent",
|
|
||||||
"Whether to be very verbose or not",
|
|
||||||
FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
|
||||||
|
|
||||||
/* define virtual function pointers */
|
/* define virtual function pointers */
|
||||||
object_class->set_property = gst_my_filter_set_property;
|
object_class->set_property = gst_my_filter_set_property;
|
||||||
object_class->get_property = gst_my_filter_get_property;
|
object_class->get_property = gst_my_filter_get_property;
|
||||||
|
|
||||||
|
/* define properties */
|
||||||
|
g_object_class_install_property (object_class, PROP_SILENT,
|
||||||
|
g_param_spec_boolean ("silent", "Silent",
|
||||||
|
"Whether to be very verbose or not",
|
||||||
|
FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -66,7 +74,7 @@ gst_my_filter_set_property (GObject *object,
|
||||||
GstMyFilter *filter = GST_MY_FILTER (object);
|
GstMyFilter *filter = GST_MY_FILTER (object);
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case ARG_SILENT:
|
case PROP_SILENT:
|
||||||
filter->silent = g_value_get_boolean (value);
|
filter->silent = g_value_get_boolean (value);
|
||||||
g_print ("Silent argument was changed to %s\n",
|
g_print ("Silent argument was changed to %s\n",
|
||||||
filter->silent ? "true" : "false");
|
filter->silent ? "true" : "false");
|
||||||
|
@ -86,7 +94,7 @@ gst_my_filter_get_property (GObject *object,
|
||||||
GstMyFilter *filter = GST_MY_FILTER (object);
|
GstMyFilter *filter = GST_MY_FILTER (object);
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
case ARG_SILENT:
|
case PROP_SILENT:
|
||||||
g_value_set_boolean (value, filter->silent);
|
g_value_set_boolean (value, filter->silent);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -99,10 +107,10 @@ gst_my_filter_get_property (GObject *object,
|
||||||
#include "register.func"
|
#include "register.func"
|
||||||
--><!-- example-end properties.c c --></programlisting>
|
--><!-- example-end properties.c c --></programlisting>
|
||||||
<para>
|
<para>
|
||||||
The above is a very simple example of how arguments are used. Graphical
|
The above is a very simple example of how properties are used. Graphical
|
||||||
applications - for example GStreamer Editor - will use these properties
|
applications will use these properties and will display a
|
||||||
and will display a user-controllable widget with which these properties
|
user-controllable widget with which these properties can be changed.
|
||||||
can be changed. This means that - for the property to be as user-friendly
|
This means that - for the property to be as user-friendly
|
||||||
as possible - you should be as exact as possible in the definition of the
|
as possible - you should be as exact as possible in the definition of the
|
||||||
property. Not only in defining ranges in between which valid properties
|
property. Not only in defining ranges in between which valid properties
|
||||||
can be located (for integers, floats, etc.), but also in using very
|
can be located (for integers, floats, etc.), but also in using very
|
||||||
|
@ -150,11 +158,11 @@ static void
|
||||||
gst_videotestsrc_class_init (GstvideotestsrcClass *klass)
|
gst_videotestsrc_class_init (GstvideotestsrcClass *klass)
|
||||||
{
|
{
|
||||||
[..]
|
[..]
|
||||||
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_TYPE,
|
g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_PATTERN,
|
||||||
g_param_spec_enum ("pattern", "Pattern",
|
g_param_spec_enum ("pattern", "Pattern",
|
||||||
"Type of test pattern to generate",
|
"Type of test pattern to generate",
|
||||||
GST_TYPE_VIDEOTESTSRC_PATTERN, 1, G_PARAM_READWRITE |
|
GST_TYPE_VIDEOTESTSRC_PATTERN, GST_VIDEOTESTSRC_SMPTE,
|
||||||
G_PARAM_STATIC_STRINGS));
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
[..]
|
[..]
|
||||||
}
|
}
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
|
|
@ -86,8 +86,8 @@
|
||||||
GstElement or some other class not built on top of a base class, you
|
GstElement or some other class not built on top of a base class, you
|
||||||
will most likely have to implement your own state change function to
|
will most likely have to implement your own state change function to
|
||||||
be notified of state changes. This is definitively necessary if your
|
be notified of state changes. This is definitively necessary if your
|
||||||
plugin is a decoder or an encoder, as there are no base classes for
|
plugin is a demuxer or a muxer, as there are no base classes for
|
||||||
decoders or encoders yet.
|
muxers or demuxers yet.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
An element can be notified of state changes through a virtual function
|
An element can be notified of state changes through a virtual function
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<title>Building a Test Application</title>
|
<title>Building a Test Application</title>
|
||||||
<para>
|
<para>
|
||||||
Often, you will want to test your newly written plugin in an as small
|
Often, you will want to test your newly written plugin in an as small
|
||||||
setting as possible. Usually, <filename>gst-launch</filename> is a
|
setting as possible. Usually, <filename>gst-launch-1.0</filename> is a
|
||||||
good first step at testing a plugin. If you have not installed your
|
good first step at testing a plugin. If you have not installed your
|
||||||
plugin in a directory that GStreamer searches, then you will need to
|
plugin in a directory that GStreamer searches, then you will need to
|
||||||
set the plugin path. Either set GST_PLUGIN_PATH to the directory
|
set the plugin path. Either set GST_PLUGIN_PATH to the directory
|
||||||
|
@ -12,10 +12,10 @@
|
||||||
If you based your plugin off of the gst-plugin template, then this
|
If you based your plugin off of the gst-plugin template, then this
|
||||||
will look something like
|
will look something like
|
||||||
<command>
|
<command>
|
||||||
gst-launch --gst-plugin-path=$HOME/gst-template/gst-plugin/src/.libs TESTPIPELINE
|
gst-launch-1.0 --gst-plugin-path=$HOME/gst-template/gst-plugin/src/.libs TESTPIPELINE
|
||||||
</command>
|
</command>
|
||||||
However, you will often need more
|
However, you will often need more
|
||||||
testing features than gst-launch can provide, such as seeking, events,
|
testing features than gst-launch-1.0 can provide, such as seeking, events,
|
||||||
interactivity and more. Writing your own small testing program is the
|
interactivity and more. Writing your own small testing program is the
|
||||||
easiest way to accomplish this. This section explains - in a few words
|
easiest way to accomplish this. This section explains - in a few words
|
||||||
- how to do that. For a complete application development guide, see the
|
- how to do that. For a complete application development guide, see the
|
||||||
|
@ -26,9 +26,9 @@
|
||||||
<para>
|
<para>
|
||||||
At the start, you need to initialize the &GStreamer; core library by
|
At the start, you need to initialize the &GStreamer; core library by
|
||||||
calling <function>gst_init ()</function>. You can alternatively call
|
calling <function>gst_init ()</function>. You can alternatively call
|
||||||
<function>gst_init_with_popt_tables ()</function>, which will return
|
<function>gst_init_get_option_group ()</function>, which will return
|
||||||
a pointer to popt tables. You can then use libpopt to handle the
|
a pointer to GOptionGroup. You can then use GOption to handle the
|
||||||
given argument table, and this will finish the &GStreamer; initialization.
|
initialization, and this will finish the &GStreamer; initialization.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
|
@ -43,22 +43,19 @@
|
||||||
application. Also, you can use a <classname>fakesink</classname>
|
application. Also, you can use a <classname>fakesink</classname>
|
||||||
element at the end of the pipeline to dump your data to the stdout
|
element at the end of the pipeline to dump your data to the stdout
|
||||||
(in order to do this, set the <function>dump</function> property to
|
(in order to do this, set the <function>dump</function> property to
|
||||||
TRUE). Lastly, you can use the <classname>efence</classname> element
|
TRUE). Lastly, you can use valgrind to check for memory errors.
|
||||||
(indeed, an eletric fence memory debugger wrapper element) to check
|
|
||||||
for memory errors.
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
During linking, your test application can use fixation or filtered caps
|
During linking, your test application can use filtered caps
|
||||||
as a way to drive a specific type of data to or from your element. This
|
as a way to drive a specific type of data to or from your element. This
|
||||||
is a very simple and effective way of checking multiple types of input
|
is a very simple and effective way of checking multiple types of input
|
||||||
and output in your element.
|
and output in your element.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Running the pipeline happens through the <function>gst_bin_iterate ()</function>
|
Note that during running, you should listen for at least the
|
||||||
function. Note that during running, you should connect to at least the
|
<quote>error</quote> and <quote>eos</quote> messages on the bus
|
||||||
<quote>error</quote> and <quote>eos</quote> signals on the pipeline
|
|
||||||
and/or your plugin/element to check for correct handling of this. Also,
|
and/or your plugin/element to check for correct handling of this. Also,
|
||||||
you should add events into the pipeline and make sure your plugin handles
|
you should add events into the pipeline and make sure your plugin handles
|
||||||
these correctly (with respect to clocking, internal caching, etc.).
|
these correctly (with respect to clocking, internal caching, etc.).
|
||||||
|
@ -120,6 +117,7 @@ main (gint argc,
|
||||||
GstElement *convert1, *convert2, *resample;
|
GstElement *convert1, *convert2, *resample;
|
||||||
GMainLoop *loop;
|
GMainLoop *loop;
|
||||||
GstBus *bus;
|
GstBus *bus;
|
||||||
|
guint watch_id;
|
||||||
|
|
||||||
/* initialization */
|
/* initialization */
|
||||||
gst_init (&argc, &argv);
|
gst_init (&argc, &argv);
|
||||||
|
@ -135,7 +133,7 @@ main (gint argc,
|
||||||
/* watch for messages on the pipeline's bus (note that this will only
|
/* watch for messages on the pipeline's bus (note that this will only
|
||||||
* work like this when a GLib main loop is running) */
|
* work like this when a GLib main loop is running) */
|
||||||
bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
|
bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
|
||||||
gst_bus_add_watch (bus, bus_call, loop);
|
watch_id = gst_bus_add_watch (bus, bus_call, loop);
|
||||||
gst_object_unref (bus);
|
gst_object_unref (bus);
|
||||||
|
|
||||||
filesrc = gst_element_factory_make ("filesrc", "my_filesource");
|
filesrc = gst_element_factory_make ("filesrc", "my_filesource");
|
||||||
|
@ -154,7 +152,7 @@ main (gint argc,
|
||||||
* depending on the environment (output used, sound card, driver etc.) */
|
* depending on the environment (output used, sound card, driver etc.) */
|
||||||
convert2 = gst_element_factory_make ("audioconvert", "audioconvert2");
|
convert2 = gst_element_factory_make ("audioconvert", "audioconvert2");
|
||||||
resample = gst_element_factory_make ("audioresample", "audioresample");
|
resample = gst_element_factory_make ("audioresample", "audioresample");
|
||||||
sink = gst_element_factory_make ("osssink", "audiosink");
|
sink = gst_element_factory_make ("pulsesink", "audiosink");
|
||||||
|
|
||||||
if (!sink || !decoder) {
|
if (!sink || !decoder) {
|
||||||
g_print ("Decoder or output could not be found - check your install\n");
|
g_print ("Decoder or output could not be found - check your install\n");
|
||||||
|
@ -165,9 +163,9 @@ main (gint argc,
|
||||||
return -1;
|
return -1;
|
||||||
} else if (!filter) {
|
} else if (!filter) {
|
||||||
g_print ("Your self-written filter could not be found. Make sure it "
|
g_print ("Your self-written filter could not be found. Make sure it "
|
||||||
"is installed correctly in $(libdir)/gstreamer-0.10/ or "
|
"is installed correctly in $(libdir)/gstreamer-1.0/ or "
|
||||||
"~/.gstreamer-0.10/plugins/ and that gst-inspect-0.10 lists it. "
|
"~/.gstreamer-1.0/plugins/ and that gst-inspect-1.0 lists it. "
|
||||||
"If it doesn't, check with 'GST_DEBUG=*:2 gst-inspect-0.10' for "
|
"If it doesn't, check with 'GST_DEBUG=*:2 gst-inspect-1.0' for "
|
||||||
"the reason why it is not being loaded.");
|
"the reason why it is not being loaded.");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -209,6 +207,8 @@ main (gint argc,
|
||||||
/* clean up */
|
/* clean up */
|
||||||
gst_element_set_state (pipeline, GST_STATE_NULL);
|
gst_element_set_state (pipeline, GST_STATE_NULL);
|
||||||
gst_object_unref (pipeline);
|
gst_object_unref (pipeline);
|
||||||
|
g_source_remove (watch_id);
|
||||||
|
g_main_loop_unref (loop);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue