Let us clarify the contract between GStreamer and each element in the pipeline.
Non-live source elements must place a timestamp in each buffer that they deliver when this is possible. They must choose the timestamps and the values of the SEGMENT event in such a way that the running-time of the buffer starts from 0.
Some sources, such as filesrc, is not able to generate timestamps on all buffers. It can and must however create a timestamp on the first buffer (with a running-time of 0).
The source then pushes out the SEGMENT event followed by the timestamped buffers.
Live source elements must place a timestamp in each buffer that they deliver. They must choose the timestamps and the values of the SEGMENT event in such a way that the running-time of the buffer matches exactly the running-time of the pipeline clock when the first byte in the buffer was captured.
Parser/Decoder elements must use the incoming timestamps and transfer those to the resulting output buffers. They are allowed to interpolate or reconstruct timestamps on missing input buffers when they can.
Demuxer elements can usually set the timestamps stored inside the media file onto the outgoing buffers. They need to make sure that outgoing buffers that are to be played at the same time have the same running-time. Demuxers also need to take into account the incoming timestamps on buffers and use that to calculate an offset on the outgoing buffer timestamps.
Muxer elements should use the incoming buffer running-time to mux the different streams together. They should copy the incoming running-time to the outgoing buffers.
If the element is intended to emit samples at a specific time (real time
playing), the element should require a clock, and thus implement the
The sink should then make sure that the sample with running-time is played
exactly when the pipeline clock reaches that running-time + latency.
Some elements might use the clock API such as
to perform this action. Other sinks might need to use other means of
scheduling timely playback of the data.