Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <gst/gst.h>
- #include <glib.h>
- #include <unistd.h>
- #include <string.h>
- static GstElement *pipeline;
- static gboolean first_time = TRUE;
- /* Handler for the pad-added signal */
- static void pad_added_handler (GstElement *src, GstPad *pad, GstElement *data);
- static GstClockTime get_running_time()
- {
- GstClock *clock = gst_element_get_clock(pipeline);
- GstClockTime running_time = gst_clock_get_time(clock) - gst_element_get_base_time(pipeline);
- gst_object_unref(clock);
- return running_time;
- }
- static GstPadProbeReturn dec_event_probe_CB (
- GstPad * pad,
- GstPadProbeInfo * info,
- gpointer user_data
- )
- {
- GstEvent *event_pad = NULL;
- GstEvent *new_event = NULL;
- GstSegment *segment = NULL;
- if ((info->type & GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM))
- {
- event_pad = gst_pad_probe_info_get_event(info);
- if (first_time && event_pad->type == GST_EVENT_SEGMENT){
- first_time = FALSE;
- g_print("FIRST SEGMENT EVENT RECEIVED!! REPLACING!!!! \n");
- segment = gst_segment_new();
- segment->format = GST_FORMAT_TIME;
- segment->base = get_running_time();
- segment->start = 0;
- segment->stop = -1;
- new_event = gst_event_new_segment(segment);
- gst_event_unref(GST_EVENT(info->data));
- info->data = new_event;
- return GST_PAD_PROBE_OK;
- } else if (event_pad->type == GST_EVENT_EOS){
- g_print("event_probe: EOS arrived!!!! discarding!! \n");
- return GST_PAD_PROBE_DROP;
- } else if (event_pad->type == GST_EVENT_SEEK){
- g_print("event_probe: SEEK event arrived!!!! discarding!! \n");
- return GST_PAD_PROBE_DROP;
- } else if (event_pad->type == GST_EVENT_SEGMENT){
- g_print("event_probe: SEGMENT event arrived!!!!\n");
- return GST_PAD_PROBE_OK;
- } else {
- return GST_PAD_PROBE_OK;
- }
- }
- return GST_PAD_PROBE_OK;
- }
- static gpointer thread_1(GstElement *mixer)
- {
- /* waits 5 seconds and tries to add a filesrc input to the mixer */
- sleep(5);
- GstPad *mpad = gst_element_get_request_pad(mixer, "sink_1");
- GstElement *src =gst_element_factory_make("filesrc", NULL);
- g_object_set(G_OBJECT(src), "location", "video.mkv",NULL);
- GstElement *decoder = gst_element_factory_make("decodebin", NULL);
- GstElement *convert = gst_element_factory_make("identity", NULL);
- g_signal_connect (decoder, "pad-added", G_CALLBACK (pad_added_handler), convert);
- gst_bin_add_many(GST_BIN(pipeline), src, decoder, convert, NULL);
- gst_element_link(src, decoder);
- GstPad *spad = gst_element_get_static_pad(convert, "src");
- gst_pad_link(spad, mpad);
- //gst_element_set_state(pipeline, GST_STATE_PLAYING);
- gst_element_set_state(src, GST_STATE_PLAYING);
- gst_element_set_state(decoder, GST_STATE_PLAYING);
- gst_element_set_state(convert, GST_STATE_PLAYING);
- gst_object_unref(mpad);
- gst_object_unref(spad);
- return NULL;
- }
- int main(int argc, char *argv[]) {
- /* Initialize GStreamer */
- gst_init (&argc, &argv);
- /* Create the elements */
- GstElement * source = gst_element_factory_make("videotestsrc", NULL);
- g_object_set(source, "is-live", TRUE, NULL);
- GstElement * filter = gst_element_factory_make("capsfilter", NULL);
- GstCaps * fcaps = gst_caps_from_string("video/x-raw, width=720, height=576");
- g_object_set(G_OBJECT(filter), "caps", fcaps, NULL);
- gst_caps_unref(fcaps);
- GstElement *mixer = gst_element_factory_make("videomixer", NULL);
- GstElement *sink = gst_element_factory_make("autovideosink", NULL);
- /* Create the empty pipeline */
- pipeline = gst_pipeline_new ("test-pipeline");
- /* Build the pipeline. Note that we are NOT linking the source at this
- * point. We will do it later. */
- gst_bin_add_many (GST_BIN (pipeline), source, filter, mixer, sink, NULL);
- gst_element_link_many(source, filter, NULL);
- GstPad *mpad = gst_element_get_request_pad(mixer, "sink_0");
- GstPad *fpad = gst_element_get_static_pad(filter, "src");
- gst_pad_link(fpad, mpad);
- gst_object_unref(mpad);
- gst_object_unref(fpad);
- gst_element_link (mixer, sink);
- /* Start playing */
- GMainContext *main_context = g_main_context_new();
- GMainLoop *loop = g_main_loop_new(main_context, FALSE);
- gst_element_set_state (pipeline, GST_STATE_PLAYING);
- GThread *thread = g_thread_new("thread_1", (GThreadFunc)thread_1, mixer);
- g_main_loop_run(loop);
- /* Free resources */
- g_thread_unref(thread);
- gst_element_set_state (pipeline, GST_STATE_NULL);
- gst_object_unref (pipeline);
- return 0;
- }
- /* This function will be called by the pad-added signal */
- static void pad_added_handler (GstElement *src, GstPad *new_pad, GstElement *data) {
- GstPad *sink_pad = gst_element_get_static_pad (data, "sink");
- GstPadLinkReturn ret;
- GstCaps *new_pad_caps = NULL;
- GstStructure *new_pad_struct = NULL;
- const gchar *new_pad_type = NULL;
- g_print ("Received new pad '%s' from '%s':\n", GST_PAD_NAME (new_pad), GST_ELEMENT_NAME (src));
- /* Check the new pad's type */
- new_pad_caps = gst_pad_get_current_caps (new_pad);
- new_pad_struct = gst_caps_get_structure (new_pad_caps, 0);
- new_pad_type = gst_structure_get_name (new_pad_struct);
- if (!g_str_has_prefix (new_pad_type, "video/x-raw")) {
- g_print (" It has type '%s' which is not raw audio. Ignoring.\n", new_pad_type);
- goto exit;
- }
- // adds the pad probe to the new src pad on the decoder
- gst_pad_add_probe(new_pad, (GstPadProbeType) GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM ,
- dec_event_probe_CB, NULL, NULL);
- /* Attempt the link */
- ret = gst_pad_link (new_pad, sink_pad);
- if (GST_PAD_LINK_FAILED (ret)) {
- g_print (" Type is '%s' but link failed.\n", new_pad_type);
- } else {
- g_print (" Link succeeded (type '%s').\n", new_pad_type);
- }
- exit:
- /* Unreference the new pad's caps, if we got them */
- if (new_pad_caps != NULL)
- gst_caps_unref (new_pad_caps);
- /* Unreference the sink pad */
- gst_object_unref (sink_pad);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement