[FFmpeg-devel] [PATCH] Add AVIO_FLAG_DIRECT.
Reimar Döffinger
Reimar.Doeffinger at gmx.de
Sun Mar 25 11:59:57 CEST 2012
Allows avoiding the buffer when using avio read and write functions.
Signed-off-by: Reimar Döffinger <Reimar.Doeffinger at gmx.de>
---
libavformat/avio.h | 13 +++++++++++++
libavformat/aviobuf.c | 30 +++++++++++++++++++++---------
2 files changed, 34 insertions(+), 9 deletions(-)
diff --git a/libavformat/avio.h b/libavformat/avio.h
index 95f9558..b4c975f 100644
--- a/libavformat/avio.h
+++ b/libavformat/avio.h
@@ -121,6 +121,12 @@ typedef struct {
* This field is internal to libavformat and access from outside is not allowed.
*/
int64_t maxsize;
+
+ /**
+ * avoi_read and avio_write should if possible be satisfied directly
+ * instead of going through a buffer.
+ */
+ int direct;
} AVIOContext;
/* unbuffered I/O */
@@ -320,6 +326,13 @@ int avio_get_str16be(AVIOContext *pb, int maxlen, char *buf, int buflen);
#define AVIO_FLAG_NONBLOCK 8
/**
+ * Use direct mode.
+ * avoi_read and avio_write should if possible be satisfied directly
+ * instead of going through a buffer.
+ */
+#define AVIO_FLAG_DIRECT 0x8000
+
+/**
* Create and initialize a AVIOContext for accessing the
* resource indicated by url.
* @note When the resource indicated by url has been opened in
diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c
index d1520ed..1e26e17 100644
--- a/libavformat/aviobuf.c
+++ b/libavformat/aviobuf.c
@@ -117,20 +117,25 @@ AVIOContext *avio_alloc_context(
return s;
}
+static void writeout(AVIOContext *s, const uint8_t *data, int len)
+{
+ if (s->write_packet && !s->error){
+ int ret= s->write_packet(s->opaque, data, len);
+ if(ret < 0){
+ s->error = ret;
+ }
+ }
+ s->pos += len;
+}
+
static void flush_buffer(AVIOContext *s)
{
if (s->buf_ptr > s->buffer) {
- if (s->write_packet && !s->error){
- int ret= s->write_packet(s->opaque, s->buffer, s->buf_ptr - s->buffer);
- if(ret < 0){
- s->error = ret;
- }
- }
+ writeout(s, s->buffer, s->buf_ptr - s->buffer);
if(s->update_checksum){
s->checksum= s->update_checksum(s->checksum, s->checksum_ptr, s->buf_ptr - s->checksum_ptr);
s->checksum_ptr= s->buffer;
}
- s->pos += s->buf_ptr - s->buffer;
}
s->buf_ptr = s->buffer;
}
@@ -158,6 +163,11 @@ void ffio_fill(AVIOContext *s, int b, int count)
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
{
+ if (s->direct) {
+ avio_flush(s);
+ writeout(s, buf, size);
+ return;
+ }
while (size > 0) {
int len = FFMIN(s->buf_end - s->buf_ptr, size);
memcpy(s->buf_ptr, buf, len);
@@ -199,13 +209,14 @@ int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
offset += offset1;
}
offset1 = offset - pos;
- if (!s->must_flush &&
+ if (!s->must_flush && !s->direct &&
offset1 >= 0 && offset1 <= (s->buf_end - s->buffer)) {
/* can do the seek inside the buffer */
s->buf_ptr = s->buffer + offset1;
} else if ((!s->seekable ||
offset1 <= s->buf_end + SHORT_SEEK_THRESHOLD - s->buffer) &&
!s->write_flag && offset1 >= 0 &&
+ !s->direct &&
(whence != SEEK_END || force)) {
while(s->pos < offset && !s->eof_reached)
fill_buffer(s);
@@ -458,7 +469,7 @@ int avio_read(AVIOContext *s, unsigned char *buf, int size)
if (len > size)
len = size;
if (len == 0) {
- if(size > s->buffer_size && !s->update_checksum){
+ if((s->direct || size > s->buffer_size) && !s->update_checksum){
if(s->read_packet)
len = s->read_packet(s->opaque, buf, size);
if (len <= 0) {
@@ -670,6 +681,7 @@ int ffio_fdopen(AVIOContext **s, URLContext *h)
av_free(buffer);
return AVERROR(ENOMEM);
}
+ (*s)->direct = h->flags & AVIO_FLAG_DIRECT;
(*s)->seekable = h->is_streamed ? 0 : AVIO_SEEKABLE_NORMAL;
(*s)->max_packet_size = max_packet_size;
if(h->prot) {
--
1.7.9.1
More information about the ffmpeg-devel
mailing list