found. The next section will introduce more useful behaviours, such as
plugging together a decoding pipeline.
-```
+``` c
#include <gst/gst.h>
[.. my_bus_callback goes here ..]
the BUFFERING messages. We will see more advanced methods in [Buffering
strategies](#buffering-strategies).
-```
+``` c
[...]
This is what the code would look like:
-```
+``` c
#include <gst/gst.h>
The above snippet could then also be written as:
-```
+``` c
GstBus *bus;
[..]
able to call `gst_element_factory_make
("my-element-name", "some-name")` to create an instance of the element.
-```
+``` c
/*
* Here, you would write the actual plugin code.
Since most applications seek in time units, our example below does so
too:
-```
+``` c
static void
seek_to_time (GstElement *element,
guint64 time_ns)
`_chain ()` functions, can be done in probe callbacks as well. The
example below gives a short impression on how to use them.
-```
+``` c
#include <gst/gst.h>
What follows is an example application that loosly follows this
algorithm.
-```
+``` c
#include <gst/gst.h>
Note how we use the pull mode method of pushing new buffers into appsrc
although appsrc is running in push mode.
-```
+``` c
#include <gst/gst.h>
What follows is an example on how to capture a snapshot of a video
stream using appsink.
-```
+``` c
#include <gst/gst.h>
Below is an example of how you can change the caps of a pipeline while
in the PLAYING state:
-```
+``` c
#include <stdlib.h>
Let show you how this works with an example. This example changes the
video effect on a simple pipeline every second.
-```
+``` c
#include <gst/gst.h>
the `gstcontroller` library. You need to include the header in your
application's source file:
-```
+``` c
...
#include <gst/gst.h>
#include <gst/controller/gstinterpolationcontrolsource.h>
first need to create a control-source. Lets use an interpolation
control-source:
-```
+``` c
csource = gst_interpolation_control_source_new ();
g_object_set (csource, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL);
several object properties (even in different objects) using separate
control-bindings.
-```
+``` c
gst_object_add_control_binding (object, gst_direct_control_binding_new (object, "prop1", csource));
```
the control-curve gets repeated as
well.
-```
+``` c
GstTimedValueControlSource *tv_csource = (GstTimedValueControlSource *)csource;
gst_timed_value_control_source_set (tv_csource, 0 * GST_SECOND, 0.0);
gst_timed_value_control_source_set (tv_csource, 1 * GST_SECOND, 1.0);
*source* from the element factory named *fakesrc*. It checks if the
creation succeeded. After checking, it unrefs the element.
-```
+``` c
#include <gst/gst.h>
int
()`](http://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstElementFactory.html#gst-element-factory-create)
will use the element factory to create an element with the given name.
-```
+``` c
#include <gst/gst.h>
int
`gst_object_set_name` and `gst_object_get_name` or use the `GObject`
property mechanism as shown below.
-```
+``` c
#include <gst/gst.h>
int
and `gst-inspect <factory-name>` will list all of the above information,
and a lot more.
-```
+``` c
#include <gst/gst.h>
int
In code, the above graph is written like this:
-```
+``` c
#include <gst/gst.h>
int
Let's now add all the code together to get our very first audio player:
-```
+``` c
#include <gst/gst.h>
#include <glib.h>
A typical program \[1\] would have code to initialize GStreamer that
looks like this:
-```
+``` c
#include <stdio.h>
#include <gst/gst.h>
You can also use a GOption table to initialize your own parameters as
shown in the next example:
-```
+``` c
#include <gst/gst.h>
can be passed to `gnome_program_init ()`. The following example
requires GTK 2.6 or newer (previous GTK versions do not support
command line parsing via GOption yet)
-
- ```
+
+ ``` c
#include <gtk/gtk.h>
#include <gst/gst.h>
-
+
static gchar **cmd_filenames = NULL;
-
+
static GOptionEntries cmd_options[] = {
/* here you can add command line options for your application. Check
* the GOption section in the GLib API reference for a more elaborate
* example of how to add your own command line options here */
-
+
/* at the end we have a special option that collects all remaining
* command line arguments (like filenames) for us. If you don't
* need this, you can safely remove it */
{ G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &cmd_filenames,
"Special option that collects any remaining arguments for us" },
-
+
/* mark the end of the options array with a NULL option */
{ NULL, }
};
-
+
/* this should usually be defined in your config.h */
#define VERSION "0.0.1"
-
+
gint
main (gint argc, gchar **argv)
{
GOptionContext *context;
GOptionGroup *gstreamer_group, *gtk_group;
GError *err = NULL;
-
+
context = g_option_context_new ("gtk-demo-app");
-
+
/* get command line options from GStreamer and add them to the group */
gstreamer_group = gst_init_get_option_group ();
g_option_context_add_group (context, gstreamer_group);
gtk_group = gtk_get_option_group (TRUE);
g_option_context_add_group (context, gtk_group);
-
+
/* add our own options. If you are using gettext for translation of your
* strings, use GETTEXT_PACKAGE here instead of NULL */
g_option_context_add_main_entries (context, cmd_options, NULL);
-
+
/* now parse the commandline options, note that this already
* calls gtk_init() and gst_init() */
if (!g_option_context_parse (ctx, &argc, &argv, &err)) {
exit (1);
}
g_option_context_free (ctx);
-
+
/* any filenames we got passed on the command line? parse them! */
if (cmd_filenames != NULL) {
guint i, num;
-
+
num = g_strv_length (cmd_filenames);
for (i = 0; i < num; ++i) {
/* do something with the filename ... */
g_print ("Adding to play queue: %s\n", cmd_filenames[i]);
}
-
+
g_strfreev (cmd_filenames);
cmd_filenames = NULL;
}
-
+
[..]
-
+
}
-
```
- GNOME uses Pulseaudio for audio, use the pulsesrc and pulsesink
The following example will extract tags from a file and print them:
-```
+``` c
/* compile with:
* gcc -o tags tags.c `pkg-config --cflags --libs gstreamer-1.0` */
#include <gst/gst.h>
“sometimes” pad templates. The following piece of code is an example
of how to do this:
-```
+``` c
#include <gst/gst.h>
static void
Here is an example of how to extract the width and height from a set of
fixed video caps:
-```
+``` c
static void
read_video_props (GstCaps *caps)
{
this, you also need to create your own `GstCaps`. The easiest way to do
this is by using the convenience function `gst_caps_new_simple ()`:
-```
+``` c
static gboolean
link_elements_with_filter (GstElement *element1, GstElement *element2)
{
capabilities to filter a link between two pads. Then, this function is
too simplistic and you'll want to use the method `gst_caps_new_full ()`:
-```
+``` c
static gboolean
link_elements_with_filter (GstElement *element1, GstElement *element2)
{
A ghostpad is created using the function `gst_ghost_pad_new ()`:
-```
+``` c
#include <gst/gst.h>
int
Internally, playbin will set up a pipeline to playback the media
location.
-```
+``` c
#include <gst/gst.h>
[.. my_bus_callback goes here ..]
be the whole stream), it will emit the “unknown-type” signal. The
application is then responsible for reporting the error to the user.
-```
+``` c
#include <gst/gst.h>
the playsink request pads. We only link the first audio and video pads,
you could use an input-selector to link all pads.
-```
+``` c
#include <gst/gst.h>
The following program lets you create an MP3 pipeline using the
gst\_parse\_launch () function:
-```
+``` c
#include <gst/gst.h>
int
to the function caller. Usually, that is the demuxer, although with live
sources (from a webcam), it is the source itself.
-```
+``` c
#include <gst/gst.h>
offset. The behaviour of a seek is also wrapped in the `gst_element_seek
()`.
-```
+``` c
static void
seek_to_time (GstElement *pipeline,
gint64 time_nanoseconds)
subclass that uses pthreads to create a SCHED\_RR real-time thread. Note
that creating real-time threads might require extra priveleges.
-```
-
-
-
-
-
+``` c
#include <pthread.h>
typedef struct
the fakesrc needs it. For this we intercept the STREAM\_STATUS messages
with a sync handler.
-```
+``` c
static GMainLoop* loop;
-```
+``` c
Note that this program likely needs root permissions in order to create
real-time threads. When the thread can't be created, the state change
Here is a typical event function:
-```
+``` c
static gboolean
gst_my_filter_sink_event (GstPad *pad, GstObject * parent, GstEvent * event)
{
explains how to add support for a simple interface with no further
dependencies.
-```
+``` c
static void gst_my_filter_some_interface_init (GstSomeInterface *iface);
GType
Or more
conveniently:
-```
+``` c
static void gst_my_filter_some_interface_init (GstSomeInterface *iface);
G_DEFINE_TYPE_WITH_CODE (GstMyFilter, gst_my_filter,GST_TYPE_ELEMENT,
only 2 methods that plugins writers have to implement and they most
probably look like that :
-```
+``` c
static void
gst_my_filter_set_window_handle (GstVideoOverlay *overlay, guintptr handle)
{
needed such as when receiving a CAPS event where you will know the video
geometry and maybe create the window.
-```
+``` c
static MyFilterWindow *
gst_my_filter_window_create (GstMyFilter *my_filter, gint width, gint height)
{
element will need to use a lock to protect these QoS values as shown in
the example below. Also make sure to pass the QoS event upstream.
-```
+``` c
[...]
A possible algorithm typically looks like this:
-```
+``` c
[...]
The code to parse this file and create the dynamic “sometimes” pads,
looks like this:
-```
+``` c
typedef struct _GstMyFilter {
[..]
method in `GstElement`. To clean up, you will need to implement the
`release_pad` virtual method.
-```
+``` c
static GstPad * gst_my_filter_request_new_pad (GstElement *element,
GstPadTemplate *templ,
If you want to do it in your own element, it's easiest to register the
tag in one of your class init functions, preferably `_class_init ()`.
-```
+``` c
static void
gst_my_filter_class_init (GstMyFilterClass *klass)
Warning, this example is outdated and doesn't work with the 1.0 version
of GStreamer anymore.
-```
+``` c
GType
gst_my_filter_get_type (void)
Below is an example of making a `GstMemory` object and using the
`gst_memory_map()` to access the memory region.
-```
+``` c
[...]
Below is an example of how to create a buffer and access its memory.
-```
+``` c
[...]
GstBuffer *buffer;
Let's have a look at the metadata that is used to specify a cropping
region for video frames.
-```
+``` c
#include <gst/video/gstvideometa.h>
An element can then use the metadata on the buffer when rendering the
frame like this:
-```
+``` c
#include <gst/video/gstvideometa.h>
First we start with making the `my-example-meta.h` header file that will
contain the definition of the API and structure for our metadata.
-```
+``` c
#include <gst/gst.h>
Next let's have a look at how the `my_example_meta_api_get_type ()`
function is implemented in the `my-example-meta.c` file.
-```
+``` c
#include "my-example-meta.h"
add your metadata implementation to a `GstBuffer`. Your
`my-example-meta.h` header file will need these additions:
-```
+``` c
[...]
Let's have a look at how these functions are implemented in the
`my-example-meta.c` file.
-```
+``` c
[...]
inactive state will fail. Likewise, trying to activate a bufferpool that
is not configured will fail.
-```
+``` c
GstStructure *config;
point on you can use `gst_buffer_pool_acquire_buffer ()` to retrieve a
buffer from the pool, like this:
-```
+``` c
[...]
Below is an example of the ALLOCATION query.
-```
+``` c
#include <gst/video/video.h>
#include <gst/video/gstvideometa.h>
instance variable to the default value, you will have to do that in the
`_init ()` function of your element.
-```
+``` c
/* properties */
enum {
integers here would probably completely confuse the user, because they
make no sense in this context. The example is stolen from videotestsrc.
-```
+``` c
typedef enum {
GST_VIDEOTESTSRC_SMPTE,
GST_VIDEOTESTSRC_SNOW,
the plugin system, and doesn't depend on reading a header file, this is
not crucial.)
-```
+``` c
#include <gst/gst.h>
/* Definition of structure storing data for this element. */
`GObject` basics in your source file so that all functions will be
called appropriately:
-```
+``` c
#include "filter.h"
G_DEFINE_TYPE (GstMyFilter, gst_my_filter, GST_TYPE_ELEMENT);
For example:
-```
+``` c
gst_element_class_set_static_metadata (klass,
"An example plugin",
"Example/FirstExample",
`_class_init ()` function should be set for this GObject in the function
where you register the type with GLib.
-```
+``` c
static void
gst_my_filter_class_init (GstMyFilterClass * klass)
{
For example:
-```
+``` c
static GstStaticPadTemplate sink_factory =
GST_STATIC_PAD_TEMPLATE (
"sink",
16-bit audio, mono or stereo at any samplerate, the correct template
would look like this:
-```
+``` c
static GstStaticPadTemplate sink_factory =
GST_STATIC_PAD_TEMPLATE (
correctly. Also, in this function, any supported element type in the
plugin should be registered.
-```
+``` c
static gboolean
linear functions - so for each incoming buffer, one buffer will go out,
too. Below is a very simple implementation of a chain function:
-```
+``` c
static GstFlowReturn gst_my_filter_chain (GstPad *pad,
GstObject *parent,
Below follows a very simple event function that we install on the sink
pad of our element.
-```
+``` c
static gboolean gst_my_filter_sink_event (GstPad *pad,
GstObject *parent,
More on this topic later. After that, you have to register the pad with
the element. This happens like this:
-```
+``` c
Below follows a very simple query function that we install on the source
pad of our element.
-```
+``` c
static gboolean gst_my_filter_src_query (GstPad *pad,
GstObject *parent,
possible support libraries. Your application should `unref ()` the
pipeline and make sure it doesn't crash.
-```
+``` c
#include <gst/gst.h>
static gboolean
will recognize AVI files, which start with a “RIFF” tag, then the size
of the file and then an “AVI” tag:
-```
+``` c
static void
gst_my_typefind_function (GstTypeFind *tf,
gpointer data)
- Ideally, elements should use their own debugging category. Most
elements use the following code to do that:
- ```
+ ``` c
GST_DEBUG_CATEGORY_STATIC (myelement_debug);
#define GST_CAT_DEFAULT myelement_debug
- Elements should use GST\_DEBUG\_FUNCPTR when setting pad functions
or overriding element class methods, for example:
- ```
+ ``` c
gst_pad_set_event_func (myelement->srcpad,
GST_DEBUG_FUNCPTR (my_element_src_event));
The controller subsystem is contained within the `gstcontroller`
library. You need to include the header in your element's source file:
-```
+``` c
...
#include <gst/gst.h>
#include <gst/controller/gstcontroller.h>
application, you should make sure it is initialized in your
`plugin_init` function:
-```
+``` c
static gboolean
plugin_init (GstPlugin *plugin)
{
by using the special flag `GST_PARAM_CONTROLLABLE`. when setting up
GObject params in the `_class_init` method.
-```
+``` c
g_object_class_install_property (gobject_class, PROP_FREQ,
g_param_spec_double ("freq", "Frequency", "Frequency of test signal",
0.0, 20000.0, 440.0,
make plugins responsible for pulling the changes in. This requires just
one action:
-```
+``` c
gst_object_sync_values(element,timestamp);
```
the CAPS query will return the negotiated caps (and nothing else). These
are the relevant code snippets for fixed caps source pads.
-```
+``` c
[..]
pad = gst_pad_new_from_static_template (..);
The fixed caps can then be set on the pad by calling `gst_pad_set_caps
()`.
-```
+``` c
[..]
caps = gst_caps_new_simple ("audio/x-raw",
element. In the sink pad CAPS event handler, we compute the caps for the
source pad and set those.
-```
+``` c
[...]
samplerates, so where input and output samplerate don't have to be the
same:
-```
+``` c
static gboolean
gst_my_filter_setcaps (GstMyFilter *filter,
elements further downstream or upstream, sorted by order of preference,
highest preference first.
-```
+``` c
static gboolean
gst_my_filter_query (GstPad *pad, GstObject * parent, GstQuery * query)
Sink elements can derive from `GstBaseSink` using the usual `GObject`
convenience macro `G_DEFINE_TYPE ()`:
-```
+``` c
G_DEFINE_TYPE (GstMySink, gst_my_sink, GST_TYPE_BASE_SINK);
[..]
activate the sinkpad in pull-mode. Inside the activate\_mode function
you can then start the task.
-```
+``` c
#include "filter.h"
#include <string.h>
flexibility than the old push-mode case that we've been looking at so
far.
+``` c
#define BLOCKSIZE 2048
static void
GST_DEBUG_OBJECT (filter, "pausing task");
gst_pad_pause_task (filter->sinkpad);
}
+```
# Providing random access