From b2b95cad20846bb3235787c266c1723acf38f971 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sat, 12 Jul 2014 01:33:12 +0200 Subject: [PATCH] DecoderBuffer: add method _need() Move code from the FAAD decoder plugin. --- src/decoder/DecoderBuffer.cxx | 25 ++++++++++++-- src/decoder/DecoderBuffer.hxx | 7 ++++ src/decoder/plugins/FaadDecoderPlugin.cxx | 41 +++++++---------------- 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 decoder_buffer_read(const DecoderBuffer *buffer) { return { - buffer->data + buffer->consumed, - buffer->length - buffer->consumed + decoder_buffer_head(buffer), + decoder_buffer_available(buffer), }; } +ConstBuffer +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 @@ -90,6 +90,13 @@ gcc_pure ConstBuffer decoder_buffer_read(const DecoderBuffer *buffer); +/** + * Wait until this number of bytes are available. Returns nullptr on + * error. + */ +ConstBuffer +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 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::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::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::FromVoid(decoder_buffer_read(buffer)); - if (data.IsEmpty()) + auto data = ConstBuffer::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::FromVoid(decoder_buffer_read(buffer)); - if (data.IsEmpty()) + data = ConstBuffer::FromVoid(decoder_buffer_need(buffer, 5)); + if (data.IsNull()) return -1; }