Xvimagesink waiting endlessly for PLAYING state

Andrzej Bartoszek trevorgryffits at gmail.com
Mon Apr 11 20:09:30 UTC 2016

Hello everyone.

I use GStreamer 1.4.1 to develop a custom player/converter application. I
cannot update GStreamer version right now. I have some problems with
playing functionality. As a sink I use xvimagesink (let's call it renderer)
located in custom bin (let's call it rendererbin). This bin is the last one
in pipeline and this sink is the only one. Whole pipeline is rather long
(several dozens of elements grouped in various bins) and contains over a
dozen custom elements so I am not posting it here. I have tried to simplify
the pipeline, but it seems that described bug occurs more often for the
long ones.

The problem is that player stops after first/second frame of video. It
happens rather often (over 10% of all cases). Xvimagesink is stuck in
PREROLLing. However, queue before renderer is full and its task on srcpad
is waiting (fruitlessly) in gst_base_sink_wait_preroll for PLAYING state.
So, why this is change is not happening (AFAIU)?

Well, it is not entirely truth. Renderer enters PLAYING state without
problems in response of proper "signal" from rendererbin. However, right
after this change comes FLUSH_START event resulting in call to
gst_element_lost_state. Renderer goes back to PAUSED state asynchronously
and signals this with proper message. This message goes to rendererbin
(causing same state change) and further - to the pipeline. And now, there
are two possibilities:
- pipeline managed to complete state change before receiving ASYNC_START
message. Pipeline change state to PAUSED and, after receiving ASYNC_DONE
message, performs state change to PLAYING - everything works fine.
- pipeline is still changing to PLAYING. In this case, ASYNC_START message
is ignored, because "element is busy" (bin_handle_async_start), and pending
state is not updated to PAUSED. Shortly after, pipeline enters PLAYING, and
pending is set to VOID_PENDING. In this way, after receiving ASYNC_DONE,
pipeline is not changing states any further. Results? Whole pipeline in
PLAYING, except renderer and rendererbin, doing nothing in PAUSED.

It's quite possible that I've misunderstood this whole state/preroll thing.
If this is the case, please let me know.

I know that I can workaround this problem by setting xvimagesink.async to
false. However, it seems that it alters synchronization, crucial in this
application, because it is combining video frames with timestamped data
coming from other sources. I am wondering if is there any better way to fix
this bug.

Thanks in advance.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/gstreamer-devel/attachments/20160411/a7916848/attachment-0001.html>

More information about the gstreamer-devel mailing list