mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-24 17:20:36 +00:00
e62fd449c2
Original commit message from CVS: * docs/pwg/building-testapp.xml: Add extra check. * examples/pwg/Makefile.am: Fix buildbot.
153 lines
5.6 KiB
XML
153 lines
5.6 KiB
XML
<!-- ############ chapter ############# -->
|
|
|
|
<chapter id="chapter-building-testapp">
|
|
<title>Building a Test Application</title>
|
|
<para>
|
|
Often, you will want to test your newly written plugin in an as small
|
|
setting as possible. Usually, <filename>gst-launch</filename> is a
|
|
good first step at testing a plugin. However, you will often need more
|
|
testing features than gst-launch can provide, such as seeking, events,
|
|
interactivity and more. Writing your own small testing program is the
|
|
easiest way to accomplish this. This section explains - in a few words
|
|
- how to do that. For a complete application development guide, see the
|
|
<ulink type="http" url="../../manual/html/index.html">Application Development
|
|
Manual</ulink>.
|
|
</para>
|
|
|
|
<para>
|
|
At the start, you need to initialize the &GStreamer; core library by
|
|
calling <function>gst_init ()</function>. You can alternatively call
|
|
<function>gst_init_with_popt_tables ()</function>, which will return
|
|
a pointer to popt tables. You can then use libpopt to handle the
|
|
given argument table, and this will finish the &GStreamer; intialization.
|
|
</para>
|
|
|
|
<para>
|
|
You can create elements using <function>gst_element_factory_make ()</function>,
|
|
where the first argument is the element type that you want to create,
|
|
and the second argument is a free-form name. The example at the end uses
|
|
a simple filesource - decoder - soundcard output pipeline, but you can
|
|
use specific debugging elements if that's necessary. For example, an
|
|
<classname>identity</classname> element can be used in the middle of
|
|
the pipeline to act as a data-to-application transmitter. This can be
|
|
used to check the data for misbehaviours or correctness in your test
|
|
application. Also, you can use a <classname>fakesink</classname>
|
|
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
|
|
TRUE). Lastly, you can use the <classname>efence</classname> element
|
|
(indeed, an eletric fence memory debugger wrapper element) to check
|
|
for memory errors.
|
|
</para>
|
|
|
|
<para>
|
|
During linking, your test application can use fixation or filtered caps
|
|
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
|
|
and output in your element.
|
|
</para>
|
|
|
|
<para>
|
|
Running the pipeline happens through the <function>gst_bin_iterate ()</function>
|
|
function. Note that during running, you should connect to at least the
|
|
<quote>error</quote> and <quote>eos</quote> signals on the pipeline
|
|
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
|
|
these correctly (with respect to clocking, internal caching, etc.).
|
|
</para>
|
|
|
|
<para>
|
|
Never forget to clean up memory in your plugin or your test application.
|
|
When going to the NULL state, your element should clean up allocated
|
|
memory and caches. Also, it should close down any references held to
|
|
possible support libraries. Your application should <function>unref ()</function>
|
|
the pipeline and make sure it doesn't crash.
|
|
</para>
|
|
|
|
<programlisting><!-- example-begin test.c -->
|
|
#include <gst/gst.h>
|
|
|
|
static gboolean
|
|
bus_call (GstBus *bus,
|
|
GstMessage *msg,
|
|
gpointer data)
|
|
{
|
|
GMainLoop *loop = data;
|
|
|
|
switch (GST_MESSAGE_TYPE (msg)) {
|
|
case GST_MESSAGE_EOS:
|
|
g_print ("End-of-stream\n");
|
|
g_main_loop_quit (loop);
|
|
break;
|
|
case GST_MESSAGE_ERROR: {
|
|
gchar *debug;
|
|
GError *err;
|
|
|
|
gst_message_parse_error (msg, &err, &debug);
|
|
g_free (debug);
|
|
|
|
g_print ("Error: %s\n", err->message);
|
|
g_error_free (err);
|
|
|
|
g_main_loop_quit (loop);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
gint
|
|
main (gint argc,
|
|
gchar *argv[])
|
|
{
|
|
GstElement *pipeline, *filesrc, *decoder, *filter, *sink;
|
|
GMainLoop *loop;
|
|
|
|
/* initialization */
|
|
gst_init (&argc, &argv);
|
|
loop = g_main_loop_new (NULL, FALSE);
|
|
if (argc != 2) {
|
|
g_print ("Usage: %s <mp3 filename>\n", argv[0]);
|
|
return 01;
|
|
}
|
|
|
|
/* create elements */
|
|
pipeline = gst_pipeline_new ("my_pipeline");
|
|
gst_bus_add_watch (gst_pipeline_get_bus (GST_PIPELINE (pipeline)),
|
|
bus_call, loop);
|
|
|
|
filesrc = gst_element_factory_make ("filesrc", "my_filesource");
|
|
decoder = gst_element_factory_make ("mad", "my_decoder");
|
|
filter = gst_element_factory_make ("my_filter", "my_filter");
|
|
sink = gst_element_factory_make ("osssink", "audiosink");
|
|
if (!sink || !decoder) {
|
|
g_print ("Decoder or output could not be found - check your install\n");
|
|
return -1;
|
|
} else if (!filter) {
|
|
g_print ("Your self-written filter could not be found. Make sure it "
|
|
"is installed correctly in $(libdir)/gstreamer-0.9/ and that "
|
|
"you've ran gst-register-0.9 to register it. Check availability "
|
|
"of the plugin afterwards using \"gst-inspect-0.9 my_filter\"");
|
|
return -1;
|
|
}
|
|
|
|
g_object_set (G_OBJECT (filesrc), "location", argv[1], NULL);
|
|
|
|
/* link everything together */
|
|
gst_element_link_many (filesrc, decoder, filter, sink, NULL);
|
|
gst_bin_add_many (GST_BIN (pipeline), filesrc, decoder, filter, sink, NULL);
|
|
|
|
/* run */
|
|
gst_element_set_state (pipeline, GST_STATE_PLAYING);
|
|
g_main_loop_run (loop);
|
|
|
|
/* clean up */
|
|
gst_element_set_state (pipeline, GST_STATE_NULL);
|
|
gst_object_unref (GST_OBJECT (pipeline));
|
|
|
|
return 0;
|
|
}
|
|
<!-- example-end test.c --></programlisting>
|
|
</chapter>
|