1.指定 Pad
如前所述,pad 是数据进出元素的端口,这使得它们成为元素创建过程中非常重要的一项。在样板代码中,我们看到了静态 pad 模板如何负责向 element 类注册 pad 模板。在这里,我们将看到如何创建实际的元素,如何使用一个 _event ()-function 来配置特定的格式,以及如何注册函数来让数据流过元素。
在 element _init () 函数中,可以从 pad 模板创建 pad,该模板已在 _class_init () 函数的 element 类中注册。创建pad之后,必须设置一个 _chain () 函数指针,该指针将接收和处理 sinkpad 上的输入数据。您还可以选择设置一个 _event () 函数指针和一个 _query () 函数指针。或者,pad 也可以在循环模式下运行,这意味着它们可以自己拉取数据。稍后将详细介绍此主题。在那之后,你必须用元素注册 pad。事情是这样的:
static void
gst_my_filter_init (GstMyFilter *filter)
{
/* pad through which data comes in to the element */
filter->sinkpad = gst_pad_new_from_static_template (
&sink_template, "sink");
/* pads are configured here with gst_pad_set_*_function () */
gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad);
/* pad through which data goes out of the element */
filter->srcpad = gst_pad_new_from_static_template (
&src_template, "src");
/* pads are configured here with gst_pad_set_*_function () */
gst_element_add_pad (GST_ELEMENT (filter), filter->srcpad);
/* properties initial value */
filter->silent = FALSE;
}
2. 链函数
所有数据都要借助于链式函数来处理。对于简单过滤器,_chain () 函数大多是线性函数,因此每进来一个缓冲区,则要送出去一个缓冲区。下面是一个非常简单的链式功能实现:
static GstFlowReturn gst_my_filter_chain (GstPad *pad,
GstObject *parent,
GstBuffer *buf);
[..]
static void
gst_my_filter_init (GstMyFilter * filter)
{
[..]
/* configure chain function on the pad before adding
* the pad to the element */
gst_pad_set_chain_function (filter->sinkpad,
gst_my_filter_chain);
[..]
}
static GstFlowReturn
gst_my_filter_chain (GstPad *pad,
GstObject *parent,
GstBuffer *buf)
{
GstMyFilter *filter = GST_MY_FILTER (parent);
if (!filter->silent)
g_print ("Have data of size %" G_GSIZE_FORMAT" bytes!\n",
gst_buffer_get_size (buf));
return gst_pad_push (filter->srcpad, buf);
}
显然,上面的函数没有什么使用价值。你通常会在那里处理数据,而不是打印进来的数据。但是,请记住,缓冲区并不总是可写的。
在更高级的元素(进行事件处理的元素)中,您可能需要另外指定一个事件处理函数,在发送流事件(如caps、流结束、newsegment、标记等)时将调用该函数。
static void
gst_my_filter_init (GstMyFilter * filter)
{
[..]
gst_pad_set_event_function (filter->sinkpad,
gst_my_filter_sink_event);
[..]
}
static gboolean
gst_my_filter_sink_event (GstPad *pad,
GstObject *parent,
GstEvent *event)
{
GstMyFilter *filter = GST_MY_FILTER (parent);
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_CAPS:
/* we should handle the format here */
break;
case GST_EVENT_EOS:
/* end-of-stream, we should close down all stream leftovers here */
gst_my_filter_stop_processing (filter);
break;
default:
break;
}
return gst_pad_event_default (pad, parent, event);
}
static GstFlowReturn
gst_my_filter_chain (GstPad *pad,
GstObject *parent,
GstBuffer *buf)
{
GstMyFilter *filter = GST_MY_FILTER (parent);
GstBuffer *outbuf;
outbuf = gst_my_filter_process_data (filter, buf);
gst_buffer_unref (buf);
if (!outbuf) {
/* something went wrong - signal an error */
GST_ELEMENT_ERROR (GST_ELEMENT (filter), STREAM, FAILED, (NULL

最低0.47元/天 解锁文章
2222

被折叠的 条评论
为什么被折叠?



