In this section we talk about some techniques for dynamically modifying the pipeline. We are talking specifically about changing the pipeline while it is in the PLAYING state without interrupting the flow.
There are some important things to consider when building dynamic pipelines:
When removing elements from the pipeline, make sure that there is no dataflow on unlinked pads because that will cause a fatal pipeline error. Always block source pads (in push mode) or sink pads (in pull mode) before unlinking pads. See also Section 18.4.1.
When adding elements to a pipeline, make sure to put the element into the right state, usually the same state as the parent, before allowing dataflow the element. When an element is newly created, it is in the NULL state and will return an error when it receives data. See also Section 18.4.1.
When adding elements to a pipeline, GStreamer will by default set the clock and base-time on the element to the current values of the pipeline. This means that the element will be able to construct the same pipeline running-time as the other elements in the pipeline. This means that sinks will synchronize buffers like the other sinks in the pipeline and that sources produce buffers with a running-time that matches the other sources.
When unlinking elements from an upstream chain, always make sure to flush any queued data in the element by sending an EOS event down the element sink pad(s) and by waiting that the EOS leaves the elements (with an event probe). See also Section 18.4.1.
A live source will produce buffers with a running-time of the current running-time in the pipeline.
A pipeline without a live source produces buffers with a running-time starting from 0. Likewise, after a flushing seek, those pipelines reset the running-time back to 0.
The running-time can be changed with
gst_pad_set_offset (). It is important to
know the running-time of the elements in the pipeline in order
to maintain synchronization.
Adding elements might change the state of the pipeline. Adding a non-prerolled sink, for example, brings the pipeline back to the prerolling state. Removing a non-prerolled sink, for example, might change the pipeline to PAUSED and PLAYING state.
Adding a live source cancels the preroll stage and put the pipeline to the playing state. Adding a live source or other live elements might also change the latency of a pipeline.
Adding or removing elements to the pipeline might change the clock selection of the pipeline. If the newly added element provides a clock, it might be worth changing the clock in the pipeline to the new clock. If, on the other hand, the element that provides the clock for the pipeline is removed, a new clock has to be selected.
Adding and removing elements might cause upstream or downstream elements to renegotiate caps and or allocators. You don't really need to do anything from the application, plugins largely adapt themself to the new pipeline topology in order to optimize their formats and allocation strategy.
What is important is that when you add, remove or change elements in the pipeline, it is possible that the pipeline needs to negotiate a new format and this can fail. Usually you can fix this by inserting the right converter elements where needed.
GStreamer offers support for doing about any dynamic pipeline modification but it requires you to know a bit of details before you can do this without causing pipeline errors. In the following sections we will demonstrate a couple of typical use-cases.