diff options
author | Max Kellermann <max@musicpd.org> | 2019-03-14 14:13:53 +0100 |
---|---|---|
committer | Max Kellermann <max@musicpd.org> | 2020-09-07 20:07:08 +0200 |
commit | 1678a6eb591b33203fb66ef81664d832cfadd2f4 (patch) | |
tree | 7281e2e260369634f3f6b9e71f52a0d0d51fa06a /test | |
parent | b4dc2c07d515b5f0360c88b10292788591ae1117 (diff) |
test/run_filter: ensure that partial frames will not get passed to the filter
Diffstat (limited to 'test')
-rw-r--r-- | test/run_filter.cxx | 54 |
1 files changed, 50 insertions, 4 deletions
diff --git a/test/run_filter.cxx b/test/run_filter.cxx index bcc3ea2af..9b2994da1 100644 --- a/test/run_filter.cxx +++ b/test/run_filter.cxx @@ -27,6 +27,7 @@ #include "filter/Prepared.hxx" #include "pcm/Volume.hxx" #include "mixer/MixerControl.hxx" +#include "system/Error.hxx" #include "util/ConstBuffer.hxx" #include "util/StringBuffer.hxx" #include "util/RuntimeError.hxx" @@ -60,6 +61,50 @@ LoadFilter(const ConfigData &config, const char *name) return filter_configured_new(*param); } +static size_t +ReadOrThrow(int fd, void *buffer, size_t size) +{ + auto nbytes = read(fd, buffer, size); + if (nbytes < 0) + throw MakeErrno("Read failed"); + + return nbytes; +} + +static void +FullRead(int fd, void *_buffer, size_t size) +{ + auto buffer = (uint8_t *)_buffer; + + while (size > 0) { + size_t nbytes = ReadOrThrow(fd, buffer, size); + if (nbytes == 0) + throw std::runtime_error("Premature end of input"); + + buffer += nbytes; + size -= nbytes; + } +} + +static size_t +ReadFrames(int fd, void *_buffer, size_t size, size_t frame_size) +{ + auto buffer = (uint8_t *)_buffer; + + size = (size / frame_size) * frame_size; + + size_t nbytes = ReadOrThrow(fd, buffer, size); + + const size_t modulo = nbytes % frame_size; + if (modulo > 0) { + size_t rest = frame_size - modulo; + FullRead(fd, buffer + nbytes, rest); + nbytes += rest; + } + + return nbytes; +} + int main(int argc, char **argv) try { if (argc < 3 || argc > 4) { @@ -80,6 +125,8 @@ try { if (argc > 3) audio_format = ParseAudioFormat(argv[3], false); + const size_t in_frame_size = audio_format.GetFrameSize(); + /* initialize the filter */ auto prepared_filter = LoadFilter(config, argv[2]); @@ -98,10 +145,9 @@ try { while (true) { char buffer[4096]; - ssize_t nbytes; - - nbytes = read(0, buffer, sizeof(buffer)); - if (nbytes <= 0) + ssize_t nbytes = ReadFrames(0, buffer, sizeof(buffer), + in_frame_size); + if (nbytes == 0) break; auto dest = filter->FilterPCM({(const void *)buffer, (size_t)nbytes}); |