參考https://blog.csdn.net/techx/article/details/44134911
簡單的理解,caps negociation 是在兩個element通過pad連接以後,要進行對話,確定媒體格式和相關的屬性。
一、caps negociation
playbin 中的element連接好以後,就要進行caps negociation了,caps negociation 包括兩部分:查詢和事件。
- 查詢(query)
- 事件(event)
1、查詢
查詢是兩個element之間進行對話,具體包括兩個對話:
- GST_QUERY_CAPS
- GST_QUERY_ACCEPT_CAPS
(1)GST_QUERY_CAPS是上游發送給下游的,詢問下游支持哪些caps(封裝格式,相關屬性)。具體的函數如下:
GstCaps * gst_pad_peer_query_caps (GstPad *pad,GstCaps *filter);
第二個參數 filter,當下遊接收到GST_QUERY_CAPS以後,如果參數filter == NULL,就返回它支持的所有caps,否則就按照filter的要求進行過濾,再返回。
下游接收到查詢後具體是在忙處理這個查詢的呢?
gst_pad_set_query_function (demux->sinkpad,GST_DEBUG_FUNCPTR (gst_flv_demux_sink_query));
下游註冊了上面的回調函數,接收到查詢以後就調用gst_ffmpegdemux_src_query函數來處理,比如flvdemux的處理函數如下。
static gboolean
gst_flv_demux_sink_query (GstPad * pad, GstObject * parent, GstQuery * query)
{
GstFlvDemux *demux = GST_FLV_DEMUX (parent);
gboolean res = FALSE;
switch (GST_QUERY_TYPE (query)) {
case GST_QUERY_BITRATE:
{
if (demux->filesize > 0
&& demux->duration > 0 && GST_CLOCK_TIME_IS_VALID (demux->duration)) {
guint bitrate = gst_util_uint64_scale (8 * demux->filesize, GST_SECOND,
demux->duration);
gst_query_set_bitrate (query, bitrate);
res = TRUE;
}
break;
}
default:
res = gst_pad_query_default (pad, (GstObject *) demux, query);
break;
}
return res;
}
(2)GST_QUERY_ACCEPT_CAPS
上面說到下游返回了它支持的caps,接下來上游將遍歷返回的列表,選擇一個最優的caps(fixed caps),並向下游出一個GST_QUERY_ACCEPT_CAPS查詢,用來告訴下游最優的caps。
下游接受到GST_QUERY_ACCEPT_CAPS查詢以後就根據自身情況決定返回值。
2、事件,同樣包括兩個事件
- GST_EVENT_CAPS
- GST_EVENT_RECONFIGURE
(1)GST_EVENT_CAPS,上游選定fixed caps以後就發送該event,告訴下游,各位,我們已經選好caps了,大家做好準備接受上游的buffer吧,當然buffer的格式已經被fixed caps限定好了。
上游發送該事件用的是:
gst_pad_push_event( srcpad, gst_event_new_caps( fixed_caps ))
下游接收事件以後的觸發動作,還是通過在init函數中指定回調函數。
gst_pad_set_event_function (demux->sinkpad,GST_DEBUG_FUNCPTR (gst_flv_demux_sink_event));
總結caps negociation的過程: