X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Favio.c;h=b6329a927d96c90cf0fdd9ba00f219b601f099ea;hb=da4c2dab17af7f7b09ed18d74ec984d214451a51;hp=0dd7e63f2a341c7a38dd563b31b29c17947ddf1f;hpb=eabbae730cf732afeb7c2a085e0e5c1e7b1b8614;p=ffmpeg diff --git a/libavformat/avio.c b/libavformat/avio.c index 0dd7e63f2a3..b6329a927d9 100644 --- a/libavformat/avio.c +++ b/libavformat/avio.c @@ -18,14 +18,39 @@ * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ + +#include "libavutil/avstring.h" +#include "libavcodec/opt.h" +#include "os_support.h" #include "avformat.h" +#if LIBAVFORMAT_VERSION_MAJOR >= 53 +/** @name Logging context. */ +/*@{*/ +static const char *urlcontext_to_name(void *ptr) +{ + URLContext *h = (URLContext *)ptr; + if(h->prot) return h->prot->name; + else return "NULL"; +} +static const AVOption options[] = {{NULL}}; +static const AVClass urlcontext_class = + { "URLContext", urlcontext_to_name, options }; +/*@}*/ +#endif + static int default_interrupt_cb(void); URLProtocol *first_protocol = NULL; URLInterruptCB *url_interrupt_cb = default_interrupt_cb; -int register_protocol(URLProtocol *protocol) +URLProtocol *av_protocol_next(URLProtocol *p) +{ + if(p) return p->next; + else return first_protocol; +} + +int av_register_protocol(URLProtocol *protocol) { URLProtocol **p; p = &first_protocol; @@ -35,13 +60,57 @@ int register_protocol(URLProtocol *protocol) return 0; } -int url_open(URLContext **puc, const char *filename, int flags) +#if LIBAVFORMAT_VERSION_MAJOR < 53 +int register_protocol(URLProtocol *protocol) +{ + return av_register_protocol(protocol); +} +#endif + +int url_open_protocol (URLContext **puc, struct URLProtocol *up, + const char *filename, int flags) { URLContext *uc; + int err; + + uc = av_malloc(sizeof(URLContext) + strlen(filename) + 1); + if (!uc) { + err = AVERROR(ENOMEM); + goto fail; + } +#if LIBAVFORMAT_VERSION_MAJOR >= 53 + uc->av_class = &urlcontext_class; +#endif + uc->filename = (char *) &uc[1]; + strcpy(uc->filename, filename); + uc->prot = up; + uc->flags = flags; + uc->is_streamed = 0; /* default = not streamed */ + uc->max_packet_size = 0; /* default: stream file */ + err = up->url_open(uc, filename, flags); + if (err < 0) { + av_free(uc); + *puc = NULL; + return err; + } + + //We must be carefull here as url_seek() could be slow, for example for http + if( (flags & (URL_WRONLY | URL_RDWR)) + || !strcmp(up->name, "file")) + if(!uc->is_streamed && url_seek(uc, 0, SEEK_SET) < 0) + uc->is_streamed= 1; + *puc = uc; + return 0; + fail: + *puc = NULL; + return err; +} + +int url_open(URLContext **puc, const char *filename, int flags) +{ URLProtocol *up; const char *p; char proto_str[128], *q; - int err; p = filename; q = proto_str; @@ -54,7 +123,7 @@ int url_open(URLContext **puc, const char *filename, int flags) p++; } /* if the protocol has length 1, we consider it is a dos drive */ - if (*p == '\0' || (q - proto_str) <= 1) { + if (*p == '\0' || is_dos_path(filename)) { file_proto: strcpy(proto_str, "file"); } else { @@ -64,76 +133,65 @@ int url_open(URLContext **puc, const char *filename, int flags) up = first_protocol; while (up != NULL) { if (!strcmp(proto_str, up->name)) - goto found; + return url_open_protocol (puc, up, filename, flags); up = up->next; } - err = -ENOENT; - goto fail; - found: - uc = av_malloc(sizeof(URLContext) + strlen(filename) + 1); - if (!uc) { - err = -ENOMEM; - goto fail; - } -#if LIBAVFORMAT_VERSION_INT >= (52<<16) - uc->filename = (char *) &uc[1]; -#endif - strcpy(uc->filename, filename); - uc->prot = up; - uc->flags = flags; - uc->is_streamed = 0; /* default = not streamed */ - uc->max_packet_size = 0; /* default: stream file */ - err = up->url_open(uc, filename, flags); - if (err < 0) { - av_free(uc); - *puc = NULL; - return err; - } - *puc = uc; - return 0; - fail: *puc = NULL; - return err; + return AVERROR(ENOENT); } int url_read(URLContext *h, unsigned char *buf, int size) { int ret; if (h->flags & URL_WRONLY) - return AVERROR_IO; + return AVERROR(EIO); ret = h->prot->url_read(h, buf, size); return ret; } -#if defined(CONFIG_MUXERS) || defined(CONFIG_PROTOCOLS) +int url_read_complete(URLContext *h, unsigned char *buf, int size) +{ + int ret, len; + + len = 0; + while (len < size) { + ret = url_read(h, buf+len, size-len); + if (ret < 1) + return ret; + len += ret; + } + return len; +} + int url_write(URLContext *h, unsigned char *buf, int size) { int ret; if (!(h->flags & (URL_WRONLY | URL_RDWR))) - return AVERROR_IO; + return AVERROR(EIO); /* avoid sending too big packets */ if (h->max_packet_size && size > h->max_packet_size) - return AVERROR_IO; + return AVERROR(EIO); ret = h->prot->url_write(h, buf, size); return ret; } -#endif //CONFIG_MUXERS || CONFIG_PROTOCOLS -offset_t url_seek(URLContext *h, offset_t pos, int whence) +int64_t url_seek(URLContext *h, int64_t pos, int whence) { - offset_t ret; + int64_t ret; if (!h->prot->url_seek) - return -EPIPE; + return AVERROR(EPIPE); ret = h->prot->url_seek(h, pos, whence); return ret; } int url_close(URLContext *h) { - int ret; + int ret = 0; + if (!h) return 0; /* can happen when url_open fails */ - ret = h->prot->url_close(h); + if (h->prot->url_close) + ret = h->prot->url_close(h); av_free(h); return ret; } @@ -147,9 +205,9 @@ int url_exist(const char *filename) return 1; } -offset_t url_filesize(URLContext *h) +int64_t url_filesize(URLContext *h) { - offset_t pos, size; + int64_t pos, size; size= url_seek(h, 0, AVSEEK_SIZE); if(size<0){ @@ -162,14 +220,13 @@ offset_t url_filesize(URLContext *h) return size; } -/* - * Return the maximum packet size associated to packetized file - * handle. If the file is not packetized (stream like http or file on - * disk), then 0 is returned. - * - * @param h file handle - * @return maximum packet size in bytes - */ +int url_get_file_handle(URLContext *h) +{ + if (!h->prot->url_get_file_handle) + return -1; + return h->prot->url_get_file_handle(h); +} + int url_get_max_packet_size(URLContext *h) { return h->max_packet_size; @@ -177,7 +234,7 @@ int url_get_max_packet_size(URLContext *h) void url_get_filename(URLContext *h, char *buf, int buf_size) { - pstrcpy(buf, buf_size, h->filename); + av_strlcpy(buf, h->filename, buf_size); } @@ -186,15 +243,24 @@ static int default_interrupt_cb(void) return 0; } -/** - * The callback is called in blocking functions to test regulary if - * asynchronous interruption is needed. -EINTR is returned in this - * case by the interrupted function. 'NULL' means no interrupt - * callback is given. - */ void url_set_interrupt_cb(URLInterruptCB *interrupt_cb) { if (!interrupt_cb) interrupt_cb = default_interrupt_cb; url_interrupt_cb = interrupt_cb; } + +int av_url_read_pause(URLContext *h, int pause) +{ + if (!h->prot->url_read_pause) + return AVERROR(ENOSYS); + return h->prot->url_read_pause(h, pause); +} + +int64_t av_url_read_seek(URLContext *h, + int stream_index, int64_t timestamp, int flags) +{ + if (!h->prot->url_read_seek) + return AVERROR(ENOSYS); + return h->prot->url_read_seek(h, stream_index, timestamp, flags); +}