Bugzilla – Bug 53709
Filter sinks (and sources?) have too small max_rewind
Last modified: 2012-08-19 11:25:05 UTC
"With filter sinks there may be an arbitrary amount of sinks and sink inputs stacked. The filter sinks may or may not have a buffer of their own, but the sink inputs certainly will each have a render_memblockq. The "real" sink inputs, for example native protocol streams, need to keep enough old data buffered to cover all audio that is buffered in the stack of filter sinks.
BUG: Currently this is broken. The sink input implementations assume that storing max_rewind plus the extra data in their own sink input's render_memblockq is enough. That's OK: the assumption really should hold. The problem is that it doesn't. The max_rewind of a filter sink is incorrect. It's simply copied from the root sink. That's not a good idea, because it ignores the data that is buffered in the filter sink's sink input's render_memblockq, and if the filter sink does any buffering of its own, then also that data is missing from max_rewind. Having a too small max_rewind value means that rewind requests get truncated too much, causing unnecessary latency.
The max_rewind variable is somewhat static. It can change when the latency configuration changes, but it can't change depending on how much data is currently buffered. max_rewind is supposed to tell an upper limit for how much the sink can have data buffered, not the currently buffered amount. Since render_memblockqs can have an arbitrary amount of data buffered, how can a filter sink provide a meaningful value for max_rewind? I think the answer is that the filter sinks should never return more data from their pop callbacks than requested. That way the render_memblockq of the sink input will never contain any extra data. Also the pa_sink_render_* functions need to have a parameter for specifying a maximum size for the rendered data, because the rendering functions are called by the filter sinks, and if the rendering can result in an arbitrarily large chunk that the filter sink has to buffer, then it's still impossible for the filter sink to provide a meaningful max_rewind value."
I have not had a look how source rewinding works, but it's quite likely that the filter sources have the same issue.