00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "libavutil/avstring.h"
00023 #include "libavcodec/opt.h"
00024 #include "os_support.h"
00025 #include "avformat.h"
00026
00027 #if LIBAVFORMAT_VERSION_MAJOR >= 53
00028
00030 static const char *urlcontext_to_name(void *ptr)
00031 {
00032 URLContext *h = (URLContext *)ptr;
00033 if(h->prot) return h->prot->name;
00034 else return "NULL";
00035 }
00036 static const AVOption options[] = {{NULL}};
00037 static const AVClass urlcontext_class =
00038 { "URLContext", urlcontext_to_name, options };
00040 #endif
00041
00042 static int default_interrupt_cb(void);
00043
00044 URLProtocol *first_protocol = NULL;
00045 URLInterruptCB *url_interrupt_cb = default_interrupt_cb;
00046
00047 URLProtocol *av_protocol_next(URLProtocol *p)
00048 {
00049 if(p) return p->next;
00050 else return first_protocol;
00051 }
00052
00053 int av_register_protocol(URLProtocol *protocol)
00054 {
00055 URLProtocol **p;
00056 p = &first_protocol;
00057 while (*p != NULL) p = &(*p)->next;
00058 *p = protocol;
00059 protocol->next = NULL;
00060 return 0;
00061 }
00062
00063 #if LIBAVFORMAT_VERSION_MAJOR < 53
00064 int register_protocol(URLProtocol *protocol)
00065 {
00066 return av_register_protocol(protocol);
00067 }
00068 #endif
00069
00070 int url_open_protocol (URLContext **puc, struct URLProtocol *up,
00071 const char *filename, int flags)
00072 {
00073 URLContext *uc;
00074 int err;
00075
00076 uc = av_malloc(sizeof(URLContext) + strlen(filename) + 1);
00077 if (!uc) {
00078 err = AVERROR(ENOMEM);
00079 goto fail;
00080 }
00081 #if LIBAVFORMAT_VERSION_MAJOR >= 53
00082 uc->av_class = &urlcontext_class;
00083 #endif
00084 uc->filename = (char *) &uc[1];
00085 strcpy(uc->filename, filename);
00086 uc->prot = up;
00087 uc->flags = flags;
00088 uc->is_streamed = 0;
00089 uc->max_packet_size = 0;
00090 err = up->url_open(uc, filename, flags);
00091 if (err < 0) {
00092 av_free(uc);
00093 *puc = NULL;
00094 return err;
00095 }
00096
00097
00098 if( (flags & (URL_WRONLY | URL_RDWR))
00099 || !strcmp(up->name, "file"))
00100 if(!uc->is_streamed && url_seek(uc, 0, SEEK_SET) < 0)
00101 uc->is_streamed= 1;
00102 *puc = uc;
00103 return 0;
00104 fail:
00105 *puc = NULL;
00106 return err;
00107 }
00108
00109 int url_open(URLContext **puc, const char *filename, int flags)
00110 {
00111 URLProtocol *up;
00112 const char *p;
00113 char proto_str[128], *q;
00114
00115 p = filename;
00116 q = proto_str;
00117 while (*p != '\0' && *p != ':') {
00118
00119 if (!isalpha(*p))
00120 goto file_proto;
00121 if ((q - proto_str) < sizeof(proto_str) - 1)
00122 *q++ = *p;
00123 p++;
00124 }
00125
00126 if (*p == '\0' || is_dos_path(filename)) {
00127 file_proto:
00128 strcpy(proto_str, "file");
00129 } else {
00130 *q = '\0';
00131 }
00132
00133 up = first_protocol;
00134 while (up != NULL) {
00135 if (!strcmp(proto_str, up->name))
00136 return url_open_protocol (puc, up, filename, flags);
00137 up = up->next;
00138 }
00139 *puc = NULL;
00140 return AVERROR(ENOENT);
00141 }
00142
00143 int url_read(URLContext *h, unsigned char *buf, int size)
00144 {
00145 int ret;
00146 if (h->flags & URL_WRONLY)
00147 return AVERROR(EIO);
00148 ret = h->prot->url_read(h, buf, size);
00149 return ret;
00150 }
00151
00152 int url_write(URLContext *h, unsigned char *buf, int size)
00153 {
00154 int ret;
00155 if (!(h->flags & (URL_WRONLY | URL_RDWR)))
00156 return AVERROR(EIO);
00157
00158 if (h->max_packet_size && size > h->max_packet_size)
00159 return AVERROR(EIO);
00160 ret = h->prot->url_write(h, buf, size);
00161 return ret;
00162 }
00163
00164 int64_t url_seek(URLContext *h, int64_t pos, int whence)
00165 {
00166 int64_t ret;
00167
00168 if (!h->prot->url_seek)
00169 return AVERROR(EPIPE);
00170 ret = h->prot->url_seek(h, pos, whence);
00171 return ret;
00172 }
00173
00174 int url_close(URLContext *h)
00175 {
00176 int ret = 0;
00177 if (!h) return 0;
00178
00179 if (h->prot->url_close)
00180 ret = h->prot->url_close(h);
00181 av_free(h);
00182 return ret;
00183 }
00184
00185 int url_exist(const char *filename)
00186 {
00187 URLContext *h;
00188 if (url_open(&h, filename, URL_RDONLY) < 0)
00189 return 0;
00190 url_close(h);
00191 return 1;
00192 }
00193
00194 int64_t url_filesize(URLContext *h)
00195 {
00196 int64_t pos, size;
00197
00198 size= url_seek(h, 0, AVSEEK_SIZE);
00199 if(size<0){
00200 pos = url_seek(h, 0, SEEK_CUR);
00201 if ((size = url_seek(h, -1, SEEK_END)) < 0)
00202 return size;
00203 size++;
00204 url_seek(h, pos, SEEK_SET);
00205 }
00206 return size;
00207 }
00208
00209 int url_get_max_packet_size(URLContext *h)
00210 {
00211 return h->max_packet_size;
00212 }
00213
00214 void url_get_filename(URLContext *h, char *buf, int buf_size)
00215 {
00216 av_strlcpy(buf, h->filename, buf_size);
00217 }
00218
00219
00220 static int default_interrupt_cb(void)
00221 {
00222 return 0;
00223 }
00224
00225 void url_set_interrupt_cb(URLInterruptCB *interrupt_cb)
00226 {
00227 if (!interrupt_cb)
00228 interrupt_cb = default_interrupt_cb;
00229 url_interrupt_cb = interrupt_cb;
00230 }
00231
00232 int av_url_read_pause(URLContext *h, int pause)
00233 {
00234 if (!h->prot->url_read_pause)
00235 return AVERROR(ENOSYS);
00236 return h->prot->url_read_pause(h, pause);
00237 }
00238
00239 int64_t av_url_read_seek(URLContext *h,
00240 int stream_index, int64_t timestamp, int flags)
00241 {
00242 if (!h->prot->url_read_seek)
00243 return AVERROR(ENOSYS);
00244 return h->prot->url_read_seek(h, stream_index, timestamp, flags);
00245 }