encoder/Interface: convert PreparedEncoder to abstract class
This commit is contained in:
parent
e7edc02647
commit
b376536a3b
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -76,8 +76,7 @@ class RecorderOutput {
|
|||
:base(recorder_output_plugin) {}
|
||||
|
||||
~RecorderOutput() {
|
||||
if (prepared_encoder != nullptr)
|
||||
prepared_encoder->Dispose();
|
||||
delete prepared_encoder;
|
||||
}
|
||||
|
||||
bool Initialize(const ConfigBlock &block, Error &error_r) {
|
||||
|
|
|
@ -45,7 +45,7 @@ class EventLoop;
|
|||
class ServerSocket;
|
||||
class HttpdClient;
|
||||
class Page;
|
||||
struct PreparedEncoder;
|
||||
class PreparedEncoder;
|
||||
class Encoder;
|
||||
struct Tag;
|
||||
|
||||
|
|
|
@ -63,9 +63,7 @@ HttpdOutput::~HttpdOutput()
|
|||
if (metadata != nullptr)
|
||||
metadata->Unref();
|
||||
|
||||
if (prepared_encoder != nullptr)
|
||||
prepared_encoder->Dispose();
|
||||
|
||||
delete prepared_encoder;
|
||||
}
|
||||
|
||||
inline bool
|
||||
|
@ -128,7 +126,7 @@ HttpdOutput::Configure(const ConfigBlock &block, Error &error)
|
|||
return false;
|
||||
|
||||
/* determine content type */
|
||||
content_type = encoder_get_mime_type(prepared_encoder);
|
||||
content_type = prepared_encoder->GetMimeType();
|
||||
if (content_type == nullptr)
|
||||
content_type = "application/octet-stream";
|
||||
|
||||
|
|
|
@ -111,7 +111,7 @@ int main(int argc, char **argv)
|
|||
EncoderToOutputStream(os, *encoder);
|
||||
|
||||
delete encoder;
|
||||
p_encoder->Dispose();
|
||||
delete p_encoder;
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
} catch (const std::exception &e) {
|
||||
|
|
|
@ -103,7 +103,7 @@ main(gcc_unused int argc, gcc_unused char **argv)
|
|||
EncoderToOutputStream(os, *encoder);
|
||||
|
||||
delete encoder;
|
||||
p_encoder->Dispose();
|
||||
delete p_encoder;
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
} catch (const std::exception &e) {
|
||||
|
|
Loading…
Reference in New Issue