diff options
author | Max Kellermann <max@musicpd.org> | 2018-01-01 19:22:45 +0100 |
---|---|---|
committer | Max Kellermann <max@musicpd.org> | 2018-01-02 23:15:51 +0100 |
commit | 6d0d8cf9cf07a5d0905f715be9a79f5de86e8b37 (patch) | |
tree | 2fd9692a25b7e80ed67320a395bf0bbed1f9f91c /src/output/Thread.cxx | |
parent | 14f669f4fbac72833e622f66f81950b4be3e3c12 (diff) |
filter/Filter: add virtual method Flush()
This will be used by filters which have internal buffers which need to
be flushed at the end, e.g. the "soxr" resampler.
Diffstat (limited to 'src/output/Thread.cxx')
-rw-r--r-- | src/output/Thread.cxx | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/src/output/Thread.cxx b/src/output/Thread.cxx index ac382864a..bad9e0a73 100644 --- a/src/output/Thread.cxx +++ b/src/output/Thread.cxx @@ -362,11 +362,42 @@ AudioOutputControl::InternalPause() noexcept skip_delay = true; } +static void +PlayFull(FilteredAudioOutput &output, ConstBuffer<void> _buffer) +{ + auto buffer = ConstBuffer<uint8_t>::FromVoid(_buffer); + + while (!buffer.empty()) { + size_t nbytes = output.Play(buffer.data, buffer.size); + assert(nbytes > 0); + + buffer.skip_front(nbytes); + } + +} + inline void AudioOutputControl::InternalDrain() noexcept { const ScopeUnlock unlock(mutex); + try { + /* flush the filter and play its remaining output */ + + while (true) { + auto buffer = source.Flush(); + if (buffer.IsNull()) + break; + + PlayFull(*output, buffer); + } + } catch (...) { + FormatError(std::current_exception(), + "Failed to flush filter on %s", GetLogName()); + InternalCloseError(std::current_exception()); + return; + } + output->Drain(); } |