GTK + and gstreamer do not display the pipeline on the first click on play button
TULLIO Arnaud
arnaud.tullio at outlook.fr
Thu Oct 7 11:04:04 UTC 2021
Hi,
would like to play and display my pipeline in my window when I click on the playbutton. It actually works but I have to click like 4 or 5 time on it in order to display the stream.
Does anyone have an idea how to display the stream in my window at the first click?
P.S : when I comment the function realize_cb my pipeline play and display on of course another window but at the first click on the play button
Below is my code :
#include <string.h>
#include <gtk/gtk.h>
#include <gst/gst.h>
#include <gst/video/videooverlay.h>
#include <gdk/gdk.h>
#if defined (GDK_WINDOWING_X11)
#include <gdk/gdkx.h>
#elif defined (GDK_WINDOWING_WIN32)
#include <gdk/gdkwin32.h>
#elif defined (GDK_WINDOWING_QUARTZ)
#include <gdk/gdkquartz.h>
#endif
/* Structure to contain all our information, so we can pass it around */
typedef struct _CustomData {
GstElement *pipeline;
GstElement *sink;
GstVideoOverlay *overlay;
GstBus *bus;
GstState state;
GtkWidget *video_window;/* Text widget to display info about the streams */
} CustomData;
/* This function is called when the GUI toolkit creates the physical window that will hold the video.
* At this point we can retrieve its handler (which has a different meaning depending on the windowing system)
* and pass it to GStreamer through the VideoOverlay interface. */
static void realize_cb (CustomData *data) {
guintptr window_handle;
gtk_widget_realize(data->video_window);
GdkWindow *window = gtk_widget_get_window (data->video_window);
if (!gdk_window_ensure_native (window))
g_error ("Couldn't create native window needed for GstVideoOverlay!");
/* Retrieve window handler from GDK */
#if defined (GDK_WINDOWING_WIN32)
window_handle = (guintptr)GDK_WINDOW_HWND (window);
#elif defined (GDK_WINDOWING_QUARTZ)
window_handle = gdk_quartz_window_get_nsview (window);
#elif defined (GDK_WINDOWING_X11)
window_handle = GDK_WINDOW_XID (window);
#endif
/* Pass it to pipeline, which implements VideoOverlay and will forward it to the video sink */
gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY (data->sink), window_handle);
}
static void playing_pipeline (GtkButton *button, CustomData *data) {
int m_port=5200;
GstStateChangeReturn ret;
GError* error = NULL;
GstElement* source;
GstCaps* caps = gst_caps_new_simple("application/x-rtp",
"media", G_TYPE_STRING, "video",
"payload", G_TYPE_INT, 96,
"encoding-name", G_TYPE_STRING, "H264",
NULL);
data->pipeline = gst_parse_launch("udpsrc name=source ! rtpjitterbuffer mode=0 ! rtph264depay ! h264parse ! avdec_h264 ! videoconvert ! xvimagesink name=mysink sync=false ", &error);
data->sink = gst_bin_get_by_name((GstBin*)data->pipeline, "mysink");
source = gst_bin_get_by_name(GST_BIN(data->pipeline), "source");
g_object_set(G_OBJECT(source), "caps", caps, NULL);
g_object_set(G_OBJECT(source), "port", m_port, NULL);
data->bus = gst_element_get_bus (data->pipeline);
gst_bus_add_signal_watch (data->bus);
gst_bus_enable_sync_message_emission(data->bus);
gst_object_unref (data->bus);
realize_cb (data);
ret = gst_element_set_state (data->pipeline, GST_STATE_PLAYING);
if (ret == GST_STATE_CHANGE_FAILURE)
{
g_printerr ("Unable to set the pipeline to the playing state.\n");
gst_object_unref (data->pipeline);
exit(1);
}
}
static gboolean draw_cb (GtkWidget *widget, cairo_t *cr, CustomData *data) {
if (data->state < GST_STATE_PAUSED) {
GtkAllocation allocation;
/* Cairo is a 2D graphics library which we use here to clean the video window.
* It is used by GStreamer for other reasons, so it will always be available to us. */
gtk_widget_get_allocation (widget, &allocation);
cairo_set_source_rgb (cr, 0, 0, 0);
cairo_rectangle (cr, 0, 0, allocation.width, allocation.height);
cairo_fill (cr);
}
return FALSE;
}
static void create_ui (CustomData *data) {
GtkWidget *main_window; /* The uppermost window, containing all other windows */
GtkWidget *main_box; /* VBox to hold main_hbox and the controls */
GtkWidget *main_hbox; /* HBox to hold the video_window and the stream info text widget */
GtkWidget *controls; /* HBox to hold the buttons and the slider */
GtkWidget *play_button;
main_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
data->video_window = gtk_drawing_area_new ();
gtk_widget_set_double_buffered (data->video_window, FALSE);
g_signal_connect (data->video_window, "draw", G_CALLBACK (draw_cb), data);
play_button = gtk_button_new_from_icon_name ("media-playback-start", GTK_ICON_SIZE_SMALL_TOOLBAR);
g_signal_connect (G_OBJECT (play_button), "clicked", G_CALLBACK (playing_pipeline), data);
controls = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_box_pack_start (GTK_BOX (controls), play_button, FALSE, FALSE, 2);
main_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_box_pack_start (GTK_BOX (main_hbox), data->video_window, TRUE, TRUE, 0);
main_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_box_pack_start (GTK_BOX (main_box), main_hbox, TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (main_box), controls, FALSE, FALSE, 0);
gtk_container_add (GTK_CONTAINER (main_window), main_box);
gtk_window_set_default_size (GTK_WINDOW (main_window), 640, 480);
gtk_widget_show_all (main_window);
}
int main (int argc, char **argv)
{
CustomData data;
/* Initialize GTK */
gtk_init (&argc, &argv);
/* Initialize GStreamer */
gst_init (&argc, &argv);
/* Initialize our data structure */
memset (&data, 0, sizeof (data));
create_ui (&data);
/* Start the GTK main loop. We will not regain control until gtk_main_quit is called. */
gtk_main ();
return 0;
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/gstreamer-devel/attachments/20211007/3374ec95/attachment-0001.htm>
More information about the gstreamer-devel
mailing list