Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FFmpeg/FFmpeg.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'libavformat/aviobuf.c')
-rw-r--r--libavformat/aviobuf.c81
1 files changed, 58 insertions, 23 deletions
diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c
index 7dc66e25a6..282a62e2b7 100644
--- a/libavformat/aviobuf.c
+++ b/libavformat/aviobuf.c
@@ -2,20 +2,20 @@
* buffered I/O
* Copyright (c) 2000,2001 Fabrice Bellard
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -24,6 +24,7 @@
#include "libavutil/intreadwrite.h"
#include "libavutil/log.h"
#include "libavutil/opt.h"
+#include "libavutil/avassert.h"
#include "avformat.h"
#include "avio.h"
#include "avio_internal.h"
@@ -80,6 +81,7 @@ int ffio_init_context(AVIOContext *s,
s->buffer_size = buffer_size;
s->buf_ptr = buffer;
s->opaque = opaque;
+ s->direct = 0;
url_resetbuf(s, write_flag ? AVIO_FLAG_WRITE : AVIO_FLAG_READ);
s->write_packet = write_packet;
s->read_packet = read_packet;
@@ -117,20 +119,25 @@ AVIOContext *avio_alloc_context(
return s;
}
+static void writeout(AVIOContext *s, const uint8_t *data, int len)
+{
+ if (s->write_packet && !s->error){
+ int ret= s->write_packet(s->opaque, (uint8_t *)data, len);
+ if(ret < 0){
+ s->error = ret;
+ }
+ }
+ s->pos += len;
+}
+
static void flush_buffer(AVIOContext *s)
{
if (s->buf_ptr > s->buffer) {
- if (s->write_packet && !s->error){
- int ret= s->write_packet(s->opaque, s->buffer, s->buf_ptr - s->buffer);
- if(ret < 0){
- s->error = ret;
- }
- }
+ writeout(s, s->buffer, s->buf_ptr - s->buffer);
if(s->update_checksum){
s->checksum= s->update_checksum(s->checksum, s->checksum_ptr, s->buf_ptr - s->checksum_ptr);
s->checksum_ptr= s->buffer;
}
- s->pos += s->buf_ptr - s->buffer;
}
s->buf_ptr = s->buffer;
}
@@ -158,6 +165,11 @@ void ffio_fill(AVIOContext *s, int b, int count)
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
{
+ if (s->direct && !s->update_checksum) {
+ avio_flush(s);
+ writeout(s, buf, size);
+ return;
+ }
while (size > 0) {
int len = FFMIN(s->buf_end - s->buf_ptr, size);
memcpy(s->buf_ptr, buf, len);
@@ -199,13 +211,14 @@ int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
offset += offset1;
}
offset1 = offset - pos;
- if (!s->must_flush &&
+ if (!s->must_flush && (!s->direct || !s->seek) &&
offset1 >= 0 && offset1 <= (s->buf_end - s->buffer)) {
/* can do the seek inside the buffer */
s->buf_ptr = s->buffer + offset1;
} else if ((!s->seekable ||
offset1 <= s->buf_end + SHORT_SEEK_THRESHOLD - s->buffer) &&
!s->write_flag && offset1 >= 0 &&
+ (!s->direct || !s->seek) &&
(whence != SEEK_END || force)) {
while(s->pos < offset && !s->eof_reached)
fill_buffer(s);
@@ -225,6 +238,7 @@ int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
return AVERROR(EPIPE);
if ((res = s->seek(s->opaque, offset, SEEK_SET)) < 0)
return res;
+ s->seek_count ++;
if (!s->write_flag)
s->buf_end = s->buffer;
s->buf_ptr = s->buffer;
@@ -234,6 +248,11 @@ int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
return offset;
}
+int64_t avio_skip(AVIOContext *s, int64_t offset)
+{
+ return avio_seek(s, offset, SEEK_CUR);
+}
+
int64_t avio_size(AVIOContext *s)
{
int64_t size;
@@ -253,6 +272,17 @@ int64_t avio_size(AVIOContext *s)
return size;
}
+int url_feof(AVIOContext *s)
+{
+ if(!s)
+ return 0;
+ if(s->eof_reached){
+ s->eof_reached=0;
+ fill_buffer(s);
+ }
+ return s->eof_reached;
+}
+
void avio_wl32(AVIOContext *s, unsigned int val)
{
avio_w8(s, val);
@@ -359,7 +389,7 @@ static void fill_buffer(AVIOContext *s)
int len= s->buffer_size - (dst - s->buffer);
int max_buffer_size = s->max_packet_size ? s->max_packet_size : IO_BUFFER_SIZE;
- /* can't fill the buffer without read_packet, just set EOF if appropiate */
+ /* can't fill the buffer without read_packet, just set EOF if appropriate */
if (!s->read_packet && s->buf_ptr >= s->buf_end)
s->eof_reached = 1;
@@ -374,7 +404,7 @@ static void fill_buffer(AVIOContext *s)
}
/* make buffer smaller in case it ended up large after probing */
- if (s->buffer_size > max_buffer_size) {
+ if (s->read_packet && s->buffer_size > max_buffer_size) {
ffio_set_buf_size(s, max_buffer_size);
s->checksum_ptr = dst = s->buffer;
@@ -395,6 +425,7 @@ static void fill_buffer(AVIOContext *s)
s->pos += len;
s->buf_ptr = dst;
s->buf_end = dst + len;
+ s->bytes_read += len;
}
}
@@ -442,7 +473,7 @@ int avio_read(AVIOContext *s, unsigned char *buf, int size)
if (len > size)
len = size;
if (len == 0) {
- if(size > s->buffer_size && !s->update_checksum){
+ if((s->direct || size > s->buffer_size) && !s->update_checksum){
if(s->read_packet)
len = s->read_packet(s->opaque, buf, size);
if (len <= 0) {
@@ -454,6 +485,7 @@ int avio_read(AVIOContext *s, unsigned char *buf, int size)
break;
} else {
s->pos += len;
+ s->bytes_read += len;
size -= len;
buf += len;
s->buf_ptr = s->buffer;
@@ -473,8 +505,8 @@ int avio_read(AVIOContext *s, unsigned char *buf, int size)
}
}
if (size1 == size) {
- if (s->error) return s->error;
- if (s->eof_reached) return AVERROR_EOF;
+ if (s->error) return s->error;
+ if (url_feof(s)) return AVERROR_EOF;
}
return size1 - size;
}
@@ -496,8 +528,8 @@ int ffio_read_partial(AVIOContext *s, unsigned char *buf, int size)
memcpy(buf, s->buf_ptr, len);
s->buf_ptr += len;
if (!len) {
- if (s->error) return s->error;
- if (s->eof_reached) return AVERROR_EOF;
+ if (s->error) return s->error;
+ if (url_feof(s)) return AVERROR_EOF;
}
return len;
}
@@ -649,11 +681,12 @@ int ffio_fdopen(AVIOContext **s, URLContext *h)
return AVERROR(ENOMEM);
*s = avio_alloc_context(buffer, buffer_size, h->flags & AVIO_FLAG_WRITE, h,
- ffurl_read, ffurl_write, ffurl_seek);
+ (void*)ffurl_read, (void*)ffurl_write, (void*)ffurl_seek);
if (!*s) {
av_free(buffer);
return AVERROR(ENOMEM);
}
+ (*s)->direct = h->flags & AVIO_FLAG_DIRECT;
(*s)->seekable = h->is_streamed ? 0 : AVIO_SEEKABLE_NORMAL;
(*s)->max_packet_size = max_packet_size;
if(h->prot) {
@@ -681,7 +714,7 @@ int ffio_set_buf_size(AVIOContext *s, int buf_size)
static int url_resetbuf(AVIOContext *s, int flags)
{
- assert(flags == AVIO_FLAG_WRITE || flags == AVIO_FLAG_READ);
+ av_assert1(flags == AVIO_FLAG_WRITE || flags == AVIO_FLAG_READ);
if (flags & AVIO_FLAG_WRITE) {
s->buf_end = s->buffer + s->buffer_size;
@@ -713,7 +746,7 @@ int ffio_rewind_with_probe_data(AVIOContext *s, unsigned char *buf, int buf_size
alloc_size = FFMAX(s->buffer_size, new_size);
if (alloc_size > buf_size)
- if (!(buf = av_realloc(buf, alloc_size)))
+ if (!(buf = av_realloc_f(buf, 1, alloc_size)))
return AVERROR(ENOMEM);
if (new_size > buf_size) {
@@ -764,6 +797,8 @@ int avio_close(AVIOContext *s)
avio_flush(s);
h = s->opaque;
av_freep(&s->buffer);
+ if (!s->write_flag)
+ 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);
}
@@ -835,7 +870,7 @@ static int dyn_buf_write(void *opaque, uint8_t *buf, int buf_size)
}
if (new_allocated_size > d->allocated_size) {
- d->buffer = av_realloc(d->buffer, new_allocated_size);
+ d->buffer = av_realloc_f(d->buffer, 1, new_allocated_size);
if(d->buffer == NULL)
return AVERROR(ENOMEM);
d->allocated_size = new_allocated_size;