Building an Application
创建应用程序
PS:这部分讲述的是底层的API,当你创建应用程序的时候,你可能使用的是高层的API。
#include <gst/gst.h> int main (int argc, char *argv[]) { const gchar *nano_str; guint major, minor, micro, nano; gst_init (&argc, &argv); gst_version (&major, &minor, µ, &nano); if (nano == 1) nano_str = "(CVS)"; else if (nano == 2) nano_str = "(Prerelease)"; else nano_str = ""; printf ("This program is linked against GStreamer %d.%d.%d %s\n", major, minor, micro, nano_str); return 0; }
|
这只是一个获得gstreamer的版本号并打印的简单程序,你所要从中知道的是:
gst_init
Initializes the GStreamer library, setting up internal path lists, registering built-in elements, and loading standard plugins.
This function should be called before calling any other GLib functions.
PS:
gstreamer是基于Glib的,所以当有些函数不在reference manual中的时候,应该在Glib的文档寻找。
例如以下的例子,是基于Glib的命令行参数解析(Glib可以认为是Linux编程的实用库,不要事事亲力亲为,要看看有没有大家都在用的东西。还有好多东西要学啊!头脑却很僵化!)
#include <gst/gst.h> int main (int argc, char *argv[]) { gboolean silent = FALSE; gchar *savefile = NULL; GOptionContext *ctx; GError *err = NULL; GOptionEntry entries[] = { { "silent", ’s’, 0, G_OPTION_ARG_NONE, &silent, "do not output status information", NULL }, { "output", ’o’, 0, G_OPTION_ARG_STRING, &savefile, "save xml representation of pipeline to FILE and exit", "FILE" }, { NULL } }; /* we must initialise the threading system before using any * other GLib funtion, such as g_option_context_new() */ if (!g_thread_supported ()) g_thread_init (NULL); ctx = g_option_context_new ("- Your application"); g_option_context_add_main_entries (ctx, entries, NULL); g_option_context_add_group (ctx, gst_init_get_option_group ()); if (!g_option_context_parse (ctx, &argc, &argv, &err)) { g_print ("Failed to initialize: %s\n", err->message); g_error_free (err); return 1; } printf ("Run me with --help to see the Application options appended.\n"); return 0; } 10
|
暂时跳过这个例子。
Elements
The most important object in GStreamer for the application programmer is the GstElement (../../gstreamer/html/GstElement.html) object. An element is the basic building block for a media pipeline. All the different high-level components you will use are derived from GstElement. Every decoder, encoder, demuxer, video or audio output is in fact a GstElement。
GstElements大体上分为三类:
source element 源元素
Filter-like elements 类过滤器元素
指的是对数据流进行一定操作的功能元素,例如muxer,demuxer,encodec, decodec, filter(例如音量过滤器?), convetor(例如video scaler,比例变换)等。
sink elememnts 接收器元素
Creating a GstElement
The simplest way to create an element is to use gst_element_factory_make ()
(
factory-make). This function takes a factory name and an element name for the newly created
element. The name of the element is something you can use later on to look up the element in a bin, for
example. The name will also be used in debug output. You can pass NULL as the name argument to get a
unique, default name.
When you don’t need the element anymore, you need to unref it using gst_object_unref ()
().
This decreases the reference count for the element by 1. An element has a refcount of 1 when it
gets created. An element gets destroyed completely when the refcount is decreased to 0.
创建一个元素最简单的方法就是使用gst_element_factory_make (),就好像让一个工厂为你生产一样。
像liunx的文件管理机制一样,使用引用计数来决定对象的销毁。注意到,对gst_object_unref ()
Decrements the reference count on object
. If reference count hits zero, destroy object
. This function does not take the lock on object
as it relies on atomic refcounting.
The unref method should never be called with the LOCK held since this might deadlock the dispose function.
锁机制会在某些地方用在element上,但是这个函数保证了操作是原子的,你不应该为它加锁。
获得一个fakesrc工厂生产的名为“source"的元素:
#include <gst/gst.h> int main (int argc, char *argv[]) { GstElement *element; /* init GStreamer */ gst_init (&argc, &argv); /* create element */ element = gst_element_factory_make ("fakesrc", "source"); if (!element) { g_print ("Failed to create element of type ’fakesrc’\n"); return -1; } gst_object_unref (GST_OBJECT (element)); return
|
gst_element_factory_make是两个函数结合:
#include <gst/gst.h> GstElement *src; GstElementFactory *srcfactory; gst_init(&argc,&argv); srcfactory = gst_element_factory_find("filesrc"); g_return_if_fail(srcfactory != NULL); src = gst_element_factory_create(srcfactory,"src"); g_return_if_fail(src != NULL); ...
|
注意到使用g_return_if_fail(assertion)可以避免繁杂的测试-返回。
前面还有使用g_print代替printf,anyway,使用它们。
这些,事实上,都是Glib的东西。well,简单讲标准C库封装了一下,减少了一定的冗余度。
继承树(明明是C,还是把很多对象的东西搞进来,未免有些:自我陶醉了吧?Glib的家伙们!话说回来,到底怎么做的?
好像是进行struct的类型强制转换。)
GObject +----GstObject +----GstElement +----GstBin
|
所以你对GstElement可以进行和GObject相关的properties的操作以及Glib的信号操作。
对于Gstreamer的继承体系,有很多疑惑的地方。
GObject GstObject GstPad GstProxyPad GstGhostPad GstPadTemplate GstPluginFeature GstElementFactory GstTypeFindFactory GstIndexFactory GstElement GstBin GstPipeline GstBus GstTask GstClock GstSystemClock GstPlugin GstRegistry GstIndex GstXML GInterface GstChildProxy GstURIHandler GstImplementsInterface GstPreset GstTagSetter
|
GstElementFactory是一种GstPluginFeature,而GstPluginFeature是可以添加到GstPlugin的。
GstElementFactory提供了制造和查询一个Element的接口。例如你可以确定哪些pads是这个element兼容的。
Linking elements
By linking a source element with zero or more filter-like elements and finally a sink element, you set up a
media pipeline. Data will flow through the elements. This is the basic concept of media handling in
GStreamer.
#include <gst/gst.h> int main (int argc, char *argv[]) { GstElement *pipeline; GstElement *source, *filter, *sink; /* init */ gst_init (&argc, &argv); /* create pipeline */ pipeline = gst_pipeline_new ("my-pipeline"); /* create elements */ source = gst_element_factory_make ("fakesrc", "source"); filter = gst_element_factory_make ("identity", "filter"); sink = gst_element_factory_make ("fakesink", "sink"); /* must add elements to pipeline before linking them */ gst_bin_add_many (GST_BIN (pipeline), source, filter, sink, NULL); /* link */ if (!gst_element_link_many (source, filter, sink, NULL)) { g_warning ("Failed to link elements!"); } [..] }
|
Important: you must add elements to a bin or pipeline before linking them, since adding an element to a bin will disconnect any already existing links. Also, you cannot directly link elements that are not in the same bin or pipeline; if you want to link elements or pads at different hierarchy levels, you will need to use ghost pads (more about ghost pads later).
在连接之前,你必须把元素放在容器(流水线)中,这样前面的连接可以自动被断开。
如果你想要连接处于不同继承水平的元素,可以使用ghost pads。
(了解一个很好用的库是好事情,但是事实上,最重要的还是:性格——程序员该有的性格!此外才是基本的知识——如数据结构,C等,然后再其次是Linux的IPC,库调用等。而某一个库事实上是其次的东西,但是有可能是紧急的东西,因为得马上派上用场。)
Element States
一个元素有四种状态:
1.NULL
2.READY
3.PAUSED
4.PLAYING
你可以使用gst_element_set_state () 来设置元素的状态,如果从NULL直接到PLAYING,gstreamer也会自动经历中间的状态。
Bins
A bin is a container element. You can add elements to a bin. Since a bin is an element itself, a bin can be handled in the same way as any other element. Therefore, the whole previous chapter (Elements) applies to bins as well.
#include <gst/gst.h> int main (int argc, char *argv[]) { GstElement *bin, *pipeline, *source, *sink; /* init */ gst_init (&argc, &argv); /* create */ pipeline = gst_pipeline_new ("my_pipeline"); bin = gst_bin_new ("my_bin"); source = gst_element_factory_make ("fakesrc", "source"); sink = gst_element_factory_make ("fakesink", "sink"); /* First add the elements to the bin */ gst_bin_add_many (GST_BIN (bin), source, sink, NULL); /* add the bin to the pipeline */ gst_bin_add (GST_BIN (pipeline), bin); /* link the elements */ gst_element_link (source, sink); [..] }
|
你可以按照element方式来创建bin和pipeline(使用工厂),也可以使用gst_bin_new () and gst_pipeline_new () .从容器中增加和删除一个元素:gst_bin_add () and gst_bin_remove(). pipeline是最高层的bin,因此你可以把bin放进pipeline中。
Custom bins
The application programmer can create custom bins packed with elements to perform a specific task.
应用程序程序员可以定制容器以完成某项任务。
int main (int argc, char *argv[]) { GstElement *player; /* init */ gst_init (&argc, &argv); /* create player */ player = gst_element_factory_make ("oggvorbisplayer", "player"); /* set the source audio file */ g_object_set (player, "location", "helloworld.ogg", NULL); /* start playback */ gst_element_set_state (GST_ELEMENT (player), GST_STATE_PLAYING); [..] }
|
使用上面几行代码就可以完成一个Ogg/Vorbis格式的解码器。
Custom bins can be created with a plugin or an XML description. You will find more information about
creating custom bin in the Plugin Writers Guide
().
Examples of such custom bins are the playbin and decodebin elements from gst-plugins-base
().
定制容器可以使用插件或者XML描述。你可以在base plugins中找到播放和解码元素作为定制容器的示例。
Bus
总线
A bus is a simple system that takes care of forwarding messages from the pipeline threads to an application in its own thread context. The advantage of a bus is that an application does not need to be
thread-aware in order to use GStreamer, even though GStreamer itself is heavily threaded. Every pipeline contains a bus by default, so applications do not need to create a bus or anything. The only thing applications should do is set a message handler on a bus, which is similar to a signal handler to an object.When the mainloop is running, the bus will periodically be checked for new messages, and
the callback will be called when any message is available.
总线是处理流水线向应用程序传递的消息的机制,消息会被应用程序自己的线程上下文处理。这样,你就不需要太过考虑线程方面的问题,尽管gstreamer是“严重”多线程的。
每一条流水线都有默认的总线,你不需要自己创建它。你需要为总线安装消息处理函数。当循环运行的时候,总线会周期捕捉消息,然后回调函数会处理任何可达消息。
有两种方法可以使用总线:
1.Run a GLib/Gtk+ main loop (or iterate the default GLib main context yourself regularly) and attach some kind of watch to the bus. This way the GLib main loop will check the bus for new messages and notify you whenever there are messages. Typically you would use gst_bus_add_watch () or gst_bus_add_signal_watch () in this case.
To use a bus, attach a message handler to the bus of a pipeline using gst_bus_add_watch (). This handler will be called whenever the pipeline emits a message to the bus. In this handler, check the signal type (see next section) and do something accordingly. The return value of the handler should be TRUE to remove the message from the bus.
结合实例讲解这一段:
#include <gst/gst.h> static GMainLoop *loop;
/*处理消息的回调函数*/ static gboolean my_bus_callback (GstBus *bus, GstMessage *message, gpointer data) {
/*根据消息类型进行处理*/ g_print ("Got %s message\n", GST_MESSAGE_TYPE_NAME (message)); switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_ERROR: { GError *err; gchar *debug; gst_message_parse_error (message, &err, &debug); g_print ("Error: %s\n", err->message); g_error_free (err); g_free (debug); g_main_loop_quit (loop); break; } case GST_MESSAGE_EOS: /* end-of-stream */ g_main_loop_quit (loop); break; default: /* unhandled message */ break; } /* we want to be notified again the next time there is a message * on the bus, so returning TRUE (FALSE means we want to stop watching * for messages on the bus and our callback should not be called again) */ return TRUE; }
/*主函数*/ gint main (gint argc, gchar *argv[]) { GstElement *pipeline; GstBus *bus; /* init */ gst_init (&argc, &argv); /* create pipeline, add handler */ pipeline = gst_pipeline_new ("my_pipeline"); /* adds a watch for new message on our pipeline’s message bus to * the default GLib main context, which is the main context that our * GLib main loop is attached to below */
/*得到流水线的总线的句柄*/ bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); /*为总线添加检测函数*/
gst_bus_add_watch (bus, my_bus_callback, NULL); /*操作结束,释放应用程序引起的引用计数*/
gst_object_unref (bus); [..] /* create a mainloop that runs/iterates the default GLib main context * (context NULL), in other words: makes the context check if anything * it watches for has happened. When a message has been posted on the * bus, the default main context will automatically call our * my_bus_callback() function to notify us of that message. * The main loop will be run until someone calls g_main_loop_quit() */
/*创建Glib的主循环实例*/ loop = g_main_loop_new (NULL, FALSE);
/*运行主循环实例*/ g_main_loop_run (loop);
/*通过g_main_loop_quit()退出了主循环, 接着需要清理*/ /* clean up */ gst_element_set_state (pipeline, GST_STATE_NULL); gst_object_unref (pipeline); g_main_loop_unref (loop); return 0; }
|
2 Check for messages on the bus yourself. This can be done using gst_bus_peek () and/or gst_bus_poll ().
Message types
• Error, warning and information notifications: those are used by elements if a message should be shown
to the user about the state of the pipeline. Error messages are fatal and terminate the data-passing. The
error should be repaired to resume pipeline activity. Warnings are not fatal, but imply a problem
nevertheless. Information messages are for non-problem notifications. All those messages contain a
GError with the main error type and message, and optionally a debug string. Both can be extracted
using gst_message_parse_error (), _parse_warning () and _parse_info (). Both error
and debug string should be free’ed after use.
• End-of-stream notification: this is emitted when the stream has ended. The state of the pipeline will
not change, but further media handling will stall. Applications can use this to skip to the next song in
their playlist. After end-of-stream, it is also possible to seek back in the stream. Playback will then
continue automatically. This message has no specific arguments.
• Tags: emitted when metadata was found in the stream. This can be emitted multiple times for a
pipeline (e.g. once for descriptive metadata such as artist name or song title, and another one for
stream-information, such as samplerate and bitrate). Applications should cache metadata internally.
gst_message_parse_tag () should be used to parse the taglist, which should be
gst_tag_list_free ()’ed when no longer needed.
• State-changes: emitted after a successful state change. gst_message_parse_state_changed ()
can be used to parse the old and new state of this transition.
• Buffering: emitted during caching of network-streams. One can manually extract the progress (in
percent) from the message by extracting the “buffer-percent” property from the structure returned by
gst_message_get_structure ().
• Element messages: these are special messages that are unique to certain elements and usually represent
additional features. The element’s documentation should mention in detail which element messages a
particular element may send. As an example, the ’qtdemux’ QuickTime demuxer element may send a
’redirect’ element message on certain occasions if the stream contains a redirect instruction.
• Application-specific messages: any information on those can be extracted by getting the message
structure (see above) and reading its fields. Usually these messages can safely be ignored.
Application messages are primarily meant for internal use in applications in case the application needs
to marshal information from some thread into the main thread. This is particularly useful when the
application is making use of element signals (as those signals will be emitted in the context of the
streaming thread).
Pads
A pad type is defined by two properties: its direction and its availability. As we’ve mentioned before, GStreamer defines two pad directions: source pads and sink pads. A pad can have any of three availabilities: always, sometimes and on request.
Dynamic (or sometimes) pads
Some elements might not have all of their pads when the element is created. This can happen, for
example, with an Ogg demuxer element. The element will read the Ogg stream and create dynamic pads
for each contained elementary stream (vorbis, theora) when it detects such a stream in the Ogg stream.
Likewise, it will delete the pad when the stream ends. This principle is very useful for demuxer elements,
for example.
Request pads
An element can also have request pads. These pads are not created automatically but are only created on
demand. This is very useful for multiplexers, aggregators and tee elements. Aggregators are elements
that merge the content of several input streams together into one output stream. Tee elements are the
reverse: they are elements that have one input stream and copy this stream to each of their output pads,
which are created on request. Whenever an application needs another copy of the stream, it can simply
request a new output pad from the tee element.
关于焊盘,它是由对象GstPad定义的。但是作为元素的接口来说,还没找到创建焊盘然后附属到元素的例子。
动态焊盘(Dynamic)是由元素,例如demux自动生成的。
预定焊盘(Requested)是元素根据请求生成的。
焊盘模板也不是独立的概念,它是属于元素的,元素能够生成的焊盘类型由它的焊盘模板决定。
The gst_element_get_request_pad () method can be used to get a pad from the element based on
the name of the pad template. It is also possible to request a pad that is compatible with another pad
template. This is very useful if you want to link an element to a multiplexer element and you need to
request a pad that is compatible. The method gst_element_get_compatible_pad () can be used to
request a compatible pad, as shown in the next example. It will request a compatible pad from an Ogg
multiplexer from any input.
你可以要求生成某种类型的焊盘,这时你需要指定元素和焊盘模板类型,例如:
pad = gst_element_get_request_pad (tee, "src%d");
|
你也可以要求生成和其他焊盘兼容的焊盘:
static void link_to_multiplexer (GstPad *tolink_pad, GstElement *mux) { GstPad *pad; gchar *srcname, *sinkname; srcname = gst_pad_get_name (tolink_pad); pad = gst_element_get_compatible_pad (mux, tolink_pad); gst_pad_link (tolinkpad, pad); sinkname = gst_pad_get_name (pad); gst_object_unref (GST_OBJECT (pad)); g_print ("A new pad %s was created and linked to %s\n", srcname, sinkname); g_free (sinkname); g_free (srcname); }
|
正如:
pad = gst_element_get_compatible_pad (mux, tolink_pad);
|
你指定的是你要兼容的类型。
Capabilities of a pad
Capabilities are attached to pad templates and to pads. For pad templates, it will describe the types of media that may stream over a pad created from this template. For pads, it can either be a list of possible caps (usually a copy of the pad template’s capabilities), in which case the pad is not yet negotiated, or it is
the type of media that currently streams over this pad, in which case the pad has been negotiated already.
焊盘的接受力
接受力是焊盘模板或者焊盘的属性。对于焊盘模板来说,它描述了从中衍生的焊盘能通过的媒体类型。对于焊盘来说,它或者是从焊盘模板所衍生的可能的一系列兼容类型(如果是未协商的),或者是正在通过的媒体类型(如果是已协商的)。
A pads capabilities are described in a GstCaps object. Internally, a GstCaps
(../../gstreamer/html/gstreamer-GstCaps.html) will contain one or more GstStructure
(../../gstreamer/html/gstreamer-GstStructure.html) that will describe one media type. A negotiated pad
will have capabilities set that contain exactly one structure. Also, this structure will contain only fixed
values. These constraints are not true for unnegotiated pads or pad templates.
模板的接受力又GstCaps对象定义,它包含了一个或多个GstStructure,每一个都描述了一种媒体类型。
而协商了的焊盘,它们的接受力被定义为一个GstStructure,而且它的值是固定的。例如,对于音频数据流而言,如果之前这个GstStructure可以有1声道或者2声道,经过协商,它就会被定义为1声道(或则2声道)。也就是说,流的格式的参数被协商而确定下来。
As an example, below is a dump of the capabilities of the “vorbisdec” element, which you will get by
running gst-inspect vorbisdec. You will see two pads: a source and a sink pad. Both of these pads are
always available, and both have capabilities attached to them. The sink pad will accept vorbis-encoded
audio data, with the mime-type “audio/x-vorbis”. The source pad will be used to send raw (decoded)
audio samples to the next element, with a raw audio mime-type (in this case, “audio/x-raw-int”) The
source pad will also contain properties for the audio samplerate and the amount of channels, plus some
more that you don’t need to worry about for now.
下面给出了焊盘模板的定义。如果你从这个元素要求生成src的焊盘,那么它就会根据SRC模板生成相应的焊盘。就好像,套色拼隔板?
Pad Templates: SRC template: ’src’ Availability: Always Capabilities: audio/x-raw-float rate: [ 8000, 50000 ] channels: [ 1, 2 ] endianness: 1234 width: 32 buffer-frames: 0 SINK template: ’sink’ Availability: Always Capabilities: audio/x-vorbis
|
Properties and values
Properties are used to describe extra information for capabilities. A property consists of a key (a string)
and a value. There are different possible value types that can be used:
• Basic types, this can be pretty much any GType registered with Glib. Those properties indicate a
specific, non-dynamic value for this property. Examples include:
• An integer value (G_TYPE_INT): the property has this exact value.
• A boolean value (G_TYPE_BOOLEAN): the property is either TRUE or FALSE.
• A float value (G_TYPE_FLOAT): the property has this exact floating point value.
• A string value (G_TYPE_STRING): the property contains a UTF-8 string.
• A fraction value (GST_TYPE_FRACTION): contains a fraction expressed by an integer numerator
and denominator.
• Range types are GTypes registered by GStreamer to indicate a range of possible values. They are used
for indicating allowed audio samplerate values or supported video sizes. The two types defined in
GStreamer are:
• An integer range value (GST_TYPE_INT_RANGE): the property denotes a range of possible integers,
with a lower and an upper boundary. The “vorbisdec” element, for example, has a rate property that
can be between 8000 and 50000.
• A float range value (GST_TYPE_FLOAT_RANGE): the property denotes a range of possible floating
point values, with a lower and an upper boundary.
• A fraction range value (GST_TYPE_FRACTION_RANGE): the property denotes a range of possible
fraction values, with a lower and an upper boundary.
• A list value (GST_TYPE_LIST): the property can take any value from a list of basic values given in
this list.
Example: caps that express that either a sample rate of 44100 Hz and a sample rate of 48000 Hz is
supported would use a list of integer values, with one value being 44100 and one value being 48000.
• An array value (GST_TYPE_ARRAY): the property is an array of values. Each value in the array is a full
value on its own, too. All values in the array should be of the same elementary type. This means that
an array can contain any combination of integers, lists of integers, integer ranges together, and the
same for floats or strings, but it can not contain both floats and ints at the same time.
Example: for audio where there are more than two channels involved the channel layout needs to be
specified (for one and two channel audio the channel layout is implicit unless stated otherwise in the
caps). So the channel layout would be an array of integer enum values where each enum value
represents a loudspeaker position. Unlike a GST_TYPE_LIST, the values in an array will be interpreted
as a whole.
参数是接受力的详细信息,例如接收力是音频流,那么就会有声道数这个参数,指明可以接受的声道的数目。
而参数有很多种数据类型,它的值和数据类型相关,例如数据类型是list,那么它的值就是list中的一个;如果是interger,那么值就是一个整数。
What capabilities are used for
Capabilities (short: caps) describe the type of data that is streamed between two pads, or that one pad
(template) supports. This makes them very useful for various purposes:
• Autoplugging: automatically finding elements to link to a pad based on its capabilities. All
autopluggers use this method.
• Compatibility detection: when two pads are linked, GStreamer can verify if the two pads are talking
about the same media type. The process of linking two pads and checking if they are compatible is
called “caps negotiation”.
• Metadata: by reading the capabilities from a pad, applications can provide information about the type
of media that is being streamed over the pad, which is information about the stream that is currently
being played back.
• Filtering: an application can use capabilities to limit the possible media types that can stream between
two pads to a specific subset of their supported stream types. An application can, for example, use
“filtered caps” to set a specific (fixed or non-fixed) video size that should stream between two pads.
You will see an example of filtered caps later in this manual, in Section 18.2. You can do caps filtering
by inserting a capsfilter element into your pipeline and setting its “caps” property. Caps filters are often
placed after converter elements like audioconvert, audioresample, ffmpegcolorspace or videoscale to
force those converters to convert data to a specific output format at a certain point in a stream.
caps有几种用途:
1.自动插件
2. 兼容性检查,The process of linking two pads and checking if they are compatible is
called “caps negotiation”.
连接两个pads,并且进行兼容性检查的过程叫做协商。
3.元数据,媒体流的信息
4.过滤器
Using capabilities for metadata
A pad can have a set (i.e. one or more) of capabilities attached to it. Capabilities (GstCaps) are
represented as an array of one or more GstStructures, and each GstStructure is an array of fields
where each field consists of a field name string (e.g. "width") and a typed value (e.g. G_TYPE_INT or
GST_TYPE_INT_RANGE).
前面提到过一个pad的兼容性是由一组GstStructures定义的,而一个GstStructure是由一组域定义的。每个域都有key string和一个特定数据类型的值。
Creating capabilities for filtering
While capabilities are mainly used inside a plugin to describe the media type of the pads, the application
programmer often also has to have basic understanding of capabilities in order to interface with the
plugins, especially when using filtered caps. When you’re using filtered caps or fixation, you’re limiting
the allowed types of media that can stream between two pads to a subset of their supported media types.
You do this using a capsfilter element in your pipeline. In order to do this, you also need to create
your own GstCaps.
通过过滤器,你可以规定两个元素之间允许通过的数据。
static gboolean link_elements_with_filter (GstElement *element1, GstElement *element2) { gboolean link_ok; GstCaps *caps; caps = gst_caps_new_simple ("video/x-raw-yuv", "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC (’I’, ’4’, ’2’, ’0’), "width", G_TYPE_INT, 384, "height", G_TYPE_INT, 288, "framerate", GST_TYPE_FRACTION, 25, 1, NULL); link_ok = gst_element_link_filtered (element1, element2, caps); gst_caps_unref (caps); if (!link_ok) { g_warning ("Failed to link element1 and element2!"); } return link_ok; }
|
This will force the data flow between those two elements to a certain video format, width, height and
framerate (or the linking will fail if that cannot be achieved in the context of the elments involved). Keep
in mind that when you use gst_element_link_filtered () it will automatically create a
capsfilter element for you and insert it into your bin or pipeline between the two elements you want
to connect (this is important if you ever want to disconnect those elements because then you will have to
disconnect both elements from the capsfilter instead).
注意,这样会在两个元素之间插入一个capsfilter,当你需要断开两个元素的连接的时候,你需要把它们从这个过滤器元素上断开。
Ghost pads
bin没有自己的pad,为了统一的把它当作一个元素使用,Ghost pads被使用,就像UNIX的符号链接。
A ghostpad is created using the function gst_ghost_pad_new ():
#include <gst/gst.h> int main (int argc, char *argv[]) { GstElement *bin, *sink; GstPad *pad; /* init */ gst_init (&argc, &argv); /* create element, add to bin */ sink = gst_element_factory_make ("fakesink", "sink"); bin = gst_bin_new ("mybin"); gst_bin_add (GST_BIN (bin), sink); /* add ghostpad */ pad = gst_element_get_static_pad (sink, "sink"); gst_element_add_pad (bin, gst_ghost_pad_new ("sink", pad)); gst_object_unref (GST_OBJECT (pad)); [..] }
|