test/run_filter: ensure that partial frames will not get passed to the filter

This commit is contained in:
Max Kellermann 2019-03-14 14:13:53 +01:00
parent a6ecf6c992
commit 1a0865da7a
1 changed files with 50 additions and 4 deletions

View File

@ -26,6 +26,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"
@ -59,6 +60,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) {
@ -79,6 +124,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]);
@ -97,10 +144,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});