#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; }