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 #include "libavutil/avstring.h"
23 #include "libavcodec/opt.h"
26 #if LIBAVFORMAT_VERSION_MAJOR >= 53
27 /** @name Logging context. */
29 static const char *urlcontext_to_name(void *ptr
)
31 URLContext
*h
= (URLContext
*)ptr
;
32 if(h
->prot
) return h
->prot
->name
;
35 static const AVOption options
[] = {{NULL
}};
36 static const AVClass urlcontext_class
=
37 { "URLContext", urlcontext_to_name
, options
};
41 static int default_interrupt_cb(void);
43 URLProtocol
*first_protocol
= NULL
;
44 URLInterruptCB
*url_interrupt_cb
= default_interrupt_cb
;
46 URLProtocol
*av_protocol_next(URLProtocol
*p
)
49 else return first_protocol
;
52 int register_protocol(URLProtocol
*protocol
)
56 while (*p
!= NULL
) p
= &(*p
)->next
;
58 protocol
->next
= NULL
;
62 int url_open_protocol (URLContext
**puc
, struct URLProtocol
*up
,
63 const char *filename
, int flags
)
68 uc
= av_malloc(sizeof(URLContext
) + strlen(filename
) + 1);
70 err
= AVERROR(ENOMEM
);
73 #if LIBAVFORMAT_VERSION_MAJOR >= 53
74 uc
->av_class
= &urlcontext_class
;
76 uc
->filename
= (char *) &uc
[1];
77 strcpy(uc
->filename
, filename
);
80 uc
->is_streamed
= 0; /* default = not streamed */
81 uc
->max_packet_size
= 0; /* default: stream file */
82 err
= up
->url_open(uc
, filename
, flags
);
89 //We must be carefull here as url_seek() could be slow, for example for http
90 if( (flags
& (URL_WRONLY
| URL_RDWR
))
91 || !strcmp(up
->name
, "file"))
92 if(!uc
->is_streamed
&& url_seek(uc
, 0, SEEK_SET
) < 0)
101 int url_open(URLContext
**puc
, const char *filename
, int flags
)
105 char proto_str
[128], *q
;
109 while (*p
!= '\0' && *p
!= ':') {
110 /* protocols can only contain alphabetic chars */
113 if ((q
- proto_str
) < sizeof(proto_str
) - 1)
117 /* if the protocol has length 1, we consider it is a dos drive */
118 if (*p
== '\0' || (q
- proto_str
) <= 1) {
120 strcpy(proto_str
, "file");
127 if (!strcmp(proto_str
, up
->name
))
128 return url_open_protocol (puc
, up
, filename
, flags
);
132 return AVERROR(ENOENT
);
135 int url_read(URLContext
*h
, unsigned char *buf
, int size
)
138 if (h
->flags
& URL_WRONLY
)
140 ret
= h
->prot
->url_read(h
, buf
, size
);
144 int url_write(URLContext
*h
, unsigned char *buf
, int size
)
147 if (!(h
->flags
& (URL_WRONLY
| URL_RDWR
)))
149 /* avoid sending too big packets */
150 if (h
->max_packet_size
&& size
> h
->max_packet_size
)
152 ret
= h
->prot
->url_write(h
, buf
, size
);
156 offset_t
url_seek(URLContext
*h
, offset_t pos
, int whence
)
160 if (!h
->prot
->url_seek
)
161 return AVERROR(EPIPE
);
162 ret
= h
->prot
->url_seek(h
, pos
, whence
);
166 int url_close(URLContext
*h
)
169 if (!h
) return 0; /* can happen when url_open fails */
171 if (h
->prot
->url_close
)
172 ret
= h
->prot
->url_close(h
);
177 int url_exist(const char *filename
)
180 if (url_open(&h
, filename
, URL_RDONLY
) < 0)
186 offset_t
url_filesize(URLContext
*h
)
190 size
= url_seek(h
, 0, AVSEEK_SIZE
);
192 pos
= url_seek(h
, 0, SEEK_CUR
);
193 if ((size
= url_seek(h
, -1, SEEK_END
)) < 0)
196 url_seek(h
, pos
, SEEK_SET
);
201 int url_get_max_packet_size(URLContext
*h
)
203 return h
->max_packet_size
;
206 void url_get_filename(URLContext
*h
, char *buf
, int buf_size
)
208 av_strlcpy(buf
, h
->filename
, buf_size
);
212 static int default_interrupt_cb(void)
217 void url_set_interrupt_cb(URLInterruptCB
*interrupt_cb
)
220 interrupt_cb
= default_interrupt_cb
;
221 url_interrupt_cb
= interrupt_cb
;
224 int av_url_read_pause(URLContext
*h
, int pause
)
226 if (!h
->prot
->url_read_pause
)
227 return AVERROR(ENOSYS
);
228 return h
->prot
->url_read_pause(h
, pause
);
231 offset_t
av_url_read_seek(URLContext
*h
,
232 int stream_index
, int64_t timestamp
, int flags
)
234 if (!h
->prot
->url_read_seek
)
235 return AVERROR(ENOSYS
);
236 return h
->prot
->url_read_seek(h
, stream_index
, timestamp
, flags
);