summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorR S Nikhil Krishna <rsnk96@gmail.com>2020-12-29 01:48:30 +0530
committerThibault Saunier <tsaunier@igalia.com>2021-01-05 18:04:56 -0300
commitddbe5ce83bfd918831aa09d0ba401cdc3b0b7c74 (patch)
tree406587d27c7d6010fa40b7d659f99eee7c34b30e
parentbe19c30254e9d3f06d11f95188f2d674fa09e932 (diff)
Updated python port of Tutorial 2 with fixed line numbers
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-docs/-/merge_requests/126>
-rw-r--r--.gitignore2
-rw-r--r--examples/tutorials/python/basic-tutorial-2.py64
-rw-r--r--images/basic-concepts-pipeline.pngbin0 -> 14067 bytes
-rw-r--r--markdown/tutorials/basic/concepts.md423
4 files changed, 278 insertions, 211 deletions
diff --git a/.gitignore b/.gitignore
index e013a1b..be37554 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,6 @@
/built_doc
+.vscode
+build/
/hotdoc-private*
/.hotdoc.d
/*.stamp
diff --git a/examples/tutorials/python/basic-tutorial-2.py b/examples/tutorials/python/basic-tutorial-2.py
new file mode 100644
index 0000000..d3571b2
--- /dev/null
+++ b/examples/tutorials/python/basic-tutorial-2.py
@@ -0,0 +1,64 @@
+#!/usr/bin/env python3
+import sys
+import gi
+import logging
+
+gi.require_version("GLib", "2.0")
+gi.require_version("GObject", "2.0")
+gi.require_version("Gst", "1.0")
+
+from gi.repository import Gst, GLib, GObject
+
+
+logging.basicConfig(level=logging.DEBUG, format="[%(name)s] [%(levelname)8s] - %(message)s")
+logger = logging.getLogger(__name__)
+
+# Initialize GStreamer
+Gst.init(sys.argv[1:])
+
+# Create the elements
+source = Gst.ElementFactory.make("videotestsrc", "source")
+sink = Gst.ElementFactory.make("autovideosink", "sink")
+
+# Create the empty pipeline
+pipeline = Gst.Pipeline.new("test-pipeline")
+
+if not pipeline or not source or not sink:
+ logger.error("Not all elements could be created.")
+ sys.exit(1)
+
+
+# Build the pipeline
+pipeline.add(source, sink)
+if not source.link(sink):
+ logger.error("Elements could not be linked.")
+ sys.exit(1)
+
+# Modify the source's properties
+source.props.pattern = 0
+# Can alternatively be done using `source.set_property("pattern",0)`
+# or using `Gst.util_set_object_arg(source, "pattern", 0)`
+
+# Start playing
+ret = pipeline.set_state(Gst.State.PLAYING)
+if ret == Gst.StateChangeReturn.FAILURE:
+ logger.error("Unable to set the pipeline to the playing state.")
+ sys.exit(1)
+
+# Wait for EOS or error
+bus = pipeline.get_bus()
+msg = bus.timed_pop_filtered(Gst.CLOCK_TIME_NONE, Gst.MessageType.ERROR | Gst.MessageType.EOS)
+
+# Parse message
+if msg:
+ if msg.type == Gst.MessageType.ERROR:
+ err, debug_info = msg.parse_error()
+ logger.error(f"Error received from element {msg.src.get_name()}: {err.message}")
+ logger.error(f"Debugging information: {debug_info if debug_info else 'none'}")
+ elif msg.type == Gst.MessageType.EOS:
+ logger.info("End-Of-Stream reached.")
+ else:
+ # This should not happen as we only asked for ERRORs and EOS
+ logger.error("Unexpected message received.")
+
+pipeline.set_state(Gst.State.NULL)
diff --git a/images/basic-concepts-pipeline.png b/images/basic-concepts-pipeline.png
new file mode 100644
index 0000000..0a3a19a
--- /dev/null
+++ b/images/basic-concepts-pipeline.png
Binary files differ
diff --git a/markdown/tutorials/basic/concepts.md b/markdown/tutorials/basic/concepts.md
index 9bf7e75..3346209 100644
--- a/markdown/tutorials/basic/concepts.md
+++ b/markdown/tutorials/basic/concepts.md
@@ -1,9 +1,12 @@
-# Basic tutorial 2: GStreamer concepts
+---
+short-description: Gstreamer Elements, Pipeline and the Bus
+...
+{{ ALERT_JS.md }}
+
+# Basic tutorial 2: GStreamer concepts
-{{ ALERT_PY.md }}
-{{ ALERT_JS.md }}
## Goal
@@ -22,102 +25,40 @@ and linking them all together. In the process, we will learn:
## Manual Hello World
-Copy this code into a text file named `basic-tutorial-2.c` (or find it
-in your GStreamer installation).
-
-**basic-tutorial-2.c**
-
-``` c
-#include <gst/gst.h>
-
-int main(int argc, char *argv[]) {
- GstElement *pipeline, *source, *sink;
- GstBus *bus;
- GstMessage *msg;
- GstStateChangeReturn ret;
-
- /* Initialize GStreamer */
- gst_init (&argc, &argv);
-
- /* Create the elements */
- source = gst_element_factory_make ("videotestsrc", "source");
- sink = gst_element_factory_make ("autovideosink", "sink");
-
- /* Create the empty pipeline */
- pipeline = gst_pipeline_new ("test-pipeline");
-
- if (!pipeline || !source || !sink) {
- g_printerr ("Not all elements could be created.\n");
- return -1;
- }
-
- /* Build the pipeline */
- gst_bin_add_many (GST_BIN (pipeline), source, sink, NULL);
- if (gst_element_link (source, sink) != TRUE) {
- g_printerr ("Elements could not be linked.\n");
- gst_object_unref (pipeline);
- return -1;
- }
-
- /* Modify the source's properties */
- g_object_set (source, "pattern", 0, NULL);
-
- /* Start playing */
- ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
- if (ret == GST_STATE_CHANGE_FAILURE) {
- g_printerr ("Unable to set the pipeline to the playing state.\n");
- gst_object_unref (pipeline);
- return -1;
- }
-
- /* Wait until error or EOS */
- bus = gst_element_get_bus (pipeline);
- msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_ERROR | GST_MESSAGE_EOS);
-
- /* Parse message */
- if (msg != NULL) {
- GError *err;
- gchar *debug_info;
-
- switch (GST_MESSAGE_TYPE (msg)) {
- case GST_MESSAGE_ERROR:
- gst_message_parse_error (msg, &err, &debug_info);
- g_printerr ("Error received from element %s: %s\n", GST_OBJECT_NAME (msg->src), err->message);
- g_printerr ("Debugging information: %s\n", debug_info ? debug_info : "none");
- g_clear_error (&err);
- g_free (debug_info);
- break;
- case GST_MESSAGE_EOS:
- g_print ("End-Of-Stream reached.\n");
- break;
- default:
- /* We should not reach here because we only asked for ERRORs and EOS */
- g_printerr ("Unexpected message received.\n");
- break;
- }
- gst_message_unref (msg);
- }
-
- /* Free resources */
- gst_object_unref (bus);
- gst_element_set_state (pipeline, GST_STATE_NULL);
- gst_object_unref (pipeline);
- return 0;
-}
-```
-
-> ![Information](images/icons/emoticons/information.svg)
-> Need help?
->
-> If you need help to compile this code, refer to the **Building the tutorials** section for your platform: [Linux](installing/on-linux.md#InstallingonLinux-Build), [Mac OS X](installing/on-mac-osx.md#InstallingonMacOSX-Build) or [Windows](installing/on-windows.md#InstallingonWindows-Build), or use this specific command on Linux:
->
-> `` gcc basic-tutorial-2.c -o basic-tutorial-2 `pkg-config --cflags --libs gstreamer-1.0` ``
->
->If you need help to run this code, refer to the **Running the tutorials** section for your platform: [Linux](installing/on-linux.md#InstallingonLinux-Run), [Mac OS X](installing/on-mac-osx.md#InstallingonMacOSX-Run) or [Windows](installing/on-windows.md#InstallingonWindows-Run).
->
->This tutorial opens a window and displays a test pattern, without audio
->
->Required libraries: `gstreamer-1.0`
+{{ C+JS_FALLBACK.md }}
+ Copy this code into a text file named `basic-tutorial-2.c` (or find it
+ in your GStreamer installation).
+
+ **basic-tutorial-2.c**
+
+ {{ tutorials/basic-tutorial-2.c }}
+
+ > ![Information](images/icons/emoticons/information.svg)
+ > Need help?
+ >
+ > If you need help to compile this code, refer to the **Building the tutorials** section for your platform: [Linux], [Mac OS X] or [Windows], or use this specific command on Linux:
+ >
+ > `` gcc basic-tutorial-2.c -o basic-tutorial-2 `pkg-config --cflags --libs gstreamer-1.0` ``
+ >
+ >If you need help to run this code, refer to the **Running the tutorials** section for your platform: [Linux][1], [Mac OS X][[2]] or [Windows][3].
+ >
+ >This tutorial opens a window and displays a test pattern, without audio
+ >
+ >Required libraries: `gstreamer-1.0`
+{{ END_LANG.md }}
+
+
+{{ PY.md }}
+ Copy this code into a text file named `basic-tutorial-2.py` (or find it
+ in your GStreamer installation).
+ **basic-tutorial-2.py**
+
+ {{ tutorials/python/basic-tutorial-2.py }}
+
+ Then, you can run the file with `python3 basic-tutorial-2.py`
+{{ END_LANG.md }}
+
+
## Walkthrough
@@ -134,68 +75,84 @@ to the sink elements (data consumers), passing through filter elements.
We will skip GStreamer initialization, since it is the same as the
previous tutorial:
-``` c
-/* Create the elements */
-source = gst_element_factory_make ("videotestsrc", "source");
-sink = gst_element_factory_make ("autovideosink", "sink");
-```
+{{ C+JS_FALLBACK.md }}
+ {{ tutorials/basic-tutorial-2.c[13:16] }}
+{{ END_LANG.md }}
+
+{{ PY.md }}
+ {{ tutorials/python/basic-tutorial-2.py[18:21] }}
+{{ END_LANG.md }}
+
As seen in this code, new elements can be created
-with `gst_element_factory_make()`. The first parameter is the type of
+with [gst_element_factory_make]\(). The first parameter is the type of
element to create ([Basic tutorial 14: Handy
-elements](tutorials/basic/handy-elements.md) shows a
+elements] shows a
few common types, and [Basic tutorial 10: GStreamer
-tools](tutorials/basic/gstreamer-tools.md) shows how to
+tools] shows how to
obtain the list of all available types). The second parameter is the
name we want to give to this particular instance. Naming your elements
is useful to retrieve them later if you didn't keep a pointer (and for
-more meaningful debug output). If you pass NULL for the name, however,
+more meaningful debug output). If you pass [NULL] for the name, however,
GStreamer will provide a unique name for you.
-For this tutorial we create two elements: a `videotestsrc` and
-an `autovideosink`.
+For this tutorial we create two elements: a [videotestsrc] and
+an [autovideosink]. There are no filter elements. Hence, the pipeline would
+look like the following:
+
+![](images/basic-concepts-pipeline.png)
-`videotestsrc` is a source element (it produces data), which creates a
+**Figure 2**. Pipeline built in this tutorial
+
+[videotestsrc] is a source element (it produces data), which creates a
test video pattern. This element is useful for debugging purposes (and
tutorials) and is not usually found in real applications.
-`autovideosink` is a sink element (it consumes data), which displays on
+[autovideosink] is a sink element (it consumes data), which displays on
a window the images it receives. There exist several video sinks,
depending on the operating system, with a varying range of capabilities.
-`autovideosink` automatically selects and instantiates the best one, so
+[autovideosink] automatically selects and instantiates the best one, so
you do not have to worry with the details, and your code is more
platform-independent.
### Pipeline creation
-``` c
-/* Create the empty pipeline */
-pipeline = gst_pipeline_new ("test-pipeline");
-```
+{{ C+JS_FALLBACK.md }}
+ {{ tutorials/basic-tutorial-2.c[17:19] }}
+{{ END_LANG.md }}
+
+{{ PY.md }}
+ {{ tutorials/python/basic-tutorial-2.py[22:24] }}
+{{ END_LANG.md }}
All elements in GStreamer must typically be contained inside a pipeline
before they can be used, because it takes care of some clocking and
-messaging functions. We create the pipeline with `gst_pipeline_new()`.
-
-``` c
-/* Build the pipeline */
-gst_bin_add_many (GST_BIN (pipeline), source, sink, NULL);
-if (gst_element_link (source, sink) != TRUE) {
- g_printerr ("Elements could not be linked.\n");
- gst_object_unref (pipeline);
- return -1;
-}
-```
-
-A pipeline is a particular type of `bin`, which is the element used to
-contain other elements. Therefore all methods which apply to bins also
-apply to pipelines. In our case, we call `gst_bin_add_many()` to add the
-elements to the pipeline (mind the cast). This function accepts a list
-of elements to be added, ending with `NULL`. Individual elements can be
-added with `gst_bin_add()`.
+messaging functions. We create the pipeline with [gst_pipeline_new]\().
+
+{{ C+JS_FALLBACK.md }}
+ {{ tutorials/basic-tutorial-2.c[25:32] }}
+{{ END_LANG.md }}
+
+{{ PY.md }}
+ {{ tutorials/python/basic-tutorial-2.py[30:35] }}
+{{ END_LANG.md }}
+
+A pipeline is a particular type of [bin], which is the element used to
+contain other elements. Therefore all methods which apply to bins also
+apply to pipelines.
+{{ C+JS_FALLBACK.md }}
+ In our case, we call [gst_bin_add_many]\() to add the
+ elements to the pipeline (mind the cast). This function accepts a list
+ of elements to be added, ending with [NULL]. Individual elements can be
+ added with [gst_bin_add]\().
+{{ END_LANG.md }}
+{{ PY.md }}
+ In our case, we call [gst_bin_add]\() to add elements to the pipeline.
+ The function accepts any number of Gst Elements as its arguments
+{{ END_LANG.md }}
These elements, however, are not linked with each other yet. For this,
-we need to use `gst_element_link()`. Its first parameter is the source,
+we need to use [gst_element_link]\(). Its first parameter is the source,
and the second one the destination. The order counts, because links must
be established following the data flow (this is, from source elements to
sink elements). Keep in mind that only elements residing in the same bin
@@ -204,33 +161,66 @@ trying to link them!
### Properties
-``` c
-/* Modify the source's properties */
-g_object_set (source, "pattern", 0, NULL);
-```
+GStreamer elements are all a particular kind of [GObject], which is the
+entity offering **property** facilities.
Most GStreamer elements have customizable properties: named attributes
that can be modified to change the element's behavior (writable
properties) or inquired to find out about the element's internal state
(readable properties).
-Properties are read from with `g_object_get()` and written to
-with `g_object_set()`.
+{{ C+JS_FALLBACK.md }}
+ Properties are read from with [g_object_get]\() and written to
+ with [g_object_set]\().
+
+ [g_object_set]\() accepts a [NULL]-terminated list of property-name,
+ property-value pairs, so multiple properties can be changed in one go.
+
+ This is why the property handling methods have the `g_` prefix.
+{{ END_LANG.md }}
+
+{{ PY.md }}
+ For understanding how to get and set [properties](https://pygobject.readthedocs.io/en/latest/guide/api/properties.html),
+ let us assume we have a Gst Element `source` with a property `pattern`
+
+ The current state of a property can be fetched by either:
+ 1. Accessing the property as an attribute of the `props` attribute of an
+ element. Ex: `_ = source.props.pattern` to print it on the screen
+ 2. Using the `get_property` method of the element.
+ Ex: `_ = source.get_property("pattern")`
-`g_object_set()` accepts a `NULL`-terminated list of property-name,
-property-value pairs, so multiple properties can be changed in one go.
+ And properties can be set by one of three methods:
+ 1. Setting the property as an attribute of the `props` attribute.
+ Ex: `source.props.pattern = 1` or equivalently `source.props.pattern="snow"`
+ 2. Using the `set_property` method of the element.
+ Ex: `source.set_property("pattern", 1)` or equivalently `source.set_property("pattern", "snow")`
+ 3. Using the `Gst.util_set_object_arg()` method. This mode also allows you to
+ pass Gst Caps and other structures. Ex: `Gst.util_set_object_arg(source, "pattern", "snow")`,
+ or equivalently, `Gst.util_set_object_arg(source, "pattern", 1)`
-GStreamer elements are all a particular kind of `GObject`, which is the
-entity offering property facilities. This is why the property handling
-methods have the `g_` prefix.
+ Note: In all three methods of setting a property, if a string is passed as
+ the value to set, it has to be the serialized version of a flag or value
+ (using [gst_value_serialize]\())
+{{ END_LANG.md }}
-The line of code above changes the “pattern” property of `videotestsrc`,
+Coming back to what's in the example above,
+{{ C+JS_FALLBACK.md }}
+ {{ tutorials/basic-tutorial-2.c[33:35] }}
+{{ END_LANG.md }}
+
+{{ PY.md }}
+ {{ tutorials/python/basic-tutorial-2.py[36:40] }}
+{{ END_LANG.md }}
+
+
+The line of code above changes the “pattern” property of [videotestsrc],
which controls the type of test video the element outputs. Try different
values!
The names and possible values of all the properties an element exposes
can be found using the gst-inspect-1.0 tool described in [Basic tutorial 10:
-GStreamer tools](tutorials/basic/gstreamer-tools.md).
+GStreamer tools] or alternatively in the docs for that element
+([here](GstVideoTestSrcPattern) in the case of videotestsrc).
### Error checking
@@ -238,65 +228,41 @@ At this point, we have the whole pipeline built and setup, and the rest
of the tutorial is very similar to the previous one, but we are going to
add more error checking:
-``` c
-/* Start playing */
-ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
-if (ret == GST_STATE_CHANGE_FAILURE) {
- g_printerr ("Unable to set the pipeline to the playing state.\n");
- gst_object_unref (pipeline);
- return -1;
-}
-```
-
-We call `gst_element_set_state()`, but this time we check its return
+{{ C+JS_FALLBACK.md }}
+ {{ tutorials/basic-tutorial-2.c[36:43] }}
+{{ END_LANG.md }}
+
+{{ PY.md }}
+ {{ tutorials/python/basic-tutorial-2.py[41:46] }}
+{{ END_LANG.md }}
+
+We call [gst_element_set_state]\(), but this time we check its return
value for errors. Changing states is a delicate process and a few more
details are given in [Basic tutorial 3: Dynamic
-pipelines](tutorials/basic/dynamic-pipelines.md).
-
-``` c
-/* Wait until error or EOS */
-bus = gst_element_get_bus (pipeline);
-msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_ERROR | GST_MESSAGE_EOS);
-
-/* Parse message */
-if (msg != NULL) {
- GError *err;
- gchar *debug_info;
-
- switch (GST_MESSAGE_TYPE (msg)) {
- case GST_MESSAGE_ERROR:
- gst_message_parse_error (msg, &err, &debug_info);
- g_printerr ("Error received from element %s: %s\n", GST_OBJECT_NAME (msg->src), err->message);
- g_printerr ("Debugging information: %s\n", debug_info ? debug_info : "none");
- g_clear_error (&err);
- g_free (debug_info);
- break;
- case GST_MESSAGE_EOS:
- g_print ("End-Of-Stream reached.\n");
- break;
- default:
- /* We should not reach here because we only asked for ERRORs and EOS */
- g_printerr ("Unexpected message received.\n");
- break;
- }
- gst_message_unref (msg);
-}
-```
-
-`gst_bus_timed_pop_filtered()` waits for execution to end and returns
-with a `GstMessage` which we previously ignored. We
-asked `gst_bus_timed_pop_filtered()` to return when GStreamer
-encountered either an error condition or an `EOS`, so we need to check
+pipelines].
+
+{{ C+JS_FALLBACK.md }}
+ {{ tutorials/basic-tutorial-2.c[44:75] }}
+{{ END_LANG.md }}
+
+{{ PY.md }}
+ {{ tutorials/python/basic-tutorial-2.py[47:62] }}
+{{ END_LANG.md }}
+
+[gst_bus_timed_pop_filtered]\() waits for execution to end and returns
+with a [GstMessage] which we previously ignored. We
+asked [gst_bus_timed_pop_filtered]\() to return when GStreamer
+encountered either an error condition or an [EOS], so we need to check
which one happened, and print a message on screen (Your application will
probably want to undertake more complex actions).
-`GstMessage` is a very versatile structure which can deliver virtually
+[GstMessage] is a very versatile structure which can deliver virtually
any kind of information. Fortunately, GStreamer provides a series of
parsing functions for each kind of message.
In this case, once we know the message contains an error (by using the
-`GST_MESSAGE_TYPE()` macro), we can use
-`gst_message_parse_error()` which returns a GLib `GError` error
+[GST_MESSAGE_TYPE]\() macro), we can use
+[gst_message_parse_error]\() which returns a GLib [GError] error
structure and a string useful for debugging. Examine the code to see how
these are used and freed afterward.
@@ -304,48 +270,48 @@ these are used and freed afterward.
At this point it is worth introducing the GStreamer bus a bit more
formally. It is the object responsible for delivering to the application
-the `GstMessage`s generated by the elements, in order and to the
+the [GstMessage]s generated by the elements, in order and to the
application thread. This last point is important, because the actual
streaming of media is done in another thread than the application.
Messages can be extracted from the bus synchronously with
-`gst_bus_timed_pop_filtered()` and its siblings, or asynchronously,
+[gst_bus_timed_pop_filtered]\() and its siblings, or asynchronously,
using signals (shown in the next tutorial). Your application should
always keep an eye on the bus to be notified of errors and other
playback-related issues.
The rest of the code is the cleanup sequence, which is the same as
in [Basic tutorial 1: Hello
-world!](tutorials/basic/hello-world.md).
+world!].
## Exercise
If you feel like practicing, try this exercise: Add a video filter
element in between the source and the sink of this pipeline. Use
-`vertigotv` for a nice effect. You will need to create it, add it to the
+[vertigotv] for a nice effect. You will need to create it, add it to the
pipeline, and link it with the other elements.
Depending on your platform and available plugins, you might get a
“negotiation” error, because the sink does not understand what the
filter is producing (more about negotiation in [Basic tutorial 6: Media
formats and Pad
-Capabilities](tutorials/basic/media-formats-and-pad-capabilities.md)).
-In this case, try to add an element called `videoconvert` after the
+Capabilities]).
+In this case, try to add an element called [videoconvert] after the
filter (this is, build a pipeline of 4 elements. More on
-`videoconvert` in [Basic tutorial 14: Handy
-elements](tutorials/basic/handy-elements.md)).
+[videoconvert] in [Basic tutorial 14: Handy
+elements]).
## Conclusion
This tutorial showed:
- - How to create elements with `gst_element_factory_make()`
+ - How to create elements with [gst_element_factory_make]\()
- - How to create an empty pipeline with `gst_pipeline_new()`
+ - How to create an empty pipeline with [gst_pipeline_new]\()
- - How to add elements to the pipeline with `gst_bin_add_many()`
+ - How to add elements to the pipeline with [gst_bin_add_many]\()
- - How to link the elements with each other with `gst_element_link()`
+ - How to link the elements with each other with [gst_element_link]\()
This concludes the first of the two tutorials devoted to basic GStreamer
concepts. The second one comes next.
@@ -354,3 +320,38 @@ Remember that attached to this page you should find the complete source
code of the tutorial and any accessory files needed to build it.
It has been a pleasure having you here, and see you soon!
+
+ [Linux]: installing/on-linux.md#InstallingonLinux-Build
+ [Mac OS X]: installing/on-mac-osx.md#InstallingonMacOSX-Build
+ [Windows]: installing/on-windows.md#InstallingonWindows-Build
+ [1]: installing/on-linux.md#InstallingonLinux-Run
+ [2]: installing/on-mac-osx.md#InstallingonMacOSX-Run
+ [3]: installing/on-windows.md#InstallingonWindows-Run
+ [Basic tutorial 14: Handy elements]: tutorials/basic/handy-elements.md
+ [Basic tutorial 10: GStreamer tools]: tutorials/basic/gstreamer-tools.md
+ [Basic tutorial 10: GStreamer tools]: tutorials/basic/gstreamer-tools.md
+ [Basic tutorial 3: Dynamic pipelines]: tutorials/basic/dynamic-pipelines.md
+ [Basic tutorial 1: Hello world!]: tutorials/basic/hello-world.md
+ [Basic tutorial 6: Media formats and Pad Capabilities]: tutorials/basic/media-formats-and-pad-capabilities.md
+ [gst_element_factory_make]: gst_element_factory_make
+ [videotestsrc]: videotestsrc
+ [autovideosink]: autovideosink
+ [bin]: GstBin
+ [NULL]: NULL
+ [gst_bin_add_many]: gst_bin_add_many
+ [gst_bin_add]: gst_bin_add
+ [gst_element_link]: gst_element_link
+ [GObject]: GObject
+ [gst_value_serialize]: gst_value_serialize
+ [g_object_get]: g_object_get
+ [g_object_set]: g_object_set
+ [gst_element_set_state]: gst_element_set_state
+ [gst_bus_timed_pop_filtered]: gst_bus_timed_pop_filtered
+ [GstMessage]: GstMessage
+ [EOS]: GST_MESSAGE_EOS
+ [GST_MESSAGE_TYPE]: GST_MESSAGE_TYPE
+ [gst_message_parse_error]: gst_message_parse_error
+ [GError]: GError
+ [vertigotv]: vertigotv
+ [videoconvert]: videoconvert
+ [gst_pipeline_new]: gst_pipeline_new \ No newline at end of file