Advertisement
Guest User

add filesrc to videomixer dynamically

a guest
Jan 14th, 2014
164
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.95 KB | None | 0 0
  1. #include <gst/gst.h>
  2. #include <glib.h>
  3. #include <unistd.h>
  4. #include <string.h>
  5.  
  6. static GstElement *pipeline;
  7. static gboolean first_time = TRUE;
  8.  
  9. /* Handler for the pad-added signal */
  10. static void pad_added_handler (GstElement *src, GstPad *pad, GstElement *data);
  11.  
  12. static GstClockTime get_running_time()
  13. {
  14.     GstClock *clock = gst_element_get_clock(pipeline);
  15.     GstClockTime running_time = gst_clock_get_time(clock) - gst_element_get_base_time(pipeline);
  16.     gst_object_unref(clock);
  17.  
  18.     return running_time;
  19. }
  20.  
  21.  
  22. static GstPadProbeReturn dec_event_probe_CB (
  23.     GstPad * pad,
  24.     GstPadProbeInfo * info,
  25.     gpointer user_data
  26. )
  27. {
  28.  
  29.     GstEvent *event_pad = NULL;
  30.     GstEvent *new_event = NULL;
  31.     GstSegment *segment = NULL;
  32.     if ((info->type & GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM))
  33.     {
  34.         event_pad = gst_pad_probe_info_get_event(info);
  35.         if (first_time && event_pad->type == GST_EVENT_SEGMENT){
  36.             first_time = FALSE;
  37.             g_print("FIRST SEGMENT EVENT RECEIVED!! REPLACING!!!! \n");
  38.             segment = gst_segment_new();
  39.             segment->format = GST_FORMAT_TIME;
  40.             segment->base = get_running_time();
  41.             segment->start = 0;
  42.             segment->stop = -1;
  43.             new_event = gst_event_new_segment(segment);
  44.             gst_event_unref(GST_EVENT(info->data));
  45.             info->data = new_event;
  46.             return GST_PAD_PROBE_OK;
  47.         } else if (event_pad->type == GST_EVENT_EOS){
  48.             g_print("event_probe: EOS arrived!!!! discarding!! \n");
  49.             return GST_PAD_PROBE_DROP;
  50.         } else if (event_pad->type == GST_EVENT_SEEK){
  51.             g_print("event_probe: SEEK event arrived!!!! discarding!! \n");
  52.             return GST_PAD_PROBE_DROP;
  53.         } else if (event_pad->type == GST_EVENT_SEGMENT){
  54.             g_print("event_probe: SEGMENT event arrived!!!!\n");
  55.             return GST_PAD_PROBE_OK;
  56.         } else {
  57.             return GST_PAD_PROBE_OK;
  58.         }
  59.  
  60.     }
  61.  
  62.     return GST_PAD_PROBE_OK;
  63.  
  64. }
  65.  
  66. static gpointer thread_1(GstElement *mixer)
  67. {
  68.   /* waits 5 seconds and tries to add a filesrc input to the mixer */
  69.   sleep(5);
  70.   GstPad *mpad = gst_element_get_request_pad(mixer, "sink_1");
  71.  
  72.   GstElement *src =gst_element_factory_make("filesrc", NULL);
  73.   g_object_set(G_OBJECT(src), "location", "video.mkv",NULL);
  74.  
  75.   GstElement *decoder = gst_element_factory_make("decodebin", NULL);
  76.   GstElement *convert = gst_element_factory_make("identity", NULL);
  77.   g_signal_connect (decoder, "pad-added", G_CALLBACK (pad_added_handler), convert);
  78.    
  79.   gst_bin_add_many(GST_BIN(pipeline), src, decoder, convert, NULL);
  80.   gst_element_link(src, decoder);
  81.   GstPad *spad = gst_element_get_static_pad(convert, "src");
  82.   gst_pad_link(spad, mpad);
  83.  
  84.  
  85.   //gst_element_set_state(pipeline, GST_STATE_PLAYING);
  86.  
  87.   gst_element_set_state(src, GST_STATE_PLAYING);
  88.   gst_element_set_state(decoder, GST_STATE_PLAYING);
  89.   gst_element_set_state(convert, GST_STATE_PLAYING);
  90.  
  91.  
  92.   gst_object_unref(mpad);
  93.   gst_object_unref(spad);
  94.   return NULL;
  95. }
  96.  
  97. int main(int argc, char *argv[]) {
  98.   /* Initialize GStreamer */
  99.   gst_init (&argc, &argv);
  100.    
  101.   /* Create the elements */
  102.   GstElement * source = gst_element_factory_make("videotestsrc", NULL);
  103.   g_object_set(source, "is-live", TRUE, NULL);
  104.   GstElement * filter = gst_element_factory_make("capsfilter", NULL);
  105.   GstCaps * fcaps = gst_caps_from_string("video/x-raw, width=720, height=576");
  106.   g_object_set(G_OBJECT(filter), "caps", fcaps, NULL);
  107.   gst_caps_unref(fcaps);
  108.   GstElement *mixer = gst_element_factory_make("videomixer", NULL);
  109.   GstElement *sink = gst_element_factory_make("autovideosink", NULL);
  110.    
  111.   /* Create the empty pipeline */
  112.   pipeline = gst_pipeline_new ("test-pipeline");
  113.    
  114.   /* Build the pipeline. Note that we are NOT linking the source at this
  115.    * point. We will do it later. */
  116.   gst_bin_add_many (GST_BIN (pipeline), source, filter, mixer, sink, NULL);
  117.   gst_element_link_many(source, filter, NULL);
  118.   GstPad *mpad = gst_element_get_request_pad(mixer, "sink_0");
  119.   GstPad *fpad = gst_element_get_static_pad(filter, "src");
  120.   gst_pad_link(fpad, mpad);
  121.   gst_object_unref(mpad);
  122.   gst_object_unref(fpad);
  123.   gst_element_link (mixer, sink);
  124.    
  125.   /* Start playing */
  126.   GMainContext *main_context = g_main_context_new();
  127.   GMainLoop *loop = g_main_loop_new(main_context, FALSE);
  128.   gst_element_set_state (pipeline, GST_STATE_PLAYING);
  129.   GThread *thread = g_thread_new("thread_1", (GThreadFunc)thread_1, mixer);
  130.   g_main_loop_run(loop);
  131.    
  132.    
  133.   /* Free resources */
  134.   g_thread_unref(thread);
  135.   gst_element_set_state (pipeline, GST_STATE_NULL);
  136.   gst_object_unref (pipeline);
  137.   return 0;
  138. }
  139.    
  140. /* This function will be called by the pad-added signal */
  141. static void pad_added_handler (GstElement *src, GstPad *new_pad, GstElement *data) {
  142.   GstPad *sink_pad = gst_element_get_static_pad (data, "sink");
  143.   GstPadLinkReturn ret;
  144.   GstCaps *new_pad_caps = NULL;
  145.   GstStructure *new_pad_struct = NULL;
  146.   const gchar *new_pad_type = NULL;
  147.    
  148.   g_print ("Received new pad '%s' from '%s':\n", GST_PAD_NAME (new_pad), GST_ELEMENT_NAME (src));
  149.    
  150.   /* Check the new pad's type */
  151.   new_pad_caps = gst_pad_get_current_caps (new_pad);
  152.   new_pad_struct = gst_caps_get_structure (new_pad_caps, 0);
  153.   new_pad_type = gst_structure_get_name (new_pad_struct);
  154.   if (!g_str_has_prefix (new_pad_type, "video/x-raw")) {
  155.     g_print ("  It has type '%s' which is not raw audio. Ignoring.\n", new_pad_type);
  156.     goto exit;
  157.   }
  158.    
  159.   // adds the pad probe to the new src pad on the decoder
  160.   gst_pad_add_probe(new_pad, (GstPadProbeType) GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM ,
  161.           dec_event_probe_CB, NULL, NULL);
  162.   /* Attempt the link */
  163.   ret = gst_pad_link (new_pad, sink_pad);
  164.   if (GST_PAD_LINK_FAILED (ret)) {
  165.     g_print ("  Type is '%s' but link failed.\n", new_pad_type);
  166.   } else {
  167.     g_print ("  Link succeeded (type '%s').\n", new_pad_type);
  168.   }
  169.    
  170. exit:
  171.   /* Unreference the new pad's caps, if we got them */
  172.   if (new_pad_caps != NULL)
  173.     gst_caps_unref (new_pad_caps);
  174.    
  175.   /* Unreference the sink pad */
  176.   gst_object_unref (sink_pad);
  177. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement