aboutsummaryrefslogtreecommitdiffstats
path: root/src/decoder
diff options
context:
space:
mode:
Diffstat (limited to 'src/decoder')
-rw-r--r--src/decoder/DecoderBuffer.cxx25
-rw-r--r--src/decoder/DecoderBuffer.hxx7
-rw-r--r--src/decoder/plugins/FaadDecoderPlugin.cxx41
3 files changed, 42 insertions, 31 deletions
diff --git a/src/decoder/DecoderBuffer.cxx b/src/decoder/DecoderBuffer.cxx
index b337cbc0b..e26a702b7 100644
--- a/src/decoder/DecoderBuffer.cxx
+++ b/src/decoder/DecoderBuffer.cxx
@@ -117,21 +117,40 @@ decoder_buffer_fill(DecoderBuffer *buffer)
return true;
}
+static const void *
+decoder_buffer_head(const DecoderBuffer *buffer)
+{
+ return buffer->data + buffer->consumed;
+}
+
size_t
decoder_buffer_available(const DecoderBuffer *buffer)
{
- return buffer->length - buffer->consumed;;
+ return buffer->length - buffer->consumed;
}
ConstBuffer<void>
decoder_buffer_read(const DecoderBuffer *buffer)
{
return {
- buffer->data + buffer->consumed,
- buffer->length - buffer->consumed
+ decoder_buffer_head(buffer),
+ decoder_buffer_available(buffer),
};
}
+ConstBuffer<void>
+decoder_buffer_need(DecoderBuffer *buffer, size_t min_size)
+{
+ while (true) {
+ const auto available = decoder_buffer_available(buffer);
+ if (available >= min_size)
+ return { decoder_buffer_head(buffer), available };
+
+ if (!decoder_buffer_fill(buffer))
+ return nullptr;
+ }
+}
+
void
decoder_buffer_consume(DecoderBuffer *buffer, size_t nbytes)
{
diff --git a/src/decoder/DecoderBuffer.hxx b/src/decoder/DecoderBuffer.hxx
index ad9750eda..4a482be75 100644
--- a/src/decoder/DecoderBuffer.hxx
+++ b/src/decoder/DecoderBuffer.hxx
@@ -91,6 +91,13 @@ ConstBuffer<void>
decoder_buffer_read(const DecoderBuffer *buffer);
/**
+ * Wait until this number of bytes are available. Returns nullptr on
+ * error.
+ */
+ConstBuffer<void>
+decoder_buffer_need(DecoderBuffer *buffer, size_t min_size);
+
+/**
* Consume (delete, invalidate) a part of the buffer. The "nbytes"
* parameter must not be larger than the length returned by
* decoder_buffer_read().
diff --git a/src/decoder/plugins/FaadDecoderPlugin.cxx b/src/decoder/plugins/FaadDecoderPlugin.cxx
index 47dbc7c66..6a415bb53 100644
--- a/src/decoder/plugins/FaadDecoderPlugin.cxx
+++ b/src/decoder/plugins/FaadDecoderPlugin.cxx
@@ -66,15 +66,10 @@ static size_t
adts_find_frame(DecoderBuffer *buffer)
{
while (true) {
- auto data = ConstBuffer<uint8_t>::FromVoid(decoder_buffer_read(buffer));
- if (data.size < 8) {
- /* not enough data yet */
- if (!decoder_buffer_fill(buffer))
- /* failed */
- return 0;
-
- continue;
- }
+ auto data = ConstBuffer<uint8_t>::FromVoid(decoder_buffer_need(buffer, 8));
+ if (data.IsNull())
+ /* failed */
+ return 0;
/* find the 0xff marker */
const uint8_t *p = (const uint8_t *)
@@ -100,17 +95,10 @@ adts_find_frame(DecoderBuffer *buffer)
continue;
}
- if (data.size < frame_length) {
- /* available buffer size is smaller than the
- frame will be - attempt to read more
- data */
- if (!decoder_buffer_fill(buffer)) {
- /* not enough data; discard this frame
- to prevent a possible buffer
- overflow */
- decoder_buffer_clear(buffer);
- }
-
+ if (decoder_buffer_need(buffer, frame_length).IsNull()) {
+ /* not enough data; discard this frame to
+ prevent a possible buffer overflow */
+ decoder_buffer_clear(buffer);
continue;
}
@@ -181,9 +169,8 @@ faad_song_duration(DecoderBuffer *buffer, InputStream &is)
const auto size = is.GetSize();
const size_t fileread = size >= 0 ? size : 0;
- decoder_buffer_fill(buffer);
- auto data = ConstBuffer<uint8_t>::FromVoid(decoder_buffer_read(buffer));
- if (data.IsEmpty())
+ auto data = ConstBuffer<uint8_t>::FromVoid(decoder_buffer_need(buffer, 5));
+ if (data.IsNull())
return -1;
size_t tagsize = 0;
@@ -195,13 +182,11 @@ faad_song_duration(DecoderBuffer *buffer, InputStream &is)
tagsize += 10;
- const bool success = decoder_buffer_skip(buffer, tagsize) &&
- decoder_buffer_fill(buffer);
- if (!success)
+ if (!decoder_buffer_skip(buffer, tagsize))
return -1;
- data = ConstBuffer<uint8_t>::FromVoid(decoder_buffer_read(buffer));
- if (data.IsEmpty())
+ data = ConstBuffer<uint8_t>::FromVoid(decoder_buffer_need(buffer, 5));
+ if (data.IsNull())
return -1;
}