gst_element_set_state blocks when setting GST_STATE_NULL when using vaapisink and QWidget

meistrimees at gmail.com meistrimees at gmail.com
Tue Nov 9 09:55:25 UTC 2021


I prepared a simple test program that I could reproduce the issue. I have
tested with latest stable version of GStreamer 1.18.5, using radeonsi
driver, but it will probably happen with Intel drivers as well.
Increasing the number of  pipeline-s will increase the chance of getting
one of them stuck on teardown.

I'm considering opening a bugreport, but I want a second opinion before I
do. Maybe I'm missing something here.

#include <QApplication>

#include <QDebug>

#include <QWidget>

#include <QGridLayout>


#include <gst/gst.h>

#include <gst/video/videooverlay.h>


int main(int argc, char *argv[])

{

  gst_init(0, 0);


  QApplication app(argc, argv);

  app.connect(&app, &QApplication::lastWindowClosed, &app, &QApplication::quit);


  // We will arrenge videoWidgets into the colums and rows

  QWidget mainWidget;

  QGridLayout *layout = new QGridLayout;

  layout->setHorizontalSpacing(0);

  mainWidget.setLayout(layout);


  int streamCount = 9;

  int rowCount = 3;

  int colCount = streamCount % rowCount == 0 ? streamCount / rowCount
: streamCount / rowCount + 1;


  const char *pipelineStr = "videotestsrc ! vaapisink name=\"thesink\"";

  QVector<GstElement *> pipelines;


  for (int i = 0; i < streamCount; ++i)

  {

    GError *error = NULL;

    GstElement *pipeline = gst_parse_launch(pipelineStr, &error);


    if (error) {

      qInfo() << "Error: " << error->message;

      g_clear_error(&error);

    }


    if (!pipeline) {

      qInfo() << "Unable to create pipeline";

      continue;

    }


    GstElement *sink = gst_bin_get_by_name(GST_BIN(pipeline), "thesink");


    if (!sink)

    {

      qInfo() << "Failed to get vaapisink element";

      continue;

    }


    QWidget *videoWidget = new QWidget();

    layout->addWidget(videoWidget, i / colCount, i % colCount);


    if (sink)

    {

      gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(sink),
videoWidget->winId());

      g_object_unref(sink);

    }


    switch (gst_element_set_state(pipeline, GST_STATE_PLAYING)) // <-
blocks indefinitely

    {

    case GST_STATE_CHANGE_FAILURE:

      qInfo() << "Failed to start pipeline" << i;

      break;

    case GST_STATE_CHANGE_SUCCESS:

      qInfo() << "Pipeline" << i << "started";

      break;

    case GST_STATE_CHANGE_ASYNC:

      qInfo() << "Pipeline" << i << "is starting";

      break;

    case GST_STATE_CHANGE_NO_PREROLL:

      qInfo() << "Pipeline" << i << "started, but no data yet";

      break;

    default:

       qInfo() << "Unknown value";

      break;

    }


    pipelines.append(pipeline);

  }


  mainWidget.resize(1280, 720);

  mainWidget.showMaximized();


  int ret = app.exec();


  qInfo() << "Terminating";

  mainWidget.hide();


  for (int i = 0; i < pipelines.size(); ++i) {

    qInfo() << "Stopping pipeline" << i;

    switch (gst_element_set_state(pipelines[i], GST_STATE_NULL))

    {

    case GST_STATE_CHANGE_FAILURE:

      qInfo() << "Failed to stop pipeline" << i;

      break;

    case GST_STATE_CHANGE_SUCCESS:

      qInfo() << "Pipeline" << i << "stopped";

      break;

    case GST_STATE_CHANGE_ASYNC:

      qInfo() << "Pipeline" << i << "is stopping";

      break;

    case GST_STATE_CHANGE_NO_PREROLL:

      qInfo() << "Preroll" << i;

      break;

    default:

       qInfo() << "Unknown value";

      break;

    }


    g_object_unref(pipelines[i]);

  }


  return ret;

}


If someone could confirm the issue I would open a bug report.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/gstreamer-devel/attachments/20211109/d8c7d9e8/attachment-0001.htm>


More information about the gstreamer-devel mailing list