GNOME Bugzilla – Bug 732558
queue: ignore not-negotiated if a reconfigure is pending
Last modified: 2014-07-01 16:40:25 UTC
This commit avoids NOT_NEGOTIATED error when the queue pushes a stored buffer after sink element needs a reconfigure. Pushing the buffer provokes sending sticky events, where one of them is the event with the old caps, and if they are not compatible with the new ones allowed by the sink, GST_FLOW_NOT_NEGOTIATED is returned. Queue should ignore this error if the src pad needs to be reconfigured (as basesrc does), so it also has to manage RECONFIGURE flag in this pad, clearing it when a CAPS event is pushed by the queue's thread. Based on commit 5c0e02c79c88f8dddcf9b93bd9f30d75c24ac82e See https://bugzilla.gnome.org/show_bug.cgi?id=681198
Created attachment 279695 [details] [review] A patch to solve the bug
Not sure this is correct. What happens if upstream never tries to reconfigure? It will then continue pushing buffers into queue that are then dropped... forever
I think that it can not take place for some motives: 1) When pads are linked a reconfigure event is sent (or am I wrong?). 2) When a CAPS event is sent I use gst_pad_check_reconfigure to clear the RECONFIGURE flag in the srcpad, so when a buffer is pushed, gst_pad_needs_reconfigure only returns TRUE after received RECONFIGURED and before sent the CAPS event.
Yes, but why should there ever be a CAPS event? RECONFIGURE events can be sent at any time, not only during linking. And elements can just ignore them if they want to, they don't have to renegotiate or anything. The RECONFIGURE event is just a hint that it would be a good idea to renegotiate.
In this case, I agree with you, but in what way can we solve the problem? This commit was done to solve it: http://cgit.freedesktop.org/gstreamer/gstreamer/commit/?id=5c0e02c79c88f8dddcf9b93bd9f30d75c24ac82e But if we use a queue it does not work because a shared var (srcresult) is used by the queue, and its chain function always returns the value of the last buffer in pushed the queue's thread (if push func return value was different from GST_FLOW_OK).
In basesrc that can be done because we know that nothing is upstream of basesrc, and basesrc will renegotiate in any case. How to solve that problem for you depends on the exact pipeline you have, why it needs to be reconfigured and what you do with your pipeline in general.
So, if I have understood you well, we can say that this must be managed by the app level (where the pipeline is built) and not by GStreamer core elements?
Depends on your pipeline, but can be done at the app level.
So, I will evaluate my pipeline and see if we can do it into GStreamer elements. I prefer it to encapsulate the software and avoid workarounds in the app level for me and for other developers. If I have more info I will tell you. Thanks for your help ;).
Let's close it for now then :) You could also write a simple element that you put everywhere in your pipeline where necessary, that does exactly what your patch does, and otherwise just works like identity.