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”