#include #include #include #include #include #include static GMainLoop *mainloop = NULL; static gint64 d = 0; static gint64 gap = 10; typedef enum { MY_STREAM_TYPE_AUDIO = 0, MY_STREAM_TYPE_VIDEO = 1 } MyStreamType; typedef struct _StreamData StreamData; struct _StreamData { GstElement *bin; MyStreamType type; }; static void _stream_decode_pad_added_cb (GstElement *decode, GstPad *pad, gboolean arg1, gpointer user_data) { StreamData *data = (StreamData *) user_data; GstElement *queue; GstPad* sink_pad; GstCaps* caps = gst_pad_get_caps (pad); gchar *str_caps = gst_caps_to_string (caps); g_debug ("decode caps: [%d] [%s]", data->type, str_caps); switch (data->type) { case MY_STREAM_TYPE_AUDIO: g_debug ("Audio"); if (strstr (str_caps, "audio") == NULL) goto done; break; case MY_STREAM_TYPE_VIDEO: g_debug ("Video"); if (strstr (str_caps, "video") == NULL) goto done; break; } queue = gst_bin_get_by_name (GST_BIN (data->bin), "queue"); sink_pad = gst_element_get_pad (queue, "sink"); if (gst_pad_link (pad, sink_pad) != GST_PAD_LINK_OK) { g_warning ("Failed to link decode"); } gst_object_unref (queue); gst_object_unref (sink_pad); //g_free (data); g_debug ("Linked"); done: gst_caps_unref (caps); g_free (str_caps); } static GstElement* _create_src_element (const gchar* name, const gchar* uri, MyStreamType type, guint priority) { StreamData *data; GstElement *bin; GstElement *src; GstElement *decode; GstElement *queue; GstPad *src_pad; GstElement *gnl_src; g_debug ("element from uri: %s", uri); bin = gst_bin_new ("bin"); src = gst_element_make_from_uri (GST_URI_SRC, uri, "src"); g_return_val_if_fail (src != NULL, NULL); decode = gst_element_factory_make ("decodebin", NULL); g_return_val_if_fail (decode != NULL, NULL); queue = gst_element_factory_make ("queue", "queue"); g_return_val_if_fail (queue != NULL, NULL); gst_bin_add_many (GST_BIN (bin), src, decode, queue, NULL); gst_element_link (src, decode); data = g_new0 (StreamData, 1); data->bin = bin; data->type = type; g_debug ("Type : %d = %d", type, data->type); g_signal_connect (G_OBJECT (decode), "new-decoded-pad", G_CALLBACK (_stream_decode_pad_added_cb), data); src_pad = gst_element_get_pad (queue, "src"); g_return_val_if_fail (src_pad != NULL, NULL); gst_element_add_pad (bin, gst_ghost_pad_new ("src", src_pad)); gst_object_unref (src_pad); gnl_src = gst_element_factory_make ("gnlsource", name); g_return_val_if_fail (gnl_src != NULL, NULL); gst_bin_add (GST_BIN (gnl_src), bin); g_debug ("ADDING WITH: START [%lli] DUR [%lli]", d, gap); if (d == 0) { g_object_set (G_OBJECT (gnl_src), //"start", 0L, "duration", 10 * GST_SECOND, //"media-start", 0L, //"media-duration", 10 * GST_SECOND, "priority", priority, NULL); } else { g_object_set (G_OBJECT (gnl_src), "start", 10 * GST_SECOND, "duration", 10 * GST_SECOND, ///"media-start", 10 * GST_SECOND, //"media-duration", 10 * GST_SECOND, "priority", priority, NULL); } d++; return gnl_src; } static void _composition_pad_added_cb (GstElement *composition, GstPad *pad, gpointer data) { GstPad *sink_pad = gst_element_get_pad (GST_ELEMENT (data), "sink"); g_debug ("compose pad added"); if (gst_pad_link (pad, sink_pad) != GST_PAD_LINK_OK) { g_warning ("Failed to link decode"); } g_debug ("Linked ok"); } static void _compose_add_file (GstElement *compose, const gchar* e_name, const gchar* uri, MyStreamType type, guint priority) { GstElement *src; src = _create_src_element (e_name, uri, type, priority); gst_bin_add (GST_BIN (compose), src); } int main (int argc, char** argv) { GstElement* pipe; GstElement* gnl_compose_a; GstElement* gnl_compose_v; GstElement* asink; GstElement* vsink; GstElement* aqueue; GstElement* vqueue; g_type_init (); gst_init (&argc, &argv); mainloop = g_main_loop_new (NULL, FALSE); pipe = gst_pipeline_new ("test_pipeline"); gnl_compose_a = gst_element_factory_make ("gnlcomposition", "acompose"); g_return_val_if_fail (gnl_compose_a != NULL, 1); gnl_compose_v = gst_element_factory_make ("gnlcomposition", "vcompose"); g_return_val_if_fail (gnl_compose_v != NULL, 1); //_compose_add_file (gnl_compose_a, "src0", argv[1], MY_STREAM_TYPE_AUDIO, 1); //_compose_add_file (gnl_compose_a, "src1", argv[2], MY_STREAM_TYPE_AUDIO, 1); d = 0; _compose_add_file (gnl_compose_v, "src2", argv[1], MY_STREAM_TYPE_VIDEO, 1); _compose_add_file (gnl_compose_v, "src3", argv[2], MY_STREAM_TYPE_VIDEO, 1); //aqueue = gst_element_factory_make ("queue", "aqueue"); //asink = gst_element_factory_make ("alsasink", "asink"); vqueue = gst_element_factory_make ("queue", "vqueue"); vsink = gst_element_factory_make ("xvimagesink", "vsink"); gst_bin_add_many (GST_BIN (pipe), gnl_compose_a, gnl_compose_v, vqueue, vsink, //aqueue, asink, NULL); gst_element_link (vqueue, vsink); //gst_element_link (aqueue, asink); //g_signal_connect (G_OBJECT (gnl_compose_a), "pad-added", // G_CALLBACK (_composition_pad_added_cb), aqueue); g_signal_connect (G_OBJECT (gnl_compose_v), "pad-added", G_CALLBACK (_composition_pad_added_cb), vqueue); //g_idle_add (_play, pipe); gst_element_set_state (GST_ELEMENT (pipe), GST_STATE_PLAYING); g_main_loop_run (mainloop); return 0; }