Pipeline gstreamer does not start after going from PAUSED to PLAYING

I have an application that can consume from 2 rstps for that I use two different pipelines and my idea is to play and pause one of them to change between them.

The code below shows a represenation of the code where i inizialize the two pipelines and then i just start one of them. Afterwards whenever i want the idea is to pause one od them and to start the other. The code works fine for the first change (i.e stop pipeline1 and start piline2, but when i want to stop pipeline2 and start again pipeline1 the image is frozen.

// callback function 
static GstPadProbeReturn my_function(GstPad *pad, GstPadProbeInfo *info, gpointer u_data)
{
    //in this function i have a way from other aplication to detect that i want a change in the pipeline
    if(pipeline==2){
       // stop pipeline 1
       stop(gst_pipeline_1);
       // change to pipeline 2
       change_pipeline(gst_pipeline_2);
    }else{
	// stop pipeline 2
        stop(gst_pipeline_2);
	// change to pipeline 1
        change_pipeline(gst_pipeline_optical);
    }
}


//function to start the pipeline
GstElement& start_pipeline(int pipeid)
{
  
  GstElement *pipe = nullptr; 
  //depending on the pipeid i get a different pipeline
  pipeline = "STRING WITH A PIPELINE"
  pipe = gst_parse_launch(pipeline.c_str(), &gerror);
  return *pipe;
}

// function to select the pipeline to use
void change_pipeline(GstElement *pipe)
{

    gst_pipeline = pipe;
    src_pad = gst_element_get_static_pad(conv, "src");
    gst_pad_add_probe(src_pad, GST_PAD_PROBE_TYPE_BUFFER, my_function, NULL, NULL);
    ret = gst_element_set_state((GstElement *)gst_pipeline, GST_STATE_PLAYING);
    g_usleep(1000);
    bus = gst_pipeline_get_bus(GST_PIPELINE(gst_pipeline));
    gst_bus_poll(bus, GST_MESSAGE_EOS, GST_CLOCK_TIME_NONE);
   
}

I have printed the status of the piplines and the PAUSE is working to go from pipeline 1 to piline 2

----- status pipeline1 ---
GstElement(capsfilter10), status = PAUSED, pending = VOID_PENDING
GstElement(capsfilter4), status = PAUSED, pending = VOID_PENDING
GstElement(capsfilter3), status = PAUSED, pending = VOID_PENDING
GstElement(capsfilter2), status = PAUSED, pending = VOID_PENDING
GstElement(capsfilter1), status = PAUSED, pending = VOID_PENDING
GstElement(udpsink0), status = PAUSED, pending = VOID_PENDING
GstElement(rtpvp9pay0), status = PAUSED, pending = VOID_PENDING
GstElement(nvv4l2vp9enc0), status = PAUSED, pending = VOID_PENDING
GstElement(queue0), status = PAUSED, pending = VOID_PENDING
GstElement(nvvconv1), status = PAUSED, pending = VOID_PENDING
GstElement(myconv), status = PAUSED, pending = VOID_PENDING
GstElement(nvv4l2decoder0), status = PAUSED, pending = VOID_PENDING
GstElement(rtph265depay0), status = PAUSED, pending = VOID_PENDING
GstElement(rtspsrc0), status = PAUSED, pending = VOID_PENDING
========================
----- status pipeline2 ---
GstElement(capsfilter9), status = PLAYING, pending = VOID_PENDING
GstElement(capsfilter8), status = PLAYING, pending = VOID_PENDING
GstElement(capsfilter7), status = PLAYING, pending = VOID_PENDING
GstElement(capsfilter6), status = PLAYING, pending = VOID_PENDING
GstElement(udpsink1), status = PLAYING, pending = VOID_PENDING
GstElement(rtpvp9pay1), status = PLAYING, pending = VOID_PENDING
GstElement(nvv4l2vp9enc1), status = PLAYING, pending = VOID_PENDING
GstElement(queue1), status = PLAYING, pending = VOID_PENDING
GstElement(nvvconv3), status = PLAYING, pending = VOID_PENDING
GstElement(myconv), status = PLAYING, pending = VOID_PENDING
GstElement(nvv4l2decoder1), status = PLAYING, pending = VOID_PENDING
GstElement(rtph265depay1), status = PLAYING, pending = VOID_PENDING
GstElement(rtspsrc1), status = PLAYING, pending = VOID_PENDING

then to go from pipline 2 to pipeline 1. the status it looks that it is working but the stream is frozen and the code goes unitl gst_bus_poll(bus, GST_MESSAGE_EOS, GST_CLOCK_TIME_NONE);

----- status pipeline1 ---
GstElement(capsfilter10), status = PLAYING, pending = VOID_PENDING
GstElement(capsfilter4), status = PLAYING, pending = VOID_PENDING
GstElement(capsfilter3), status = PLAYING, pending = VOID_PENDING
GstElement(capsfilter2), status = PLAYING, pending = VOID_PENDING
GstElement(capsfilter1), status = PLAYING, pending = VOID_PENDING
GstElement(udpsink0), status = PLAYING, pending = VOID_PENDING
GstElement(rtpvp9pay0), status = PLAYING, pending = VOID_PENDING
GstElement(nvv4l2vp9enc0), status = PLAYING, pending = VOID_PENDING
GstElement(queue0), status = PLAYING, pending = VOID_PENDING
GstElement(nvvconv1), status = PLAYING, pending = VOID_PENDING
GstElement(myconv), status = PLAYING, pending = VOID_PENDING
GstElement(nvv4l2decoder0), status = PLAYING, pending = VOID_PENDING
GstElement(rtph265depay0), status = PLAYING, pending = VOID_PENDING
GstElement(rtspsrc0), status = PLAYING, pending = VOID_PENDING
========================
----- status pipeline2 ---
GstElement(capsfilter11), status = PAUSED, pending = VOID_PENDING
GstElement(capsfilter9), status = PAUSED, pending = VOID_PENDING
GstElement(capsfilter8), status = PAUSED, pending = VOID_PENDING
GstElement(capsfilter7), status = PAUSED, pending = VOID_PENDING
GstElement(capsfilter6), status = PAUSED, pending = VOID_PENDING
GstElement(udpsink1), status = PAUSED, pending = VOID_PENDING
GstElement(rtpvp9pay1), status = PAUSED, pending = VOID_PENDING
GstElement(nvv4l2vp9enc1), status = PAUSED, pending = VOID_PENDING
GstElement(queue1), status = PAUSED, pending = VOID_PENDING
GstElement(nvvconv3), status = PAUSED, pending = VOID_PENDING
GstElement(myconv), status = PAUSED, pending = VOID_PENDING
GstElement(nvv4l2decoder1), status = PAUSED, pending = VOID_PENDING
GstElement(rtph265depay1), status = PAUSED, pending = VOID_PENDING
GstElement(rtspsrc1), status = PAUSED, pending = VOID_PENDING
========================

Another option i have tried is to set the pipelines to NULL and create again the pipeline but then i got the error:

“GStreamer-WARNING **: 19:09:21.163: Trying to join task 0x7f100243b0 from its thread would deadlock. You cannot change the state of an element from its streaming thread. Use g_idle_add() or post a GstMessage on the bus to schedule the state change from the main thread”

Hi,
For live source you would need to send EoS in the application, please refer to this sample:
GStreamer C++ nvarguscamerasrc - #5 by DaneLLL

Would need to send EoS by calling:

gst_element_send_event ((GstElement*)gst_pipeline, gst_event_new_eos ());

And please switch to NULL state and re-initialize the pipeline.

Hi,

I am trying to send EoS message and then afterwards switch to NULL. However, the problem is that i do not get the EoS message. The program is block in gst_bus_poll

The other option is to set the state to NULL:

gst_element_set_state((GstElement *)gst_pipeline, GST_STATE_NULL);

However this produces a warning:

“GStreamer-WARNING **: 19:09:21.163: Trying to join task 0x7f100243b0 from its thread would deadlock. You cannot change the state of an element from its streaming thread. Use g_idle_add() or post a GstMessage on the bus to schedule the state change from the main thread”

this results on a non–controlled behavior sometimes it works and i can change between pipelines and sometimes the image is frozen. How can avoid this warning? As i said i have tried to post a GstMessage on the bus but it is not sending the message.

Hi,
You may try to apply the string to this python sample and check if it works:
Nvv4l2decoder sometimes fails to negotiate with downstream after several pipeline re-launches - #16 by DaneLLL

We have tired UDP and RTSP and don’t hit the issue. The RTSP string is like:

    pipeline = Gst.parse_launch(
        "rtspsrc location=rtsp://10.19.107.227:8554/test ! rtph264depay ! h264parse ! nvv4l2decoder ! nvvidconv ! video/x-raw,format=I420 ! fakesink "
    )

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.