控制filesink錄製

在做的一個項目需要顯示錄製同時進行,且在需要的時候停止錄製,但是顯示不得中斷。參考鏈接中有國外的解決方案,但是其中有些方法在gstreamer-1.0中並沒有。經過幾天的修改,最終實現,部分代碼如下:

攔截eos消息的代碼:

gboolean drop_eos_probe(GstPad* pad, GstPadProbeInfo *info, gpointer data){
   gboolean ret = TRUE;
   static int called = 0;
   GstEvent * event = gst_pad_probe_info_get_event(info);
   switch(GST_EVENT_TYPE(event)){
       case GST_EVENT_EOS:
           called++;
           if(called == 1){
               g_print("removing recording bin!\n");
               GstElement *rec_bin = gst_bin_get_by_name(GST_BIN(gst_app.pipeline), "myfilebin");
               GstElement *tee = gst_bin_get_by_name(GST_BIN(gst_app.pipeline), "mytee");
               GstElement *fqueue = gst_bin_get_by_name(GST_BIN(gst_app.pipeline), "myfilequeue");
               GstPad    *srcpad = gst_element_get_static_pad(tee, "src_1");
               GstPad    *sinkpad = gst_element_get_static_pad(fqueue, "sink");
 
               //gst_pad_set_blocked(srcpad, TRUE);
               GST_OBJECT_FLAG_SET(srcpad, GST_PAD_FLAG_BLOCKED);
               gst_pad_unlink(srcpad, sinkpad);
               gst_element_remove_pad(tee, srcpad);
               gst_bin_remove(GST_BIN(gst_app.pipeline), rec_bin);
 
               //gst_pad_set_blocked(srcpad, FALSE);
               GST_OBJECT_FLAG_UNSET(srcpad, GST_PAD_FLAG_BLOCKED);
 
               gst_element_set_state(GST_ELEMENT(rec_bin), GST_STATE_NULL);
               ret = FALSE;
 
           }else{
               g_print("caught %d Not Dropping!\n", called);
           }
       break;
   }
   g_print("event : %d\n", GST_EVENT_TYPE(event));
   return ret;
}

 需要注意的是:

1、函數參數定義不一樣,1.0的版本需要改成如下的函數:

gboolean drop_eos_probe(GstPad* pad, GstPadProbeInfo *info, gpointer data)

2、gst_pad_set_blocked方法在1.0版本中已經沒有,我查詢百度也沒有發現有此方法。因此需要使用另外的方法代替:

               //gst_pad_set_blocked(srcpad, TRUE);
               GST_OBJECT_FLAG_SET(srcpad, GST_PAD_FLAG_BLOCKED);

3、src和sink必須使用gst_element_link方法鏈接的pad,也就是這兩個對象要注意別弄錯:

               GstPad    *srcpad = gst_element_get_static_pad(tee, "src_1");
               GstPad    *sinkpad = gst_element_get_static_pad(fqueue, "sink");

4、設置GST_STATE_NULL狀態的對象必須是定義的一個完整的分支鏈接:

gst_element_set_state(GST_ELEMENT(rec_bin), GST_STATE_NULL);

5、probe的事件add方法不一樣:

gst_pad_add_probe(gst_element_get_static_pad(app->fileencoder, "src"), GST_PAD_PROBE_TYPE_EVENT_BOTH, G_CALLBACK(drop_eos_probe), app->pipeline, NULL);

目前使用此方法會有警告信息,測試過程中有一次視頻卡住。其他都正常。後續會改進。 

參考鏈接:http://gstreamer-devel.966125.n4.nabble.com/Handling-EOS-in-a-branched-pipeline-td2965563.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章