Some basic questions in building dynamic rtsp pipeline for app with multiple start/stop toggles

An app is being made for rtsp streaming. The pipeline is made dynamically because camera encoding may be H264/H265.
The pipeline begins from “rtspsrc” and sends out add pad event after the pipeline is started. When add pad is received, the proper decoder, parser and video sink are created and added to a created bin + static pad. This bin is then added to the pipeline and its static pad is linked to the coming pad. Everything works fine. Note that Qt5 qml gl sink is applied in this app.

The first scenario:
the pipeline is stopped and then restarted in the app. URL does not change.

The question here is:
Do I have to destroy the bin part when remove pad event arrives and recreate the bin when the pipeline with the same URL restarts and add pad event comes again?

what I tried is as follows:

void buildPipeline() { 
      m_pipeline = gst_pipeline_new( nullptr );
      GstElement * rtsp_src = gst_element_factory_make( "rtspsrc", nullptr );
      m_addPadHandlerId = g_signal_connect( rtsp_src, "pad-added",   G_CALLBACK( &RtspCamera::onPadAdded ), this );
      m_removePadHandlerId = g_signal_connect( rtsp_src, "pad-removed", G_CALLBACK( &RtspCamera::onPadRemoved ), this );
}

void buildSinkBin() {
     videosink = gst_bin_new( "videosink" );
     GstElement * jitter = gst_element_factory_make( "rtpjitterbuffer", nullptr );
     ....
        
     GstPad * jitter_sink_pad = gst_element_get_static_pad( jitter, "sink" );
     if ( nullptr != jitter_sink_pad ) {
          GstPad * ghost_sinkpad = gst_ghost_pad_new( "sink", jitter_sink_pad );
          gst_pad_set_active( ghost_sinkpad, TRUE );
          gst_element_add_pad( bin, ghost_sinkpad );
          gst_object_unref( jitter_sink_pad );
     }    
}

void addPad( GstPad * pad ) {
      buildSinkBin();
      gst_bin_add( GST_BIN( m_pipeline ), videosink );
      gst_element_sync_state_with_parent( videosink );

      GstPad * sink_pad = gst_element_get_static_pad( videosink, "sink" );
      if ( nullptr != sink_pad ) {
          if ( GST_PAD_LINK_OK != gst_pad_link( pad, sink_pad ) ) {
          }
          gst_object_unref( sink_pad );
      }
}

void removePad( GstPad * pad ) {
}

When the pipeline is stopped and removePad is called, should I delete videosink
and recreate it when the pipeline is restarted while rtsp url does not change?

Since URL does not change, I would like to reuse the videosink without destroying it.

Rather than mucking with dynamic pipeline I would probably try to design this using interpipe (Rust) or gstinsterpipe given the dynamic nature of the inbound encodings. I personally don’t like building out dynamic pipelines given there are usually headaches. If I did take that approach then I would destroy the down stream bin and recreated it.

1 Like

Thanks for your reply, Steve. I tried to destroy down stream bin and recreated it. Doing it or not has no difference. One problem shows up after the widget sink and pipeline are destroyed. The app freezes when new widget and new pipeline are created. If only pipeline is destroyed and Qt widget for sink does not change, no problem. My app has up to 7 cameras and they are switched often.

found some info about gstinsterpipe and will take a look at it.
Agree that dynamic pipelines do cause some headaches.

It sounds like a setup similar to this example. The one main consideration here is renegotiation given input media property changes. That should be doable. If you do not need special handling of events then the Rust based inter may work for your particular setup.

Hope you get it figured out. Wish I could help more.

1 Like

Thanks a lot, Steve. Will check it out.

qml sink is created as follows:
auto video_item = m_videoItem->findChild< QQuickItem * >( “videoContent” );
GstElement * sink = gst_element_factory_make( “qmlglsink”, nullptr );
g_object_set( sink, “widget”, video_item, nullptr );

the sink element is added to RTSP pipeline as
GstElement * vsinkbin = gst_element_factory_make( “glsinkbin”, nullptr );
g_object_set( vsinkbin, “sink”, m_sink, nullptr );

When pipeline is deleted, is the sink widget video_item deleted as well?
My problem is:
GUI will freeze if pipeline is started/stopped twice, then delete pipeline and qml item widget to recreate the same pipeline for another URL in a new qml item widget.

no issues if pipeline is started/stopped only once, then delete pipeline and qml item widget to recreate the same pipeline for another URL in a new qml item widget.

dynamic change of qml item widget is required in the app.