Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*COMPILATION: gcc -g -Wall -O2 work1.c -o work1 `pkg-config --libs --cflags gtk+-2.0 glib-2.0 gstreamer-0.10 gstreamer-interfaces-0.10` -export-dynamic */
- #include <gst/gst.h>
- #include <gtk/gtk.h>
- #include <gst/interfaces/xoverlay.h>
- #include <gdk/gdkx.h>
- static const char _GUI[] =
- "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
- "<interface>"
- " <requires lib=\"gtk+\" version=\"2.24\"/>"
- " <!-- interface-naming-policy project-wide -->"
- " <object class=\"GtkWindow\" id=\"window\">"
- " <property name=\"can_focus\">False</property>"
- " <child>"
- " <object class=\"GtkVBox\" id=\"vbox1\">"
- " <property name=\"visible\">True</property>"
- " <property name=\"can_focus\">False</property>"
- " <child>"
- " <object class=\"GtkHBox\" id=\"hbox1\">"
- " <property name=\"visible\">True</property>"
- " <property name=\"can_focus\">False</property>"
- " <child>"
- " <object class=\"GtkButton\" id=\"button1\">"
- " <property name=\"label\" translatable=\"yes\">button</property>"
- " <property name=\"visible\">True</property>"
- " <property name=\"can_focus\">True</property>"
- " <property name=\"receives_default\">True</property>"
- " <property name=\"use_action_appearance\">False</property>"
- " </object>"
- " <packing>"
- " <property name=\"expand\">True</property>"
- " <property name=\"fill\">True</property>"
- " <property name=\"position\">0</property>"
- " </packing>"
- " </child>"
- " <child>"
- " <object class=\"GtkButton\" id=\"button2\">"
- " <property name=\"label\" translatable=\"yes\">button</property>"
- " <property name=\"visible\">True</property>"
- " <property name=\"can_focus\">True</property>"
- " <property name=\"receives_default\">True</property>"
- " <property name=\"use_action_appearance\">False</property>"
- " </object>"
- " <packing>"
- " <property name=\"expand\">True</property>"
- " <property name=\"fill\">True</property>"
- " <property name=\"position\">1</property>"
- " </packing>"
- " </child>"
- " <child>"
- " <object class=\"GtkButton\" id=\"button3\">"
- " <property name=\"label\" translatable=\"yes\">button</property>"
- " <property name=\"visible\">True</property>"
- " <property name=\"can_focus\">True</property>"
- " <property name=\"receives_default\">True</property>"
- " <property name=\"use_action_appearance\">False</property>"
- " </object>"
- " <packing>"
- " <property name=\"expand\">True</property>"
- " <property name=\"fill\">True</property>"
- " <property name=\"position\">2</property>"
- " </packing>"
- " </child>"
- " <child>"
- " <object class=\"GtkButton\" id=\"button4\">"
- " <property name=\"label\" translatable=\"yes\">button</property>"
- " <property name=\"visible\">True</property>"
- " <property name=\"can_focus\">True</property>"
- " <property name=\"receives_default\">True</property>"
- " <property name=\"use_action_appearance\">False</property>"
- " </object>"
- " <packing>"
- " <property name=\"expand\">True</property>"
- " <property name=\"fill\">True</property>"
- " <property name=\"position\">3</property>"
- " </packing>"
- " </child>"
- " </object>"
- " <packing>"
- " <property name=\"expand\">False</property>"
- " <property name=\"fill\">True</property>"
- " <property name=\"position\">0</property>"
- " </packing>"
- " </child>"
- " <child>"
- " <object class=\"GtkDrawingArea\" id=\"drawingarea\">"
- " <property name=\"width_request\">1600</property>"
- " <property name=\"height_request\">600</property>"
- " <property name=\"visible\">True</property>"
- " <property name=\"can_focus\">False</property>"
- " </object>"
- " <packing>"
- " <property name=\"expand\">True</property>"
- " <property name=\"fill\">True</property>"
- " <property name=\"position\">1</property>"
- " </packing>"
- " </child>"
- " <child>"
- " <object class=\"GtkLabel\" id=\"label\">"
- " <property name=\"visible\">True</property>"
- " <property name=\"can_focus\">False</property>"
- " <property name=\"label\" translatable=\"yes\">label</property>"
- " </object>"
- " <packing>"
- " <property name=\"expand\">False</property>"
- " <property name=\"fill\">True</property>"
- " <property name=\"position\">2</property>"
- " </packing>"
- " </child>"
- " </object>"
- " </child>"
- " </object>"
- "</interface>";
- GstElement *pipeline;
- static gboolean expose_cb(GtkWidget* widget, GdkEventExpose* event, GstElement* videosink) {
- g_print ("expose_cb\n");
- //expose callback is garanted to be called after realized callback
- gst_x_overlay_expose (GST_X_OVERLAY (videosink));
- return FALSE;
- }
- static GstBusSyncReply bus_call(GstBus * bus, GstMessage *message, gpointer data) {
- GtkWidget *window = (GtkWidget*) data;
- g_print("***Got message: %s\n", GST_MESSAGE_TYPE_NAME(message));
- // ignore anything but 'prepare-xwindow-id' element messages
- if (GST_MESSAGE_TYPE(message) == GST_MESSAGE_ERROR){
- GError *err;
- gchar *debug;
- gst_message_parse_error(message, &err, &debug);
- g_print("******ERR:%s\n", err->message);
- g_print("******ERR:%s\n", debug);
- g_error_free(err);
- g_free(debug);
- return GST_BUS_PASS;
- }
- if (GST_MESSAGE_TYPE(message) == GST_MESSAGE_WARNING){
- GError *warn;
- gchar *debug;
- gst_message_parse_error(message, &warn, &debug);
- g_print("******ERR:%s\n", warn->message);
- g_error_free(warn);
- g_free(debug);
- return GST_BUS_PASS;
- }
- if (GST_MESSAGE_TYPE(message) != GST_MESSAGE_ELEMENT)
- return GST_BUS_PASS;
- if (!gst_structure_has_name(message->structure, "prepare-xwindow-id"))
- return GST_BUS_PASS;
- g_print("Got prepare-xwindow-id msg\n");
- gst_x_overlay_set_window_handle(GST_X_OVERLAY(GST_MESSAGE_SRC(message)), GDK_WINDOW_XWINDOW(window->window));
- //~ gst_message_unref (message);
- return GST_BUS_PASS;
- }
- static void area_realize_cb(GtkWidget* widget, GstElement* pipeline) {
- g_print ("drawing area realized\n");
- #if GTK_CHECK_VERSION(2,18,0)
- if (!gdk_window_ensure_native (widget->window))
- g_error ("Failed to create native window!");
- #endif
- //avoid flickering when resizing or obscuring the main window
- gdk_window_set_back_pixmap(widget->window, NULL, FALSE);
- gtk_widget_set_app_paintable(widget,TRUE);
- gtk_widget_set_double_buffered(widget, FALSE);
- gst_element_set_state (pipeline, GST_STATE_PLAYING);
- }
- static void make_window_black(GtkWidget *window) {
- GdkColor color;
- gdk_color_parse("black", &color);
- gtk_widget_modify_bg(window, GTK_STATE_NORMAL, &color);
- }
- int destroy_cb(GtkWidget * widget, gpointer data) {
- g_print("Window destroyed\n");
- /* clean up */
- gst_element_set_state(pipeline, GST_STATE_NULL);
- gst_object_unref(pipeline);
- gtk_main_quit();
- return FALSE;
- }
- static gboolean key_press_event_cb(GtkWidget *widget, GdkEventKey *event, gpointer data) {
- if (event->keyval == 'f') {
- g_print("Toggling fullscreen\n");
- gboolean is_fullscreen = (gdk_window_get_state(GDK_WINDOW(widget->window)) == GDK_WINDOW_STATE_FULLSCREEN);
- if (is_fullscreen)
- gtk_window_unfullscreen(GTK_WINDOW(widget));
- else
- gtk_window_fullscreen(GTK_WINDOW(widget));
- return TRUE;
- }
- else if (event->keyval == 'q') {
- destroy_cb(widget, data);
- return TRUE;
- }
- else {
- return TRUE;
- }
- }
- static void on_pad_added (GstElement *element, GstPad *pad, gpointer data) {
- gchar *padname;
- GstPad *sinkpad;
- GstElement *decoder = (GstElement *) data;
- padname = gst_pad_get_name(pad);
- g_print ("A new pad %s was created\n", padname);
- if (g_str_has_prefix(padname, "recv_rtp_src_0")) { //only link video src pad / recv_rtp_src_0 is video, recv_rtp_src_1 is audio
- /* We can now link this pad with the rtsp-decoder sink pad */
- g_print ("%slinking source/demuxer\n", padname);
- sinkpad = gst_element_get_static_pad (decoder, "sink");
- gst_pad_link (pad, sinkpad);
- gst_object_unref (sinkpad);
- }
- g_free (padname);
- }
- //callbacks for gtk buttons
- static void button_state_null_cb(GtkWidget* widget, GstElement* pipeline){
- gst_element_set_state (pipeline, GST_STATE_NULL);
- g_print ("GST_STATE_NULL\n");
- }
- static void button_state_ready_cb(GtkWidget* widget, GstElement* pipeline){
- gst_element_set_state (pipeline, GST_STATE_READY);
- g_print ("GST_STATE_READY\n");
- }
- static void button_state_paused_cb(GtkWidget* widget, GstElement* pipeline){
- gst_element_set_state (pipeline, GST_STATE_PAUSED);
- g_print ("GST_STATE_PAUSED\n");
- }
- static void button_state_playing_cb(GtkWidget* widget, GstElement* pipeline){
- gst_element_set_state (pipeline, GST_STATE_PLAYING);
- g_print ("GST_STATE_PLAYING\n");
- }
- //test callbacks
- void onbyessrc_cb(GstElement* rtpbin, guint session, guint ssrc, gpointer user_data){
- g_print("*-*-*-*-*-*-*on-bye-ssrc\n");
- }
- void onssrcactive_cb(GstElement* rtpbin, guint session, guint ssrc, gpointer user_data){
- g_print("*-*-*-*-*-*-*on-ssrc-active\n");
- }
- void onbyetimeout_cb(GstElement* rtpbin, guint session, guint ssrc, gpointer user_data){
- g_print("*-*-*-*-*-*-*on-bye-timeout\n");
- }
- int main (gint argc, gchar *argv[]) {
- GstStateChangeReturn ret;
- GstCaps *caps1;
- GstCaps *caps2;
- GstElement *src1;
- GstElement *src2;
- GstElement *demux1;
- GstElement *demux2;
- GstElement *decoder1;
- GstElement *decoder2;
- GstElement *videorate1;
- GstElement *videorate2;
- GstElement *videorate3;
- GstElement *colorspace1;
- GstElement *colorspace2;
- GstElement *colorspace3;
- GstElement *colorspace4;
- GstElement *videobox1;
- GstElement *videobox2;
- GstElement *videobox3;
- GstElement *videomixer;
- GstElement *videoscale1;
- GstElement *videoscale2;
- GstElement *videoscale3;
- GstElement *par1;
- GstElement *par2;
- GstElement *par3;
- GstElement *sink;
- GtkBuilder *builder;
- GtkWidget *window;
- GtkWidget *drawingArea;
- GtkWidget *button1;
- GtkWidget *button2;
- GtkWidget *button3;
- GtkWidget *button4;
- /* initialization */
- gst_init(&argc, &argv);
- gtk_init(&argc, &argv);
- builder = gtk_builder_new ();
- gtk_builder_add_from_string(builder, _GUI, -1, NULL);
- window = GTK_WIDGET (gtk_builder_get_object (builder, "window"));
- drawingArea = GTK_WIDGET (gtk_builder_get_object (builder, "drawingarea"));
- button1 = GTK_WIDGET (gtk_builder_get_object (builder, "button1"));
- button2 = GTK_WIDGET (gtk_builder_get_object (builder, "button2"));
- button3 = GTK_WIDGET (gtk_builder_get_object (builder, "button3"));
- button4 = GTK_WIDGET (gtk_builder_get_object (builder, "button4"));
- gtk_builder_connect_signals (builder, NULL);
- g_object_unref (G_OBJECT (builder));
- /* create elements */
- pipeline = gst_pipeline_new("my_pipeline");
- videobox1 = gst_element_factory_make ("videobox", "videobox1");
- videobox2 = gst_element_factory_make ("videobox", "videobox2");
- videobox3 = gst_element_factory_make ("videobox", "videobox3");
- videomixer = gst_element_factory_make ("videomixer", "mixer");
- src1 = gst_element_factory_make ("rtspsrc", "Source1");
- src2 = gst_element_factory_make ("rtspsrc", "Source2");
- demux1 = gst_element_factory_make ("rtph264depay", "Depay1");
- demux2 = gst_element_factory_make ("rtpmp4vdepay", "Depay2");
- decoder1 = gst_element_factory_make ("ffdec_h264", "Decoder1");
- decoder2 = gst_element_factory_make ("ffdec_mpeg4", "Decoder2");
- videorate1 = gst_element_factory_make ("videorate", "Videorate1");
- videorate2 = gst_element_factory_make ("videorate", "Videorate2");
- videorate3 = gst_element_factory_make ("videorate", "Videorate3");
- colorspace1 = gst_element_factory_make ("ffmpegcolorspace", "Colorspace");
- colorspace2 = gst_element_factory_make ("ffmpegcolorspace", "Colorspace2");
- colorspace3 = gst_element_factory_make ("ffmpegcolorspace", "Colorspace3");
- colorspace4 = gst_element_factory_make ("ffmpegcolorspace", "Colorspace4");
- videoscale1 = gst_element_factory_make ("videoscale", "scalingvideo1");
- videoscale2 = gst_element_factory_make ("videoscale", "scalingvideo2");
- videoscale3 = gst_element_factory_make ("videoscale", "scalingvideo3");
- par1 = gst_element_factory_make ("capsfilter", "capsfilter1");
- par2 = gst_element_factory_make ("capsfilter", "capsfilter2");
- par3 = gst_element_factory_make ("capsfilter", "capsfilter3");
- sink = gst_element_factory_make("ximagesink", "videosink");
- caps1 = gst_caps_new_simple("video/x-raw-yuv", "width", G_TYPE_INT, 320, "height", G_TYPE_INT, 240, NULL);
- caps2 = gst_caps_new_simple("video/x-raw-yuv", "width", G_TYPE_INT, 320, "height", G_TYPE_INT, 240, NULL);
- g_object_set (G_OBJECT (src1), "location", "rtsp://10.0.0.50/udpstream", NULL);
- g_object_set (G_OBJECT (src2), "location", "rtsp://10.0.0.51/udpstream", NULL);
- //~ g_object_set (G_OBJECT (src1), "protocols", (1 << 0), NULL);
- g_object_set (G_OBJECT (src1), "timeout", (guint64)1000000, NULL);
- g_object_set (G_OBJECT (src2), "timeout", (guint64)1000000, NULL);
- g_object_set (G_OBJECT (src1), "tcp-timeout", (guint64)1000000, NULL);
- g_object_set (G_OBJECT (src2), "tcp-timeout", (guint64)1000000, NULL);
- g_object_set (G_OBJECT (src1), "retry", (guint)1, NULL);
- g_object_set (G_OBJECT (src2), "retry", (guint)1, NULL);
- g_object_set (G_OBJECT (src1), "latency", 200, NULL);
- g_object_set (G_OBJECT (src2), "latency", 200, NULL);
- //~ g_object_set (G_OBJECT(par1), "caps", caps, NULL );
- g_object_set (G_OBJECT(par2), "caps", caps1, NULL );
- g_object_set (G_OBJECT(par3), "caps", caps2, NULL );
- g_object_set(videobox1, /*"border-alpha", 0,*/ "top", -300, "left", 0, NULL);
- g_object_set(videobox2, /*"border-alpha", 0,*/ "top", 0, "left", -800, NULL);
- g_object_set(videobox3, /*"border-alpha", 0,*/ "top", 0, "left", 0, NULL);
- g_object_set(G_OBJECT(sink), "force-aspect-ratio", TRUE, NULL);
- gst_bin_add_many (GST_BIN (pipeline), src1,src2, demux1,demux2, decoder1, decoder2, videorate1, videorate2,videorate3, colorspace1, colorspace2, colorspace3, colorspace4, videoscale1, videoscale2, videoscale3, par1, par2, par3, sink, videobox1, videobox2,videobox3, videomixer, NULL);
- if (!gst_element_link_many (demux1, decoder1, colorspace2, /*videoscale1, par2,*/ videobox2, videorate2, videomixer, NULL)){
- g_warning ("Linking part (B2) Fail...");
- return -1;
- }
- if (!gst_element_link_many (demux2, decoder2, colorspace3, /*videoscale2, par3,*/ videobox3, videorate3, videomixer, NULL)){
- g_warning ("Linking part (B3) Fail...");
- return -1;
- }
- if (!gst_element_link_many (videomixer,colorspace4, /*videoscale3,*/ sink, NULL)){
- g_warning ("Linking part (B4) Fail...");
- return -1;
- }
- if (! g_signal_connect (src1, "pad-added", G_CALLBACK (on_pad_added),demux1)) {
- g_warning ("Linking part (A) with part (B) Fail...");
- }
- if (! g_signal_connect (src2, "pad-added", G_CALLBACK (on_pad_added),demux2)) {
- g_warning ("Linking part (A) with part (B) Fail...");
- }
- gst_caps_unref(caps1) ;
- gst_caps_unref(caps2) ;
- //set window id on this event
- GstBus* bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
- gst_bus_add_watch(bus, (GstBusFunc)bus_call, drawingArea);
- gst_object_unref (bus);
- // attach key press signal to key press callback
- gtk_widget_set_events(window, GDK_KEY_PRESS_MASK);
- g_signal_connect(G_OBJECT(window), "key-press-event", G_CALLBACK(key_press_event_cb), pipeline);
- g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(destroy_cb), pipeline);
- g_signal_connect (G_OBJECT(drawingArea), "realize", G_CALLBACK (area_realize_cb), pipeline);
- g_signal_connect(G_OBJECT(drawingArea), "expose-event", G_CALLBACK(expose_cb), sink);
- g_signal_connect (G_OBJECT (button1), "clicked", G_CALLBACK (button_state_null_cb), pipeline);
- g_signal_connect (G_OBJECT (button2), "clicked", G_CALLBACK (button_state_ready_cb), pipeline);
- g_signal_connect (G_OBJECT (button3), "clicked", G_CALLBACK (button_state_paused_cb), pipeline);
- g_signal_connect (G_OBJECT (button4), "clicked", G_CALLBACK (button_state_playing_cb), pipeline);
- /* run */
- make_window_black(drawingArea);
- gtk_widget_show (window);
- ret = gst_element_set_state(pipeline, GST_STATE_PLAYING);
- if (ret == GST_STATE_CHANGE_FAILURE) {
- g_print("Failed to start up pipeline!\n");
- return 1;
- }
- //trying to connect rtpbin signals inside of the rtpsrc (only first one (src1))
- {
- GList *child = NULL, *children = GST_BIN_CHILDREN (src1);
- gchar *objectName;
- for (child = children; child != NULL; child = g_list_next (child)) {
- objectName = gst_object_get_name(child->data);
- g_print("\tfound object: %s\n", objectName);
- if (g_str_has_prefix(objectName, "rtpbin")) {
- GstElement *ch = GST_ELEMENT(child->data);
- g_print("\tselected object name:%s\n", objectName);
- GstElementFactory *fac;
- fac=gst_element_get_factory(ch);
- g_print("\tselected object detail%s\n", fac->details.longname);
- g_signal_connect (ch, "on-bye-ssrc", G_CALLBACK (onbyessrc_cb), ch);
- g_signal_connect (ch, "on-bye-timeout", G_CALLBACK (onbyessrc_cb), ch);
- g_signal_connect (ch, "on-ssrc-active", G_CALLBACK (onbyessrc_cb), ch);
- }
- g_free(objectName);
- }
- }
- gtk_main ();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement