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.
This commit is contained in:
Max Kellermann
2018-01-01 19:22:45 +01:00
parent 14f669f4fb
commit 6d0d8cf9cf
9 changed files with 134 additions and 7 deletions

View File

@@ -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();
}