我的程序是basic_tutorial-5.c的副本,除了我已将其修改为在GTK环境中包含的一个框中的四个单独窗口中一次播放四个视频。视频播放,暂停和停止按钮以及要搜索的滑块都很棒。我还添加了缩放和取消缩放功能。选择缩放按钮将使其中一个窗口填满屏幕。理想情况下,选择unzoom按钮应恢复所有四个视频,但仅显示最近“缩放”窗口,其他三个视频为黑色。然后,我仍然可以选择一个不同的视频进行缩放,它将填满整个屏幕,并且完全不会显示最近放大的视频。除非我选择停止按钮,否则其他视频不会再出现。如何让其他视频“刷新”而不必选择停止?这是代码:
#include <string.h>
#include <gtk/gtk.h>
#include <gst/gst.h>
#include <gst/video/videooverlay.h>
#include <gdk/gdk.h>
#include <gdk/gdkx.h>
typedef struct _CustomData {
GstElement *pipe1,*pipe2,*pipe3,*pipe4; /* Four pipelines */
GtkWidget *slider;
GtkWidget *streams_list;
gulong slider_update_signal_id;
GstState state;
gint64 duration;
} CustomData;
GtkWidget *main_window;
GtkWidget *vid_win1,*vid_win2,*vid_win3,*vid_win4;
GtkWidget *main_box;
GtkWidget *main_hbox1,*main_hbox2;
GtkWidget *sub_hbox1;
GtkWidget *controls;
GtkWidget *play_button, *pause_button, *stop_button;
GtkWidget *zb1,*zb2,*zb3,*zb4,*uzb1,*uzb2,*uzb3,*uzb4;
gboolean zoomed = FALSE;
static void realize_cb (GtkWidget *widget, GstElement *data) {
GdkWindow *window = gtk_widget_get_window (widget);
guintptr window_handle;
if (!gdk_window_ensure_native (window))
g_error ("Couldn't create native window needed for GstXOverlay!");
window_handle = GDK_WINDOW_XID (window);
gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY(data), window_handle);
}
static void pause_cb (GtkButton *button, CustomData *data) {
gst_element_set_state (data->pipe1, GST_STATE_PAUSED);
gst_element_set_state (data->pipe2, GST_STATE_PAUSED);
gst_element_set_state (data->pipe3, GST_STATE_PAUSED);
gst_element_set_state (data->pipe4, GST_STATE_PAUSED);
}
static gboolean refresh_ui (CustomData *data) {
GstFormat fmt = GST_FORMAT_TIME;
gint64 current = -1;
if (data->state < GST_STATE_PAUSED)
return TRUE;
if (!GST_CLOCK_TIME_IS_VALID (data->duration)) {
if ((!gst_element_query_duration (data->pipe1, fmt, &data->duration)) ||
(!gst_element_query_duration (data->pipe2, fmt, &data->duration)) ||
(!gst_element_query_duration (data->pipe3, fmt, &data->duration)) ||
(!gst_element_query_duration (data->pipe4, fmt, &data->duration))) {
g_printerr ("Could not query current duration.\n");
} else {
gtk_range_set_range (GTK_RANGE (data->slider), 0, (gdouble)data->duration / GST_SECOND);
}
}
if ((gst_element_query_position (data->pipe1, fmt, ¤t)) ||
(gst_element_query_position (data->pipe2, fmt, ¤t)) ||
(gst_element_query_position (data->pipe3, fmt, ¤t)) ||
(gst_element_query_position (data->pipe4, fmt, ¤t))) {
g_signal_handler_block (data->slider, data->slider_update_signal_id);
gtk_range_set_value (GTK_RANGE (data->slider), (gdouble)current / GST_SECOND);
g_signal_handler_unblock (data->slider, data->slider_update_signal_id);
}
return TRUE;
}
static void zoom_cb (GtkButton *button, CustomData *data) {
if (!(zoomed)) {
g_object_ref (zb1);
gtk_container_remove (GTK_CONTAINER(sub_hbox1),zb1);
g_object_ref (zb2);
gtk_container_remove (GTK_CONTAINER(sub_hbox1),zb2);
g_object_ref (zb3);
gtk_container_remove (GTK_CONTAINER(sub_hbox1),zb3);
g_object_ref (zb4);
gtk_container_remove (GTK_CONTAINER(sub_hbox1),zb4);
if (button == (GTK_BUTTON(zb1))){
g_object_ref (vid_win2);
gtk_container_remove (GTK_CONTAINER(main_hbox1), vid_win2);
g_object_ref (main_hbox2);
gtk_container_remove (GTK_CONTAINER(main_box), main_hbox2);
gtk_box_pack_start (GTK_BOX (sub_hbox1), uzb1, FALSE, FALSE, 0);
gtk_widget_show_all (main_box);
} else
if (button == (GTK_BUTTON(zb2))){
g_object_ref (vid_win1);
gtk_container_remove (GTK_CONTAINER(main_hbox1), vid_win1);
g_object_ref (main_hbox2);
gtk_container_remove (GTK_CONTAINER(main_box), main_hbox2);
gtk_box_pack_start (GTK_BOX (sub_hbox1), uzb2, FALSE, FALSE, 0);
gtk_widget_show_all (main_box);
} else
if (button == (GTK_BUTTON(zb3))){
g_object_ref (vid_win4);
gtk_container_remove (GTK_CONTAINER(main_hbox2), vid_win4);
g_object_ref (main_hbox1);
gtk_container_remove (GTK_CONTAINER(main_box), main_hbox1);
gtk_box_pack_start (GTK_BOX (sub_hbox1), uzb3, FALSE, FALSE, 0);
gtk_widget_show_all (main_box);
} else
if (button == (GTK_BUTTON(zb4))){
g_object_ref (vid_win3);
gtk_container_remove (GTK_CONTAINER(main_hbox2), vid_win3);
g_object_ref (main_hbox1);
gtk_container_remove (GTK_CONTAINER(main_box), main_hbox1);
gtk_box_pack_start (GTK_BOX (sub_hbox1), uzb4, FALSE, FALSE, 0);
gtk_widget_show_all (main_box);
}
zoomed = TRUE;
gtk_widget_show_all (main_window);
gtk_widget_realize (main_window);
}
} // zoom_cb
static void unzoom_cb (GtkButton *button, CustomData *data){
if (zoomed) {
if (button == (GTK_BUTTON(uzb1))){
g_object_ref (uzb1);
gtk_container_remove (GTK_CONTAINER(sub_hbox1), uzb1);
gtk_box_pack_end (GTK_BOX (main_hbox1), vid_win2, TRUE, TRUE, 0);
gtk_box_pack_end (GTK_BOX (main_box), main_hbox2, TRUE, TRUE, 0);
g_object_unref (vid_win2);
g_object_unref (main_hbox2);
gtk_widget_show_all (vid_win2);
gtk_widget_show_all (main_hbox1);
gtk_widget_show_all (main_hbox2);
gtk_widget_show_all (main_box);
} else
if (button == (GTK_BUTTON(uzb2))){
g_object_ref (uzb2);
gtk_container_remove (GTK_CONTAINER(sub_hbox1), uzb2);
gtk_box_pack_start (GTK_BOX (main_hbox1), vid_win1, TRUE, TRUE, 0);
gtk_box_pack_end (GTK_BOX (main_box), main_hbox2, TRUE, TRUE, 0);
g_object_unref (vid_win1);
g_object_unref (main_hbox2);
gtk_widget_show_all (vid_win1);
gtk_widget_show_all (main_hbox1);
gtk_widget_show_all (main_hbox2);
gtk_widget_show_all (main_box);
} else
if (button == (GTK_BUTTON(uzb3))){
g_object_ref (uzb3);
gtk_container_remove (GTK_CONTAINER(sub_hbox1), uzb3);
gtk_box_pack_end (GTK_BOX (main_hbox2), vid_win4, TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (main_box), main_hbox1, TRUE, TRUE, 0);
g_object_unref (vid_win4);
g_object_unref (main_hbox1);
gtk_widget_show_all (vid_win4);
gtk_widget_show_all (main_hbox1);
gtk_widget_show_all (main_hbox2);
gtk_widget_show_all (main_box);
} else
if (button == (GTK_BUTTON(uzb4))){
g_object_ref (uzb4);
gtk_container_remove (GTK_CONTAINER(sub_hbox1), uzb4);
gtk_box_pack_start (GTK_BOX (main_hbox2), vid_win3, TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (main_box), main_hbox1, TRUE, TRUE, 0);
g_object_unref (vid_win3);
g_object_unref (main_hbox1);
gtk_widget_show_all (vid_win3);
gtk_widget_show_all (main_hbox1);
gtk_widget_show_all (main_hbox2);
gtk_widget_show_all (main_box);
}
gtk_box_pack_start (GTK_BOX (sub_hbox1), zb1, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (sub_hbox1), zb2, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (sub_hbox1), zb3, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (sub_hbox1), zb4, FALSE, FALSE, 0);
gtk_widget_show_all (main_window);
gtk_widget_show_all (vid_win1);
gtk_widget_show_all (vid_win2);
gtk_widget_show_all (vid_win3);
gtk_widget_show_all (vid_win4);
zoomed = FALSE;
}
} // unzoom
static void play_cb (GtkButton *button, CustomData *data) {
gst_element_set_state (data->pipe1, GST_STATE_PLAYING);
gst_element_set_state (data->pipe2, GST_STATE_PLAYING);
gst_element_set_state (data->pipe3, GST_STATE_PLAYING);
gst_element_set_state (data->pipe4, GST_STATE_PLAYING);
} // play_cb
static void stop_cb (GtkButton *button, CustomData *data) {
gst_element_set_state (data->pipe1, GST_STATE_READY);
gst_element_set_state (data->pipe2, GST_STATE_READY);
gst_element_set_state (data->pipe3, GST_STATE_READY);
gst_element_set_state (data->pipe4, GST_STATE_READY);
} // stop_cb
static void delete_event_cb (GtkWidget *widget, GdkEvent *event, CustomData *data) {
stop_cb (NULL, data);
g_signal_connect (widget, "destroy", G_CALLBACK (gtk_main_quit), NULL);
gtk_main_quit ();
} // delete_event
static gboolean expose_cb (GtkWidget *widget, GdkEventExpose *event, CustomData *data) {
if (data->state < GST_STATE_PAUSED) {
GtkAllocation allocation;
GdkWindow *window = gtk_widget_get_window (widget);
cairo_t *cr;
gtk_widget_get_allocation (widget, &allocation);
cr = gdk_cairo_create (window);
cairo_set_source_rgb (cr, 0, 0, 0);
cairo_rectangle (cr, 0, 0, allocation.width, allocation.height);
cairo_fill (cr);
cairo_destroy (cr);
}
return FALSE;
}
static void slider_cb (GtkRange *range, CustomData *data) {
gdouble value = gtk_range_get_value (GTK_RANGE (data->slider));
gst_element_seek_simple (data->pipe1, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT,
(gint64)(value * GST_SECOND));
gst_element_seek_simple (data->pipe2, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT,
(gint64)(value * GST_SECOND));
gst_element_seek_simple (data->pipe3, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT,
(gint64)(value * GST_SECOND));
gst_element_seek_simple (data->pipe4, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT,
(gint64)(value * GST_SECOND));
}
static void create_ui (CustomData *data) {
main_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
g_signal_connect (G_OBJECT (main_window), "delete-event", G_CALLBACK (delete_event_cb), data);
vid_win1 = gtk_drawing_area_new ();
vid_win2 = gtk_drawing_area_new ();
vid_win3 = gtk_drawing_area_new ();
vid_win4 = gtk_drawing_area_new ();
gtk_widget_set_double_buffered (vid_win1, FALSE);
gtk_widget_set_double_buffered (vid_win2, FALSE);
gtk_widget_set_double_buffered (vid_win3, FALSE);
gtk_widget_set_double_buffered (vid_win4, FALSE);
g_signal_connect (vid_win1, "realize", G_CALLBACK (realize_cb), data->pipe1);
g_signal_connect (vid_win2, "realize", G_CALLBACK (realize_cb), data->pipe2);
g_signal_connect (vid_win3, "realize", G_CALLBACK (realize_cb), data->pipe3);
g_signal_connect (vid_win4, "realize", G_CALLBACK (realize_cb), data->pipe4);
g_signal_connect (vid_win1, "expose_event", G_CALLBACK (expose_cb), data->pipe1);
g_signal_connect (vid_win2, "expose_event", G_CALLBACK (expose_cb), data->pipe2);
g_signal_connect (vid_win3, "expose_event", G_CALLBACK (expose_cb), data->pipe3);
g_signal_connect (vid_win4, "expose_event", G_CALLBACK (expose_cb), data->pipe4);
play_button = gtk_button_new_from_stock (GTK_STOCK_MEDIA_PLAY);
g_signal_connect (G_OBJECT (play_button), "clicked", G_CALLBACK (play_cb), data);
pause_button = gtk_button_new_from_stock (GTK_STOCK_MEDIA_PAUSE);
g_signal_connect (G_OBJECT (pause_button), "clicked", G_CALLBACK (pause_cb), data);
stop_button = gtk_button_new_from_stock (GTK_STOCK_MEDIA_STOP);
g_signal_connect (G_OBJECT (stop_button), "clicked", G_CALLBACK (stop_cb), data);
data->slider = gtk_hscale_new_with_range (0, 100, 1);
gtk_scale_set_draw_value (GTK_SCALE (data->slider), 0);
data->slider_update_signal_id = g_signal_connect (G_OBJECT (data->slider), "value-changed", G_CALLBACK (slider_cb), data);
zb1 = gtk_button_new_with_label ("Zoom1");
g_signal_connect (G_OBJECT (zb1), "clicked", G_CALLBACK (zoom_cb), data);
zb2 = gtk_button_new_with_label ("Zoom2");
g_signal_connect (G_OBJECT (zb2), "clicked", G_CALLBACK (zoom_cb), data);
zb3 = gtk_button_new_with_label ("Zoom3");
g_signal_connect (G_OBJECT (zb3), "clicked", G_CALLBACK (zoom_cb), data);
zb4 = gtk_button_new_with_label ("Zoom4");
g_signal_connect (G_OBJECT (zb4), "clicked", G_CALLBACK (zoom_cb), data);
uzb1 = gtk_button_new_with_label ("Unzoom1");
g_signal_connect (G_OBJECT (uzb1), "clicked", G_CALLBACK (unzoom_cb), data);
uzb2 = gtk_button_new_with_label ("Unzoom2");
g_signal_connect (G_OBJECT (uzb2), "clicked", G_CALLBACK (unzoom_cb), data);
uzb3 = gtk_button_new_with_label ("Unzoom3");
g_signal_connect (G_OBJECT (uzb3), "clicked", G_CALLBACK (unzoom_cb), data);
uzb4 = gtk_button_new_with_label ("Unzoom4");
g_signal_connect (G_OBJECT (uzb4), "clicked", G_CALLBACK (unzoom_cb), data);
sub_hbox1 = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (sub_hbox1), zb1, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (sub_hbox1), zb2, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (sub_hbox1), zb3, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (sub_hbox1), zb4, FALSE, FALSE, 0);
data->streams_list = gtk_text_view_new ();
gtk_text_view_set_editable (GTK_TEXT_VIEW (data->streams_list), FALSE);
controls = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (controls), play_button, FALSE, FALSE, 2);
gtk_box_pack_start (GTK_BOX (controls), pause_button, FALSE, FALSE, 2);
gtk_box_pack_start (GTK_BOX (controls), stop_button, FALSE, FALSE, 2);
gtk_box_pack_start (GTK_BOX (controls), data->slider, TRUE, TRUE, 2);
main_hbox1 = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (main_hbox1), vid_win1, TRUE, TRUE, 0);
gtk_box_pack_end (GTK_BOX (main_hbox1), vid_win2, TRUE, TRUE, 0);
main_hbox2 = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (main_hbox2), vid_win3, TRUE, TRUE, 0);
gtk_box_pack_end (GTK_BOX (main_hbox2), vid_win4, TRUE, TRUE, 0);
main_box = gtk_vbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (main_box), main_hbox1, TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (main_box), main_hbox2, TRUE, TRUE, 0);
gtk_box_pack_end (GTK_BOX (main_box), controls, FALSE, FALSE, 0);
gtk_box_pack_end (GTK_BOX (main_box), sub_hbox1, FALSE, FALSE, 0);
gtk_container_add (GTK_CONTAINER (main_window), main_box);
gtk_window_set_default_size (GTK_WINDOW (main_window), 1280, 720);
gtk_widget_show_all (main_window);
} // create_ui
static void tags_cb (GstElement *pipe1, gint stream, CustomData *data) {
gst_element_post_message (pipe1,
gst_message_new_application (GST_OBJECT (pipe1),
gst_structure_new ("tags-changed", NULL)));
}
static void error_cb (GstBus *bus, GstMessage *msg, CustomData *data) {
GError *err;
gchar *debug_info;
gst_message_parse_error (msg, &err, &debug_info);
g_printerr ("Error received from element %s: %s\n", GST_OBJECT_NAME (msg->src), err->message);
g_printerr ("Debugging information: %s\n", debug_info ? debug_info : "none");
g_clear_error (&err);
g_free (debug_info);
gst_element_set_state (data->pipe1, GST_STATE_READY);
gst_element_set_state (data->pipe2, GST_STATE_READY);
gst_element_set_state (data->pipe3, GST_STATE_READY);
gst_element_set_state (data->pipe4, GST_STATE_READY);
} // error_cb
static void eos_cb (GstBus *bus, GstMessage *msg, CustomData *data) {
g_print ("End-Of-Stream reached.\n");
gst_element_set_state (data->pipe1, GST_STATE_READY);
gst_element_set_state (data->pipe2, GST_STATE_READY);
gst_element_set_state (data->pipe3, GST_STATE_READY);
gst_element_set_state (data->pipe4, GST_STATE_READY);
} // eos_cb
static void state_changed_cb (GstBus *bus, GstMessage *msg, CustomData *data) {
GstState old_state, new_state, pending_state;
gst_message_parse_state_changed (msg, &old_state, &new_state, &pending_state);
if (GST_MESSAGE_SRC (msg) == GST_OBJECT (data->pipe1)) {
data->state = new_state;
g_print ("State set to %s\n", gst_element_state_get_name (new_state));
if (old_state == GST_STATE_READY && new_state == GST_STATE_PAUSED) {
refresh_ui (data);
}
}
}
static void analyze_streams (CustomData *data) {
gint i;
GstTagList *tags;
gchar *str, *total_str;
guint rate;
gint n_video; // n_audio, n_text; disregarding audio and subtitle for now
GtkTextBuffer *text;
text = gtk_text_view_get_buffer (GTK_TEXT_VIEW (data->streams_list));
gtk_text_buffer_set_text (text, "", -1);
g_object_get (data->pipe1, "n-video", &n_video, NULL);
for (i = 0; i < n_video; i++) {
tags = NULL;
g_signal_emit_by_name (data->pipe1, "get-video-tags", i, &tags);
if (tags) {
total_str = g_strdup_printf ("video stream %d:\n", i);
gtk_text_buffer_insert_at_cursor (text, total_str, -1);
g_free (total_str);
gst_tag_list_get_string (tags, GST_TAG_VIDEO_CODEC, &str);
total_str = g_strdup_printf (" codec: %s\n", str ? str : "unknown");
gtk_text_buffer_insert_at_cursor (text, total_str, -1);
g_free (total_str);
g_free (str);
gst_tag_list_free (tags);
}
}
}
static void application_cb (GstBus *bus, GstMessage *msg, CustomData *data) {
if (g_strcmp0 (gst_message_type_get_name (GST_MESSAGE_TYPE(msg)), "tags-changed") == 0) {
if (gst_message_has_name (msg, "tags-changed")) {
analyze_streams (data);
}
}
}
int main(int argc, char *argv[]) {
CustomData data;
GstStateChangeReturn ret1,ret2,ret3,ret4;
GstBus *bus1,*bus2,*bus3,*bus4;
gtk_init (&argc, &argv);
gst_init (&argc, &argv);
memset (&data, 0, sizeof (data));
data.duration = GST_CLOCK_TIME_NONE;
data.pipe1 = gst_element_factory_make ("playbin", "play1");
data.pipe2 = gst_element_factory_make ("playbin", "play2");
data.pipe3 = gst_element_factory_make ("playbin", "play3");
data.pipe4 = gst_element_factory_make ("playbin", "play4");
if ((!data.pipe1) || (!data.pipe2) || (!data.pipe3) || (!data.pipe4)) {
g_printerr ("Not all elements could be created.\n");
return -1;
}
/* Set the URI to play */
// g_object_set (data.playbin, "uri", "http://docs.gstreamer.com/media/sintel_trailer-480p.webm", NULL);
g_object_set (data.pipe1, "uri", "file:///home/useruseron/vdtest/hrtstcd1.mp4", NULL);
g_object_set (data.pipe2, "uri", "file:///home/useruseron/vdtest/hrtstcd3.mp4", NULL);
g_object_set (data.pipe3, "uri", "file:///home/useruseron/vdtest/hrtstcd5.mp4", NULL);
g_object_set (data.pipe4, "uri", "file:///home/useruseron/vdtest/hrtstcd7.mp4", NULL);
/* Connect to interesting signals in playbin */
g_signal_connect (G_OBJECT (data.pipe1), "video-tags-changed", (GCallback) tags_cb, &data);
g_signal_connect (G_OBJECT (data.pipe2), "video-tags-changed", (GCallback) tags_cb, &data);
g_signal_connect (G_OBJECT (data.pipe3), "video-tags-changed", (GCallback) tags_cb, &data);
g_signal_connect (G_OBJECT (data.pipe4), "video-tags-changed", (GCallback) tags_cb, &data);
create_ui (&data);
bus1 = gst_element_get_bus (data.pipe1);
gst_bus_add_signal_watch (bus1);
g_signal_connect (G_OBJECT (bus1), "message::error", (GCallback)error_cb, &data);
g_signal_connect (G_OBJECT (bus1), "message::eos", (GCallback)eos_cb, &data);
g_signal_connect (G_OBJECT (bus1), "message::state-changed", (GCallback)state_changed_cb, &data);
g_signal_connect (G_OBJECT (bus1), "message::application", (GCallback)application_cb, &data);
gst_object_unref (bus1);
bus2 = gst_element_get_bus (data.pipe2);
gst_bus_add_signal_watch (bus2);
g_signal_connect (G_OBJECT (bus2), "message::error", (GCallback)error_cb, &data);
g_signal_connect (G_OBJECT (bus2), "message::eos", (GCallback)eos_cb, &data);
g_signal_connect (G_OBJECT (bus2), "message::state-changed", (GCallback)state_changed_cb, &data);
g_signal_connect (G_OBJECT (bus2), "message::application", (GCallback)application_cb, &data);
gst_object_unref (bus2);
bus3 = gst_element_get_bus (data.pipe3);
gst_bus_add_signal_watch (bus3);
g_signal_connect (G_OBJECT (bus3), "message::error", (GCallback)error_cb, &data);
g_signal_connect (G_OBJECT (bus3), "message::eos", (GCallback)eos_cb, &data);
g_signal_connect (G_OBJECT (bus3), "message::state-changed", (GCallback)state_changed_cb, &data);
g_signal_connect (G_OBJECT (bus3), "message::application", (GCallback)application_cb, &data);
gst_object_unref (bus3);
bus4 = gst_element_get_bus (data.pipe4);
gst_bus_add_signal_watch (bus4);
g_signal_connect (G_OBJECT (bus4), "message::error", (GCallback)error_cb, &data);
g_signal_connect (G_OBJECT (bus4), "message::eos", (GCallback)eos_cb, &data);
g_signal_connect (G_OBJECT (bus4), "message::state-changed", (GCallback)state_changed_cb, &data);
g_signal_connect (G_OBJECT (bus4), "message::application", (GCallback)application_cb, &data);
gst_object_unref (bus4);
ret1 = gst_element_set_state (data.pipe1, GST_STATE_PLAYING);
ret2 = gst_element_set_state (data.pipe2, GST_STATE_PLAYING);
ret3 = gst_element_set_state (data.pipe3, GST_STATE_PLAYING);
ret4 = gst_element_set_state (data.pipe4, GST_STATE_PLAYING);
if ((ret1 == GST_STATE_CHANGE_FAILURE) || (ret2 == GST_STATE_CHANGE_FAILURE) ||
(ret3 == GST_STATE_CHANGE_FAILURE) || (ret4 == GST_STATE_CHANGE_FAILURE)) {
g_printerr ("Unable to set the pipeline to the playing state.\n");
gst_object_unref (data.pipe1);
gst_object_unref (data.pipe2);
gst_object_unref (data.pipe3);
gst_object_unref (data.pipe4);
return -1;
}
g_timeout_add_seconds (1, (GSourceFunc)refresh_ui, &data);
gtk_main ();
gst_element_set_state (data.pipe1, GST_STATE_NULL);
gst_element_set_state (data.pipe2, GST_STATE_NULL);
gst_element_set_state (data.pipe3, GST_STATE_NULL);
gst_element_set_state (data.pipe4, GST_STATE_NULL);
gst_object_unref (data.pipe1);
gst_object_unref (data.pipe2);
gst_object_unref (data.pipe3);
gst_object_unref (data.pipe4);
return 0;
}