summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorMax Kellermann <max@musicpd.org>2019-03-14 14:13:53 +0100
committerMax Kellermann <max@musicpd.org>2020-09-07 20:07:08 +0200
commit1678a6eb591b33203fb66ef81664d832cfadd2f4 (patch)
tree7281e2e260369634f3f6b9e71f52a0d0d51fa06a /test
parentb4dc2c07d515b5f0360c88b10292788591ae1117 (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.cxx54
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});