[FFmpeg-cvslog] r22821 - in trunk/libavformat: avio.h aviobuf.c utils.c

thardin subversion
Thu Apr 8 11:02:27 CEST 2010


Author: thardin
Date: Thu Apr  8 11:02:27 2010
New Revision: 22821

Log:
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.

Modified:
   trunk/libavformat/avio.h
   trunk/libavformat/aviobuf.c
   trunk/libavformat/utils.c

Modified: trunk/libavformat/avio.h
==============================================================================
--- trunk/libavformat/avio.h	Thu Apr  8 08:27:39 2010	(r22820)
+++ trunk/libavformat/avio.h	Thu Apr  8 11:02:27 2010	(r22821)
@@ -433,6 +433,21 @@ int url_resetbuf(ByteIOContext *s, int f
 #endif
 
 /**
+ * Rewinds the ByteIOContext using the specified buffer containing the first buf_size bytes of the file.
+ * Used after probing to avoid seeking.
+ * Joins buf and s->buffer, taking any overlap into consideration.
+ * @note s->buffer must overlap with buf or they can't be joined and the function fails
+ * @note This function is NOT part of the public API
+ *
+ * @param s The read-only ByteIOContext to rewind
+ * @param buf The probe buffer containing the first buf_size bytes of the file
+ * @param buf_size The size of buf
+ * @return 0 in case of success, a negative value corresponding to an
+ * AVERROR code in case of failure
+ */
+int ff_rewind_with_probe_data(ByteIOContext *s, unsigned char *buf, int buf_size);
+
+/**
  * Creates and initializes a ByteIOContext for accessing the
  * resource indicated by url.
  * @note When the resource indicated by url has been opened in

Modified: trunk/libavformat/aviobuf.c
==============================================================================
--- trunk/libavformat/aviobuf.c	Thu Apr  8 08:27:39 2010	(r22820)
+++ trunk/libavformat/aviobuf.c	Thu Apr  8 11:02:27 2010	(r22821)
@@ -295,6 +295,7 @@ static void fill_buffer(ByteIOContext *s
 {
     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 @@ static void fill_buffer(ByteIOContext *s
         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 @@ static int url_resetbuf(ByteIOContext *s
     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;

Modified: trunk/libavformat/utils.c
==============================================================================
--- trunk/libavformat/utils.c	Thu Apr  8 08:27:39 2010	(r22820)
+++ trunk/libavformat/utils.c	Thu Apr  8 11:02:27 2010	(r22821)
@@ -516,19 +516,16 @@ int ff_probe_input_buffer(ByteIOContext 
         }
     }
 
-    av_free(buf);
-
     if (!*fmt) {
+        av_free(buf);
         return AVERROR_INVALIDDATA;
     }
 
-    if (url_fseek(*pb, 0, SEEK_SET) < 0) {
-        url_fclose(*pb);
-        if (url_fopen(pb, filename, URL_RDONLY) < 0)
-            return AVERROR(EIO);
-    }
+    /* rewind. reuse probe buffer to avoid seeking */
+    if ((ret = ff_rewind_with_probe_data(*pb, buf, pd.buf_size)) < 0)
+        av_free(buf);
 
-    return 0;
+    return ret;
 }
 
 int av_open_input_file(AVFormatContext **ic_ptr, const char *filename,



More information about the ffmpeg-cvslog mailing list