diff --git a/Makefile.am b/Makefile.am index bf1db8653..5884df7bc 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1149,6 +1149,11 @@ libencoder_plugins_a_SOURCES += \ src/encoder/plugins/WaveEncoderPlugin.hxx endif +if HAVE_OGG +libencoder_plugins_a_SOURCES += \ + src/encoder/plugins/OggEncoder.hxx +endif + if ENABLE_VORBISENC libencoder_plugins_a_SOURCES += \ src/encoder/plugins/VorbisEncoderPlugin.cxx \ diff --git a/src/encoder/plugins/OggEncoder.hxx b/src/encoder/plugins/OggEncoder.hxx new file mode 100644 index 000000000..7a64c4dc1 --- /dev/null +++ b/src/encoder/plugins/OggEncoder.hxx @@ -0,0 +1,59 @@ +/* + * Copyright 2003-2016 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MPD_OGG_ENCODER_HXX +#define MPD_OGG_ENCODER_HXX + +#include "config.h" +#include "../EncoderAPI.hxx" +#include "lib/xiph/OggStream.hxx" +#include "lib/xiph/OggSerial.hxx" + +#include + +/** + * An abstract base class which contains code common to all encoders + * with Ogg container output. + */ +class OggEncoder : public Encoder { +protected: + OggStream stream; + +public: + OggEncoder(bool _implements_tag) + :Encoder(_implements_tag) { + stream.Initialize(GenerateOggSerial()); + } + + ~OggEncoder() override { + stream.Deinitialize(); + } + + /* virtual methods from class Encoder */ + bool Flush(Error &) override { + stream.Flush(); + return true; + } + + size_t Read(void *dest, size_t length) override { + return stream.PageOut(dest, length); + } +}; + +#endif diff --git a/src/encoder/plugins/OpusEncoderPlugin.cxx b/src/encoder/plugins/OpusEncoderPlugin.cxx index 86d18be5d..249d1dd11 100644 --- a/src/encoder/plugins/OpusEncoderPlugin.cxx +++ b/src/encoder/plugins/OpusEncoderPlugin.cxx @@ -19,9 +19,7 @@ #include "config.h" #include "OpusEncoderPlugin.hxx" -#include "lib/xiph/OggStream.hxx" -#include "lib/xiph/OggSerial.hxx" -#include "../EncoderAPI.hxx" +#include "OggEncoder.hxx" #include "AudioFormat.hxx" #include "config/ConfigError.hxx" #include "util/Alloc.hxx" @@ -37,7 +35,7 @@ namespace { -class OpusEncoder final : public Encoder { +class OpusEncoder final : public OggEncoder { const AudioFormat audio_format; const size_t frame_size; @@ -50,8 +48,6 @@ class OpusEncoder final : public Encoder { unsigned char buffer2[1275 * 3 + 7]; - OggStream stream; - int lookahead; ogg_int64_t packetno = 0; @@ -64,7 +60,6 @@ public: /* virtual methods from class Encoder */ bool End(Error &) override; - bool Flush(Error &) override; bool Write(const void *data, size_t length, Error &) override; size_t Read(void *dest, size_t length) override; @@ -150,7 +145,7 @@ opus_encoder_init(const ConfigBlock &block, Error &error) } OpusEncoder::OpusEncoder(AudioFormat &_audio_format, ::OpusEncoder *_enc) - :Encoder(false), + :OggEncoder(false), audio_format(_audio_format), frame_size(_audio_format.GetFrameSize()), buffer_frames(_audio_format.sample_rate / 50), @@ -159,8 +154,6 @@ OpusEncoder::OpusEncoder(AudioFormat &_audio_format, ::OpusEncoder *_enc) enc(_enc) { opus_encoder_ctl(enc, OPUS_GET_LOOKAHEAD(&lookahead)); - - stream.Initialize(GenerateOggSerial()); } Encoder * @@ -206,7 +199,6 @@ PreparedOpusEncoder::Open(AudioFormat &audio_format, Error &error) OpusEncoder::~OpusEncoder() { - stream.Deinitialize(); free(buffer); opus_encoder_destroy(enc); } @@ -261,13 +253,6 @@ OpusEncoder::End(Error &error) return DoEncode(true, error); } -bool -OpusEncoder::Flush(gcc_unused Error &error) -{ - stream.Flush(); - return true; -} - bool OpusEncoder::WriteSilence(unsigned fill_frames, Error &error) { diff --git a/src/encoder/plugins/VorbisEncoderPlugin.cxx b/src/encoder/plugins/VorbisEncoderPlugin.cxx index 4baca33e5..43e8d175b 100644 --- a/src/encoder/plugins/VorbisEncoderPlugin.cxx +++ b/src/encoder/plugins/VorbisEncoderPlugin.cxx @@ -19,9 +19,7 @@ #include "config.h" #include "VorbisEncoderPlugin.hxx" -#include "lib/xiph/OggStream.hxx" -#include "lib/xiph/OggSerial.hxx" -#include "../EncoderAPI.hxx" +#include "OggEncoder.hxx" #include "AudioFormat.hxx" #include "config/ConfigError.hxx" #include "util/StringUtil.hxx" @@ -31,18 +29,16 @@ #include -class VorbisEncoder final : public Encoder { +class VorbisEncoder final : public OggEncoder { AudioFormat audio_format; vorbis_dsp_state vd; vorbis_block vb; vorbis_info vi; - OggStream stream; - public: VorbisEncoder() - :Encoder(true) {} + :OggEncoder(true) {} virtual ~VorbisEncoder() { Clear(); @@ -56,16 +52,11 @@ public: return PreTag(error); } - bool Flush(Error &error) override; bool PreTag(Error &error) override; bool SendTag(const Tag &tag, Error &error) override; bool Write(const void *data, size_t length, Error &) override; - size_t Read(void *dest, size_t length) override { - return stream.PageOut(dest, length); - } - private: void HeaderOut(vorbis_comment &vc); void SendHeader(); @@ -189,7 +180,6 @@ VorbisEncoder::Open(float quality, int bitrate, AudioFormat &_audio_format, vorbis_analysis_init(&vd, &vi); vorbis_block_init(&vd, &vb); - stream.Initialize(GenerateOggSerial()); SendHeader(); @@ -234,7 +224,6 @@ PreparedVorbisEncoder::Open(AudioFormat &audio_format, Error &error) void VorbisEncoder::Clear() { - stream.Deinitialize(); vorbis_block_clear(&vb); vorbis_dsp_clear(&vd); vorbis_info_clear(&vi); @@ -253,13 +242,6 @@ VorbisEncoder::BlockOut() } } -bool -VorbisEncoder::Flush(gcc_unused Error &error) -{ - stream.Flush(); - return true; -} - bool VorbisEncoder::PreTag(gcc_unused Error &error) {