一般情況下,使用者打開一個多媒體檔案,gstreamer首先需要知道檔案的類型,然後建立相應的解碼器來解析這個檔案,最終實作播放這個檔案。
一個實作流程執行個體如下:
(1) app程式通知gstreamer會根據uri、檔案路徑,建立相應類型的src元件,一般為filesrc元件(element))
(2) 接着根據插件名建立type_find元件
(3) 将filesrc element與typefind element連接配接link起來,添加到一個gstbin(pipeline)中
(4) 當app使用者打開檔案後,接着通知 gstreamer去切換狀态。
case GST_STATE_CHANGE_READY_TO_PAUSED:
if (!gst_element_pads_activate (element, TRUE)) {
result = GST_STATE_CHANGE_FAILURE;
}
注意:When changing states, a bin will set the state on all of its children in
sink-to-source order.說明,狀态切換先發生在typefind元件上。
(5)gst_element_pads_activate (element, TRUE)函數裡接着調用 iter = gst_element_iterate_src_pads (element);
res =
iterator_activate_fold_with_resync (iter,
(GstIteratorFoldFunction) activate_pads, &active);
接着
(6)接着activate_pads函數調用gst_pad_set_active,接着調用(GST_PAD_ACTIVATEFUNC (pad)) (pad)(該宏由gsttypefindelement在執行個體初始化時
gst_pad_set_activate_function (typefind->sink,
GST_DEBUG_FUNCPTR (gst_type_find_element_activate)); 即GST_PAD_ACTIVATEFUNC (pad) = gst_type_find_element_activate)是以實際是調用gst_type_find_element_activate()函數,
(7)在static gboolean gst_type_find_element_activate (GstPad * pad)函數裡:
if (!gst_pad_check_pull_range (pad) || !gst_pad_activate_pull (pad, TRUE)) {
start_typefinding (typefind);
return gst_pad_activate_push (pad, TRUE);
}
typefind會先activate在pull mode,最後調用XX_XX_get_range函數
即:gst_pad_check_pull_range 會調用pad上的函數指針,最終會調用到basesrc的check_get_range虛函數。即:
先調用gst_base_src_pad_check_get_range----》
接着調用gst_base_src_check_get_range----》
( bclass->check_get_range ) 這裡調用::gst_base_src_default_check_get_range----》
然後調用gst_base_src_start--》
( bclass = GST_BASE_SRC_GET_CLASS (basesrc);
if (bclass->start)
result = bclass->start (basesrc);
else
result = TRUE; )
在filesrc元件裡,對start函數進行了覆寫,即調用gst_file_src_start。
(8)Filesrc最終會調用open函數打開檔案。接着src元件狀态也發生切換,建立一個task,最後把檔案資訊推送給typefind;
(9) typefind會從src讀取一部分資料然後送出typefind_callback,在callback裡面建立合适的plugin.
未完待續,會接着補充。
Smith先生版權所有,
如需轉載,請注明出處:本部落格連結http://blog.csdn.net/acs713/article/details/7742976