做做笔记,仅供参考。
以一个例子来看gstreamer的协商。
例子:gst-launch-1.0.exe videotestsrc ! video/x-raw,width=300,height=300 ! videobox left=-10 top=-100 bottom=-200 right=-300 ! fakesink
最顶上的是videotestsrc插件的gst_base_src_loop线程,这个线程负责采集数据,发送给下游插件。
从堆栈中可以看到,在发送之前,先要调用gst_base_src_negotiate_unlocked进行协商,这个函数会调用基类的缺省函数gst_base_src_default_negotiate。这个函数为了得到videotestsrc的src_caps,会调用peercaps = gst_pad_peer_query_caps (GST_BASE_SRC_PAD (basesrc), thiscaps); 内部会调用gst_pad_peer_query(videotestsrc的src_pad);
在gst_peer_query里会调用 res = gst_pad_query (peerpad, query), 实际调用的是gst_pad_query(casfilter的sink_pad), 这个函数的里调用func (pad, parent, query); 实际的func是gst_base_transform_default_query->gst_base_transform_query_caps, 然后又调用gst_pad_peer_query(casfilter的src_pad),
参考上面的分析,又调到gst_pad_peer_query(videobox的src_pad), 最终调用的是gst_base_sink_sink_query(fakesink的sink);
什么时候执行setcaps?
以gst_base_transform_setcaps为例,
static gboolean
gst_base_transform_sink_eventfunc (GstBaseTransform * trans, GstEvent * event)
{
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_CAPS:
{
GstCaps *caps;
gst_event_parse_caps (event, &caps);
/* clear any pending reconfigure flag */
gst_pad_check_reconfigure (trans->srcpad);
ret = gst_base_transform_setcaps (trans, trans->sinkpad, caps);
if (!ret)
gst_pad_mark_reconfigure (trans->srcpad);
forward = FALSE;
break;
}
}
}
sink的event响应函数会接收到GST_EVENT_CAPS消息,从消息中得到caps,然后调用gst_base_transform_setcaps将caps设置到sinkpad上。gst_base_transform_setcaps会调用gst_base_transform_configure_caps (trans, incaps, outcaps), incaps设要上游传来的caps,outcaps是
/* find best possible caps for the other pad */
outcaps = gst_base_transform_find_transform (trans, pad, incaps);
gst_base_transform_configure_caps会调用子类的set_caps,如下:
/* now configure the element with the caps */
if (klass->set_caps) {
GST_DEBUG_OBJECT (trans, "Calling set_caps method to setup caps");
ret = klass->set_caps (trans, in, out);
}
什么时候执行GST_EVENT_CAPS?
这个消息是gst_pad_set_caps发送,gst_event_new_caps就是创建一个GST_EVENT_CAPS消息。
static inline gboolean gst_pad_set_caps (GstPad * pad, GstCaps * caps)
{。。。。。。
event = gst_event_new_caps (caps);
if (GST_PAD_IS_SRC (pad))
res = gst_pad_push_event (pad, event);
else
res = gst_pad_send_event (pad, event);
return res;
}
未完待续。。。。。。。。