diff aviobuf.c @ 5941:bde9a4b67f86 libavformat

Reusing the probe buffer to rewind the ByteIOContext in ff_probe_input_buffer() instead of seeking back to the start of the file. Once exhausted, the size of the buffer is reduced.
author thardin
date Thu, 08 Apr 2010 09:02:27 +0000
parents 6a24c2ae6ee4
children b106b59bf663
line wrap: on
line diff
--- a/aviobuf.c	Wed Apr 07 19:40:46 2010 +0000
+++ b/aviobuf.c	Thu Apr 08 09:02:27 2010 +0000
@@ -295,6 +295,7 @@
 {
     uint8_t *dst= !s->max_packet_size && s->buf_end - s->buffer < s->buffer_size ? s->buf_ptr : s->buffer;
     int len= s->buffer_size - (dst - s->buffer);
+    int max_buffer_size = s->max_packet_size ? s->max_packet_size : IO_BUFFER_SIZE;
 
     assert(s->buf_ptr == s->buf_end);
 
@@ -308,6 +309,14 @@
         s->checksum_ptr= s->buffer;
     }
 
+    /* make buffer smaller in case it ended up large after probing */
+    if (s->buffer_size > max_buffer_size) {
+        url_setbufsize(s, max_buffer_size);
+
+        s->checksum_ptr = dst = s->buffer;
+        len = s->buffer_size;
+    }
+
     if(s->read_packet)
         len = s->read_packet(s->opaque, dst, len);
     else
@@ -611,6 +620,42 @@
     return 0;
 }
 
+int ff_rewind_with_probe_data(ByteIOContext *s, unsigned char *buf, int buf_size)
+{
+    int64_t buffer_start;
+    int buffer_size;
+    int overlap, new_size;
+
+    if (s->write_flag)
+        return AVERROR(EINVAL);
+
+    buffer_size = s->buf_end - s->buffer;
+
+    /* the buffers must touch or overlap */
+    if ((buffer_start = s->pos - buffer_size) > buf_size)
+        return AVERROR(EINVAL);
+
+    overlap = buf_size - buffer_start;
+    new_size = buf_size + buffer_size - overlap;
+
+    if (new_size > buf_size) {
+        if (!(buf = av_realloc(buf, new_size)))
+            return AVERROR(ENOMEM);
+
+        memcpy(buf + buf_size, s->buffer + overlap, buffer_size - overlap);
+        buf_size = new_size;
+    }
+
+    av_free(s->buffer);
+    s->buf_ptr = s->buffer = buf;
+    s->pos = s->buffer_size = buf_size;
+    s->buf_end = s->buf_ptr + buf_size;
+    s->eof_reached = 0;
+    s->must_flush = 0;
+
+    return 0;
+}
+
 int url_fopen(ByteIOContext **s, const char *filename, int flags)
 {
     URLContext *h;