diff --git a/libavformat/avio_internal.h b/libavformat/avio_internal.h index 311e297e9a..4f4a428a4c 100644 --- a/libavformat/avio_internal.h +++ b/libavformat/avio_internal.h @@ -37,6 +37,23 @@ int ffio_init_context(AVIOContext *s, int64_t (*seek)(void *opaque, int64_t offset, int whence)); +/** + * Read size bytes from AVIOContext, returning a pointer. + * Note that the data pointed at by the returned pointer is only + * valid until the next call that references the same IO context. + * @param s IO context + * @param buf pointer to buffer into which to assemble the requested + * data if it is not available in contiguous addresses in the + * underlying buffer + * @param size number of bytes requested + * @param data address at which to store pointer: this will be a + * a direct pointer into the underlying buffer if the requested + * number of bytes are available at contiguous addresses, otherwise + * will be a copy of buf + * @return number of bytes read or AVERROR + */ +int ffio_read_indirect(AVIOContext *s, unsigned char *buf, int size, unsigned char **data); + /** * Read size bytes from AVIOContext into buf. * This reads at most 1 packet. If that is not enough fewer bytes will be diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c index 6efc0cfae0..466f3908b5 100644 --- a/libavformat/aviobuf.c +++ b/libavformat/aviobuf.c @@ -525,6 +525,18 @@ int avio_read(AVIOContext *s, unsigned char *buf, int size) return size1 - size; } +int ffio_read_indirect(AVIOContext *s, unsigned char *buf, int size, unsigned char **data) +{ + if (s->buf_end - s->buf_ptr >= size && !s->write_flag) { + *data = s->buf_ptr; + s->buf_ptr += size; + return size; + } else { + *data = buf; + return avio_read(s, buf, size); + } +} + int ffio_read_partial(AVIOContext *s, unsigned char *buf, int size) { int len;