From 71cadd60a2f71d2d39bd7999e080c206291b55da Mon Sep 17 00:00:00 2001
From: Adrian Trzcinski <atrzcinski@vewd.com>
Date: Tue, 4 Dec 2018 19:00:22 +0100
Subject: [PATCH] avformat/avio: fill_buffer drops less data
Signed-off-by: Adrian Trzcinski <atrzcinski@vewd.com>
---
libavformat/avio.h | 1 +
libavformat/aviobuf.c | 21 ++++++++++++++++-----
libavformat/utils.c | 1 +
3 files changed, 18 insertions(+), 5 deletions(-)
@@ -225,6 +225,7 @@ typedef struct AVIOContext {
*/
unsigned char *buffer; /**< Start of the buffer. */
int buffer_size; /**< Maximum buffer size */
+ int time_units_in_buffer; /**< Number of time units in buffer */
unsigned char *buf_ptr; /**< Current position in the buffer */
unsigned char *buf_end; /**< End of the data, may be less than
buffer+buffer_size if the read function returned
@@ -92,6 +92,7 @@ int ffio_init_context(AVIOContext *s,
s->buffer = buffer;
s->orig_buffer_size =
s->buffer_size = buffer_size;
+ s->time_units_in_buffer = 0;
s->buf_ptr = buffer;
s->buf_ptr_max = buffer;
s->opaque = opaque;
@@ -550,9 +551,19 @@ static void fill_buffer(AVIOContext *s)
{
int max_buffer_size = s->max_packet_size ?
s->max_packet_size : IO_BUFFER_SIZE;
- uint8_t *dst = s->buf_end - s->buffer + max_buffer_size < s->buffer_size ?
- s->buf_end : s->buffer;
- int len = s->buffer_size - (dst - s->buffer);
+ int need_erase = !(s->buf_end - s->buffer + max_buffer_size < s->buffer_size);
+ uint8_t *dst = need_erase ? s->buffer : s->buf_end;
+ int len;
+
+ if (need_erase && s->time_units_in_buffer > 1) {
+ const int bytes_in_time_unit = (s->buf_end - s->buffer) / s->time_units_in_buffer;
+ const int offset = bytes_in_time_unit * (s->time_units_in_buffer - 1);
+ memcpy(s->buffer, s->buffer + offset, bytes_in_time_unit);
+ dst = s->buf_end = s->buffer + bytes_in_time_unit;
+ s->buf_ptr = s->buf_ptr - s->buffer < offset ? s->buffer : s->buf_ptr - offset;
+ }
+
+ len = s->buffer_size - (dst - s->buffer);
/* can't fill the buffer without read_packet, just set EOF if appropriate */
if (!s->read_packet && s->buf_ptr >= s->buf_end)
@@ -562,7 +573,7 @@ static void fill_buffer(AVIOContext *s)
if (s->eof_reached)
return;
- if (s->update_checksum && dst == s->buffer) {
+ if (s->update_checksum && need_erase) {
if (s->buf_end > s->checksum_ptr)
s->checksum = s->update_checksum(s->checksum, s->checksum_ptr,
s->buf_end - s->checksum_ptr);
@@ -571,7 +582,7 @@ static void fill_buffer(AVIOContext *s)
/* make buffer smaller in case it ended up large after probing */
if (s->read_packet && s->orig_buffer_size && s->buffer_size > s->orig_buffer_size) {
- if (dst == s->buffer && s->buf_ptr != dst) {
+ if (need_erase && s->buf_ptr != dst) {
int ret = ffio_set_buf_size(s, s->orig_buffer_size);
if (ret < 0)
av_log(s, AV_LOG_WARNING, "Failed to decrease buffer size\n");
@@ -2138,6 +2138,7 @@ void ff_configure_buffers_for_index(AVFormatContext *s, int64_t time_tolerance)
av_log(s, AV_LOG_VERBOSE, "Reconfiguring buffers to size %"PRId64"\n", pos_delta);
ffio_set_buf_size(s->pb, pos_delta);
s->pb->short_seek_threshold = FFMAX(s->pb->short_seek_threshold, pos_delta/2);
+ s->pb->time_units_in_buffer = 2;
}
if (skip < (1<<23)) {
--
2.19.2