diff --git a/NEWS b/NEWS index 3eb1f94bd..de839ce21 100644 --- a/NEWS +++ b/NEWS @@ -8,12 +8,13 @@ ver 0.22 (not yet released) - ffmpeg: new plugin based on FFmpeg's libavfilter library - hdcd: new plugin based on FFmpeg's "af_hdcd" for HDCD playback -ver 0.21.9 (not yet released) +ver 0.21.9 (2019/05/20) * input - buffer: fix deadlock bug * Android - fix crash on ARMv7 - request storage permission on Android 6+ +* fix spurious "single" mode bug ver 0.21.8 (2019/04/23) * input diff --git a/doc/protocol.rst b/doc/protocol.rst index 6cd51166d..187c6ed32 100644 --- a/doc/protocol.rst +++ b/doc/protocol.rst @@ -14,6 +14,9 @@ Once the client is connected to the server, they conduct a conversation until the client closes the connection. The conversation flow is always initiated by the client. +All data between the client and the server is encoded in +UTF-8. + The client transmits a command sequence, terminated by the newline character ``\n``. The server will respond with one or more lines, the last of which will be a @@ -42,9 +45,6 @@ quotation marks. Argument strings are separated from the command and any other arguments by linear white-space (' ' or '\\t'). -All data between the client and the server is encoded in -UTF-8. - Responses ========= @@ -52,6 +52,28 @@ A command returns ``OK`` on completion or ``ACK some error`` on failure. These denote the end of command execution. +Some commands return more data before the response ends with ``OK``. +Each line is usually in the form ``NAME: VALUE``. Example:: + + foo: bar + OK + +.. _binary: + +Binary Responses +---------------- + +Some commands can return binary data. This is initiated by a line +containing ``binary: 1234`` (followed as usual by a newline). After +that, the specified number of bytes of binary data follows (without an +extra newline, because this binary data is not a text line), and +finally the ``OK`` line. Example:: + + foo: bar + binary: 42 + <42 bytes>OK + + Failure responses ----------------- @@ -112,9 +134,9 @@ list begins with `command_list_begin` or `command_list_ok_begin` and ends with `command_list_end`. -It does not execute any commands until the list has ended. -The return value is whatever the return for a list of commands -is. On success for all commands, +It does not execute any commands until the list has ended. The +response is a concatentation of all individual responses. +On success for all commands, ``OK`` is returned. If a command fails, no more commands are executed and the appropriate ``ACK`` error is returned. If @@ -795,7 +817,7 @@ The music database Returns the file size and actual number of bytes read at the requested offset, followed - by the chunk requested as raw bytes, then a + by the chunk requested as raw bytes (see :ref:`binary`), then a newline and the completion code. Example:: @@ -803,8 +825,7 @@ The music database albumart foo/bar.ogg 0 size: 1024768 binary: 8192 - <8192 bytes> - OK + <8192 bytes>OK :command:`count {FILTER} [group {GROUPTYPE}]` Count the number of songs and their total playtime in diff --git a/src/player/Thread.cxx b/src/player/Thread.cxx index 8ef61b6b9..555bfa7d6 100644 --- a/src/player/Thread.cxx +++ b/src/player/Thread.cxx @@ -999,7 +999,7 @@ Player::Run() noexcept } } - if (dc.IsIdle() && queued && dc.pipe == pipe) { + if (dc.IsIdle() && queued) { /* the decoder has finished the current song; make it decode the next song */ @@ -1061,6 +1061,16 @@ Player::Run() noexcept SongBorder(); } else if (dc.IsIdle()) { + if (queued) + /* the decoder has just stopped, + between the two IsIdle() checks, + probably while UnlockCheckOutputs() + left the mutex unlocked; to restart + the decoder instead of stopping + playback completely, let's re-enter + this loop */ + continue; + /* check the size of the pipe again, because the decoder thread may have added something since we last checked */