GTK + and gstreamer do not display the pipeline on the first click on play button

TULLIO Arnaud arnaud.tullio at
Thu Oct 7 11:04:04 UTC 2021

 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>

/* 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;
  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);

  /* 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",

    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_object_unref (data->bus);

    realize_cb (data);

    ret = gst_element_set_state (data->pipeline, GST_STATE_PLAYING);

        g_printerr ("Unable to set the pipeline to the playing state.\n");
        gst_object_unref (data->pipeline);

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: <>

More information about the gstreamer-devel mailing list