playback: Use bitrate estimation from downstream for buffering
Submitted by Edward Hervey
When listening to internet radio streams (http, doesn't matter which codec) at one point (sometimes within a few seconds, sometimes after 30mins) it stops playing.
Sometimes is just stops playing back and never resumes, sometimes it stops playing back, buffers up some more data, and then resumes playback.
After digging a bit deeper it seems that for the stops-and-never-resumes scenario the issue is that souphttpsrc just stops reading (i.e. the server doesn't return anything).
After having a look at various graphs of what is being read, my gutt feeling (tm) is that we are playing back (and therefore reading from the server) slightly slower/faster than the remote server, resulting in the following:
- We connect to server and start downloading data (initially it might give us a burst from the previous X seconds of stream, which corresponds to the size of the ringbuffer the server keeps for providing encoded content)
- We read/playback the stream slightly slower/faster
- Eventually we end up wanting data which the server either no longer has in its queue (slower local playback) or hasn't encoded yet (faster local playback).
Taking the following values:
Server buffer : 5s
Readout speed : 0.2% slower than server encoding rate
We end up with:
Time after which we'll end up wanting to read data past the 5s buffer size:
5s / 0.002 => 2500s => 41m40s
If we were reading faster, then it's the opposite problem:
The server gives a burst of 5 seconds of data, after 41m40s we end up having caught up with live playback and need to buffer up some more data.
So essentially ... with the current implementation, unless your soundcard is at exactly the same playback rate as the server's encoding system ... you'll always end up with either:
- Your playback just stops (because we're playing back slightly slower and eventually have no more data to read from the server).
- Your playback pauses until there is more data to read (because we're playing back slightly faster).
Note : There might also be an issue with queue2 throttling the input too aggressively, will attach more findings after.