caps指pad的capabilities,翻译为该pad支持的规格。每一个组件都有自己可以处理的数据规格,规定了当前元素的功能和支持的参数,比如常见的音视频格式、比特率等。
在元素连接的过程中,相邻的元素需要协商彼此可以衔接的数据格式,以便将对应的数据传给对方。比如解码器支持输出RGB和YUV,显示组件支持YUV,两者协商,决定使用YUV的数据格式。
caps协商主要通过问询和事件机制来实现. caps规格协商分为三类:固定协商、传输协商、动态协商。
1.固定协商
src pad只提供一种规格,下游元素不能请求其它的规格,则其实就直接设定死了,并不需要协商过程。比如typefinder或者filesrc,只是读取二进制数据,不存在更多的格式。

主要流程:
- gst_pad_use_fixed_caps (src_pad),标记规格是固定
- gst_pad_set_caps,设定src_pad的规格,通知到下游节点
/* capsnego */
caps = gst_caps_new_simple ("audio/x-raw", "format", G_TYPE_STRING, GST_MPC_FORMAT, "layout", G_TYPE_STRING, "interleaved",
"channels", G_TYPE_INT, i.channels, "rate", G_TYPE_INT, i.sample_freq, NULL);
gst_pad_use_fixed_caps (musepackdec->srcpad);
if (!gst_pad_set_caps (musepackdec->srcpad, caps)) {
GST_ELEMENT_ERROR (musepackdec, CORE, NEGOTIATION, (NULL), (NULL));
return FALSE;
}
gst_pad_set_caps函数会向对等节点发送GST_EVENT_CAPS消息,下游的对等节点收到之后就会进行对应的传输协商。此时下游节点会在event函数中收到GST_EVENT_CAPS事件,解析到该规格,然后往更下游设定。
2. 传输协商
传输协商是单向地决定某个规格,sink pad上收到上游的GST_EVENT_CAPS,解析caps的内容,然后将其设置到src pad。
上面提到,固定协商中,上游节点使用了gst_pad_set_caps函数来设定了固定的规格,下游的节点sink_pad就会从event GST_EVENT_CAPS收到这个固定的规格,然后将这个规格设定到自己的src pad。

主要流程:
- gst_xxx_sink_event,收到GST_EVENT_CAPS事件
- gst_pad_set_caps,解析并设定caps,将caps通知到下游节点
static gboolean gst_my_filter_setcaps (GstMyFilter *filter, GstCaps *caps)
{
GstStructure *structure;
int rate, channels;
gboolean ret;
GstCaps *outcaps;
structure = gst_caps_get_structure (caps, 0);
ret = gst_structure_get_int (structure, "rate", &rate);
ret = ret && gst_structure_get_int (structure, "channels", &channels);
if (!ret)
return FALSE;
outcaps = gst_caps_new_simple ("audio/x-raw", "format", G_TYPE_STRING, GST_AUDIO_NE(S16)

本文详细阐述了GStreamer中caps规格协商的三种类型:固定协商、传输协商和动态协商,包括如何通过事件和函数实现不同类型的协商过程以及实际操作示例。
最低0.47元/天 解锁文章
1302

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



