X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Faviobuf.c;h=898f35d903cf15fc8bab87a0589e451a34cdb257;hb=f7de52354fe15ba7cae141b44ffdd01e560f0e47;hp=a0cb9a89212d54e8c023ca20d4b0cfe1e944f6b7;hpb=b7f2fdde74608d848f943377c40d3df804c5f955;p=ffmpeg diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c index a0cb9a89212..898f35d903c 100644 --- a/libavformat/aviobuf.c +++ b/libavformat/aviobuf.c @@ -1,30 +1,34 @@ /* - * Buffered I/O for ffmpeg system + * buffered I/O * Copyright (c) 2000,2001 Fabrice Bellard * - * This file is part of FFmpeg. + * This file is part of Libav. * - * FFmpeg is free software; you can redistribute it and/or + * Libav 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. * - * FFmpeg is distributed in the hope that it will be useful, + * Libav 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 FFmpeg; if not, write to the Free Software + * License along with Libav; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "libavutil/crc.h" +#include "libavutil/dict.h" #include "libavutil/intreadwrite.h" +#include "libavutil/log.h" +#include "libavutil/opt.h" #include "avformat.h" #include "avio.h" #include "avio_internal.h" #include "internal.h" +#include "url.h" #include #define IO_BUFFER_SIZE 32768 @@ -36,10 +40,33 @@ */ #define SHORT_SEEK_THRESHOLD 4096 +#if !FF_API_OLD_AVIO +static void *ffio_url_child_next(void *obj, void *prev) +{ + AVIOContext *s = obj; + return prev ? NULL : s->opaque; +} + +static const AVClass *ffio_url_child_class_next(const AVClass *prev) +{ + return prev ? NULL : &ffurl_context_class; +} + +static const AVOption ffio_url_options[] = { + { NULL }, +}; + +const AVClass ffio_url_class = { + .class_name = "AVIOContext", + .item_name = av_default_item_name, + .version = LIBAVUTIL_VERSION_INT, + .option = ffio_url_options, + .child_next = ffio_url_child_next, + .child_class_next = ffio_url_child_class_next, +}; +#endif static void fill_buffer(AVIOContext *s); -#if !FF_API_URL_RESETBUF static int url_resetbuf(AVIOContext *s, int flags); -#endif int ffio_init_context(AVIOContext *s, unsigned char *buffer, @@ -54,7 +81,7 @@ int ffio_init_context(AVIOContext *s, s->buffer_size = buffer_size; s->buf_ptr = buffer; s->opaque = opaque; - url_resetbuf(s, write_flag ? URL_WRONLY : URL_RDONLY); + url_resetbuf(s, write_flag ? AVIO_FLAG_WRITE : AVIO_FLAG_READ); s->write_packet = write_packet; s->read_packet = read_packet; s->seek = seek; @@ -62,7 +89,10 @@ int ffio_init_context(AVIOContext *s, s->must_flush = 0; s->eof_reached = 0; s->error = 0; +#if FF_API_OLD_AVIO s->is_streamed = 0; +#endif + s->seekable = AVIO_SEEKABLE_NORMAL; s->max_packet_size = 0; s->update_checksum= NULL; if(!read_packet && !write_flag){ @@ -111,6 +141,8 @@ AVIOContext *avio_alloc_context( int64_t (*seek)(void *opaque, int64_t offset, int whence)) { AVIOContext *s = av_mallocz(sizeof(AVIOContext)); + if (!s) + return NULL; ffio_init_context(s, buffer, buffer_size, write_flag, opaque, read_packet, write_packet, seek); return s; @@ -202,7 +234,7 @@ int64_t avio_seek(AVIOContext *s, int64_t offset, int whence) offset1 >= 0 && offset1 <= (s->buf_end - s->buffer)) { /* can do the seek inside the buffer */ s->buf_ptr = s->buffer + offset1; - } else if ((s->is_streamed || + } else if ((!s->seekable || offset1 <= s->buf_end + SHORT_SEEK_THRESHOLD - s->buffer) && !s->write_flag && offset1 >= 0 && (whence != SEEK_END || force)) { @@ -397,6 +429,41 @@ void put_flush_packet(AVIOContext *s) { avio_flush(s); } +int av_url_read_fpause(AVIOContext *s, int pause) +{ + return avio_pause(s, pause); +} +int64_t av_url_read_fseek(AVIOContext *s, int stream_index, + int64_t timestamp, int flags) +{ + return avio_seek_time(s, stream_index, timestamp, flags); +} +void init_checksum(AVIOContext *s, + unsigned long (*update_checksum)(unsigned long c, const uint8_t *p, unsigned int len), + unsigned long checksum) +{ + ffio_init_checksum(s, update_checksum, checksum); +} +unsigned long get_checksum(AVIOContext *s) +{ + return ffio_get_checksum(s); +} +int url_open_dyn_buf(AVIOContext **s) +{ + return avio_open_dyn_buf(s); +} +int url_open_dyn_packet_buf(AVIOContext **s, int max_packet_size) +{ + return ffio_open_dyn_packet_buf(s, max_packet_size); +} +int url_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer) +{ + return avio_close_dyn_buf(s, pbuffer); +} +int url_fdopen(AVIOContext **s, URLContext *h) +{ + return ffio_fdopen(s, h); +} #endif int avio_put_str(AVIOContext *s, const char *str) @@ -539,14 +606,14 @@ unsigned long ff_crc04C11DB7_update(unsigned long checksum, const uint8_t *buf, return av_crc(av_crc_get_table(AV_CRC_32_IEEE), checksum, buf, len); } -unsigned long get_checksum(AVIOContext *s) +unsigned long ffio_get_checksum(AVIOContext *s) { s->checksum= s->update_checksum(s->checksum, s->checksum_ptr, s->buf_ptr - s->checksum_ptr); s->update_checksum= NULL; return s->checksum; } -void init_checksum(AVIOContext *s, +void ffio_init_checksum(AVIOContext *s, unsigned long (*update_checksum)(unsigned long c, const uint8_t *p, unsigned int len), unsigned long checksum) { @@ -730,13 +797,14 @@ int avio_get_str(AVIOContext *s, int maxlen, char *buf, int buflen) { int i; + if (buflen <= 0) + return AVERROR(EINVAL); // reserve 1 byte for terminating 0 buflen = FFMIN(buflen - 1, maxlen); for (i = 0; i < buflen; i++) if (!(buf[i] = avio_r8(s))) return i + 1; - if (buflen) - buf[i] = 0; + buf[i] = 0; for (; i < maxlen; i++) if (!avio_r8(s)) return i + 1; @@ -748,6 +816,8 @@ int avio_get_str(AVIOContext *s, int maxlen, char *buf, int buflen) {\ char* q = buf;\ int ret = 0;\ + if (buflen <= 0) \ + return AVERROR(EINVAL); \ while (ret + 1 < maxlen) {\ uint8_t tmp;\ uint32_t ch;\ @@ -784,12 +854,12 @@ uint64_t ffio_read_varlen(AVIOContext *bc){ return val; } -int url_fdopen(AVIOContext **s, URLContext *h) +int ffio_fdopen(AVIOContext **s, URLContext *h) { uint8_t *buffer; int buffer_size, max_packet_size; - max_packet_size = url_get_max_packet_size(h); + max_packet_size = h->max_packet_size; if (max_packet_size) { buffer_size = max_packet_size; /* no need to bufferize more than one packet */ } else { @@ -799,25 +869,24 @@ int url_fdopen(AVIOContext **s, URLContext *h) if (!buffer) return AVERROR(ENOMEM); - *s = av_mallocz(sizeof(AVIOContext)); - if(!*s) { + *s = avio_alloc_context(buffer, buffer_size, h->flags & AVIO_FLAG_WRITE, h, + ffurl_read, ffurl_write, ffurl_seek); + if (!*s) { av_free(buffer); return AVERROR(ENOMEM); } - - if (ffio_init_context(*s, buffer, buffer_size, - (h->flags & URL_WRONLY || h->flags & URL_RDWR), h, - url_read, url_write, url_seek) < 0) { - av_free(buffer); - av_freep(s); - return AVERROR(EIO); - } +#if FF_API_OLD_AVIO (*s)->is_streamed = h->is_streamed; +#endif + (*s)->seekable = h->is_streamed ? 0 : AVIO_SEEKABLE_NORMAL; (*s)->max_packet_size = max_packet_size; if(h->prot) { (*s)->read_pause = (int (*)(void *, int))h->prot->url_read_pause; (*s)->read_seek = (int64_t (*)(void *, int, int64_t, int))h->prot->url_read_seek; } +#if !FF_API_OLD_AVIO + (*s)->av_class = &ffio_url_class; +#endif return 0; } @@ -832,24 +901,15 @@ int ffio_set_buf_size(AVIOContext *s, int buf_size) s->buffer = buffer; s->buffer_size = buf_size; s->buf_ptr = buffer; - url_resetbuf(s, s->write_flag ? URL_WRONLY : URL_RDONLY); + url_resetbuf(s, s->write_flag ? AVIO_FLAG_WRITE : AVIO_FLAG_READ); return 0; } -#if FF_API_URL_RESETBUF -int url_resetbuf(AVIOContext *s, int flags) -#else static int url_resetbuf(AVIOContext *s, int flags) -#endif { -#if FF_API_URL_RESETBUF - if (flags & URL_RDWR) - return AVERROR(EINVAL); -#else - assert(flags == URL_WRONLY || flags == URL_RDONLY); -#endif + assert(flags == AVIO_FLAG_WRITE || flags == AVIO_FLAG_READ); - if (flags & URL_WRONLY) { + if (flags & AVIO_FLAG_WRITE) { s->buf_end = s->buffer + s->buffer_size; s->write_flag = 1; } else { @@ -899,16 +959,22 @@ int ffio_rewind_with_probe_data(AVIOContext *s, unsigned char *buf, int buf_size } int avio_open(AVIOContext **s, const char *filename, int flags) +{ + return avio_open2(s, filename, flags, NULL, NULL); +} + +int avio_open2(AVIOContext **s, const char *filename, int flags, + const AVIOInterruptCB *int_cb, AVDictionary **options) { URLContext *h; int err; - err = url_open(&h, filename, flags); + err = ffurl_open(&h, filename, flags, int_cb, options); if (err < 0) return err; - err = url_fdopen(s, h); + err = ffio_fdopen(s, h); if (err < 0) { - url_close(h); + ffurl_close(h); return err; } return 0; @@ -920,13 +986,15 @@ int avio_close(AVIOContext *s) av_free(s->buffer); av_free(s); - return url_close(h); + return ffurl_close(h); } +#if FF_API_OLD_AVIO URLContext *url_fileno(AVIOContext *s) { return s->opaque; } +#endif int avio_printf(AVIOContext *s, const char *fmt, ...) { @@ -969,15 +1037,15 @@ int url_fget_max_packet_size(AVIOContext *s) } #endif -int av_url_read_fpause(AVIOContext *s, int pause) +int avio_pause(AVIOContext *s, int pause) { if (!s->read_pause) return AVERROR(ENOSYS); return s->read_pause(s->opaque, pause); } -int64_t av_url_read_fseek(AVIOContext *s, int stream_index, - int64_t timestamp, int flags) +int64_t avio_seek_time(AVIOContext *s, int stream_index, + int64_t timestamp, int flags) { URLContext *h = s->opaque; int64_t ret; @@ -996,9 +1064,6 @@ int64_t av_url_read_fseek(AVIOContext *s, int stream_index, return ret; } -/* url_open_dyn_buf and url_close_dyn_buf are used in rtp.c to send a response - * back to the server even if CONFIG_MUXERS is false. */ -#if CONFIG_MUXERS || CONFIG_NETWORK /* buffer handling */ #if FF_API_OLD_AVIO int url_open_buf(AVIOContext **s, uint8_t *buf, int buf_size, int flags) @@ -1008,7 +1073,7 @@ int url_open_buf(AVIOContext **s, uint8_t *buf, int buf_size, int flags) if(!*s) return AVERROR(ENOMEM); ret = ffio_init_context(*s, buf, buf_size, - (flags & URL_WRONLY || flags & URL_RDWR), + flags & AVIO_FLAG_WRITE, NULL, NULL, NULL, NULL); if(ret != 0) av_freep(s); @@ -1093,7 +1158,6 @@ static int64_t dyn_buf_seek(void *opaque, int64_t offset, int whence) static int url_open_dyn_buf_internal(AVIOContext **s, int max_packet_size) { DynBuffer *d; - int ret; unsigned io_buffer_size = max_packet_size ? max_packet_size : 1024; if(sizeof(DynBuffer) + io_buffer_size < io_buffer_size) @@ -1101,38 +1165,31 @@ static int url_open_dyn_buf_internal(AVIOContext **s, int max_packet_size) d = av_mallocz(sizeof(DynBuffer) + io_buffer_size); if (!d) return AVERROR(ENOMEM); - *s = av_mallocz(sizeof(AVIOContext)); + d->io_buffer_size = io_buffer_size; + *s = avio_alloc_context(d->io_buffer, d->io_buffer_size, 1, d, NULL, + max_packet_size ? dyn_packet_buf_write : dyn_buf_write, + max_packet_size ? NULL : dyn_buf_seek); if(!*s) { av_free(d); return AVERROR(ENOMEM); } - d->io_buffer_size = io_buffer_size; - ret = ffio_init_context(*s, d->io_buffer, io_buffer_size, - 1, d, NULL, - max_packet_size ? dyn_packet_buf_write : dyn_buf_write, - max_packet_size ? NULL : dyn_buf_seek); - if (ret == 0) { - (*s)->max_packet_size = max_packet_size; - } else { - av_free(d); - av_freep(s); - } - return ret; + (*s)->max_packet_size = max_packet_size; + return 0; } -int url_open_dyn_buf(AVIOContext **s) +int avio_open_dyn_buf(AVIOContext **s) { return url_open_dyn_buf_internal(s, 0); } -int url_open_dyn_packet_buf(AVIOContext **s, int max_packet_size) +int ffio_open_dyn_packet_buf(AVIOContext **s, int max_packet_size) { if (max_packet_size <= 0) return -1; return url_open_dyn_buf_internal(s, max_packet_size); } -int url_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer) +int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer) { DynBuffer *d = s->opaque; int size; @@ -1153,4 +1210,3 @@ int url_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer) av_free(s); return size - padding; } -#endif /* CONFIG_MUXERS || CONFIG_NETWORK */