InputStream: "protect" attributes
This commit is contained in:
parent
e138e2c880
commit
0b4fa41aff
@ -121,12 +121,12 @@ mpd_ffmpeg_stream_seek(void *opaque, int64_t pos, int whence)
|
|||||||
AvioStream *stream = (AvioStream *)opaque;
|
AvioStream *stream = (AvioStream *)opaque;
|
||||||
|
|
||||||
if (whence == AVSEEK_SIZE)
|
if (whence == AVSEEK_SIZE)
|
||||||
return stream->input.size;
|
return stream->input.GetSize();
|
||||||
|
|
||||||
if (!stream->input.LockSeek(pos, whence, IgnoreError()))
|
if (!stream->input.LockSeek(pos, whence, IgnoreError()))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
return stream->input.offset;
|
return stream->input.GetOffset();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -135,7 +135,7 @@ AvioStream::Open()
|
|||||||
io = avio_alloc_context(buffer, sizeof(buffer),
|
io = avio_alloc_context(buffer, sizeof(buffer),
|
||||||
false, this,
|
false, this,
|
||||||
mpd_ffmpeg_stream_read, nullptr,
|
mpd_ffmpeg_stream_read, nullptr,
|
||||||
input.seekable
|
input.IsSeekable()
|
||||||
? mpd_ffmpeg_stream_seek : nullptr);
|
? mpd_ffmpeg_stream_seek : nullptr);
|
||||||
return io != nullptr;
|
return io != nullptr;
|
||||||
}
|
}
|
||||||
@ -481,7 +481,7 @@ ffmpeg_decode(Decoder &decoder, InputStream &input)
|
|||||||
: 0;
|
: 0;
|
||||||
|
|
||||||
decoder_initialized(decoder, audio_format,
|
decoder_initialized(decoder, audio_format,
|
||||||
input.seekable, total_time);
|
input.IsSeekable(), total_time);
|
||||||
|
|
||||||
#if LIBAVUTIL_VERSION_MAJOR >= 53
|
#if LIBAVUTIL_VERSION_MAJOR >= 53
|
||||||
AVFrame *frame = av_frame_alloc();
|
AVFrame *frame = av_frame_alloc();
|
||||||
|
@ -137,7 +137,7 @@ flac_got_first_frame(struct flac_data *data, const FLAC__FrameHeader *header)
|
|||||||
data->frame_size = data->audio_format.GetFrameSize();
|
data->frame_size = data->audio_format.GetFrameSize();
|
||||||
|
|
||||||
decoder_initialized(data->decoder, data->audio_format,
|
decoder_initialized(data->decoder, data->audio_format,
|
||||||
data->input_stream.seekable,
|
data->input_stream.IsSeekable(),
|
||||||
(float)data->total_frames /
|
(float)data->total_frames /
|
||||||
(float)data->audio_format.sample_rate);
|
(float)data->audio_format.sample_rate);
|
||||||
|
|
||||||
|
@ -145,13 +145,13 @@ flac_decoder_initialize(struct flac_data *data, FLAC__StreamDecoder *sd,
|
|||||||
if (data->initialized) {
|
if (data->initialized) {
|
||||||
/* done */
|
/* done */
|
||||||
decoder_initialized(data->decoder, data->audio_format,
|
decoder_initialized(data->decoder, data->audio_format,
|
||||||
data->input_stream.seekable,
|
data->input_stream.IsSeekable(),
|
||||||
(float)data->total_frames /
|
(float)data->total_frames /
|
||||||
(float)data->audio_format.sample_rate);
|
(float)data->audio_format.sample_rate);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data->input_stream.seekable)
|
if (data->input_stream.IsSeekable())
|
||||||
/* allow the workaround below only for nonseekable
|
/* allow the workaround below only for nonseekable
|
||||||
streams*/
|
streams*/
|
||||||
return false;
|
return false;
|
||||||
|
@ -75,7 +75,7 @@ FlacIOTell(FLAC__IOHandle handle)
|
|||||||
{
|
{
|
||||||
InputStream *is = (InputStream *)handle;
|
InputStream *is = (InputStream *)handle;
|
||||||
|
|
||||||
return is->offset;
|
return is->GetOffset();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -37,7 +37,7 @@ ToFlacIOHandle(InputStream &is)
|
|||||||
static inline const FLAC__IOCallbacks &
|
static inline const FLAC__IOCallbacks &
|
||||||
GetFlacIOCallbacks(const InputStream &is)
|
GetFlacIOCallbacks(const InputStream &is)
|
||||||
{
|
{
|
||||||
return is.seekable
|
return is.IsSeekable()
|
||||||
? flac_io_callbacks_seekable
|
? flac_io_callbacks_seekable
|
||||||
: flac_io_callbacks;
|
: flac_io_callbacks;
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ FlacInput::Read(FLAC__byte buffer[], size_t *bytes)
|
|||||||
FLAC__StreamDecoderSeekStatus
|
FLAC__StreamDecoderSeekStatus
|
||||||
FlacInput::Seek(FLAC__uint64 absolute_byte_offset)
|
FlacInput::Seek(FLAC__uint64 absolute_byte_offset)
|
||||||
{
|
{
|
||||||
if (!input_stream.seekable)
|
if (!input_stream.IsSeekable())
|
||||||
return FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED;
|
return FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED;
|
||||||
|
|
||||||
::Error error;
|
::Error error;
|
||||||
@ -62,20 +62,20 @@ FlacInput::Seek(FLAC__uint64 absolute_byte_offset)
|
|||||||
FLAC__StreamDecoderTellStatus
|
FLAC__StreamDecoderTellStatus
|
||||||
FlacInput::Tell(FLAC__uint64 *absolute_byte_offset)
|
FlacInput::Tell(FLAC__uint64 *absolute_byte_offset)
|
||||||
{
|
{
|
||||||
if (!input_stream.seekable)
|
if (!input_stream.IsSeekable())
|
||||||
return FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED;
|
return FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED;
|
||||||
|
|
||||||
*absolute_byte_offset = (FLAC__uint64)input_stream.offset;
|
*absolute_byte_offset = (FLAC__uint64)input_stream.GetOffset();
|
||||||
return FLAC__STREAM_DECODER_TELL_STATUS_OK;
|
return FLAC__STREAM_DECODER_TELL_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
FLAC__StreamDecoderLengthStatus
|
FLAC__StreamDecoderLengthStatus
|
||||||
FlacInput::Length(FLAC__uint64 *stream_length)
|
FlacInput::Length(FLAC__uint64 *stream_length)
|
||||||
{
|
{
|
||||||
if (input_stream.size < 0)
|
if (!input_stream.KnownSize())
|
||||||
return FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED;
|
return FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED;
|
||||||
|
|
||||||
*stream_length = (FLAC__uint64)input_stream.size;
|
*stream_length = (FLAC__uint64)input_stream.GetSize();
|
||||||
return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
|
return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ bool
|
|||||||
OggSeekFindEOS(OggSyncState &oy, ogg_stream_state &os, ogg_packet &packet,
|
OggSeekFindEOS(OggSyncState &oy, ogg_stream_state &os, ogg_packet &packet,
|
||||||
InputStream &is)
|
InputStream &is)
|
||||||
{
|
{
|
||||||
if (is.size > 0 && is.size - is.offset < 65536)
|
if (is.KnownSize() && is.GetRest() < 65536)
|
||||||
return OggFindEOS(oy, os, packet);
|
return OggFindEOS(oy, os, packet);
|
||||||
|
|
||||||
if (!is.CheapSeeking())
|
if (!is.CheapSeeking())
|
||||||
|
@ -185,7 +185,7 @@ LoadEOSPacket(InputStream &is, Decoder *decoder, int serialno,
|
|||||||
troubl */
|
troubl */
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
const auto old_offset = is.offset;
|
const auto old_offset = is.GetOffset();
|
||||||
if (old_offset < 0)
|
if (old_offset < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -332,16 +332,16 @@ bool
|
|||||||
MPDOpusDecoder::Seek(OggSyncState &oy, double where_s)
|
MPDOpusDecoder::Seek(OggSyncState &oy, double where_s)
|
||||||
{
|
{
|
||||||
assert(eos_granulepos > 0);
|
assert(eos_granulepos > 0);
|
||||||
assert(input_stream.seekable);
|
assert(input_stream.IsSeekable());
|
||||||
assert(input_stream.size > 0);
|
assert(input_stream.KnownSize());
|
||||||
assert(input_stream.offset >= 0);
|
assert(input_stream.GetOffset() >= 0);
|
||||||
|
|
||||||
const ogg_int64_t where_granulepos(where_s * opus_sample_rate);
|
const ogg_int64_t where_granulepos(where_s * opus_sample_rate);
|
||||||
|
|
||||||
/* interpolate the file offset where we expect to find the
|
/* interpolate the file offset where we expect to find the
|
||||||
given granule position */
|
given granule position */
|
||||||
/* TODO: implement binary search */
|
/* TODO: implement binary search */
|
||||||
InputStream::offset_type offset(where_granulepos * input_stream.size
|
InputStream::offset_type offset(where_granulepos * input_stream.GetSize()
|
||||||
/ eos_granulepos);
|
/ eos_granulepos);
|
||||||
|
|
||||||
if (!OggSeekPageAtOffset(oy, os, input_stream, offset, SEEK_SET))
|
if (!OggSeekPageAtOffset(oy, os, input_stream, offset, SEEK_SET))
|
||||||
|
@ -88,7 +88,7 @@ static long ogg_tell_cb(void *data)
|
|||||||
{
|
{
|
||||||
struct vorbis_input_stream *vis = (struct vorbis_input_stream *)data;
|
struct vorbis_input_stream *vis = (struct vorbis_input_stream *)data;
|
||||||
|
|
||||||
return (long)vis->input_stream->offset;
|
return (long)vis->input_stream->GetOffset();
|
||||||
}
|
}
|
||||||
|
|
||||||
static const ov_callbacks vorbis_is_callbacks = {
|
static const ov_callbacks vorbis_is_callbacks = {
|
||||||
|
@ -377,7 +377,7 @@ wavpack_input_read_bytes(void *id, void *data, int32_t bcount)
|
|||||||
static uint32_t
|
static uint32_t
|
||||||
wavpack_input_get_pos(void *id)
|
wavpack_input_get_pos(void *id)
|
||||||
{
|
{
|
||||||
return wpin(id)->is->offset;
|
return wpin(id)->is->GetOffset();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -406,16 +406,16 @@ wavpack_input_push_back_byte(void *id, int c)
|
|||||||
static uint32_t
|
static uint32_t
|
||||||
wavpack_input_get_length(void *id)
|
wavpack_input_get_length(void *id)
|
||||||
{
|
{
|
||||||
if (wpin(id)->is->size < 0)
|
if (!wpin(id)->is->KnownSize())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return wpin(id)->is->size;
|
return wpin(id)->is->GetSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
wavpack_input_can_seek(void *id)
|
wavpack_input_can_seek(void *id)
|
||||||
{
|
{
|
||||||
return wpin(id)->is->seekable;
|
return wpin(id)->is->IsSeekable();
|
||||||
}
|
}
|
||||||
|
|
||||||
static WavpackStreamReader mpd_is_reader = {
|
static WavpackStreamReader mpd_is_reader = {
|
||||||
@ -484,7 +484,7 @@ static void
|
|||||||
wavpack_streamdecode(Decoder &decoder, InputStream &is)
|
wavpack_streamdecode(Decoder &decoder, InputStream &is)
|
||||||
{
|
{
|
||||||
int open_flags = OPEN_NORMALIZE;
|
int open_flags = OPEN_NORMALIZE;
|
||||||
bool can_seek = is.seekable;
|
bool can_seek = is.IsSeekable();
|
||||||
|
|
||||||
wavpack_input isp_wvc;
|
wavpack_input isp_wvc;
|
||||||
InputStream *is_wvc = wavpack_open_wvc(decoder, is.GetURI(),
|
InputStream *is_wvc = wavpack_open_wvc(decoder, is.GetURI(),
|
||||||
@ -492,7 +492,7 @@ wavpack_streamdecode(Decoder &decoder, InputStream &is)
|
|||||||
&isp_wvc);
|
&isp_wvc);
|
||||||
if (is_wvc != nullptr) {
|
if (is_wvc != nullptr) {
|
||||||
open_flags |= OPEN_WVC;
|
open_flags |= OPEN_WVC;
|
||||||
can_seek &= is_wvc->seekable;
|
can_seek &= is_wvc->IsSeekable();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!can_seek) {
|
if (!can_seek) {
|
||||||
|
@ -64,6 +64,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
Cond &cond;
|
Cond &cond;
|
||||||
|
|
||||||
|
protected:
|
||||||
/**
|
/**
|
||||||
* indicates whether the stream is ready for reading and
|
* indicates whether the stream is ready for reading and
|
||||||
* whether the other attributes in this struct are valid
|
* whether the other attributes in this struct are valid
|
||||||
@ -80,7 +81,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
offset_type size;
|
offset_type size;
|
||||||
|
|
||||||
public:
|
|
||||||
/**
|
/**
|
||||||
* the current offset within the stream
|
* the current offset within the stream
|
||||||
*/
|
*/
|
||||||
@ -217,6 +217,13 @@ public:
|
|||||||
mime = _mime;
|
mime = _mime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gcc_pure
|
||||||
|
bool KnownSize() const {
|
||||||
|
assert(ready);
|
||||||
|
|
||||||
|
return size >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
gcc_pure
|
gcc_pure
|
||||||
offset_type GetSize() const {
|
offset_type GetSize() const {
|
||||||
assert(ready);
|
assert(ready);
|
||||||
@ -239,6 +246,15 @@ public:
|
|||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gcc_pure
|
||||||
|
offset_type GetRest() const {
|
||||||
|
assert(ready);
|
||||||
|
assert(size >= 0);
|
||||||
|
assert(offset >= 0);
|
||||||
|
|
||||||
|
return size - offset;
|
||||||
|
}
|
||||||
|
|
||||||
gcc_pure
|
gcc_pure
|
||||||
bool IsSeekable() const {
|
bool IsSeekable() const {
|
||||||
assert(ready);
|
assert(ready);
|
||||||
|
@ -93,7 +93,7 @@ private:
|
|||||||
* buffer contain more data for the next read operation?
|
* buffer contain more data for the next read operation?
|
||||||
*/
|
*/
|
||||||
bool ReadingFromBuffer() const {
|
bool ReadingFromBuffer() const {
|
||||||
return tail > 0 && offset < input->offset;
|
return tail > 0 && offset < input->GetOffset();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -116,7 +116,7 @@ private:
|
|||||||
SetReady();
|
SetReady();
|
||||||
}
|
}
|
||||||
|
|
||||||
offset = src->offset;
|
offset = src->GetOffset();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -127,7 +127,7 @@ RewindInputStream::Read(void *ptr, size_t read_size, Error &error)
|
|||||||
/* buffered read */
|
/* buffered read */
|
||||||
|
|
||||||
assert(head == (size_t)offset);
|
assert(head == (size_t)offset);
|
||||||
assert(tail == (size_t)input->offset);
|
assert(tail == (size_t)input->GetOffset());
|
||||||
|
|
||||||
if (read_size > tail - head)
|
if (read_size > tail - head)
|
||||||
read_size = tail - head;
|
read_size = tail - head;
|
||||||
@ -142,7 +142,7 @@ RewindInputStream::Read(void *ptr, size_t read_size, Error &error)
|
|||||||
|
|
||||||
size_t nbytes = input->Read(ptr, read_size, error);
|
size_t nbytes = input->Read(ptr, read_size, error);
|
||||||
|
|
||||||
if (input->offset > (InputPlugin::offset_type)sizeof(buffer))
|
if (input->GetOffset() > (offset_type)sizeof(buffer))
|
||||||
/* disable buffering */
|
/* disable buffering */
|
||||||
tail = 0;
|
tail = 0;
|
||||||
else if (tail == (size_t)offset) {
|
else if (tail == (size_t)offset) {
|
||||||
@ -151,7 +151,7 @@ RewindInputStream::Read(void *ptr, size_t read_size, Error &error)
|
|||||||
memcpy(buffer + tail, ptr, nbytes);
|
memcpy(buffer + tail, ptr, nbytes);
|
||||||
tail += nbytes;
|
tail += nbytes;
|
||||||
|
|
||||||
assert(tail == (size_t)input->offset);
|
assert(tail == (size_t)input->GetOffset());
|
||||||
}
|
}
|
||||||
|
|
||||||
CopyAttributes();
|
CopyAttributes();
|
||||||
@ -172,7 +172,7 @@ RewindInputStream::Seek(InputPlugin::offset_type new_offset, int whence,
|
|||||||
|
|
||||||
assert(!ReadingFromBuffer() ||
|
assert(!ReadingFromBuffer() ||
|
||||||
head == (size_t)offset);
|
head == (size_t)offset);
|
||||||
assert(tail == (size_t)input->offset);
|
assert(tail == (size_t)input->GetOffset());
|
||||||
|
|
||||||
head = (size_t)new_offset;
|
head = (size_t)new_offset;
|
||||||
offset = new_offset;
|
offset = new_offset;
|
||||||
@ -194,7 +194,7 @@ InputStream *
|
|||||||
input_rewind_open(InputStream *is)
|
input_rewind_open(InputStream *is)
|
||||||
{
|
{
|
||||||
assert(is != nullptr);
|
assert(is != nullptr);
|
||||||
assert(is->offset == 0);
|
assert(is->GetOffset() == 0);
|
||||||
|
|
||||||
if (is->IsReady() && is->IsSeekable())
|
if (is->IsReady() && is->IsSeekable())
|
||||||
/* seekable resources don't need this plugin */
|
/* seekable resources don't need this plugin */
|
||||||
|
@ -51,7 +51,7 @@ ExpatParser::Parse(const char *data, size_t length, bool is_final,
|
|||||||
bool
|
bool
|
||||||
ExpatParser::Parse(InputStream &is, Error &error)
|
ExpatParser::Parse(InputStream &is, Error &error)
|
||||||
{
|
{
|
||||||
assert(is.ready);
|
assert(is.IsReady());
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
char buffer[4096];
|
char buffer[4096];
|
||||||
|
@ -248,7 +248,7 @@ playlist_list_open_stream_suffix(InputStream &is, const char *suffix)
|
|||||||
SongEnumerator *
|
SongEnumerator *
|
||||||
playlist_list_open_stream(InputStream &is, const char *uri)
|
playlist_list_open_stream(InputStream &is, const char *uri)
|
||||||
{
|
{
|
||||||
assert(is.ready);
|
assert(is.IsReady());
|
||||||
|
|
||||||
const char *const mime = is.GetMimeType();
|
const char *const mime = is.GetMimeType();
|
||||||
if (mime != nullptr) {
|
if (mime != nullptr) {
|
||||||
|
Loading…
Reference in New Issue
Block a user