X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Faviobuf.c;h=636cb46161ad05dae0fbac1397c79c774836e8e4;hb=2f3a3a7e3270d9c4486fc4d1ed708c2f54338f9c;hp=1667e9f08b4a1b5c33f29841e2b6a749145e29cc;hpb=7383a835e47cd8915ff9cdd693e06716dbae3b3a;p=ffmpeg diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c index 1667e9f08b4..636cb46161a 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,10 +101,10 @@ 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; + s->min_packet_size = 0; s->max_packet_size = 0; s->update_checksum = NULL; s->short_seek_threshold = SHORT_SEEK_THRESHOLD; @@ -142,6 +143,11 @@ AVIOContext *avio_alloc_context( return s; } +void avio_context_free(AVIOContext **ps) +{ + av_freep(ps); +} + static void writeout(AVIOContext *s, const uint8_t *data, int len) { if (!s->error) { @@ -171,15 +177,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 +235,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) @@ -255,6 +264,8 @@ int64_t avio_seek(AVIOContext *s, int64_t offset, int whence) offset1 = pos + (s->buf_ptr - s->buffer); if (offset == 0) return offset1; + if (offset > INT64_MAX - offset1) + return AVERROR(EINVAL); offset += offset1; } if (offset < 0) @@ -269,8 +280,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 +311,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 +319,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; @@ -486,6 +497,11 @@ void avio_wb24(AVIOContext *s, unsigned int val) void avio_write_marker(AVIOContext *s, int64_t time, enum AVIODataMarkerType type) { + if (type == AVIO_DATA_MARKER_FLUSH_POINT) { + if (s->buf_ptr - s->buffer >= s->min_packet_size) + avio_flush(s); + return; + } if (!s->write_data_type) return; // If ignoring boundary points, just treat it as unknown @@ -687,7 +703,7 @@ int ffio_read_indirect(AVIOContext *s, unsigned char *buf, int size, const unsig } } -int ffio_read_partial(AVIOContext *s, unsigned char *buf, int size) +int avio_read_partial(AVIOContext *s, unsigned char *buf, int size) { int len; @@ -938,6 +954,7 @@ int ffio_fdopen(AVIOContext **s, URLContext *h) (*s)->seekable = h->is_streamed ? 0 : AVIO_SEEKABLE_NORMAL; (*s)->max_packet_size = max_packet_size; + (*s)->min_packet_size = h->min_packet_size; if(h->prot) { (*s)->read_pause = io_read_pause; (*s)->read_seek = io_read_seek; @@ -994,7 +1011,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 +1069,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; } @@ -1112,7 +1128,9 @@ int avio_close(AVIOContext *s) else av_log(s, AV_LOG_DEBUG, "Statistics: %"PRId64" bytes read, %d seeks\n", s->bytes_read, s->seek_count); av_opt_free(s); - av_free(s); + + avio_context_free(&s); + return ffurl_close(h); } @@ -1345,7 +1363,9 @@ int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer) *pbuffer = d->buffer; size = d->size; av_free(d); - av_free(s); + + avio_context_free(&s); + return size - padding; } @@ -1388,6 +1408,8 @@ int ffio_close_null_buf(AVIOContext *s) size = d->size; av_free(d); - av_free(s); + + avio_context_free(&s); + return size; }