summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libavformat/avio.h42
-rw-r--r--libavformat/aviobuf.c26
-rw-r--r--libavformat/version.h2
3 files changed, 41 insertions, 29 deletions
diff --git a/libavformat/avio.h b/libavformat/avio.h
index 525eb7129e..844a5723d3 100644
--- a/libavformat/avio.h
+++ b/libavformat/avio.h
@@ -168,8 +168,9 @@ typedef struct AVIOContext {
const AVClass *av_class;
/*
- * The following shows the relationship between buffer, buf_ptr, buf_end, buf_size,
- * and pos, when reading and when writing (since AVIOContext is used for both):
+ * The following shows the relationship between buffer, buf_ptr,
+ * buf_ptr_max, buf_end, buf_size, and pos, when reading and when writing
+ * (since AVIOContext is used for both):
*
**********************************************************************************
* READING
@@ -196,21 +197,24 @@ typedef struct AVIOContext {
* WRITING
**********************************************************************************
*
- * | buffer_size |
- * |-------------------------------|
- * | |
+ * | buffer_size |
+ * |--------------------------------------|
+ * | |
*
- * buffer buf_ptr buf_end
- * +-------------------+-----------+
- * |/ / / / / / / / / /| |
- * write buffer: | / to be flushed / | |
- * |/ / / / / / / / / /| |
- * +-------------------+-----------+
+ * buf_ptr_max
+ * buffer (buf_ptr) buf_end
+ * +-----------------------+--------------+
+ * |/ / / / / / / / / / / /| |
+ * write buffer: | / / to be flushed / / | |
+ * |/ / / / / / / / / / / /| |
+ * +-----------------------+--------------+
+ * buf_ptr can be in this
+ * due to a backward seek
*
- * pos
- * +--------------------------+-----------------------------------+
- * output file: | | |
- * +--------------------------+-----------------------------------+
+ * pos
+ * +-------------+----------------------------------------------+
+ * output file: | | |
+ * +-------------+----------------------------------------------+
*
*/
unsigned char *buffer; /**< Start of the buffer. */
@@ -226,7 +230,7 @@ typedef struct AVIOContext {
int (*write_packet)(void *opaque, uint8_t *buf, int buf_size);
int64_t (*seek)(void *opaque, int64_t offset, int whence);
int64_t pos; /**< position in the file of the current buffer */
- int must_flush; /**< true if the next seek should flush */
+ int must_flush; /**< unused */
int eof_reached; /**< true if eof reached */
int write_flag; /**< true if open for writing */
int max_packet_size;
@@ -329,6 +333,12 @@ typedef struct AVIOContext {
int (*short_seek_get)(void *opaque);
int64_t written;
+
+ /**
+ * Maximum reached position before a backward seek in the write buffer,
+ * used keeping track of already written data for a later flush.
+ */
+ unsigned char *buf_ptr_max;
} AVIOContext;
/**
diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c
index 1667e9f08b..dcb91570d8 100644
--- a/libavformat/aviobuf.c
+++ b/libavformat/aviobuf.c
@@ -91,6 +91,7 @@ int ffio_init_context(AVIOContext *s,
s->orig_buffer_size =
s->buffer_size = buffer_size;
s->buf_ptr = buffer;
+ s->buf_ptr_max = buffer;
s->opaque = opaque;
s->direct = 0;
@@ -100,7 +101,6 @@ int ffio_init_context(AVIOContext *s,
s->read_packet = read_packet;
s->seek = seek;
s->pos = 0;
- s->must_flush = 0;
s->eof_reached = 0;
s->error = 0;
s->seekable = seek ? AVIO_SEEKABLE_NORMAL : 0;
@@ -171,15 +171,16 @@ static void writeout(AVIOContext *s, const uint8_t *data, int len)
static void flush_buffer(AVIOContext *s)
{
- if (s->write_flag && s->buf_ptr > s->buffer) {
- writeout(s, s->buffer, s->buf_ptr - s->buffer);
+ s->buf_ptr_max = FFMAX(s->buf_ptr, s->buf_ptr_max);
+ if (s->write_flag && s->buf_ptr_max > s->buffer) {
+ writeout(s, s->buffer, s->buf_ptr_max - s->buffer);
if (s->update_checksum) {
s->checksum = s->update_checksum(s->checksum, s->checksum_ptr,
- s->buf_ptr - s->checksum_ptr);
+ s->buf_ptr_max - s->checksum_ptr);
s->checksum_ptr = s->buffer;
}
}
- s->buf_ptr = s->buffer;
+ s->buf_ptr = s->buf_ptr_max = s->buffer;
if (!s->write_flag)
s->buf_end = s->buffer;
}
@@ -228,8 +229,10 @@ void avio_write(AVIOContext *s, const unsigned char *buf, int size)
void avio_flush(AVIOContext *s)
{
+ int seekback = s->write_flag ? FFMIN(0, s->buf_ptr - s->buf_ptr_max) : 0;
flush_buffer(s);
- s->must_flush = 0;
+ if (seekback)
+ avio_seek(s, seekback, SEEK_CUR);
}
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
@@ -269,8 +272,9 @@ int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
short_seek = s->short_seek_threshold;
offset1 = offset - pos; // "offset1" is the relative offset from the beginning of s->buffer
- if (!s->must_flush && (!s->direct || !s->seek) &&
- offset1 >= 0 && offset1 <= buffer_size - s->write_flag) {
+ s->buf_ptr_max = FFMAX(s->buf_ptr_max, s->buf_ptr);
+ if ((!s->direct || !s->seek) &&
+ offset1 >= 0 && offset1 <= (s->write_flag ? s->buf_ptr_max - s->buffer : buffer_size)) {
/* can do the seek inside the buffer */
s->buf_ptr = s->buffer + offset1;
} else if ((!(s->seekable & AVIO_SEEKABLE_NORMAL) ||
@@ -299,7 +303,6 @@ int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
int64_t res;
if (s->write_flag) {
flush_buffer(s);
- s->must_flush = 1;
}
if (!s->seek)
return AVERROR(EPIPE);
@@ -308,7 +311,7 @@ int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
s->seek_count ++;
if (!s->write_flag)
s->buf_end = s->buffer;
- s->buf_ptr = s->buffer;
+ s->buf_ptr = s->buf_ptr_max = s->buffer;
s->pos = offset;
}
s->eof_reached = 0;
@@ -994,7 +997,7 @@ int ffio_set_buf_size(AVIOContext *s, int buf_size)
s->buffer = buffer;
s->orig_buffer_size =
s->buffer_size = buf_size;
- s->buf_ptr = buffer;
+ s->buf_ptr = s->buf_ptr_max = buffer;
url_resetbuf(s, s->write_flag ? AVIO_FLAG_WRITE : AVIO_FLAG_READ);
return 0;
}
@@ -1052,7 +1055,6 @@ int ffio_rewind_with_probe_data(AVIOContext *s, unsigned char **bufp, int buf_si
s->pos = buf_size;
s->buf_end = s->buf_ptr + buf_size;
s->eof_reached = 0;
- s->must_flush = 0;
return 0;
}
diff --git a/libavformat/version.h b/libavformat/version.h
index b00a8b0333..1fb8ffb2b9 100644
--- a/libavformat/version.h
+++ b/libavformat/version.h
@@ -32,7 +32,7 @@
// Major bumping may affect Ticket5467, 5421, 5451(compatibility with Chromium)
// Also please add any ticket numbers that you believe might be affected here
#define LIBAVFORMAT_VERSION_MAJOR 57
-#define LIBAVFORMAT_VERSION_MINOR 73
+#define LIBAVFORMAT_VERSION_MINOR 74
#define LIBAVFORMAT_VERSION_MICRO 100
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \