diff options
Diffstat (limited to 'ffmpeg/libavformat/aviobuf.c')
| -rw-r--r-- | ffmpeg/libavformat/aviobuf.c | 119 |
1 files changed, 105 insertions, 14 deletions
diff --git a/ffmpeg/libavformat/aviobuf.c b/ffmpeg/libavformat/aviobuf.c index 7a73a17..eb5a6e5 100644 --- a/ffmpeg/libavformat/aviobuf.c +++ b/ffmpeg/libavformat/aviobuf.c @@ -92,7 +92,7 @@ int ffio_init_context(AVIOContext *s, s->must_flush = 0; s->eof_reached = 0; s->error = 0; - s->seekable = AVIO_SEEKABLE_NORMAL; + s->seekable = seek ? AVIO_SEEKABLE_NORMAL : 0; s->max_packet_size = 0; s->update_checksum = NULL; @@ -131,6 +131,7 @@ static void writeout(AVIOContext *s, const uint8_t *data, int len) s->error = ret; } } + s->writeout_count ++; s->pos += len; } @@ -318,15 +319,22 @@ int avio_put_str16le(AVIOContext *s, const char *str) { const uint8_t *q = str; int ret = 0; + int err = 0; while (*q) { uint32_t ch; uint16_t tmp; - GET_UTF8(ch, *q++, break;) + GET_UTF8(ch, *q++, goto invalid;) PUT_UTF16(ch, tmp, avio_wl16(s, tmp); ret += 2;) + continue; +invalid: + av_log(s, AV_LOG_ERROR, "Invaid UTF8 sequence in avio_put_str16le\n"); + err = AVERROR(EINVAL); } avio_wl16(s, 0); + if (err) + return err; ret += 2; return ret; } @@ -391,12 +399,11 @@ void avio_wb24(AVIOContext *s, unsigned int val) static void fill_buffer(AVIOContext *s) { - uint8_t *dst = !s->max_packet_size && - s->buf_end - s->buffer < s->buffer_size ? - s->buf_end : 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; + 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); /* can't fill the buffer without read_packet, just set EOF if appropriate */ if (!s->read_packet && s->buf_ptr >= s->buf_end) @@ -415,10 +422,13 @@ static void fill_buffer(AVIOContext *s) /* make buffer smaller in case it ended up large after probing */ if (s->read_packet && s->buffer_size > max_buffer_size) { - ffio_set_buf_size(s, max_buffer_size); + if (dst == s->buffer) { + ffio_set_buf_size(s, max_buffer_size); - s->checksum_ptr = dst = s->buffer; - len = s->buffer_size; + s->checksum_ptr = dst = s->buffer; + } + av_assert0(len >= max_buffer_size); + len = max_buffer_size; } if (s->read_packet) @@ -522,6 +532,18 @@ int avio_read(AVIOContext *s, unsigned char *buf, int size) return size1 - size; } +int ffio_read_indirect(AVIOContext *s, unsigned char *buf, int size, const unsigned char **data) +{ + if (s->buf_end - s->buf_ptr >= size && !s->write_flag) { + *data = s->buf_ptr; + s->buf_ptr += size; + return size; + } else { + *data = buf; + return avio_read(s, buf, size); + } +} + int ffio_read_partial(AVIOContext *s, unsigned char *buf, int size) { int len; @@ -722,6 +744,31 @@ int ffio_fdopen(AVIOContext **s, URLContext *h) return 0; } +int ffio_ensure_seekback(AVIOContext *s, int buf_size) +{ + uint8_t *buffer; + int max_buffer_size = s->max_packet_size ? + s->max_packet_size : IO_BUFFER_SIZE; + + buf_size += s->buf_ptr - s->buffer + max_buffer_size; + + if (buf_size < s->buffer_size || s->seekable) + return 0; + av_assert0(!s->write_flag); + + buffer = av_malloc(buf_size); + if (!buffer) + return AVERROR(ENOMEM); + + memcpy(buffer, s->buffer, s->buffer_size); + av_free(s->buffer); + s->buf_ptr = buffer + (s->buf_ptr - s->buffer); + s->buf_end = buffer + (s->buf_end - s->buffer); + s->buffer = buffer; + s->buffer_size = buf_size; + return 0; +} + int ffio_set_buf_size(AVIOContext *s, int buf_size) { uint8_t *buffer; @@ -827,7 +874,9 @@ int avio_close(AVIOContext *s) avio_flush(s); h = s->opaque; av_freep(&s->buffer); - if (!s->write_flag) + if (s->write_flag) + av_log(s, AV_LOG_DEBUG, "Statistics: %d seeks, %d writeouts\n", s->seek_count, s->writeout_count); + else av_log(s, AV_LOG_DEBUG, "Statistics: %"PRId64" bytes read, %d seeks\n", s->bytes_read, s->seek_count); av_free(s); return ffurl_close(h); @@ -907,9 +956,12 @@ static int dyn_buf_write(void *opaque, uint8_t *buf, int buf_size) } if (new_allocated_size > d->allocated_size) { - d->buffer = av_realloc_f(d->buffer, 1, new_allocated_size); - if(d->buffer == NULL) - return AVERROR(ENOMEM); + int err; + if ((err = av_reallocp(&d->buffer, new_allocated_size)) < 0) { + d->allocated_size = 0; + d->size = 0; + return err; + } d->allocated_size = new_allocated_size; } memcpy(d->buffer + d->pos, buf, buf_size); @@ -984,11 +1036,17 @@ int ffio_open_dyn_packet_buf(AVIOContext **s, int max_packet_size) int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer) { - DynBuffer *d = s->opaque; + DynBuffer *d; int size; static const char padbuf[FF_INPUT_BUFFER_PADDING_SIZE] = {0}; int padding = 0; + if (!s) { + *pbuffer = NULL; + return 0; + } + d = s->opaque; + /* don't attempt to pad fixed-size packet buffers */ if (!s->max_packet_size) { avio_write(s, padbuf, sizeof(padbuf)); @@ -1003,3 +1061,36 @@ int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer) av_free(s); return size - padding; } + +static int null_buf_write(void *opaque, uint8_t *buf, int buf_size) +{ + DynBuffer *d = opaque; + + d->pos += buf_size; + if (d->pos > d->size) + d->size = d->pos; + return buf_size; +} + +int ffio_open_null_buf(AVIOContext **s) +{ + int ret = url_open_dyn_buf_internal(s, 0); + if (ret >= 0) { + AVIOContext *pb = *s; + pb->write_packet = null_buf_write; + } + return ret; +} + +int ffio_close_null_buf(AVIOContext *s) +{ + DynBuffer *d = s->opaque; + int size; + + avio_flush(s); + + size = d->size; + av_free(d); + av_free(s); + return size; +} |
