0

To begin, I run this command to set all of my pipeline elements to paused:
int ret = gst_element_set_state (pipeline, GST_STATE_PAUSED);

Next, I check all of my pipeline components to ensure that they are in the paused state (which they are):

GstElement(imagesaver), status = PAUSED, pending = VOID_PENDING
GstElement(saveImageTee), status = PAUSED, pending = VOID_PENDING
GstElement(imagevideoconvert), status = PAUSED, pending = VOID_PENDING
GstElement(imagecapsfilter), status = PAUSED, pending = VOID_PENDING
GstElement(imagevideocrop), status = PAUSED, pending = VOID_PENDING
GstElement(videomuxer), status = PAUSED, pending = VOID_PENDING
GstElement(h264encoder), status = PAUSED, pending = VOID_PENDING
GstElement(imagequeue), status = PAUSED, pending = VOID_PENDING
GstElement(featurescanner), status = PAUSED, pending = PAUSED
GstElement(scannerqueue), status = PAUSED, pending = VOID_PENDING
GstElement(cfilter), status = PAUSED, pending = VOID_PENDING
GstElement(videoconversion), status = PAUSED, pending = VOID_PENDING
GstElement(convertqueue), status = PAUSED, pending = VOID_PENDING
GstElement(crop), status = PAUSED, pending = VOID_PENDING
GstElement(cropQueue), status = PAUSED, pending = VOID_PENDING
GstElement(source), status = PAUSED, pending = VOID_PENDING

Then I try to play my pipeline: int ret = gst_element_set_state(pipeline, GST_STATE_PLAYING);

Which results in all my elements being set to the NULL state

GstElement(imagesaver), status = NULL, pending = VOID_PENDING
GstElement(saveImageTee), status = NULL, pending = VOID_PENDING
GstElement(imagevideoconvert), status = NULL, pending = VOID_PENDING
GstElement(imagecapsfilter), status = NULL, pending = VOID_PENDING
GstElement(imagevideocrop), status = NULL, pending = VOID_PENDING
GstElement(videomuxer), status = NULL, pending = VOID_PENDING
GstElement(h264encoder), status = NULL, pending = VOID_PENDING
GstElement(imagequeue), status = NULL, pending = VOID_PENDING
GstElement(featurescanner), status = NULL, pending = VOID_PENDING
GstElement(scannerqueue), status = NULL, pending = VOID_PENDING
GstElement(cfilter), status = NULL, pending = VOID_PENDING
GstElement(videoconversion), status = NULL, pending = VOID_PENDING
GstElement(convertqueue), status = NULL, pending = VOID_PENDING
GstElement(crop), status = NULL, pending = VOID_PENDING
GstElement(cropQueue), status = NULL, pending = VOID_PENDING
GstElement(source), status = NULL, pending = VOID_PENDING

The error message I get with this output is:

Setting pipeline to Play state
Pipeline would not play, returned 2

The return value of 2 is: GST_STATE_CHANGE_ASYNC which I assumed would be fixed by setting my fileSink async property to false: g_object_set(G_OBJECT (fileSink), "async", gboolean(FALSE), NULL);

This is the function I am calling to play the pipeline after being in a paused state:

void ScanningProcessor::PlayPipeline()
{
    gst_element_set_state(GST_ELEMENT(fileSink), GST_STATE_PLAYING);
    if(GST_STATE(pipeline) != GST_STATE_NULL)
    {
        MBPLog::Log(LM_CameraLibrary, LS_Informational, "Setting pipeline to Play state");
        int ret = gst_element_set_state(pipeline, GST_STATE_PLAYING);
        if(ret != GST_STATE_PLAYING) 
        {
            MBPLog::Log(LM_CameraLibrary, LS_Error, "Pipeline would not play, returned %d", ret);
            gst_element_set_state (pipeline, GST_STATE_NULL);
        }
    } 
}
palacetrading
  • 71
  • 1
  • 11
  • This might require some debugging to see the root case. It would help if you provide a [Minimal, Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example) so that people can help. – Damir Tenishev Sep 17 '21 at 00:35
  • `if(GST_STATE(pipeline) != GST_STATE_NULL)` - your code does not throw an exception or a popup with error. Put some code in that displays the error. – moi Sep 18 '21 at 14:10
  • @moi My code always enters that section of the code because the pipeline is in the PAUSED state. I then get a return value of 1 when I play the pipeline which means success but the pipeline elements are all NULL and not PLAYING so its not working – palacetrading Sep 19 '21 at 17:07
  • Try `gst_element_set_state(pipeline, GST_STATE_NULL);` before `gst_element_set_state(pipeline, GST_STATE_PLAYING);` – moi Sep 21 '21 at 06:21
  • @moi that didn't solve the issue. there is something blocking the transition to playing in my pipeline. – palacetrading Sep 21 '21 at 12:38
  • idk if exactly related, but here is a similar question: https://stackoverflow.com/questions/27547500/how-to-resume-playing-after-paused-using-gstreamer – Sneaky Polar Bear Sep 23 '21 at 19:32

1 Answers1

0

Depending on what your pipeline looks like, going to the PLAYING state will always happen asynchronously (hence the GST_STATE_CHANGE_ASYNC return value). This makes sense (for example: in certain cases it takes some time to setup the connection, fetch the data and so on), but is different from what you seem to expect.

In other words, if you really want to check if you're going into the playing state, you should call gst_element_get_state(), which actually waits (and as such blocks your thread) for the state change to happen.

GstStateChangeReturn ret;
GstState state;
GstState pending;

ret = gst_element_get_state (pipeline, &state, NULL, GST_CLOCK_TIME_NONE);
if (ret == GST_STATE_CHANGE_FAILURE) {
  MBPLog::Log(LM_CameraLibrary, LS_Error, "Pipeline would not play");
  return; // or whatever cleanup you want
} else {
  MBPLog::Log(LM_CameraLibrary, LS_Informational, "Pipeline is now in Playing state");
  // If you specified an actual timeout instead of GST_CLOCK_TIME_NONE,
  // you should check here if the return value is still
  // GST_STATE_CHANGE_SUCCESS of course.
}
nielsdg
  • 2,318
  • 1
  • 13
  • 22
  • Does setting the async parameter to false not fix that? Btw I no longer get the return value of GST_STATE_CHANGE_ASYNC after I did what I just described. I now get a return value of 1 which means success but when I check my pipeline elements they are all NULL and not PLAYING – palacetrading Sep 19 '21 at 17:10