output/httpd: use AudioOutputWrapper

This commit is contained in:
Max Kellermann 2017-01-25 10:03:17 +01:00
parent ddd8b16f2b
commit 8d70d10aba
2 changed files with 43 additions and 96 deletions

View File

@ -26,6 +26,7 @@
#define MPD_OUTPUT_HTTPD_INTERNAL_H #define MPD_OUTPUT_HTTPD_INTERNAL_H
#include "HttpdClient.hxx" #include "HttpdClient.hxx"
#include "output/Wrapper.hxx"
#include "output/Internal.hxx" #include "output/Internal.hxx"
#include "output/Timer.hxx" #include "output/Timer.hxx"
#include "thread/Mutex.hxx" #include "thread/Mutex.hxx"
@ -49,6 +50,8 @@ class Encoder;
struct Tag; struct Tag;
class HttpdOutput final : ServerSocket, DeferredMonitor { class HttpdOutput final : ServerSocket, DeferredMonitor {
friend struct AudioOutputWrapper<HttpdOutput>;
AudioOutput base; AudioOutput base;
/** /**
@ -152,9 +155,7 @@ public:
HttpdOutput(EventLoop &_loop, const ConfigBlock &block); HttpdOutput(EventLoop &_loop, const ConfigBlock &block);
~HttpdOutput(); ~HttpdOutput();
operator AudioOutput *() { static HttpdOutput *Create(const ConfigBlock &block);
return &base;
}
#if CLANG_OR_GCC_VERSION(4,7) #if CLANG_OR_GCC_VERSION(4,7)
constexpr constexpr
@ -168,6 +169,14 @@ public:
void Bind(); void Bind();
void Unbind(); void Unbind();
void Enable() {
Bind();
}
void Disable() {
Unbind();
}
/** /**
* Caller must lock the mutex. * Caller must lock the mutex.
* *
@ -249,6 +258,9 @@ public:
void CancelAllClients(); void CancelAllClients();
void Cancel();
bool Pause();
private: private:
virtual void RunDeferred() override; virtual void RunDeferred() override;

View File

@ -117,18 +117,10 @@ HttpdOutput::Unbind()
}); });
} }
static AudioOutput * HttpdOutput *
httpd_output_init(const ConfigBlock &block) HttpdOutput::Create(const ConfigBlock &block)
{ {
return *new HttpdOutput(io_thread_get(), block); return new HttpdOutput(io_thread_get(), block);
}
static void
httpd_output_finish(AudioOutput *ao)
{
HttpdOutput *httpd = HttpdOutput::Cast(ao);
delete httpd;
} }
/** /**
@ -247,22 +239,6 @@ HttpdOutput::ReadPage()
return Page::Copy(buffer, size); return Page::Copy(buffer, size);
} }
static void
httpd_output_enable(AudioOutput *ao)
{
HttpdOutput *httpd = HttpdOutput::Cast(ao);
httpd->Bind();
}
static void
httpd_output_disable(AudioOutput *ao)
{
HttpdOutput *httpd = HttpdOutput::Cast(ao);
httpd->Unbind();
}
inline void inline void
HttpdOutput::OpenEncoder(AudioFormat &audio_format) HttpdOutput::OpenEncoder(AudioFormat &audio_format)
{ {
@ -282,6 +258,8 @@ HttpdOutput::Open(AudioFormat &audio_format)
assert(!open); assert(!open);
assert(clients.empty()); assert(clients.empty());
const std::lock_guard<Mutex> protect(mutex);
OpenEncoder(audio_format); OpenEncoder(audio_format);
/* initialize other attributes */ /* initialize other attributes */
@ -291,20 +269,12 @@ HttpdOutput::Open(AudioFormat &audio_format)
open = true; open = true;
} }
static void
httpd_output_open(AudioOutput *ao, AudioFormat &audio_format)
{
HttpdOutput *httpd = HttpdOutput::Cast(ao);
const std::lock_guard<Mutex> protect(httpd->mutex);
httpd->Open(audio_format);
}
inline void inline void
HttpdOutput::Close() HttpdOutput::Close()
{ {
assert(open); const std::lock_guard<Mutex> protect(mutex);
assert(open);
open = false; open = false;
delete timer; delete timer;
@ -319,15 +289,6 @@ HttpdOutput::Close()
delete encoder; delete encoder;
} }
static void
httpd_output_close(AudioOutput *ao)
{
HttpdOutput *httpd = HttpdOutput::Cast(ao);
const std::lock_guard<Mutex> protect(httpd->mutex);
httpd->Close();
}
void void
HttpdOutput::RemoveClient(HttpdClient &client) HttpdOutput::RemoveClient(HttpdClient &client)
{ {
@ -365,14 +326,6 @@ HttpdOutput::Delay() const
: std::chrono::steady_clock::duration::zero(); : std::chrono::steady_clock::duration::zero();
} }
static std::chrono::steady_clock::duration
httpd_output_delay(AudioOutput *ao)
{
HttpdOutput *httpd = HttpdOutput::Cast(ao);
return httpd->Delay();
}
void void
HttpdOutput::BroadcastPage(Page *page) HttpdOutput::BroadcastPage(Page *page)
{ {
@ -426,22 +379,12 @@ HttpdOutput::Play(const void *chunk, size_t size)
return size; return size;
} }
static size_t bool
httpd_output_play(AudioOutput *ao, const void *chunk, size_t size) HttpdOutput::Pause()
{ {
HttpdOutput *httpd = HttpdOutput::Cast(ao); if (LockHasClients()) {
return httpd->Play(chunk, size);
}
static bool
httpd_output_pause(AudioOutput *ao)
{
HttpdOutput *httpd = HttpdOutput::Cast(ao);
if (httpd->LockHasClients()) {
static const char silence[1020] = { 0 }; static const char silence[1020] = { 0 };
httpd->Play(silence, sizeof(silence)); Play(silence, sizeof(silence));
} }
return true; return true;
@ -503,14 +446,6 @@ HttpdOutput::SendTag(const Tag &tag)
} }
} }
static void
httpd_output_tag(AudioOutput *ao, const Tag &tag)
{
HttpdOutput *httpd = HttpdOutput::Cast(ao);
httpd->SendTag(tag);
}
inline void inline void
HttpdOutput::CancelAllClients() HttpdOutput::CancelAllClients()
{ {
@ -528,30 +463,30 @@ HttpdOutput::CancelAllClients()
cond.broadcast(); cond.broadcast();
} }
static void void
httpd_output_cancel(AudioOutput *ao) HttpdOutput::Cancel()
{ {
HttpdOutput *httpd = HttpdOutput::Cast(ao); BlockingCall(io_thread_get(), [this](){
CancelAllClients();
BlockingCall(io_thread_get(), [httpd](){
httpd->CancelAllClients();
}); });
} }
typedef AudioOutputWrapper<HttpdOutput> Wrapper;
const struct AudioOutputPlugin httpd_output_plugin = { const struct AudioOutputPlugin httpd_output_plugin = {
"httpd", "httpd",
nullptr, nullptr,
httpd_output_init, &Wrapper::Init,
httpd_output_finish, &Wrapper::Finish,
httpd_output_enable, &Wrapper::Enable,
httpd_output_disable, &Wrapper::Disable,
httpd_output_open, &Wrapper::Open,
httpd_output_close, &Wrapper::Close,
httpd_output_delay, &Wrapper::Delay,
httpd_output_tag, &Wrapper::SendTag,
httpd_output_play, &Wrapper::Play,
nullptr, nullptr,
httpd_output_cancel, &Wrapper::Cancel,
httpd_output_pause, &Wrapper::Pause,
nullptr, nullptr,
}; };