docs/manual/advanced-dataaccess.xml: Add section on how to use fakesrc/fakesink/identity in your application, plus se...

Original commit message from CVS:
* docs/manual/advanced-dataaccess.xml:
Add section on how to use fakesrc/fakesink/identity in your
application, plus section on how to embed plugins. Also mention
probes.
* docs/manual/appendix-checklist.xml:
* docs/manual/appendix-debugging.xml:
* docs/manual/appendix-gnome.xml:
* docs/manual/appendix-integration.xml:
Debug -> checklist, GNOME -> integration, add sections on Linux,
KDE integration and add other things useful for application
development.
* docs/manual/manual.xml:
Remove some fixmes, update some file pointers.
* docs/pwg/appendix-checklist.xml:
Fix typo.
* docs/pwg/building-boiler.xml:
Remove ugly header and add commented fixme.
* docs/pwg/pwg.xml:
Add fixme.
* examples/manual/Makefile.am:
Add example for added docs.
This commit is contained in:
Ronald S. Bultje 2004-12-23 14:26:14 +00:00
parent 41713ca927
commit 1fef270158
12 changed files with 565 additions and 492 deletions

View file

@ -1,3 +1,27 @@
2004-12-23 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
* docs/manual/advanced-dataaccess.xml:
Add section on how to use fakesrc/fakesink/identity in your
application, plus section on how to embed plugins. Also mention
probes.
* docs/manual/appendix-checklist.xml:
* docs/manual/appendix-debugging.xml:
* docs/manual/appendix-gnome.xml:
* docs/manual/appendix-integration.xml:
Debug -> checklist, GNOME -> integration, add sections on Linux,
KDE integration and add other things useful for application
development.
* docs/manual/manual.xml:
Remove some fixmes, update some file pointers.
* docs/pwg/appendix-checklist.xml:
Fix typo.
* docs/pwg/building-boiler.xml:
Remove ugly header and add commented fixme.
* docs/pwg/pwg.xml:
Add fixme.
* examples/manual/Makefile.am:
Add example for added docs.
2004-12-23 Thomas Vander Stichele <thomas at apestaart dot org> 2004-12-23 Thomas Vander Stichele <thomas at apestaart dot org>
* configure.ac: * configure.ac:

View file

@ -0,0 +1,241 @@
<chapter id="chapter-dataaccess">
<title>Pipeline manipulation</title>
<para>
This chapter will discuss how you can manipulate your pipeline in several
ways from your application on. Parts of this chapter are downright
hackish, so be assured that you'll need some programming knowledge
before you start reading this.
</para>
<para>
Topics that will be discussed here include how you can insert data into
a pipeline from your application, how to read data from a pipeline,
how to manipulate the pipeline's speed, length, starting point and how
to listen to a pipeline's data processing.
</para>
<sect1 id="section-data-probe">
<title>Data probes</title>
<para>
Probes are best envisioned as pad listeners. They are attached to a
pad in a pipeline, and you can add callback functions to this probe.
Those callback functions will be called whenever data is being sent
over this pad. The callback can then decide whether the data should
be discarded or it can replace the piece of data with another piece
of data. In this callback, it can also trigger actions in the
application itself. For pipeline manipulation, probes are rather
limited, but for pipeline tracking, they can be very useful.
</para>
</sect1>
<sect1 id="section-data-spoof">
<title>Manually adding or removing data from/to a pipeline</title>
<para>
Many people have expressed the wish to use their own sources to inject
data into a pipeline. Some people have also expressed the wish to grab
the output in a pipeline and take care of the actual output inside
their application. While either of these methods are stongly
discouraged, &GStreamer; offers hacks to do this. <emphasis>However,
there is no support for those methods.</emphasis> If it doesn't work,
you're on your own. Also, synchronization, thread-safety and other
things that you've been able to take for granted so far are no longer
guanranteed if you use any of those methods. It's always better to
simply write a plugin and have the pipeline schedule and manage it.
See the Plugin Writer's Guide for more information on this topic. Also
see the next section, which will explain how to embed plugins statically
in your application.
</para>
<para>
After all those disclaimers, let's start. There's three possible
elements that you can use for the above-mentioned purposes. Those are
called <quote>fakesrc</quote> (an imaginary source),
<quote>fakesink</quote> (an imaginary sink) and <quote>identity</quote>
(an imaginary filter). The same method applies to each of those
elements. Here, we will discuss how to use those elements to insert
(using fakesrc) or grab (using fakesink or identity) data from a
pipeline, and how to set negotiation.
</para>
<sect2 id="section-spoof-handoff">
<title>Inserting or grabbing data</title>
<para>
The three before-mentioned elements (fakesrc, fakesink and identity)
each have a <quote>handoff</quote> signal that will be called in
the <function>_get ()</function>- (fakesrc) or <function>_chain
()</function>-function (identity, fakesink). In the signal handler,
you can set (fakesrc) or get (identity, fakesink) data to/from the
provided buffer. Note that in the case of fakesrc, you have to set
the size of the provided buffer using the <quote>sizemax</quote>
property. For both fakesrc and fakesink, you also have to set the
<quote>signal-handoffs</quote> property for this method to work.
</para>
<para>
Note that your handoff function should <emphasis>not</emphasis>
block, since this will block pipeline iteration. Also, do not try
to use all sort of weird hacks in such functions to accomplish
something that looks like synchronization or so; it's not the right
way and will lead to issues elsewhere. If you're doing any of this,
you're basically misunderstanding the &GStreamer; design.
</para>
</sect2>
<sect2 id="section-spoof-format">
<title>Forcing a format</title>
<para>
Sometimes, when using fakesrc as a source in your pipeline, you'll
want to set a specific format, for example a video size and format
or an audio bitsize and number of channels. You can do this by
forcing a specific <classname>GstCaps</classname> on the pipeline,
which is possible by using <emphasis>filtered caps</emphasis>. You
can set a filtered caps on a link by using
<function>gst_pad_link_filtered ()</function>, where the third
argument is the format to force on the link.
</para>
</sect2>
<sect2 id="section-spoof-example">
<title>Example application</title>
<para>
This example application will generate black/white (it switches
every second) video to an X-window output by using fakesrc as a
source and using filtered caps to force a format. Since the depth
of the image depends on your X-server settings, we use a colorspace
conversion element to make sure that the output to your X server
will have the correct bitdepth. You can also set timestamps on the
provided buffers to override the fixed framerate.
</para>
<programlisting><!-- example-begin fakesrc.c -->
#include &lt;string.h&gt; /* for memset () */
#include &lt;gst/gst.h&gt;
static void
cb_handoff (GstElement *fakesrc,
GstBuffer *buffer,
GstPad *pad,
gpointer user_data)
{
static gboolean white = FALSE;
/* this makes the image black/white */
memset (GST_BUFFER_DATA (buffer), white ? 0xff : 0x0,
GST_BUFFER_SIZE (buffer));
white = !white;
}
gint
main (gint argc,
gchar *argv[])
{
GstElement *pipeline, *fakesrc, *conv, *videosink;
GstCaps *filter;
/* init GStreamer */
gst_init (&amp;argc, &amp;argv);
/* setup pipeline */
pipeline = gst_pipeline_new ("pipeline");
fakesrc = gst_element_factory_make ("fakesrc", "source");
conv = gst_element_factory_make ("ffmpegcolorspace", "conv");
videosink = gst_element_factory_make ("ximagesink", "videosink");
/* setup */
filter = gst_caps_new_simple ("video/x-raw-rgb",
"width", G_TYPE_INT, 384,
"height", G_TYPE_INT, 288,
"framerate", G_TYPE_DOUBLE, (gdouble) 1.0,
"bpp", G_TYPE_INT, 16,
"depth", G_TYPE_INT, 16,
"endianness", G_TYPE_INT, G_BYTE_ORDER,
NULL);
gst_element_link_filtered (fakesrc, conv, filter);
gst_element_link (conv, videosink);
gst_bin_add_many (GST_BIN (pipeline), fakesrc, conv, videosink, NULL);
/* setup fake source */
g_object_set (G_OBJECT (fakesrc),
"signal-handoffs", TRUE,
"sizemax", 384 * 288 * 2,
"sizetype", 2, NULL);
g_signal_connect (fakesrc, "handoff", G_CALLBACK (cb_handoff), NULL);
/* play */
gst_element_set_state (pipeline, GST_STATE_PLAYING);
while (gst_bin_iterate (GST_BIN (pipeline))) ;
/* clean up */
gst_element_set_state (pipeline, GST_STATE_NULL);
gst_object_unref (GST_OBJECT (pipeline));
return 0;
}
<!-- example-end fakesrc.c --></programlisting>
</sect2>
</sect1>
<sect1 id="section-data-manager">
<title>Embedding static elements in your application</title>
<para>
The <ulink type="http"
url="http://gstreamer.freedesktop.org/data/doc/gstreamer/head/pwg/html/index.html">Plugin
Writer's Guide</ulink> describes in great detail how to write elements
for the &GStreamer; framework. In this section, we will solely discuss
how to embed such elements statically in your application. This can be
useful for application-specific elements that have no use elsewhere in
&GStreamer;.
</para>
<para>
Dynamically loaded plugins contain a structure that's defined using
<function>GST_PLUGIN_DEFINE ()</function>. This structure is loaded
when the plugin is loaded by the &GStreamer; core. The structure
contains an initialization function (usually called
<function>plugin_init</function>) that will be called right after that.
It's purpose is to register the elements provided by the plugin with
the &GStreamer; framework. If you want to embed elements directly in
your application, the only thing you need to do is to manually run
this structure using <function>_gst_plugin_register_static
()</function>. The initialization will then be called, and the elements
will from then on be available like any other element, without
them having to be dynamically loadable libraries. In the example below,
you would be able to call <function>gst_element_factory_make
("my-element-name", "some-name")</function> to create an instance
of the element.
</para>
<programlisting>
/*
* Here, you would write the actual plugin code.
*/
[..]
static gboolean
register_elements (GstPlugin *plugin)
{
return gst_element_register (plugin, "my-element-name",
GST_RANK_NONE, MY_PLUGIN_TYPE);
}
static GstPluginDesc plugin_desc = {
GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"my-private-plugins",
"Private elements of my application",
register_elements,
NULL,
"0.0.1",
"LGPL",
"my-application",
"http://www.my-application.net/",
GST_PADDING_INIT
};
/*
* Call this function right after calling gst_init ().
*/
void
my_elements_init (void)
{
_gst_plugin_register_static (&amp;plugin_desc);
}
</programlisting>
</sect1>
</chapter>

View file

@ -1,152 +1,163 @@
<chapter id="chapter-debugging"> <chapter id="chapter-checklist-element">
<title>Things to check when writing an application</title>
<para>
This chapter contains a fairly random selection of things that can be
useful to keep in mind when writing &GStreamer;-based applications. It's
up to you how much you're going to use the information provided here.
We will shortly discuss how to debug pipeline problems using &GStreamer;
applications. Also, we will touch upon how to acquire knowledge about
plugins and elements and how to test simple pipelines before building
applications around them.
</para>
<sect1 id="section-checklist-programming">
<title>Good programming habits</title>
<itemizedlist>
<listitem>
<para>
Always connect to the <quote>error</quote> signal of your topmost
pipeline to be notified of errors in your pipeline.
</para>
</listitem>
<listitem>
<para>
Always check return values of &GStreamer; functions. Especially,
check return values of <function>gst_element_link ()</function>
and <function>gst_element_set_state ()</function>.
</para>
</listitem>
<listitem>
<para>
Always use your pipeline object to keep track of the current state
of your pipeline. Don't keep private variables in your application.
Also, don't update your user interface if a user presses the
<quote>play</quote> button. Instead, connect to the
<quote>state-changed</quote> signal of your topmost pipeline and
update the user interface whenever this signal is triggered.
</para>
</listitem>
</itemizedlist>
</sect1>
<sect1 id="section-checklist-debug">
<title>Debugging</title> <title>Debugging</title>
<para> <para>
GStreamer has an extensive set of debugging tools for Applications can make use of the extensive &GStreamer; debugging system
plugin developers. to debug pipeline problems. Elements will write output to this system
to log what they're doing. It's not used for error reporting, but it
is very useful for tracking what an element is doing exactly, which
can come in handy when debugging application issues (such as failing
seeks, out-of-sync media, etc.).
</para> </para>
<sect1 id="section-debugging-command-line">
<title>Command line options</title>
<para> <para>
Applications using the GStreamer libraries accept the following set Most &GStreamer;-based applications accept the commandline option
of command line argruments that help in debugging. <option>--gst-debug=LIST</option> and related family members. The
list consists of a comma-separated list of category/level pairs,
which can set the debugging level for a specific debugging category.
For example, <option>--gst-debug=oggdemux:5</option> would turn
on debugging for the Ogg demuxer element. You can use wildcards as
well. A debugging level of 0 will turn off all debugging, and a level
of 5 will turn on all debugging. Intermediate values only turn on
some debugging (based on message severity; 2, for example, will only
display errors and warnings). Here's a list of all available options:
</para> </para>
<para> <para>
<itemizedlist> <itemizedlist>
<listitem> <listitem>
<para> <para>
<option>--gst-debug-help</option> <option>--gst-debug-help</option> will print available debug
Print available debug categories and exit categories and exit.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
<option>--gst-debug-level=<replaceable>LEVEL</replaceable></option> <option>--gst-debug-level=<replaceable>LEVEL</replaceable></option>
Sets the default debug level from 0 (no output) to 5 (everything) will set the default debug level (which can range from 0 (no
output) to 5 (everything)).
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
<option>--gst-debug=<replaceable>LIST</replaceable></option> <option>--gst-debug=<replaceable>LIST</replaceable></option>
Comma-separated list of category_name:level pairs to set specific takes a comma-separated list of category_name:level pairs to
levels for the individual categories. set specific levels for the individual categories. Example:
Example: GST_AUTOPLUG:5,GST_ELEMENT_*:3 <option>GST_AUTOPLUG:5,avidemux:3</option>.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
<option>--gst-debug-no-color</option> <option>--gst-debug-no-color</option> will disable color debugging.
Disable color debugging output
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
<option>--gst-debug-disable</option> <option>--gst-debug-disable</option> disables debugging alltogether.
Disable debugging
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
<para> <para>
<option>--gst-plugin-spew</option> <option>--gst-plugin-spew</option> enables printout of errors while
Enable printout of errors while loading GStreamer plugins. loading &GStreamer; plugins.
</para> </para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>
</para> </para>
</sect1> </sect1>
<sect1 id="section-debugging-adding"> <sect1 id="section-checklist-conversion">
<title>Adding debugging to a plugin</title> <title>Conversion plugins</title>
<para> <para>
Plugins can define their own categories for the debugging system. &GStreamer; contains a bunch of conversion plugins that most
Three things need to happen: applications will find useful. Specifically, those are videoscalers
<itemizedlist> (videoscale), colorspace convertors (ffmpegcolorspace), audio format
<listitem> convertors and channel resamplers (audioconvert) and audio samplerate
<para> convertors (audioscale). Those convertors don't do anything when not
The debugging variable needs to be defined somewhere. required, they will act in passthrough mode. They will activate when
If you only have one source file, you can Use GST_DEBUG_CATEGORY_STATIC to the hardware doesn't support a specific request, though. All
define a static debug category variable. applications are recommended to use those elements.
</para>
<para>
If you have multiple source files, you should define the variable using
GST_DEBUG_CATEGORY in the source file where you're initializing the debug
category. The other source files should use GST_DEBUG_CATEGORY_EXTERN to
declare the debug category variable, possibly by including a common header
that has this statement.
</para>
</listitem>
<listitem>
<para>
The debugging category needs to be initialized. This is done through
GST_DEBUG_CATEGORY_INIT.
If you're using a global debugging category for the complete plugin,
you can call this in the
plugin's <function>plugin_init</function>.
If the debug category is only used for one of the elements, you can call it
from the element's <function>_class_init</function> function.
</para>
</listitem>
<listitem>
<para>
You should also define a default category to be used for debugging. This is
done by defining GST_CAT_DEFAULT for the source files where you're using
debug macros.
</para>
</listitem>
</itemizedlist>
</para>
<para>
Elements can then log debugging information using the set of macros. There
are five levels of debugging information:
<orderedlist>
<listitem>
<para>ERROR for fatal errors (for example, internal errors)</para>
</listitem>
<listitem>
<para>WARNING for warnings</para>
</listitem>
<listitem>
<para>INFO for normal information</para>
</listitem>
<listitem>
<para>DEBUG for debug information (for example, device parameters)</para>
</listitem>
<listitem>
<para>LOG for regular operation information (for example, chain handlers)</para>
</listitem>
</orderedlist>
</para>
<para>
For each of these levels, there are four macros to log debugging information.
Taking the LOG level as an example, there is
<itemizedlist>
<listitem>
<para>
GST_CAT_LOG_OBJECT logs debug information in the given GstCategory
and for the given GstObject
</para>
</listitem>
<listitem>
<para>
GST_CAT_LOG logs debug information in the given GstCategory
but without a GstObject (this is useful for libraries, for example)
</para>
</listitem>
<listitem>
<para>
GST_LOG_OBJECT logs debug information in the default GST_CAT_DEFAULT
category (as defined somewhere in the source), for the given GstObject
</para>
</listitem>
<listitem>
<para>
GST_LOG logs debug information in the default GST_CAT_DEFAULT
category, without a GstObject
</para>
</listitem>
</itemizedlist>
</para> </para>
</sect1> </sect1>
<sect1 id="section-checklist-applications">
<title>Utility applications provided with &GStreamer;</title>
<para>
&GStreamer; comes with a default set of command-line utilities that
can help in application development. We will discuss only
<command>gst-launch</command> and <command>gst-inspect</command> here.
</para>
<sect2 id="section-applications-launch">
<title><command>gst-launch</command></title>
<para>
<command>gst-launch</command> is a simple script-like commandline
application that can be used to test pipelines. For example, the
command <command>gst-launch sinesrc ! alsasink</command> will run
a pipeline which generates a sine-wave audio stream and plays it
to your ALSA audio card. <command>gst-launch</command> also allows
the use of threads (using curly brackets, so <quote>{</quote>
and <quote>}</quote>) and bins (using brackets, so <quote>(</quote>
and <quote>)</quote>). You can use dots to imply padnames on elements,
or even omit the padname to automatically select a pad. Using
all this, the pipeline <command>gst-launch filesrc location=file.ogg
! oggdemux name=d { d. ! theoradec ! ffmpegcolorspace ! xvimagesink
} { d. ! vorbisdec ! alsasink }</command> will play an Ogg file
containing a Theora video-stream and a Vorbis audio-stream. You can
also use autopluggers such as decodebin on the commandline. See the
manual page of <command>gst-launch</command> for more information.
</para>
</sect2>
<sect2 id="section-applications-inspect">
<title><command>gst-inspect</command></title>
<para>
<command>gst-inspect</command> can be used to inspect all properties,
signals, dynamic parameters and the object hierarchy of an element.
This acn be very useful to see which <classname>GObject</classname>
properties or which signals (and using what arguments) an element
supports. Run <command>gst-inspect fakesrc</command> to get an idea
of what it does. See the manual page of <command>gst-inspect</command>
for more information.
</para>
</sect2>
</sect1>
</chapter> </chapter>

View file

@ -1,152 +0,0 @@
<chapter id="chapter-debugging">
<title>Debugging</title>
<para>
GStreamer has an extensive set of debugging tools for
plugin developers.
</para>
<sect1 id="section-debugging-command-line">
<title>Command line options</title>
<para>
Applications using the GStreamer libraries accept the following set
of command line argruments that help in debugging.
</para>
<para>
<itemizedlist>
<listitem>
<para>
<option>--gst-debug-help</option>
Print available debug categories and exit
</para>
</listitem>
<listitem>
<para>
<option>--gst-debug-level=<replaceable>LEVEL</replaceable></option>
Sets the default debug level from 0 (no output) to 5 (everything)
</para>
</listitem>
<listitem>
<para>
<option>--gst-debug=<replaceable>LIST</replaceable></option>
Comma-separated list of category_name:level pairs to set specific
levels for the individual categories.
Example: GST_AUTOPLUG:5,GST_ELEMENT_*:3
</para>
</listitem>
<listitem>
<para>
<option>--gst-debug-no-color</option>
Disable color debugging output
</para>
</listitem>
<listitem>
<para>
<option>--gst-debug-disable</option>
Disable debugging
</para>
</listitem>
<listitem>
<para>
<option>--gst-plugin-spew</option>
Enable printout of errors while loading GStreamer plugins.
</para>
</listitem>
</itemizedlist>
</para>
</sect1>
<sect1 id="section-debugging-adding">
<title>Adding debugging to a plugin</title>
<para>
Plugins can define their own categories for the debugging system.
Three things need to happen:
<itemizedlist>
<listitem>
<para>
The debugging variable needs to be defined somewhere.
If you only have one source file, you can Use GST_DEBUG_CATEGORY_STATIC to
define a static debug category variable.
</para>
<para>
If you have multiple source files, you should define the variable using
GST_DEBUG_CATEGORY in the source file where you're initializing the debug
category. The other source files should use GST_DEBUG_CATEGORY_EXTERN to
declare the debug category variable, possibly by including a common header
that has this statement.
</para>
</listitem>
<listitem>
<para>
The debugging category needs to be initialized. This is done through
GST_DEBUG_CATEGORY_INIT.
If you're using a global debugging category for the complete plugin,
you can call this in the
plugin's <function>plugin_init</function>.
If the debug category is only used for one of the elements, you can call it
from the element's <function>_class_init</function> function.
</para>
</listitem>
<listitem>
<para>
You should also define a default category to be used for debugging. This is
done by defining GST_CAT_DEFAULT for the source files where you're using
debug macros.
</para>
</listitem>
</itemizedlist>
</para>
<para>
Elements can then log debugging information using the set of macros. There
are five levels of debugging information:
<orderedlist>
<listitem>
<para>ERROR for fatal errors (for example, internal errors)</para>
</listitem>
<listitem>
<para>WARNING for warnings</para>
</listitem>
<listitem>
<para>INFO for normal information</para>
</listitem>
<listitem>
<para>DEBUG for debug information (for example, device parameters)</para>
</listitem>
<listitem>
<para>LOG for regular operation information (for example, chain handlers)</para>
</listitem>
</orderedlist>
</para>
<para>
For each of these levels, there are four macros to log debugging information.
Taking the LOG level as an example, there is
<itemizedlist>
<listitem>
<para>
GST_CAT_LOG_OBJECT logs debug information in the given GstCategory
and for the given GstObject
</para>
</listitem>
<listitem>
<para>
GST_CAT_LOG logs debug information in the given GstCategory
but without a GstObject (this is useful for libraries, for example)
</para>
</listitem>
<listitem>
<para>
GST_LOG_OBJECT logs debug information in the default GST_CAT_DEFAULT
category (as defined somewhere in the source), for the given GstObject
</para>
</listitem>
<listitem>
<para>
GST_LOG logs debug information in the default GST_CAT_DEFAULT
category, without a GstObject
</para>
</listitem>
</itemizedlist>
</para>
</sect1>
</chapter>

View file

@ -1,95 +0,0 @@
<chapter id="chapter-gnome">
<title>GNOME integration</title>
<para>
GStreamer is fairly easy to integrate with GNOME applications.
GStreamer uses libxml 2.0, GLib 2.0 and popt, as do all other
GNOME applications.
There are however some basic issues you need to address in your GNOME
applications.
</para>
<sect1>
<title>Command line options</title>
<para>
GNOME applications call gnome_program_init () to parse command-line
options and initialize the necessary gnome modules.
GStreamer applications normally call gst_init (&amp;argc, &amp;argv) to
do the same for GStreamer.
</para>
<para>
Each of these two swallows the program options passed to the program,
so we need a different way to allow both GNOME and GStreamer to parse
the command-line options. This is shown in the following example.
</para>
<programlisting>
<!-- example-begin gnome.c -->
#include &lt;gnome.h&gt;
#include &lt;gst/gst.h&gt;
int
main (int argc, char **argv)
{
GstPoptOption options[] = {
{ NULL, '\0', POPT_ARG_INCLUDE_TABLE, NULL, 0, "GStreamer", NULL },
POPT_TABLEEND
};
GnomeProgram *program;
poptContext context;
const gchar **argvn;
GstElement *pipeline;
GstElement *src, *sink;
options[0].arg = (void *) gst_init_get_popt_table ();
g_print ("Calling gnome_program_init with the GStreamer popt table\n");
/* gnome_program_init will initialize GStreamer now
* as a side effect of having the GStreamer popt table passed. */
if (! (program = gnome_program_init ("my_package", "0.1", LIBGNOMEUI_MODULE,
argc, argv,
GNOME_PARAM_POPT_TABLE, options,
NULL)))
g_error ("gnome_program_init failed");
g_print ("Getting gnome-program popt context\n");
g_object_get (program, "popt-context", &amp;context, NULL);
argvn = poptGetArgs (context);
if (!argvn) {
g_print ("Run this example with some arguments to see how it works.\n");
return 0;
}
g_print ("Printing rest of arguments\n");
while (*argvn) {
g_print ("argument: %s\n", *argvn);
++argvn;
}
/* do some GStreamer things to show everything's initialized properly */
g_print ("Doing some GStreamer stuff to show that everything works\n");
pipeline = gst_pipeline_new ("pipeline");
src = gst_element_factory_make ("fakesrc", "src");
sink = gst_element_factory_make ("fakesink", "sink");
gst_bin_add_many (GST_BIN (pipeline), src, sink, NULL);
gst_element_link (src, sink);
gst_element_set_state (pipeline, GST_STATE_PLAYING);
gst_bin_iterate (GST_BIN (pipeline));
gst_element_set_state (pipeline, GST_STATE_NULL);
return 0;
}
<!-- example-end gnome.c -->
</programlisting>
<para>
If you try out this program, you will see that when called with
--help, it will print out both GStreamer and GNOME help arguments.
All of the arguments that didn't belong to either end up in the
argvn pointer array.
</para>
<para>
FIXME: flesh this out more. How do we get the GStreamer arguments
at the end ?
FIXME: add a GConf bit.
</para>
</sect1>
</chapter>

View file

@ -1,95 +1,161 @@
<chapter id="chapter-gnome"> <chapter id="chapter-intgration">
<title>GNOME integration</title> <title>Integration</title>
<para> <para>
GStreamer is fairly easy to integrate with GNOME applications. &GStreamer; tries to integrate closely with operating systems (such
GStreamer uses libxml 2.0, GLib 2.0 and popt, as do all other as Linux and UNIX-like operating systems, OS X or Windows) and desktop
GNOME applications. environments (such as GNOME or KDE). In this chapter, we'll mention
There are however some basic issues you need to address in your GNOME some specific techniques to integrate your application with your
applications. operating system or desktop environment of choice.
</para> </para>
<sect1> <sect1 id="section-integration-nix">
<title>Command line options</title> <title>Linux and UNIX-like operating systems</title>
<para> <para>
GNOME applications call gnome_program_init () to parse command-line &GStreamer; provides a basic set of elements that are useful when
options and initialize the necessary gnome modules. integrating with Linux or a UNIX-like operating system.
GStreamer applications normally call gst_init (&amp;argc, &amp;argv) to
do the same for GStreamer.
</para> </para>
<itemizedlist>
<listitem>
<para> <para>
Each of these two swallows the program options passed to the program, For audio input and output, &GStreamer; provides input and
so we need a different way to allow both GNOME and GStreamer to parse output elements for several audio subsystems. Amongst others,
the command-line options. This is shown in the following example. &GStreamer; includes elements for ALSA (alsasrc, alsamixer,
alsasink), OSS (osssrc, ossmixer, osssink) and Sun audio
(sunaudiosrc, sunaudiomixer, sunaudiosink).
</para> </para>
</listitem>
<listitem>
<para>
For video input, &GStreamer; contains source elements for
Video4linux (v4lsrc, v4lmjpegsrc, v4lelement and v4lmjpegisnk)
and Video4linux2 (v4l2src, v4l2element).
</para>
</listitem>
<listitem>
<para>
For video output, &GStreamer; provides elements for output
to X-windows (ximagesink), Xv-windows (xvimagesink; for
hardware-accelerated video), direct-framebuffer (dfbimagesink)
and openGL image contexts (glsink).
</para>
</listitem>
</itemizedlist>
</sect1>
<programlisting> <sect1 id="section-integration-gnome">
<!-- example-begin gnome.c --> <title>GNOME desktop</title>
<para>
&GStreamer; has been the media backend of the <ulink type="http"
url="http://www.gnome.org/">GNOME</ulink> desktop since GNOME-2.2
onwards. Nowadays, a whole bunch of GNOME applications make use of
&GStreamer; for media-processing, including (but not limited to)
<ulink type="http" url="http://www.rhythmbox.org/">Rhythmbox</ulink>,
<ulink type="http" url="http://www.hadess.net/totem.php3">Totem</ulink>
and <ulink type="http"
url="http://www.burtonini.com/blog/computers/sound-juicer">Sound
Juicer</ulink>.
</para>
<para>
Most of these GNOME applications make use of some specific techniques
to integrate as closely as possible with the GNOME desktop:
</para>
<itemizedlist>
<listitem>
<para>
GNOME applications call <function>gnome_program_init ()</function>
to parse command-line options and initialize the necessary gnome
modules. &GStreamer; applications would normally call
<function>gst_init ()</function> to do the same for GStreamer.
This would mean that only one of the two can parse command-line
options. To work around this issue, &GStreamer; can provide a
<classname>poptOption</classname> array which can be passed to
<function>gnome_program_init ()</function>.
</para>
<programlisting><!-- example-begin gnome.c a -->
#include &lt;gnome.h&gt; #include &lt;gnome.h&gt;
#include &lt;gst/gst.h&gt; #include &lt;gst/gst.h&gt;
int gint
main (int argc, char **argv) main (gint argc,
gchar *argv[])
{ {
GstPoptOption options[] = { struct poptOption options[] = {
{ NULL, '\0', POPT_ARG_INCLUDE_TABLE, NULL, 0, "GStreamer", NULL }, {NULL, '\0', POPT_ARG_INCLUDE_TABLE, NULL, 0, "GStreamer", NULL},
POPT_TABLEEND POPT_TABLEEND
}; };
GnomeProgram *program;
poptContext context;
const gchar **argvn;
GstElement *pipeline;
GstElement *src, *sink;
/* init GStreamer and GNOME using the GStreamer popt tables */
options[0].arg = (void *) gst_init_get_popt_table (); options[0].arg = (void *) gst_init_get_popt_table ();
g_print ("Calling gnome_program_init with the GStreamer popt table\n"); gnome_program_init ("my-application", "0.0.1", LIBGNOMEUI_MODULE, argc, argv,
/* gnome_program_init will initialize GStreamer now
* as a side effect of having the GStreamer popt table passed. */
if (! (program = gnome_program_init ("my_package", "0.1", LIBGNOMEUI_MODULE,
argc, argv,
GNOME_PARAM_POPT_TABLE, options, GNOME_PARAM_POPT_TABLE, options,
NULL))) NULL);
g_error ("gnome_program_init failed"); <!-- example-end gnome.c a -->
[..]<!-- example-begin gnome.c b --><!--
g_print ("Getting gnome-program popt context\n");
g_object_get (program, "popt-context", &amp;context, NULL);
argvn = poptGetArgs (context);
if (!argvn) {
g_print ("Run this example with some arguments to see how it works.\n");
return 0;
}
g_print ("Printing rest of arguments\n");
while (*argvn) {
g_print ("argument: %s\n", *argvn);
++argvn;
}
/* do some GStreamer things to show everything's initialized properly */
g_print ("Doing some GStreamer stuff to show that everything works\n");
pipeline = gst_pipeline_new ("pipeline");
src = gst_element_factory_make ("fakesrc", "src");
sink = gst_element_factory_make ("fakesink", "sink");
gst_bin_add_many (GST_BIN (pipeline), src, sink, NULL);
gst_element_link (src, sink);
gst_element_set_state (pipeline, GST_STATE_PLAYING);
gst_bin_iterate (GST_BIN (pipeline));
gst_element_set_state (pipeline, GST_STATE_NULL);
return 0; return 0;
--><!-- example-end gnome.c b -->
<!-- example-begin gnome.c c -->
} }
<!-- example-end gnome.c --> <!-- example-end gnome.c c --></programlisting>
</programlisting> </listitem>
<listitem>
<para> <para>
If you try out this program, you will see that when called with GNOME stores the default video and audio sources and sinks in GConf.
--help, it will print out both GStreamer and GNOME help arguments. &GStreamer; provides a small utility library that can be used to
All of the arguments that didn't belong to either end up in the get the elements from the registry using functions such as
argvn pointer array. <function>gst_gconf_get_default_video_sink ()</function>. See the
header file (<filename>gst/gconf/gconf.h</filename>) for details.
All GNOME applications are recommended to use those variables.
</para>
</listitem>
<listitem>
<para>
&GStreamer; provides data input/output elements for use with the
GNOME-VFS system. These elements are called <quote>gnomevfssrc</quote>
and <quote>gnomevfssink</quote>.
</para>
</listitem>
</itemizedlist>
</sect1>
<sect1 id="section-integration-kde">
<title>KDE desktop</title>
<para>
&GStreamer; has been proposed for inclusion in KDE-4.0. Currently,
&GStreamer; is included as an optional component, and it's used by
several KDE applications, including <ulink type="http"
url="http://amarok.kde.org/">AmaroK</ulink> and <ulink type="http"
url="http://developer.kde.org/~wheeler/juk.html">JuK</ulink>. A
backend for <ulink type="http"
url="http://www.xs4all.nl/~jjvrieze/kmplayer.html">KMPlayer</ulink>
is currently under development.
</para> </para>
<para> <para>
FIXME: flesh this out more. How do we get the GStreamer arguments Although not yet as complete as the GNOME integration bits, there
at the end ? are already some KDE integration specifics available. This list will
FIXME: add a GConf bit. probably grow as &GStreamer; starts to be used in KDE-4.0:
</para>
<itemizedlist>
<listitem>
<para>
AmaroK contains a kiosrc element, which is a source element that
integrates with the KDE VFS subsystem KIO.
</para>
</listitem>
</itemizedlist>
</sect1>
<sect1 id="section-integration-osx">
<title>OS X</title>
<para>
&GStreamer; provides native video and audio output elements for OS X.
It builds using the standard development tools for OS X.
</para>
</sect1>
<sect1 id="section-integration-win32">
<title>Windows</title>
<para>
&GStreamer; builds using Microsoft Visual C .NET 2003 and using Cygwin.
</para> </para>
</sect1> </sect1>
</chapter> </chapter>

View file

@ -47,9 +47,8 @@
<!ENTITY COMPONENTS SYSTEM "highlevel-components.xml"> <!ENTITY COMPONENTS SYSTEM "highlevel-components.xml">
<!-- Appendices --> <!-- Appendices -->
<!ENTITY DEBUGGING SYSTEM "appendix-debugging.xml"> <!ENTITY CHECKLIST SYSTEM "appendix-checklist.xml">
<!ENTITY PROGRAMS SYSTEM "appendix-programs.xml"> <!ENTITY INTEGRATION SYSTEM "appendix-integration.xml">
<!ENTITY GNOME SYSTEM "appendix-gnome.xml">
<!ENTITY WIN32 SYSTEM "appendix-win32.xml"> <!ENTITY WIN32 SYSTEM "appendix-win32.xml">
<!ENTITY QUOTES SYSTEM "appendix-quotes.xml"> <!ENTITY QUOTES SYSTEM "appendix-quotes.xml">
@ -193,42 +192,6 @@
</para> </para>
</partintro> </partintro>
<!--
Idea:
* Querying and events
- seeking
- getting stream length
- prerolls and why
* Stream info
- pads info (see 2.4)
- tags
- inserting tags
* Interfaces
- each
* Clocks & Synchronization
- stress that it's automated
* Dynamic parameters
- ..
* Threading
- gstthread & queues
- buffering (network, live network/video/audio source)
- when 1-to-N, N-to-1 and N-to-N elements need threads
* Scheduling
- loop/chain/get etc. (internals)
- opt
* Autoplugging principles
- type detection
- dynamic element lookup (registry, factories and categories)
- reference part4!
- Hello world 2
* Pipeline manipulation
- data manipulation (identity, fakesrc, fakesink)
- probes (both events and data)
- length manipulation (managers, PWG)
- explain how to embed elements in applications
- explain why separate elements are to be preferred
-->
&QUERYEVENTS; &QUERYEVENTS;
&METADATA; &METADATA;
&INTERFACES; &INTERFACES;
@ -313,9 +276,8 @@ Idea:
- table please... - table please...
--> -->
&DEBUGGING; &CHECKLIST;
&PROGRAMS; &INTEGRATION;
&GNOME;
&WIN32; &WIN32;
&QUOTES; &QUOTES;

View file

@ -59,11 +59,13 @@
()</function> or <function>g_print ()</function>). Instead, ()</function> or <function>g_print ()</function>). Instead,
elements should use the logging functions provided by &GStreamer;, elements should use the logging functions provided by &GStreamer;,
named <function>GST_DEBUG ()</function>, named <function>GST_DEBUG ()</function>,
<function>GST_INFO ()</function>, <function>GST_INFO ()</function>, <function>GST_LOG ()</function>, <function>GST_INFO ()</function>,
<function>GST_WARNING ()</function> and <function>GST_WARNING ()</function> and
<function>GST_ERROR ()</function>. The various logging levels can <function>GST_ERROR ()</function>. The various logging levels can
be turned on and off at runtime and can thus be used for solving be turned on and off at runtime and can thus be used for solving
issues as they turn up. issues as they turn up. Instead of <function>GST_LOG ()</function>
(as an example), you can also use <function>GST_LOG_OBJECT
()</function> to print the object that you're logging output for.
</para> </para>
</listitem> </listitem>
<listitem> <listitem>
@ -87,7 +89,7 @@ gst_myelement_class_init (GstMyelementClass *klass)
</programlisting> </programlisting>
<para> <para>
At runtime, you can turn on debugging using the commandline At runtime, you can turn on debugging using the commandline
<command>--gst-debug=myelement:5</command>. option <command>--gst-debug=myelement:5</command>.
</para> </para>
</listitem> </listitem>
</itemizedlist> </itemizedlist>

View file

@ -63,11 +63,12 @@ U gst-template/gst-app/src/Makefile.am
<!-- ############ sect1 ############# --> <!-- ############ sect1 ############# -->
<sect1 id="section-boiler-project-stamp" xreflabel="Using the Project Stamp"> <sect1 id="section-boiler-project-stamp" xreflabel="Using the Project Stamp">
<title>!!! FIXME !!! Using the Project Stamp</title> <title>Using the Project Stamp</title>
<para> <!-- FIXME
This section needs some fixing from someone that is aware of how this works. This section needs some fixing from someone that is aware of how this
The only tool that looks like the ones cited there is <filename>gst-plugins/tools/filterstamp.sh</filename> works. The only tool that looks like the ones cited there is
</para> <filename>gst-plugins/tools/filterstamp.sh</filename>
-->
<para> <para>
The first thing to do when making a new element is to specify some basic The first thing to do when making a new element is to specify some basic
details about it: what its name is, who wrote it, what version number it details about it: what its name is, who wrote it, what version number it

View file

@ -144,6 +144,9 @@
&ADVANCED_INTERFACES; &ADVANCED_INTERFACES;
&ADVANCED_TAGGING; &ADVANCED_TAGGING;
&ADVANCED_EVENTS; &ADVANCED_EVENTS;
<!-- FIXME: add querying, event handling and conversion -->
</part> </part>
<!-- ############ part ############# --> <!-- ############ part ############# -->

View file

@ -36,6 +36,7 @@ EXAMPLES = \
query \ query \
threads \ threads \
typefind \ typefind \
fakesrc \
playbin \ playbin \
decodebin \ decodebin \
$(GST_LOADSAVE_SRC) $(GST_LOADSAVE_SRC)
@ -52,9 +53,9 @@ pad.c ghostpad.c: $(top_srcdir)/docs/manual/basics-pads.xml
$(PERL_PATH) $(srcdir)/extract.pl $@ \ $(PERL_PATH) $(srcdir)/extract.pl $@ \
$(top_srcdir)/docs/manual/basics-pads.xml $(top_srcdir)/docs/manual/basics-pads.xml
gnome.c: $(top_srcdir)/docs/manual/appendix-gnome.xml gnome.c: $(top_srcdir)/docs/manual/appendix-integration.xml
$(PERL_PATH) $(srcdir)/extract.pl $@ \ $(PERL_PATH) $(srcdir)/extract.pl $@ \
$(top_srcdir)/docs/manual/appendix-gnome.xml $(top_srcdir)/docs/manual/appendix-integration.xml
helloworld.c: $(top_srcdir)/docs/manual/basics-helloworld.xml helloworld.c: $(top_srcdir)/docs/manual/basics-helloworld.xml
$(PERL_PATH) $(srcdir)/extract.pl $@ \ $(PERL_PATH) $(srcdir)/extract.pl $@ \
@ -76,6 +77,10 @@ typefind.c dynamic.c: $(top_srcdir)/docs/manual/advanced-autoplugging.xml
$(PERL_PATH) $(srcdir)/extract.pl $@ \ $(PERL_PATH) $(srcdir)/extract.pl $@ \
$(top_srcdir)/docs/manual/advanced-autoplugging.xml $(top_srcdir)/docs/manual/advanced-autoplugging.xml
fakesrc.c: $(top_srcdir)/docs/manual/advanced-dataaccess.xml
$(PERL_PATH) $(srcdir)/extract.pl $@ \
$(top_srcdir)/docs/manual/advanced-dataaccess.xml
playbin.c decodebin.c: $(top_srcdir)/docs/manual/highlevel-components.xml playbin.c decodebin.c: $(top_srcdir)/docs/manual/highlevel-components.xml
$(PERL_PATH) $(srcdir)/extract.pl $@ \ $(PERL_PATH) $(srcdir)/extract.pl $@ \
$(top_srcdir)/docs/manual/highlevel-components.xml $(top_srcdir)/docs/manual/highlevel-components.xml

View file

@ -36,6 +36,7 @@ EXAMPLES = \
query \ query \
threads \ threads \
typefind \ typefind \
fakesrc \
playbin \ playbin \
decodebin \ decodebin \
$(GST_LOADSAVE_SRC) $(GST_LOADSAVE_SRC)
@ -52,9 +53,9 @@ pad.c ghostpad.c: $(top_srcdir)/docs/manual/basics-pads.xml
$(PERL_PATH) $(srcdir)/extract.pl $@ \ $(PERL_PATH) $(srcdir)/extract.pl $@ \
$(top_srcdir)/docs/manual/basics-pads.xml $(top_srcdir)/docs/manual/basics-pads.xml
gnome.c: $(top_srcdir)/docs/manual/appendix-gnome.xml gnome.c: $(top_srcdir)/docs/manual/appendix-integration.xml
$(PERL_PATH) $(srcdir)/extract.pl $@ \ $(PERL_PATH) $(srcdir)/extract.pl $@ \
$(top_srcdir)/docs/manual/appendix-gnome.xml $(top_srcdir)/docs/manual/appendix-integration.xml
helloworld.c: $(top_srcdir)/docs/manual/basics-helloworld.xml helloworld.c: $(top_srcdir)/docs/manual/basics-helloworld.xml
$(PERL_PATH) $(srcdir)/extract.pl $@ \ $(PERL_PATH) $(srcdir)/extract.pl $@ \
@ -76,6 +77,10 @@ typefind.c dynamic.c: $(top_srcdir)/docs/manual/advanced-autoplugging.xml
$(PERL_PATH) $(srcdir)/extract.pl $@ \ $(PERL_PATH) $(srcdir)/extract.pl $@ \
$(top_srcdir)/docs/manual/advanced-autoplugging.xml $(top_srcdir)/docs/manual/advanced-autoplugging.xml
fakesrc.c: $(top_srcdir)/docs/manual/advanced-dataaccess.xml
$(PERL_PATH) $(srcdir)/extract.pl $@ \
$(top_srcdir)/docs/manual/advanced-dataaccess.xml
playbin.c decodebin.c: $(top_srcdir)/docs/manual/highlevel-components.xml playbin.c decodebin.c: $(top_srcdir)/docs/manual/highlevel-components.xml
$(PERL_PATH) $(srcdir)/extract.pl $@ \ $(PERL_PATH) $(srcdir)/extract.pl $@ \
$(top_srcdir)/docs/manual/highlevel-components.xml $(top_srcdir)/docs/manual/highlevel-components.xml