summaryrefslogtreecommitdiff
path: root/src/encoder
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2016-05-04 18:29:31 +0200
committerMax Kellermann <max@duempel.org>2016-05-04 18:32:52 +0200
commitb376536a3bcbcc8840c4df3dc5f3850fb7b09ac5 (patch)
tree8aedb8fad4522e71de0f0aaa80b852b2332220ad /src/encoder
parente7edc0264745499609aa22bd19620e15f6ef3e62 (diff)
encoder/Interface: convert PreparedEncoder to abstract class
Diffstat (limited to 'src/encoder')
-rw-r--r--src/encoder/EncoderInterface.hxx43
-rw-r--r--src/encoder/EncoderPlugin.hxx12
-rw-r--r--src/encoder/plugins/FlacEncoderPlugin.cxx42
-rw-r--r--src/encoder/plugins/LameEncoderPlugin.cxx44
-rw-r--r--src/encoder/plugins/NullEncoderPlugin.cxx34
-rw-r--r--src/encoder/plugins/OpusEncoderPlugin.cxx48
-rw-r--r--src/encoder/plugins/ShineEncoderPlugin.cxx42
-rw-r--r--src/encoder/plugins/TwolameEncoderPlugin.cxx44
-rw-r--r--src/encoder/plugins/VorbisEncoderPlugin.cxx48
-rw-r--r--src/encoder/plugins/WaveEncoderPlugin.cxx39
10 files changed, 104 insertions, 292 deletions
diff --git a/src/encoder/EncoderInterface.hxx b/src/encoder/EncoderInterface.hxx
index a2bbab7a3..791752f85 100644
--- a/src/encoder/EncoderInterface.hxx
+++ b/src/encoder/EncoderInterface.hxx
@@ -26,6 +26,7 @@
#include <assert.h>
#include <stddef.h>
+struct AudioFormat;
struct Tag;
class Encoder {
@@ -112,19 +113,9 @@ public:
virtual size_t Read(void *dest, size_t length) = 0;
};
-struct PreparedEncoder {
- const EncoderPlugin &plugin;
-
- explicit PreparedEncoder(const EncoderPlugin &_plugin)
- :plugin(_plugin) {}
-
-
- /**
- * Frees an #Encoder object.
- */
- void Dispose() {
- plugin.finish(this);
- }
+class PreparedEncoder {
+public:
+ virtual ~PreparedEncoder() {}
/**
* Opens the object. You must call this prior to using it.
@@ -139,24 +130,16 @@ struct PreparedEncoder {
* may modify the struct to adapt it to its abilities
* @return true on success
*/
- Encoder *Open(AudioFormat &audio_format, Error &error) {
- return plugin.open(this, audio_format, error);
- }
+ virtual Encoder *Open(AudioFormat &audio_format, Error &error) = 0;
+ /**
+ * Get mime type of encoded content.
+ *
+ * @return an constant string, nullptr on failure
+ */
+ virtual const char *GetMimeType() const {
+ return nullptr;
+ }
};
-/**
- * Get mime type of encoded content.
- *
- * @return an constant string, nullptr on failure
- */
-static inline const char *
-encoder_get_mime_type(PreparedEncoder *encoder)
-{
- /* this method is optional */
- return encoder->plugin.get_mime_type != nullptr
- ? encoder->plugin.get_mime_type(encoder)
- : nullptr;
-}
-
#endif
diff --git a/src/encoder/EncoderPlugin.hxx b/src/encoder/EncoderPlugin.hxx
index de37f6d35..83792f3a7 100644
--- a/src/encoder/EncoderPlugin.hxx
+++ b/src/encoder/EncoderPlugin.hxx
@@ -20,9 +20,7 @@
#ifndef MPD_ENCODER_PLUGIN_HXX
#define MPD_ENCODER_PLUGIN_HXX
-struct PreparedEncoder;
-class Encoder;
-struct AudioFormat;
+class PreparedEncoder;
struct ConfigBlock;
class Error;
@@ -31,14 +29,6 @@ struct EncoderPlugin {
PreparedEncoder *(*init)(const ConfigBlock &block,
Error &error);
-
- void (*finish)(PreparedEncoder *encoder);
-
- Encoder *(*open)(PreparedEncoder *encoder,
- AudioFormat &audio_format,
- Error &error);
-
- const char *(*get_mime_type)(PreparedEncoder *encoder);
};
/**
diff --git a/src/encoder/plugins/FlacEncoderPlugin.cxx b/src/encoder/plugins/FlacEncoderPlugin.cxx
index f6c87ed6a..f26efd8e0 100644
--- a/src/encoder/plugins/FlacEncoderPlugin.cxx
+++ b/src/encoder/plugins/FlacEncoderPlugin.cxx
@@ -88,14 +88,18 @@ private:
}
};
-struct PreparedFlacEncoder {
- PreparedEncoder encoder;
-
+class PreparedFlacEncoder final : public PreparedEncoder {
unsigned compression;
- PreparedFlacEncoder():encoder(flac_encoder_plugin) {}
-
+public:
bool Configure(const ConfigBlock &block, Error &error);
+
+ /* virtual methods from class PreparedEncoder */
+ Encoder *Open(AudioFormat &audio_format, Error &) override;
+
+ const char *GetMimeType() const override {
+ return "audio/flac";
+ }
};
static constexpr Domain flac_encoder_domain("vorbis_encoder");
@@ -119,17 +123,7 @@ flac_encoder_init(const ConfigBlock &block, Error &error)
return nullptr;
}
- return &encoder->encoder;
-}
-
-static void
-flac_encoder_finish(PreparedEncoder *_encoder)
-{
- auto *encoder = (PreparedFlacEncoder *)_encoder;
-
- /* the real libFLAC cleanup was already performed by
- flac_encoder_close(), so no real work here */
- delete encoder;
+ return encoder;
}
static bool
@@ -190,10 +184,9 @@ FlacEncoder::Init(Error &error)
return true;
}
-static Encoder *
-flac_encoder_open(PreparedEncoder *_encoder, AudioFormat &audio_format, Error &error)
+Encoder *
+PreparedFlacEncoder::Open(AudioFormat &audio_format, Error &error)
{
- auto *encoder = (PreparedFlacEncoder *)_encoder;
unsigned bits_per_sample;
/* FIXME: flac should support 32bit as well */
@@ -222,7 +215,7 @@ flac_encoder_open(PreparedEncoder *_encoder, AudioFormat &audio_format, Error &e
return nullptr;
}
- if (!flac_encoder_setup(fse, encoder->compression,
+ if (!flac_encoder_setup(fse, compression,
audio_format, bits_per_sample, error)) {
FLAC__stream_encoder_delete(fse);
return nullptr;
@@ -304,17 +297,8 @@ FlacEncoder::Write(const void *data, size_t length, Error &error)
return true;
}
-static const char *
-flac_encoder_get_mime_type(gcc_unused PreparedEncoder *_encoder)
-{
- return "audio/flac";
-}
-
const EncoderPlugin flac_encoder_plugin = {
"flac",
flac_encoder_init,
- flac_encoder_finish,
- flac_encoder_open,
- flac_encoder_get_mime_type,
};
diff --git a/src/encoder/plugins/LameEncoderPlugin.cxx b/src/encoder/plugins/LameEncoderPlugin.cxx
index e011d65bf..8d4c0b2bf 100644
--- a/src/encoder/plugins/LameEncoderPlugin.cxx
+++ b/src/encoder/plugins/LameEncoderPlugin.cxx
@@ -53,15 +53,19 @@ public:
size_t Read(void *dest, size_t length) override;
};
-struct PreparedLameEncoder final {
- PreparedEncoder encoder;
-
+class PreparedLameEncoder final : public PreparedEncoder {
float quality;
int bitrate;
- PreparedLameEncoder():encoder(lame_encoder_plugin) {}
-
+public:
bool Configure(const ConfigBlock &block, Error &error);
+
+ /* virtual methods from class PreparedEncoder */
+ Encoder *Open(AudioFormat &audio_format, Error &) override;
+
+ const char *GetMimeType() const override {
+ return "audio/mpeg";
+ }
};
static constexpr Domain lame_encoder_domain("lame_encoder");
@@ -126,17 +130,7 @@ lame_encoder_init(const ConfigBlock &block, Error &error)
return nullptr;
}
- return &encoder->encoder;
-}
-
-static void
-lame_encoder_finish(PreparedEncoder *_encoder)
-{
- auto *encoder = (PreparedLameEncoder *)_encoder;
-
- /* the real liblame cleanup was already performed by
- lame_encoder_close(), so no real work here */
- delete encoder;
+ return encoder;
}
static bool
@@ -193,12 +187,9 @@ lame_encoder_setup(lame_global_flags *gfp, float quality, int bitrate,
return true;
}
-static Encoder *
-lame_encoder_open(PreparedEncoder *_encoder, AudioFormat &audio_format,
- Error &error)
+Encoder *
+PreparedLameEncoder::Open(AudioFormat &audio_format, Error &error)
{
- auto *encoder = (PreparedLameEncoder *)_encoder;
-
audio_format.format = SampleFormat::S16;
audio_format.channels = 2;
@@ -208,7 +199,7 @@ lame_encoder_open(PreparedEncoder *_encoder, AudioFormat &audio_format,
return nullptr;
}
- if (!lame_encoder_setup(gfp, encoder->quality, encoder->bitrate,
+ if (!lame_encoder_setup(gfp, quality, bitrate,
audio_format, error)) {
lame_close(gfp);
return nullptr;
@@ -269,16 +260,7 @@ LameEncoder::Read(void *dest, size_t length)
return length;
}
-static const char *
-lame_encoder_get_mime_type(gcc_unused PreparedEncoder *_encoder)
-{
- return "audio/mpeg";
-}
-
const EncoderPlugin lame_encoder_plugin = {
"lame",
lame_encoder_init,
- lame_encoder_finish,
- lame_encoder_open,
- lame_encoder_get_mime_type,
};
diff --git a/src/encoder/plugins/NullEncoderPlugin.cxx b/src/encoder/plugins/NullEncoderPlugin.cxx
index 308ecc8fd..7f64effbe 100644
--- a/src/encoder/plugins/NullEncoderPlugin.cxx
+++ b/src/encoder/plugins/NullEncoderPlugin.cxx
@@ -23,8 +23,6 @@
#include "util/DynamicFifoBuffer.hxx"
#include "Compiler.h"
-#include <assert.h>
-
class NullEncoder final : public Encoder {
DynamicFifoBuffer<uint8_t> buffer;
@@ -44,40 +42,22 @@ public:
}
};
-struct PreparedNullEncoder final {
- PreparedEncoder encoder;
-
- PreparedNullEncoder()
- :encoder(null_encoder_plugin) {}
+class PreparedNullEncoder final : public PreparedEncoder {
+public:
+ /* virtual methods from class PreparedEncoder */
+ Encoder *Open(AudioFormat &, Error &) override {
+ return new NullEncoder();
+ }
};
static PreparedEncoder *
null_encoder_init(gcc_unused const ConfigBlock &block,
gcc_unused Error &error)
{
- auto *encoder = new PreparedNullEncoder();
- return &encoder->encoder;
-}
-
-static void
-null_encoder_finish(PreparedEncoder *_encoder)
-{
- auto *encoder = (PreparedNullEncoder *)_encoder;
- delete encoder;
-}
-
-static Encoder *
-null_encoder_open(gcc_unused PreparedEncoder *encoder,
- gcc_unused AudioFormat &audio_format,
- gcc_unused Error &error)
-{
- return new NullEncoder();
+ return new PreparedNullEncoder();
}
const EncoderPlugin null_encoder_plugin = {
"null",
null_encoder_init,
- null_encoder_finish,
- null_encoder_open,
- nullptr,
};
diff --git a/src/encoder/plugins/OpusEncoderPlugin.cxx b/src/encoder/plugins/OpusEncoderPlugin.cxx
index 87c6d56f8..86d18be5d 100644
--- a/src/encoder/plugins/OpusEncoderPlugin.cxx
+++ b/src/encoder/plugins/OpusEncoderPlugin.cxx
@@ -77,20 +77,20 @@ private:
void GenerateTags();
};
-struct PreparedOpusEncoder {
- /** the base class */
- PreparedEncoder encoder;
-
- /* configuration */
-
+class PreparedOpusEncoder final : public PreparedEncoder {
opus_int32 bitrate;
int complexity;
int signal;
- PreparedOpusEncoder():encoder(opus_encoder_plugin) {}
-
+public:
bool Configure(const ConfigBlock &block, Error &error);
- Encoder *Open(AudioFormat &audio_format, Error &error);
+
+ /* virtual methods from class PreparedEncoder */
+ Encoder *Open(AudioFormat &audio_format, Error &) override;
+
+ const char *GetMimeType() const override {
+ return "audio/ogg";
+ }
};
static constexpr Domain opus_encoder_domain("opus_encoder");
@@ -146,17 +146,7 @@ opus_encoder_init(const ConfigBlock &block, Error &error)
return nullptr;
}
- return &encoder->encoder;
-}
-
-static void
-opus_encoder_finish(PreparedEncoder *_encoder)
-{
- auto *encoder = (PreparedOpusEncoder *)_encoder;
-
- /* the real libopus cleanup was already performed by
- opus_encoder_close(), so no real work here */
- delete encoder;
+ return encoder;
}
OpusEncoder::OpusEncoder(AudioFormat &_audio_format, ::OpusEncoder *_enc)
@@ -214,15 +204,6 @@ PreparedOpusEncoder::Open(AudioFormat &audio_format, Error &error)
return new OpusEncoder(audio_format, enc);
}
-static Encoder *
-opus_encoder_open(PreparedEncoder *_encoder,
- AudioFormat &audio_format,
- Error &error)
-{
- auto &encoder = *(PreparedOpusEncoder *)_encoder;
- return encoder.Open(audio_format, error);
-}
-
OpusEncoder::~OpusEncoder()
{
stream.Deinitialize();
@@ -405,18 +386,9 @@ OpusEncoder::Read(void *dest, size_t length)
return stream.PageOut(dest, length);
}
-static const char *
-opus_encoder_get_mime_type(gcc_unused PreparedEncoder *_encoder)
-{
- return "audio/ogg";
-}
-
}
const EncoderPlugin opus_encoder_plugin = {
"opus",
opus_encoder_init,
- opus_encoder_finish,
- opus_encoder_open,
- opus_encoder_get_mime_type,
};
diff --git a/src/encoder/plugins/ShineEncoderPlugin.cxx b/src/encoder/plugins/ShineEncoderPlugin.cxx
index 06623795d..39f30d060 100644
--- a/src/encoder/plugins/ShineEncoderPlugin.cxx
+++ b/src/encoder/plugins/ShineEncoderPlugin.cxx
@@ -84,16 +84,18 @@ public:
}
};
-struct PreparedShineEncoder {
- PreparedEncoder encoder;
-
+class PreparedShineEncoder final : public PreparedEncoder {
shine_config_t config;
- PreparedShineEncoder():encoder(shine_encoder_plugin) {}
-
+public:
bool Configure(const ConfigBlock &block, Error &error);
- bool Setup(Error &error);
+ /* virtual methods from class PreparedEncoder */
+ Encoder *Open(AudioFormat &audio_format, Error &) override;
+
+ const char *GetMimeType() const override {
+ return "audio/mpeg";
+ }
};
inline bool
@@ -117,15 +119,7 @@ shine_encoder_init(const ConfigBlock &block, Error &error)
return nullptr;
}
- return &encoder->encoder;
-}
-
-static void
-shine_encoder_finish(PreparedEncoder *_encoder)
-{
- auto *encoder = (PreparedShineEncoder *)_encoder;
-
- delete encoder;
+ return encoder;
}
static shine_t
@@ -159,13 +153,10 @@ SetupShine(shine_config_t config, AudioFormat &audio_format,
return shine;
}
-static Encoder *
-shine_encoder_open(PreparedEncoder *_encoder, AudioFormat &audio_format,
- Error &error)
+Encoder *
+PreparedShineEncoder::Open(AudioFormat &audio_format, Error &error)
{
- auto *encoder = (PreparedShineEncoder *)_encoder;
-
- auto shine = SetupShine(encoder->config, audio_format, error);
+ auto shine = SetupShine(config, audio_format, error);
if (!shine)
return nullptr;
@@ -238,16 +229,7 @@ ShineEncoder::Flush(gcc_unused Error &error)
return true;
}
-static const char *
-shine_encoder_get_mime_type(gcc_unused PreparedEncoder *_encoder)
-{
- return "audio/mpeg";
-}
-
const EncoderPlugin shine_encoder_plugin = {
"shine",
shine_encoder_init,
- shine_encoder_finish,
- shine_encoder_open,
- shine_encoder_get_mime_type,
};
diff --git a/src/encoder/plugins/TwolameEncoderPlugin.cxx b/src/encoder/plugins/TwolameEncoderPlugin.cxx
index c416f3631..7ef02addb 100644
--- a/src/encoder/plugins/TwolameEncoderPlugin.cxx
+++ b/src/encoder/plugins/TwolameEncoderPlugin.cxx
@@ -72,15 +72,19 @@ public:
size_t Read(void *dest, size_t length) override;
};
-struct PreparedTwolameEncoder final {
- PreparedEncoder encoder;
-
+class PreparedTwolameEncoder final : public PreparedEncoder {
float quality;
int bitrate;
- PreparedTwolameEncoder():encoder(twolame_encoder_plugin) {}
-
+public:
bool Configure(const ConfigBlock &block, Error &error);
+
+ /* virtual methods from class PreparedEncoder */
+ Encoder *Open(AudioFormat &audio_format, Error &) override;
+
+ const char *GetMimeType() const override {
+ return "audio/mpeg";
+ }
};
static constexpr Domain twolame_encoder_domain("twolame_encoder");
@@ -148,17 +152,7 @@ twolame_encoder_init(const ConfigBlock &block, Error &error_r)
return nullptr;
}
- return &encoder->encoder;
-}
-
-static void
-twolame_encoder_finish(PreparedEncoder *_encoder)
-{
- auto *encoder = (PreparedTwolameEncoder *)_encoder;
-
- /* the real libtwolame cleanup was already performed by
- twolame_encoder_close(), so no real work here */
- delete encoder;
+ return encoder;
}
static bool
@@ -210,12 +204,9 @@ twolame_encoder_setup(twolame_options *options, float quality, int bitrate,
return true;
}
-static Encoder *
-twolame_encoder_open(PreparedEncoder *_encoder, AudioFormat &audio_format,
- Error &error)
+Encoder *
+PreparedTwolameEncoder::Open(AudioFormat &audio_format, Error &error)
{
- auto *encoder = (PreparedTwolameEncoder *)_encoder;
-
audio_format.format = SampleFormat::S16;
audio_format.channels = 2;
@@ -225,7 +216,7 @@ twolame_encoder_open(PreparedEncoder *_encoder, AudioFormat &audio_format,
return nullptr;
}
- if (!twolame_encoder_setup(options, encoder->quality, encoder->bitrate,
+ if (!twolame_encoder_setup(options, quality, bitrate,
audio_format, error)) {
twolame_close(&options);
return nullptr;
@@ -291,16 +282,7 @@ TwolameEncoder::Read(void *dest, size_t length)
return length;
}
-static const char *
-twolame_encoder_get_mime_type(gcc_unused PreparedEncoder *_encoder)
-{
- return "audio/mpeg";
-}
-
const EncoderPlugin twolame_encoder_plugin = {
"twolame",
twolame_encoder_init,
- twolame_encoder_finish,
- twolame_encoder_open,
- twolame_encoder_get_mime_type,
};
diff --git a/src/encoder/plugins/VorbisEncoderPlugin.cxx b/src/encoder/plugins/VorbisEncoderPlugin.cxx
index ad00a858b..4baca33e5 100644
--- a/src/encoder/plugins/VorbisEncoderPlugin.cxx
+++ b/src/encoder/plugins/VorbisEncoderPlugin.cxx
@@ -73,18 +73,19 @@ private:
void Clear();
};
-struct PreparedVorbisEncoder {
- /** the base class */
- PreparedEncoder encoder;
-
- /* configuration */
-
+class PreparedVorbisEncoder final : public PreparedEncoder {
float quality;
int bitrate;
- PreparedVorbisEncoder():encoder(vorbis_encoder_plugin) {}
-
+public:
bool Configure(const ConfigBlock &block, Error &error);
+
+ /* virtual methods from class PreparedEncoder */
+ Encoder *Open(AudioFormat &audio_format, Error &) override;
+
+ const char *GetMimeType() const override {
+ return "audio/ogg";
+ }
};
static constexpr Domain vorbis_encoder_domain("vorbis_encoder");
@@ -148,17 +149,7 @@ vorbis_encoder_init(const ConfigBlock &block, Error &error)
return nullptr;
}
- return &encoder->encoder;
-}
-
-static void
-vorbis_encoder_finish(PreparedEncoder *_encoder)
-{
- auto *encoder = (PreparedVorbisEncoder *)_encoder;
-
- /* the real libvorbis/libogg cleanup was already performed by
- vorbis_encoder_close(), so no real work here */
- delete encoder;
+ return encoder;
}
bool
@@ -228,15 +219,11 @@ VorbisEncoder::SendHeader()
vorbis_comment_clear(&vc);
}
-static Encoder *
-vorbis_encoder_open(PreparedEncoder *_encoder,
- AudioFormat &audio_format,
- Error &error)
+Encoder *
+PreparedVorbisEncoder::Open(AudioFormat &audio_format, Error &error)
{
- auto &encoder = *(PreparedVorbisEncoder *)_encoder;
-
auto *e = new VorbisEncoder();
- if (!e->Open(encoder.quality, encoder.bitrate, audio_format, error)) {
+ if (!e->Open(quality, bitrate, audio_format, error)) {
delete e;
return nullptr;
}
@@ -348,16 +335,7 @@ VorbisEncoder::Write(const void *data, size_t length, gcc_unused Error &error)
return true;
}
-static const char *
-vorbis_encoder_get_mime_type(gcc_unused PreparedEncoder *_encoder)
-{
- return "audio/ogg";
-}
-
const EncoderPlugin vorbis_encoder_plugin = {
"vorbis",
vorbis_encoder_init,
- vorbis_encoder_finish,
- vorbis_encoder_open,
- vorbis_encoder_get_mime_type,
};
diff --git a/src/encoder/plugins/WaveEncoderPlugin.cxx b/src/encoder/plugins/WaveEncoderPlugin.cxx
index f09e7b160..140266984 100644
--- a/src/encoder/plugins/WaveEncoderPlugin.cxx
+++ b/src/encoder/plugins/WaveEncoderPlugin.cxx
@@ -44,10 +44,15 @@ public:
}
};
-struct PreparedWaveEncoder {
- PreparedEncoder encoder;
+class PreparedWaveEncoder final : public PreparedEncoder {
+ /* virtual methods from class PreparedEncoder */
+ Encoder *Open(AudioFormat &audio_format, Error &) override {
+ return new WaveEncoder(audio_format);
+ }
- PreparedWaveEncoder():encoder(wave_encoder_plugin) {}
+ const char *GetMimeType() const override {
+ return "audio/wav";
+ }
};
struct WaveHeader {
@@ -96,16 +101,7 @@ static PreparedEncoder *
wave_encoder_init(gcc_unused const ConfigBlock &block,
gcc_unused Error &error)
{
- auto *encoder = new PreparedWaveEncoder();
- return &encoder->encoder;
-}
-
-static void
-wave_encoder_finish(PreparedEncoder *_encoder)
-{
- auto *encoder = (PreparedWaveEncoder *)_encoder;
-
- delete encoder;
+ return new PreparedWaveEncoder();
}
WaveEncoder::WaveEncoder(AudioFormat &audio_format)
@@ -151,14 +147,6 @@ WaveEncoder::WaveEncoder(AudioFormat &audio_format)
buffer.Append(sizeof(*header));
}
-static Encoder *
-wave_encoder_open(gcc_unused PreparedEncoder *_encoder,
- AudioFormat &audio_format,
- gcc_unused Error &error)
-{
- return new WaveEncoder(audio_format);
-}
-
static size_t
pcm16_to_wave(uint16_t *dst16, const uint16_t *src16, size_t length)
{
@@ -239,16 +227,7 @@ WaveEncoder::Write(const void *src, size_t length,
return true;
}
-static const char *
-wave_encoder_get_mime_type(gcc_unused PreparedEncoder *_encoder)
-{
- return "audio/wav";
-}
-
const EncoderPlugin wave_encoder_plugin = {
"wave",
wave_encoder_init,
- wave_encoder_finish,
- wave_encoder_open,
- wave_encoder_get_mime_type,
};