aboutsummaryrefslogtreecommitdiffstats
path: root/src/decoder
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/decoder/OggFind.cxx7
-rw-r--r--src/decoder/OggFind.hxx6
-rw-r--r--src/decoder/OggSyncState.hxx78
-rw-r--r--src/decoder/OpusDecoderPlugin.cxx47
4 files changed, 102 insertions, 36 deletions
diff --git a/src/decoder/OggFind.cxx b/src/decoder/OggFind.cxx
index 4f4fd1e96..9df4c6455 100644
--- a/src/decoder/OggFind.cxx
+++ b/src/decoder/OggFind.cxx
@@ -19,16 +19,15 @@
#include "config.h"
#include "OggFind.hxx"
-#include "OggUtil.hxx"
+#include "OggSyncState.hxx"
bool
-OggFindEOS(ogg_sync_state &oy, ogg_stream_state &os, ogg_packet &packet,
- decoder *decoder, input_stream *is)
+OggFindEOS(OggSyncState &oy, ogg_stream_state &os, ogg_packet &packet)
{
while (true) {
int r = ogg_stream_packetout(&os, &packet);
if (r == 0) {
- if (!OggExpectPageIn(oy, os, decoder, is))
+ if (!oy.ExpectPageIn(os))
return false;
continue;
diff --git a/src/decoder/OggFind.hxx b/src/decoder/OggFind.hxx
index 6a55f9b34..7d18d2067 100644
--- a/src/decoder/OggFind.hxx
+++ b/src/decoder/OggFind.hxx
@@ -24,8 +24,7 @@
#include <ogg/ogg.h>
-struct decoder;
-struct input_stream;
+class OggSyncState;
/**
* Skip all pages/packets until an end-of-stream (EOS) packet for the
@@ -34,7 +33,6 @@ struct input_stream;
* @return true if the EOS packet was found
*/
bool
-OggFindEOS(ogg_sync_state &oy, ogg_stream_state &os, ogg_packet &packet,
- decoder *decoder, input_stream *is);
+OggFindEOS(OggSyncState &oy, ogg_stream_state &os, ogg_packet &packet);
#endif
diff --git a/src/decoder/OggSyncState.hxx b/src/decoder/OggSyncState.hxx
new file mode 100644
index 000000000..eaeb9bd8c
--- /dev/null
+++ b/src/decoder/OggSyncState.hxx
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2003-2013 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_SYNC_STATE_HXX
+#define MPD_OGG_SYNC_STATE_HXX
+
+#include "check.h"
+#include "OggUtil.hxx"
+
+#include <ogg/ogg.h>
+
+#include <stddef.h>
+
+/**
+ * Wrapper for an ogg_sync_state.
+ */
+class OggSyncState {
+ ogg_sync_state oy;
+
+ input_stream &is;
+ struct decoder *const decoder;
+
+public:
+ OggSyncState(input_stream &_is, struct decoder *const _decoder=nullptr)
+ :is(_is), decoder(_decoder) {
+ ogg_sync_init(&oy);
+ }
+
+ ~OggSyncState() {
+ ogg_sync_clear(&oy);
+ }
+
+ void Reset() {
+ ogg_sync_reset(&oy);
+ }
+
+ bool Feed(size_t size) {
+ return OggFeed(oy, decoder, &is, size);
+ }
+
+ bool ExpectPage(ogg_page &page) {
+ return OggExpectPage(oy, page, decoder, &is);
+ }
+
+ bool ExpectFirstPage(ogg_stream_state &os) {
+ return OggExpectFirstPage(oy, os, decoder, &is);
+ }
+
+ bool ExpectPageIn(ogg_stream_state &os) {
+ return OggExpectPageIn(oy, os, decoder, &is);
+ }
+
+ bool ExpectPageSeek(ogg_page &page) {
+ return OggExpectPageSeek(oy, page, decoder, &is);
+ }
+
+ bool ExpectPageSeekIn(ogg_stream_state &os) {
+ return OggExpectPageSeekIn(oy, os, decoder, &is);
+ }
+};
+
+#endif
diff --git a/src/decoder/OpusDecoderPlugin.cxx b/src/decoder/OpusDecoderPlugin.cxx
index 9c2f86d05..f0c0a442d 100644
--- a/src/decoder/OpusDecoderPlugin.cxx
+++ b/src/decoder/OpusDecoderPlugin.cxx
@@ -23,6 +23,7 @@
#include "OpusTags.hxx"
#include "OggUtil.hxx"
#include "OggFind.hxx"
+#include "OggSyncState.hxx"
#include "decoder_api.h"
#include "OggCodec.hxx"
#include "audio_check.h"
@@ -85,8 +86,8 @@ public:
:decoder(_decoder), input_stream(_input_stream) {}
~MPDOpusDecoder();
- bool ReadFirstPage(ogg_sync_state &oy);
- bool ReadNextPage(ogg_sync_state &oy);
+ bool ReadFirstPage(OggSyncState &oy);
+ bool ReadNextPage(OggSyncState &oy);
enum decoder_command HandlePackets();
enum decoder_command HandlePacket(const ogg_packet &packet);
@@ -107,11 +108,11 @@ MPDOpusDecoder::~MPDOpusDecoder()
}
inline bool
-MPDOpusDecoder::ReadFirstPage(ogg_sync_state &oy)
+MPDOpusDecoder::ReadFirstPage(OggSyncState &oy)
{
assert(!os_initialized);
- if (!OggExpectFirstPage(oy, os, decoder, input_stream))
+ if (!oy.ExpectFirstPage(os))
return false;
os_initialized = true;
@@ -119,12 +120,12 @@ MPDOpusDecoder::ReadFirstPage(ogg_sync_state &oy)
}
inline bool
-MPDOpusDecoder::ReadNextPage(ogg_sync_state &oy)
+MPDOpusDecoder::ReadNextPage(OggSyncState &oy)
{
assert(os_initialized);
ogg_page page;
- if (!OggExpectPage(oy, page, decoder, input_stream))
+ if (!oy.ExpectPage(page))
return false;
const auto page_serialno = ogg_page_serialno(&page);
@@ -269,14 +270,10 @@ mpd_opus_stream_decode(struct decoder *decoder,
input_stream_lock_seek(input_stream, 0, SEEK_SET, nullptr);
MPDOpusDecoder d(decoder, input_stream);
+ OggSyncState oy(*input_stream, decoder);
- ogg_sync_state oy;
- ogg_sync_init(&oy);
-
- if (!d.ReadFirstPage(oy)) {
- ogg_sync_clear(&oy);
+ if (!d.ReadFirstPage(oy))
return;
- }
while (true) {
enum decoder_command cmd = d.HandlePackets();
@@ -287,39 +284,34 @@ mpd_opus_stream_decode(struct decoder *decoder,
break;
}
-
- ogg_sync_clear(&oy);
}
static bool
-SeekFindEOS(ogg_sync_state &oy, ogg_stream_state &os, ogg_packet &packet,
- decoder *decoder, input_stream *is)
+SeekFindEOS(OggSyncState &oy, ogg_stream_state &os, ogg_packet &packet,
+ input_stream *is)
{
if (is->size > 0 && is->size - is->offset < 65536)
- return OggFindEOS(oy, os, packet, decoder, is);
+ return OggFindEOS(oy, os, packet);
if (!input_stream_cheap_seeking(is))
return false;
- ogg_sync_reset(&oy);
+ oy.Reset();
return input_stream_lock_seek(is, -65536, SEEK_END, nullptr) &&
- OggExpectPageSeekIn(oy, os, decoder, is) &&
- OggFindEOS(oy, os, packet, decoder, is);
+ oy.ExpectPageSeekIn(os) &&
+ OggFindEOS(oy, os, packet);
}
static bool
mpd_opus_scan_stream(struct input_stream *is,
const struct tag_handler *handler, void *handler_ctx)
{
- ogg_sync_state oy;
- ogg_sync_init(&oy);
+ OggSyncState oy(*is);
ogg_stream_state os;
- if (!OggExpectFirstPage(oy, os, nullptr, is)) {
- ogg_sync_clear(&oy);
+ if (!oy.ExpectFirstPage(os))
return false;
- }
/* read at most two more pages */
unsigned remaining_pages = 2;
@@ -338,7 +330,7 @@ mpd_opus_scan_stream(struct input_stream *is,
if (remaining_pages-- == 0)
break;
- if (!OggExpectPageIn(oy, os, nullptr, is)) {
+ if (!oy.ExpectPageIn(os)) {
result = false;
break;
}
@@ -369,12 +361,11 @@ mpd_opus_scan_stream(struct input_stream *is,
}
}
- if (packet.e_o_s || SeekFindEOS(oy, os, packet, nullptr, is))
+ if (packet.e_o_s || SeekFindEOS(oy, os, packet, is))
tag_handler_invoke_duration(handler, handler_ctx,
packet.granulepos / opus_sample_rate);
ogg_stream_clear(&os);
- ogg_sync_clear(&oy);
return result;
}