output/fifo: use template AudioOutputWrapper
This commit is contained in:
parent
593bb5a8a7
commit
8bfb88840b
@ -21,6 +21,7 @@
|
||||
#include "FifoOutputPlugin.hxx"
|
||||
#include "config/ConfigError.hxx"
|
||||
#include "../OutputAPI.hxx"
|
||||
#include "../Wrapper.hxx"
|
||||
#include "../Timer.hxx"
|
||||
#include "fs/AllocatedPath.hxx"
|
||||
#include "fs/FileSystem.hxx"
|
||||
@ -51,16 +52,26 @@ struct FifoOutput {
|
||||
path(AllocatedPath::Null()), input(-1), output(-1),
|
||||
created(false) {}
|
||||
|
||||
~FifoOutput() {
|
||||
Close();
|
||||
}
|
||||
|
||||
bool Initialize(const ConfigBlock &block, Error &error) {
|
||||
return base.Configure(block, error);
|
||||
}
|
||||
|
||||
static FifoOutput *Create(const ConfigBlock &block, Error &error);
|
||||
|
||||
bool Create(Error &error);
|
||||
bool Check(Error &error);
|
||||
void Delete();
|
||||
|
||||
bool Open(Error &error);
|
||||
void Close();
|
||||
|
||||
unsigned Delay() const;
|
||||
size_t Play(const void *chunk, size_t size, Error &error);
|
||||
void Cancel();
|
||||
};
|
||||
|
||||
static constexpr Domain fifo_output_domain("fifo_output");
|
||||
@ -162,14 +173,8 @@ FifoOutput::Open(Error &error)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
fifo_open(FifoOutput *fd, Error &error)
|
||||
{
|
||||
return fd->Open(error);
|
||||
}
|
||||
|
||||
static AudioOutput *
|
||||
fifo_output_init(const ConfigBlock &block, Error &error)
|
||||
inline FifoOutput *
|
||||
FifoOutput::Create(const ConfigBlock &block, Error &error)
|
||||
{
|
||||
FifoOutput *fd = new FifoOutput();
|
||||
|
||||
@ -190,21 +195,12 @@ fifo_output_init(const ConfigBlock &block, Error &error)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!fifo_open(fd, error)) {
|
||||
if (!fd->Open(error)) {
|
||||
delete fd;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return &fd->base;
|
||||
}
|
||||
|
||||
static void
|
||||
fifo_output_finish(AudioOutput *ao)
|
||||
{
|
||||
FifoOutput *fd = (FifoOutput *)ao;
|
||||
|
||||
fd->Close();
|
||||
delete fd;
|
||||
return fd;
|
||||
}
|
||||
|
||||
static bool
|
||||
@ -226,47 +222,41 @@ fifo_output_close(AudioOutput *ao)
|
||||
delete fd->timer;
|
||||
}
|
||||
|
||||
static void
|
||||
fifo_output_cancel(AudioOutput *ao)
|
||||
inline void
|
||||
FifoOutput::Cancel()
|
||||
{
|
||||
FifoOutput *fd = (FifoOutput *)ao;
|
||||
char buf[FIFO_BUFFER_SIZE];
|
||||
int bytes = 1;
|
||||
|
||||
fd->timer->Reset();
|
||||
timer->Reset();
|
||||
|
||||
while (bytes > 0 && errno != EINTR)
|
||||
bytes = read(fd->input, buf, FIFO_BUFFER_SIZE);
|
||||
bytes = read(input, buf, FIFO_BUFFER_SIZE);
|
||||
|
||||
if (bytes < 0 && errno != EAGAIN) {
|
||||
FormatErrno(fifo_output_domain,
|
||||
"Flush of FIFO \"%s\" failed",
|
||||
fd->path_utf8.c_str());
|
||||
path_utf8.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned
|
||||
fifo_output_delay(AudioOutput *ao)
|
||||
inline unsigned
|
||||
FifoOutput::Delay() const
|
||||
{
|
||||
FifoOutput *fd = (FifoOutput *)ao;
|
||||
|
||||
return fd->timer->IsStarted()
|
||||
? fd->timer->GetDelay()
|
||||
return timer->IsStarted()
|
||||
? timer->GetDelay()
|
||||
: 0;
|
||||
}
|
||||
|
||||
static size_t
|
||||
fifo_output_play(AudioOutput *ao, const void *chunk, size_t size,
|
||||
Error &error)
|
||||
inline size_t
|
||||
FifoOutput::Play(const void *chunk, size_t size, Error &error)
|
||||
{
|
||||
FifoOutput *fd = (FifoOutput *)ao;
|
||||
|
||||
if (!fd->timer->IsStarted())
|
||||
fd->timer->Start();
|
||||
fd->timer->Add(size);
|
||||
if (!timer->IsStarted())
|
||||
timer->Start();
|
||||
timer->Add(size);
|
||||
|
||||
while (true) {
|
||||
ssize_t bytes = write(fd->output, chunk, size);
|
||||
ssize_t bytes = write(output, chunk, size);
|
||||
if (bytes > 0)
|
||||
return (size_t)bytes;
|
||||
|
||||
@ -274,33 +264,35 @@ fifo_output_play(AudioOutput *ao, const void *chunk, size_t size,
|
||||
switch (errno) {
|
||||
case EAGAIN:
|
||||
/* The pipe is full, so empty it */
|
||||
fifo_output_cancel(&fd->base);
|
||||
Cancel();
|
||||
continue;
|
||||
case EINTR:
|
||||
continue;
|
||||
}
|
||||
|
||||
error.FormatErrno("Failed to write to FIFO %s",
|
||||
fd->path_utf8.c_str());
|
||||
path_utf8.c_str());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typedef AudioOutputWrapper<FifoOutput> Wrapper;
|
||||
|
||||
const struct AudioOutputPlugin fifo_output_plugin = {
|
||||
"fifo",
|
||||
nullptr,
|
||||
fifo_output_init,
|
||||
fifo_output_finish,
|
||||
&Wrapper::Init,
|
||||
&Wrapper::Finish,
|
||||
nullptr,
|
||||
nullptr,
|
||||
fifo_output_open,
|
||||
fifo_output_close,
|
||||
fifo_output_delay,
|
||||
&Wrapper::Delay,
|
||||
nullptr,
|
||||
fifo_output_play,
|
||||
&Wrapper::Play,
|
||||
nullptr,
|
||||
fifo_output_cancel,
|
||||
&Wrapper::Cancel,
|
||||
nullptr,
|
||||
nullptr,
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user