2 * Unbuffered io for ffmpeg system
3 * Copyright (c) 2001 Fabrice Bellard
5 * This file is part of FFmpeg.
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 /* needed for usleep() */
23 #define _XOPEN_SOURCE 600
25 #include "libavutil/avstring.h"
26 #include "libavcodec/opt.h"
27 #include "os_support.h"
33 #if LIBAVFORMAT_VERSION_MAJOR >= 53
34 /** @name Logging context. */
36 static const char *urlcontext_to_name(void *ptr
)
38 URLContext
*h
= (URLContext
*)ptr
;
39 if(h
->prot
) return h
->prot
->name
;
42 static const AVOption options
[] = {{NULL
}};
43 static const AVClass urlcontext_class
=
44 { "URLContext", urlcontext_to_name
, options
, LIBAVUTIL_VERSION_INT
};
48 static int default_interrupt_cb(void);
50 URLProtocol
*first_protocol
= NULL
;
51 URLInterruptCB
*url_interrupt_cb
= default_interrupt_cb
;
53 URLProtocol
*av_protocol_next(URLProtocol
*p
)
56 else return first_protocol
;
59 int av_register_protocol2(URLProtocol
*protocol
, int size
)
62 if (size
< sizeof(URLProtocol
)) {
63 URLProtocol
* temp
= av_mallocz(sizeof(URLProtocol
));
64 memcpy(temp
, protocol
, size
);
68 while (*p
!= NULL
) p
= &(*p
)->next
;
70 protocol
->next
= NULL
;
74 #if LIBAVFORMAT_VERSION_MAJOR < 53
75 /* The layout of URLProtocol as of when major was bumped to 52 */
76 struct URLProtocol_compat
{
78 int (*url_open
)(URLContext
*h
, const char *filename
, int flags
);
79 int (*url_read
)(URLContext
*h
, unsigned char *buf
, int size
);
80 int (*url_write
)(URLContext
*h
, unsigned char *buf
, int size
);
81 int64_t (*url_seek
)(URLContext
*h
, int64_t pos
, int whence
);
82 int (*url_close
)(URLContext
*h
);
83 struct URLProtocol
*next
;
86 int av_register_protocol(URLProtocol
*protocol
)
88 return av_register_protocol2(protocol
, sizeof(struct URLProtocol_compat
));
91 int register_protocol(URLProtocol
*protocol
)
93 return av_register_protocol(protocol
);
97 static int url_alloc_for_protocol (URLContext
**puc
, struct URLProtocol
*up
,
98 const char *filename
, int flags
)
104 if (!ff_network_init())
107 uc
= av_mallocz(sizeof(URLContext
) + strlen(filename
) + 1);
109 err
= AVERROR(ENOMEM
);
112 #if LIBAVFORMAT_VERSION_MAJOR >= 53
113 uc
->av_class
= &urlcontext_class
;
115 uc
->filename
= (char *) &uc
[1];
116 strcpy(uc
->filename
, filename
);
119 uc
->is_streamed
= 0; /* default = not streamed */
120 uc
->max_packet_size
= 0; /* default: stream file */
121 if (up
->priv_data_size
) {
122 uc
->priv_data
= av_mallocz(up
->priv_data_size
);
123 if (up
->priv_data_class
) {
124 *(const AVClass
**)uc
->priv_data
= up
->priv_data_class
;
125 av_opt_set_defaults(uc
->priv_data
);
139 int url_connect(URLContext
* uc
)
141 int err
= uc
->prot
->url_open(uc
, uc
->filename
, uc
->flags
);
144 uc
->is_connected
= 1;
145 //We must be careful here as url_seek() could be slow, for example for http
146 if( (uc
->flags
& (URL_WRONLY
| URL_RDWR
))
147 || !strcmp(uc
->prot
->name
, "file"))
148 if(!uc
->is_streamed
&& url_seek(uc
, 0, SEEK_SET
) < 0)
153 int url_open_protocol (URLContext
**puc
, struct URLProtocol
*up
,
154 const char *filename
, int flags
)
158 ret
= url_alloc_for_protocol(puc
, up
, filename
, flags
);
161 ret
= url_connect(*puc
);
170 int url_alloc(URLContext
**puc
, const char *filename
, int flags
)
174 char proto_str
[128], *q
;
178 while (*p
!= '\0' && *p
!= ':') {
179 /* protocols can only contain alphabetic chars */
182 if ((q
- proto_str
) < sizeof(proto_str
) - 1)
186 /* if the protocol has length 1, we consider it is a dos drive */
187 if (*p
== '\0' || is_dos_path(filename
)) {
189 strcpy(proto_str
, "file");
196 if (!strcmp(proto_str
, up
->name
))
197 return url_alloc_for_protocol (puc
, up
, filename
, flags
);
201 return AVERROR(ENOENT
);
204 int url_open(URLContext
**puc
, const char *filename
, int flags
)
206 int ret
= url_alloc(puc
, filename
, flags
);
209 ret
= url_connect(*puc
);
218 int url_read(URLContext
*h
, unsigned char *buf
, int size
)
221 if (h
->flags
& URL_WRONLY
)
223 ret
= h
->prot
->url_read(h
, buf
, size
);
227 int url_read_complete(URLContext
*h
, unsigned char *buf
, int size
)
230 int fast_retries
= 5;
234 ret
= url_read(h
, buf
+len
, size
-len
);
235 if (ret
== AVERROR(EAGAIN
)) {
242 return ret
< 0 ? ret
: len
;
244 fast_retries
= FFMAX(fast_retries
, 2);
250 int url_write(URLContext
*h
, const unsigned char *buf
, int size
)
253 if (!(h
->flags
& (URL_WRONLY
| URL_RDWR
)))
255 /* avoid sending too big packets */
256 if (h
->max_packet_size
&& size
> h
->max_packet_size
)
258 ret
= h
->prot
->url_write(h
, buf
, size
);
262 int64_t url_seek(URLContext
*h
, int64_t pos
, int whence
)
266 if (!h
->prot
->url_seek
)
267 return AVERROR(ENOSYS
);
268 ret
= h
->prot
->url_seek(h
, pos
, whence
& ~AVSEEK_FORCE
);
272 int url_close(URLContext
*h
)
275 if (!h
) return 0; /* can happen when url_open fails */
277 if (h
->is_connected
&& h
->prot
->url_close
)
278 ret
= h
->prot
->url_close(h
);
282 if (h
->prot
->priv_data_size
)
283 av_free(h
->priv_data
);
288 int url_exist(const char *filename
)
291 if (url_open(&h
, filename
, URL_RDONLY
) < 0)
297 int64_t url_filesize(URLContext
*h
)
301 size
= url_seek(h
, 0, AVSEEK_SIZE
);
303 pos
= url_seek(h
, 0, SEEK_CUR
);
304 if ((size
= url_seek(h
, -1, SEEK_END
)) < 0)
307 url_seek(h
, pos
, SEEK_SET
);
312 int url_get_file_handle(URLContext
*h
)
314 if (!h
->prot
->url_get_file_handle
)
316 return h
->prot
->url_get_file_handle(h
);
319 int url_get_max_packet_size(URLContext
*h
)
321 return h
->max_packet_size
;
324 void url_get_filename(URLContext
*h
, char *buf
, int buf_size
)
326 av_strlcpy(buf
, h
->filename
, buf_size
);
330 static int default_interrupt_cb(void)
335 void url_set_interrupt_cb(URLInterruptCB
*interrupt_cb
)
338 interrupt_cb
= default_interrupt_cb
;
339 url_interrupt_cb
= interrupt_cb
;
342 int av_url_read_pause(URLContext
*h
, int pause
)
344 if (!h
->prot
->url_read_pause
)
345 return AVERROR(ENOSYS
);
346 return h
->prot
->url_read_pause(h
, pause
);
349 int64_t av_url_read_seek(URLContext
*h
,
350 int stream_index
, int64_t timestamp
, int flags
)
352 if (!h
->prot
->url_read_seek
)
353 return AVERROR(ENOSYS
);
354 return h
->prot
->url_read_seek(h
, stream_index
, timestamp
, flags
);