summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Kellermann <max@musicpd.org>2018-09-23 15:26:42 +0200
committerMax Kellermann <max@musicpd.org>2018-09-23 15:46:29 +0200
commit5b2374b9495bb9da4b07d03328c1ecac204af8d4 (patch)
treeb6087f3627300322063d18f0c95d2b1ab72be21f
parentc1600bcf3d5af915a2c4d999d92d9418c5058f65 (diff)
player/Thread: calculate `buffered_before_play` based on a fixed duration
Previously, there was the setting `buffered_before_play` which specified a percentage of the audio buffer, defaulting to `10%`. That was working well enough for quite some time, until high-quality audio formats became common. At 44.1 kHz, 16 bit stereo, MPD collected 2.3 seconds worth of data in the buffer before starting playback. With the same default settings and 192 kHz, 24 bit stereo, that was only 0.27 seconds. Making this depend on the byte size only leads to high latency at low quality, and too little data at high quality. The natural choice would be to use a duration instead of a byte size, which should give the same good experience with all audio formats. Since the `buffered_before_play` configuration setting was not understood well by users and caused more harm than good, this commit deprecates it. It has now no effect.
-rw-r--r--NEWS1
-rw-r--r--src/config/Templates.cxx2
-rw-r--r--src/player/Thread.cxx18
3 files changed, 17 insertions, 4 deletions
diff --git a/NEWS b/NEWS
index 4fbbe18a2..b68853d3d 100644
--- a/NEWS
+++ b/NEWS
@@ -14,6 +14,7 @@ ver 0.21 (not yet released)
- proxy: require libmpdclient 2.9
- proxy: forward `sort` and `window` to server
* player
+ - hard-code "buffer_before_play" to 1 second, independent of audio format
- "one-shot" single mode
* input
- curl: download to buffer instead of throttling transfer
diff --git a/src/config/Templates.cxx b/src/config/Templates.cxx
index 3c2d78aae..8df588aca 100644
--- a/src/config/Templates.cxx
+++ b/src/config/Templates.cxx
@@ -54,7 +54,7 @@ const ConfigTemplate config_param_templates[] = {
{ "volume_normalization" },
{ "samplerate_converter" },
{ "audio_buffer_size" },
- { "buffer_before_play" },
+ { "buffer_before_play", false, true },
{ "http_proxy_host", false, true },
{ "http_proxy_port", false, true },
{ "http_proxy_user", false, true },
diff --git a/src/player/Thread.cxx b/src/player/Thread.cxx
index 017e4c5be..cd930c039 100644
--- a/src/player/Thread.cxx
+++ b/src/player/Thread.cxx
@@ -57,6 +57,12 @@
static constexpr Domain player_domain("player");
+/**
+ * Start playback as soon as enough data for this duration has been
+ * pushed to the decoder pipe.
+ */
+static constexpr auto buffer_before_play_duration = std::chrono::seconds(1);
+
class Player {
PlayerControl &pc;
@@ -80,9 +86,10 @@ class Player {
/**
* Start playback as soon as this number of chunks has been
- * pushed to the decoder pipe.
+ * pushed to the decoder pipe. This is calculated based on
+ * #buffer_before_play_duration.
*/
- const unsigned buffer_before_play;
+ unsigned buffer_before_play;
/**
* If the decoder pipe gets consumed below this threshold,
@@ -191,7 +198,6 @@ public:
Player(PlayerControl &_pc, DecoderControl &_dc,
MusicBuffer &_buffer) noexcept
:pc(_pc), dc(_dc), buffer(_buffer),
- buffer_before_play(pc.buffered_before_play),
decoder_wakeup_threshold(buffer.GetSize() * 3 / 4)
{
}
@@ -517,6 +523,12 @@ Player::CheckDecoderStartup() noexcept
play_audio_format = dc.out_audio_format;
decoder_starting = false;
+ const size_t buffer_before_play_size =
+ play_audio_format.TimeToSize(buffer_before_play_duration);
+ buffer_before_play =
+ (buffer_before_play_size + sizeof(MusicChunk::data) - 1)
+ / sizeof(MusicChunk::data);
+
idle_add(IDLE_PLAYER);
if (pending_seek > SongTime::zero()) {