Bug 54007 - The alsa sink does larger rewind than needed when the configured sink latency changes
The alsa sink does larger rewind than needed when the configured sink latency...
Status: NEW
Product: PulseAudio
Classification: Unclassified
Component: alsa
unspecified
Other All
: medium minor
Assigned To: pulseaudio-bugs
pulseaudio-bugs
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2012-08-24 13:43 UTC by Tanu Kaskinen
Modified: 2012-08-25 02:39 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tanu Kaskinen 2012-08-24 13:43:56 UTC
If a sink supports dynamic latency and the latency is adjusted downwards, there needs to be a rewind to ensure that the sink buffer doesn't contain more data than what is allowed by the new latency. This is because rewind requests can't be larger than the configured latency, and if there's more data than that in the buffer, a later rewind request may end up being too small.

The alsa sink requests the rewind in sink_update_requested_latency_cb():

    if (u->hwbuf_unused > before) {
        pa_log_debug("Requesting rewind due to latency change.");
        pa_sink_request_rewind(s, (size_t) -1);
    }

Doing a full rewind (-1 as the rewind amount) is not necessary, as far as I can see. It would be sufficient to rewind only by the difference between the old and new latency.
Comment 1 Tanu Kaskinen 2012-08-25 02:39:51 UTC
If this gets fixed, the fix may need to be more complicated than I first thought. If two sink inputs are created very quickly so that both PA_SINK_MESSAGE_ADD_INPUT messages will be processed before the rewind request from the first one is processed, and both cause the latency to go down (so the first sink input requests a low latency and the second sink input requests even lower latency), then the second rewind request will be too small if its size is calculated just by subtracting the new latency from the old one. The rewind request size needs to be calculated by subtracting the new latency from the latency that was effective before the first sink input. That information isn't currently available in pa_sink, so it would need to be added there.

Maybe it's best to just do a full rewind after all, for simplicity...