Mercurial > libavformat.hg
annotate avio.c @ 3754:8d267b43eaba libavformat
Move malloc() down until after all initializations, so that the resource is
only allocated if initialization worked. This means that on failure, we
don't have to deallocate it.
author | rbultje |
---|---|
date | Sat, 23 Aug 2008 18:46:30 +0000 |
parents | b140b68a3747 |
children | 549a09cf23fe |
rev | line source |
---|---|
0 | 1 /* |
2 * Unbuffered io for ffmpeg system | |
3 * Copyright (c) 2001 Fabrice Bellard | |
4 * | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
905
diff
changeset
|
5 * This file is part of FFmpeg. |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
905
diff
changeset
|
6 * |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
905
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
0 | 8 * modify it under the terms of the GNU Lesser General Public |
9 * License as published by the Free Software Foundation; either | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
905
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
0 | 11 * |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
905
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
0 | 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. | |
16 * | |
17 * You should have received a copy of the GNU Lesser General Public | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
905
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
896
edbe5c3717f9
Update licensing information: The FSF changed postal address.
diego
parents:
885
diff
changeset
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
0 | 20 */ |
3286 | 21 |
22 #include "libavutil/avstring.h" | |
23 #include "libavcodec/opt.h" | |
0 | 24 #include "avformat.h" |
3136
e38d5357f0d0
Add AVClass to URLContext at next major version bump
superdump
parents:
2914
diff
changeset
|
25 |
e38d5357f0d0
Add AVClass to URLContext at next major version bump
superdump
parents:
2914
diff
changeset
|
26 #if LIBAVFORMAT_VERSION_MAJOR >= 53 |
e38d5357f0d0
Add AVClass to URLContext at next major version bump
superdump
parents:
2914
diff
changeset
|
27 /** @name Logging context. */ |
e38d5357f0d0
Add AVClass to URLContext at next major version bump
superdump
parents:
2914
diff
changeset
|
28 /*@{*/ |
e38d5357f0d0
Add AVClass to URLContext at next major version bump
superdump
parents:
2914
diff
changeset
|
29 static const char *urlcontext_to_name(void *ptr) |
e38d5357f0d0
Add AVClass to URLContext at next major version bump
superdump
parents:
2914
diff
changeset
|
30 { |
e38d5357f0d0
Add AVClass to URLContext at next major version bump
superdump
parents:
2914
diff
changeset
|
31 URLContext *h = (URLContext *)ptr; |
e38d5357f0d0
Add AVClass to URLContext at next major version bump
superdump
parents:
2914
diff
changeset
|
32 if(h->prot) return h->prot->name; |
e38d5357f0d0
Add AVClass to URLContext at next major version bump
superdump
parents:
2914
diff
changeset
|
33 else return "NULL"; |
e38d5357f0d0
Add AVClass to URLContext at next major version bump
superdump
parents:
2914
diff
changeset
|
34 } |
e38d5357f0d0
Add AVClass to URLContext at next major version bump
superdump
parents:
2914
diff
changeset
|
35 static const AVOption options[] = {{NULL}}; |
e38d5357f0d0
Add AVClass to URLContext at next major version bump
superdump
parents:
2914
diff
changeset
|
36 static const AVClass urlcontext_class = |
e38d5357f0d0
Add AVClass to URLContext at next major version bump
superdump
parents:
2914
diff
changeset
|
37 { "URLContext", urlcontext_to_name, options }; |
e38d5357f0d0
Add AVClass to URLContext at next major version bump
superdump
parents:
2914
diff
changeset
|
38 /*@}*/ |
e38d5357f0d0
Add AVClass to URLContext at next major version bump
superdump
parents:
2914
diff
changeset
|
39 #endif |
0 | 40 |
177 | 41 static int default_interrupt_cb(void); |
42 | |
0 | 43 URLProtocol *first_protocol = NULL; |
177 | 44 URLInterruptCB *url_interrupt_cb = default_interrupt_cb; |
0 | 45 |
2812 | 46 URLProtocol *av_protocol_next(URLProtocol *p) |
47 { | |
48 if(p) return p->next; | |
49 else return first_protocol; | |
50 } | |
51 | |
0 | 52 int register_protocol(URLProtocol *protocol) |
53 { | |
54 URLProtocol **p; | |
55 p = &first_protocol; | |
56 while (*p != NULL) p = &(*p)->next; | |
57 *p = protocol; | |
58 protocol->next = NULL; | |
59 return 0; | |
60 } | |
61 | |
3744
b140b68a3747
Implement url_open_protocol(), which is basiclly the former url_open()
rbultje
parents:
3286
diff
changeset
|
62 int url_open_protocol (URLContext **puc, struct URLProtocol *up, |
b140b68a3747
Implement url_open_protocol(), which is basiclly the former url_open()
rbultje
parents:
3286
diff
changeset
|
63 const char *filename, int flags) |
0 | 64 { |
65 URLContext *uc; | |
66 int err; | |
67 | |
1648
90987914ad57
makes the filename member of the URLContext a pointer, so that the
gpoirier
parents:
1613
diff
changeset
|
68 uc = av_malloc(sizeof(URLContext) + strlen(filename) + 1); |
0 | 69 if (!uc) { |
1787
eb16c64144ee
This fixes error handling for BeOS, removing the need for some ifdefs.
mmu_man
parents:
1746
diff
changeset
|
70 err = AVERROR(ENOMEM); |
0 | 71 goto fail; |
72 } | |
3136
e38d5357f0d0
Add AVClass to URLContext at next major version bump
superdump
parents:
2914
diff
changeset
|
73 #if LIBAVFORMAT_VERSION_MAJOR >= 53 |
e38d5357f0d0
Add AVClass to URLContext at next major version bump
superdump
parents:
2914
diff
changeset
|
74 uc->av_class = &urlcontext_class; |
e38d5357f0d0
Add AVClass to URLContext at next major version bump
superdump
parents:
2914
diff
changeset
|
75 #endif |
1648
90987914ad57
makes the filename member of the URLContext a pointer, so that the
gpoirier
parents:
1613
diff
changeset
|
76 uc->filename = (char *) &uc[1]; |
19 | 77 strcpy(uc->filename, filename); |
0 | 78 uc->prot = up; |
79 uc->flags = flags; | |
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); | |
83 if (err < 0) { | |
84 av_free(uc); | |
85 *puc = NULL; | |
86 return err; | |
87 } | |
3277 | 88 |
89 //We must be carefull here as url_seek() could be slow, for example for http | |
90 if( (flags & (URL_WRONLY | URL_RDWR)) | |
3744
b140b68a3747
Implement url_open_protocol(), which is basiclly the former url_open()
rbultje
parents:
3286
diff
changeset
|
91 || !strcmp(up->name, "file")) |
3277 | 92 if(!uc->is_streamed && url_seek(uc, 0, SEEK_SET) < 0) |
93 uc->is_streamed= 1; | |
0 | 94 *puc = uc; |
95 return 0; | |
96 fail: | |
97 *puc = NULL; | |
98 return err; | |
99 } | |
100 | |
3744
b140b68a3747
Implement url_open_protocol(), which is basiclly the former url_open()
rbultje
parents:
3286
diff
changeset
|
101 int url_open(URLContext **puc, const char *filename, int flags) |
b140b68a3747
Implement url_open_protocol(), which is basiclly the former url_open()
rbultje
parents:
3286
diff
changeset
|
102 { |
b140b68a3747
Implement url_open_protocol(), which is basiclly the former url_open()
rbultje
parents:
3286
diff
changeset
|
103 URLProtocol *up; |
b140b68a3747
Implement url_open_protocol(), which is basiclly the former url_open()
rbultje
parents:
3286
diff
changeset
|
104 const char *p; |
b140b68a3747
Implement url_open_protocol(), which is basiclly the former url_open()
rbultje
parents:
3286
diff
changeset
|
105 char proto_str[128], *q; |
b140b68a3747
Implement url_open_protocol(), which is basiclly the former url_open()
rbultje
parents:
3286
diff
changeset
|
106 |
b140b68a3747
Implement url_open_protocol(), which is basiclly the former url_open()
rbultje
parents:
3286
diff
changeset
|
107 p = filename; |
b140b68a3747
Implement url_open_protocol(), which is basiclly the former url_open()
rbultje
parents:
3286
diff
changeset
|
108 q = proto_str; |
b140b68a3747
Implement url_open_protocol(), which is basiclly the former url_open()
rbultje
parents:
3286
diff
changeset
|
109 while (*p != '\0' && *p != ':') { |
b140b68a3747
Implement url_open_protocol(), which is basiclly the former url_open()
rbultje
parents:
3286
diff
changeset
|
110 /* protocols can only contain alphabetic chars */ |
b140b68a3747
Implement url_open_protocol(), which is basiclly the former url_open()
rbultje
parents:
3286
diff
changeset
|
111 if (!isalpha(*p)) |
b140b68a3747
Implement url_open_protocol(), which is basiclly the former url_open()
rbultje
parents:
3286
diff
changeset
|
112 goto file_proto; |
b140b68a3747
Implement url_open_protocol(), which is basiclly the former url_open()
rbultje
parents:
3286
diff
changeset
|
113 if ((q - proto_str) < sizeof(proto_str) - 1) |
b140b68a3747
Implement url_open_protocol(), which is basiclly the former url_open()
rbultje
parents:
3286
diff
changeset
|
114 *q++ = *p; |
b140b68a3747
Implement url_open_protocol(), which is basiclly the former url_open()
rbultje
parents:
3286
diff
changeset
|
115 p++; |
b140b68a3747
Implement url_open_protocol(), which is basiclly the former url_open()
rbultje
parents:
3286
diff
changeset
|
116 } |
b140b68a3747
Implement url_open_protocol(), which is basiclly the former url_open()
rbultje
parents:
3286
diff
changeset
|
117 /* if the protocol has length 1, we consider it is a dos drive */ |
b140b68a3747
Implement url_open_protocol(), which is basiclly the former url_open()
rbultje
parents:
3286
diff
changeset
|
118 if (*p == '\0' || (q - proto_str) <= 1) { |
b140b68a3747
Implement url_open_protocol(), which is basiclly the former url_open()
rbultje
parents:
3286
diff
changeset
|
119 file_proto: |
b140b68a3747
Implement url_open_protocol(), which is basiclly the former url_open()
rbultje
parents:
3286
diff
changeset
|
120 strcpy(proto_str, "file"); |
b140b68a3747
Implement url_open_protocol(), which is basiclly the former url_open()
rbultje
parents:
3286
diff
changeset
|
121 } else { |
b140b68a3747
Implement url_open_protocol(), which is basiclly the former url_open()
rbultje
parents:
3286
diff
changeset
|
122 *q = '\0'; |
b140b68a3747
Implement url_open_protocol(), which is basiclly the former url_open()
rbultje
parents:
3286
diff
changeset
|
123 } |
b140b68a3747
Implement url_open_protocol(), which is basiclly the former url_open()
rbultje
parents:
3286
diff
changeset
|
124 |
b140b68a3747
Implement url_open_protocol(), which is basiclly the former url_open()
rbultje
parents:
3286
diff
changeset
|
125 up = first_protocol; |
b140b68a3747
Implement url_open_protocol(), which is basiclly the former url_open()
rbultje
parents:
3286
diff
changeset
|
126 while (up != NULL) { |
b140b68a3747
Implement url_open_protocol(), which is basiclly the former url_open()
rbultje
parents:
3286
diff
changeset
|
127 if (!strcmp(proto_str, up->name)) |
b140b68a3747
Implement url_open_protocol(), which is basiclly the former url_open()
rbultje
parents:
3286
diff
changeset
|
128 return url_open_protocol (puc, up, filename, flags); |
b140b68a3747
Implement url_open_protocol(), which is basiclly the former url_open()
rbultje
parents:
3286
diff
changeset
|
129 up = up->next; |
b140b68a3747
Implement url_open_protocol(), which is basiclly the former url_open()
rbultje
parents:
3286
diff
changeset
|
130 } |
b140b68a3747
Implement url_open_protocol(), which is basiclly the former url_open()
rbultje
parents:
3286
diff
changeset
|
131 *puc = NULL; |
b140b68a3747
Implement url_open_protocol(), which is basiclly the former url_open()
rbultje
parents:
3286
diff
changeset
|
132 return AVERROR(ENOENT); |
b140b68a3747
Implement url_open_protocol(), which is basiclly the former url_open()
rbultje
parents:
3286
diff
changeset
|
133 } |
b140b68a3747
Implement url_open_protocol(), which is basiclly the former url_open()
rbultje
parents:
3286
diff
changeset
|
134 |
0 | 135 int url_read(URLContext *h, unsigned char *buf, int size) |
136 { | |
137 int ret; | |
138 if (h->flags & URL_WRONLY) | |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2189
diff
changeset
|
139 return AVERROR(EIO); |
0 | 140 ret = h->prot->url_read(h, buf, size); |
141 return ret; | |
142 } | |
143 | |
144 int url_write(URLContext *h, unsigned char *buf, int size) | |
145 { | |
146 int ret; | |
147 if (!(h->flags & (URL_WRONLY | URL_RDWR))) | |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2189
diff
changeset
|
148 return AVERROR(EIO); |
0 | 149 /* avoid sending too big packets */ |
150 if (h->max_packet_size && size > h->max_packet_size) | |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2189
diff
changeset
|
151 return AVERROR(EIO); |
0 | 152 ret = h->prot->url_write(h, buf, size); |
153 return ret; | |
154 } | |
155 | |
156 offset_t url_seek(URLContext *h, offset_t pos, int whence) | |
157 { | |
158 offset_t ret; | |
159 | |
160 if (!h->prot->url_seek) | |
1787
eb16c64144ee
This fixes error handling for BeOS, removing the need for some ifdefs.
mmu_man
parents:
1746
diff
changeset
|
161 return AVERROR(EPIPE); |
0 | 162 ret = h->prot->url_seek(h, pos, whence); |
163 return ret; | |
164 } | |
165 | |
166 int url_close(URLContext *h) | |
167 { | |
2757 | 168 int ret = 0; |
2710 | 169 if (!h) return 0; /* can happen when url_open fails */ |
0 | 170 |
2757 | 171 if (h->prot->url_close) |
172 ret = h->prot->url_close(h); | |
0 | 173 av_free(h); |
174 return ret; | |
175 } | |
176 | |
177 int url_exist(const char *filename) | |
178 { | |
179 URLContext *h; | |
180 if (url_open(&h, filename, URL_RDONLY) < 0) | |
181 return 0; | |
182 url_close(h); | |
183 return 1; | |
184 } | |
185 | |
186 offset_t url_filesize(URLContext *h) | |
187 { | |
188 offset_t pos, size; | |
885 | 189 |
1612
a6eaa0762191
seekless filesize retrieving support in 7 lines of code, also doesnt break compatibility
michael
parents:
1358
diff
changeset
|
190 size= url_seek(h, 0, AVSEEK_SIZE); |
a6eaa0762191
seekless filesize retrieving support in 7 lines of code, also doesnt break compatibility
michael
parents:
1358
diff
changeset
|
191 if(size<0){ |
1613 | 192 pos = url_seek(h, 0, SEEK_CUR); |
1746
2649c0a9c037
protect the size=seek(SEEK_END,-1)+1 results with an if (.. < 0), else the
gpoirier
parents:
1648
diff
changeset
|
193 if ((size = url_seek(h, -1, SEEK_END)) < 0) |
2649c0a9c037
protect the size=seek(SEEK_END,-1)+1 results with an if (.. < 0), else the
gpoirier
parents:
1648
diff
changeset
|
194 return size; |
2649c0a9c037
protect the size=seek(SEEK_END,-1)+1 results with an if (.. < 0), else the
gpoirier
parents:
1648
diff
changeset
|
195 size++; |
1613 | 196 url_seek(h, pos, SEEK_SET); |
1612
a6eaa0762191
seekless filesize retrieving support in 7 lines of code, also doesnt break compatibility
michael
parents:
1358
diff
changeset
|
197 } |
0 | 198 return size; |
199 } | |
200 | |
201 int url_get_max_packet_size(URLContext *h) | |
202 { | |
203 return h->max_packet_size; | |
204 } | |
19 | 205 |
206 void url_get_filename(URLContext *h, char *buf, int buf_size) | |
207 { | |
2189 | 208 av_strlcpy(buf, h->filename, buf_size); |
19 | 209 } |
177 | 210 |
211 | |
212 static int default_interrupt_cb(void) | |
213 { | |
214 return 0; | |
215 } | |
216 | |
217 void url_set_interrupt_cb(URLInterruptCB *interrupt_cb) | |
218 { | |
219 if (!interrupt_cb) | |
220 interrupt_cb = default_interrupt_cb; | |
221 url_interrupt_cb = interrupt_cb; | |
222 } | |
2778
50e2307414ee
Extend URLProtocol with new function pointers and api functions for
andoma
parents:
2757
diff
changeset
|
223 |
2839
b51319dd86e5
Merge recently added and still unused play and pause functions.
michael
parents:
2834
diff
changeset
|
224 int av_url_read_pause(URLContext *h, int pause) |
2778
50e2307414ee
Extend URLProtocol with new function pointers and api functions for
andoma
parents:
2757
diff
changeset
|
225 { |
50e2307414ee
Extend URLProtocol with new function pointers and api functions for
andoma
parents:
2757
diff
changeset
|
226 if (!h->prot->url_read_pause) |
50e2307414ee
Extend URLProtocol with new function pointers and api functions for
andoma
parents:
2757
diff
changeset
|
227 return AVERROR(ENOSYS); |
2839
b51319dd86e5
Merge recently added and still unused play and pause functions.
michael
parents:
2834
diff
changeset
|
228 return h->prot->url_read_pause(h, pause); |
2778
50e2307414ee
Extend URLProtocol with new function pointers and api functions for
andoma
parents:
2757
diff
changeset
|
229 } |
50e2307414ee
Extend URLProtocol with new function pointers and api functions for
andoma
parents:
2757
diff
changeset
|
230 |
2840
f51675f78402
Make recently added and still unused read_seek functions return offset_t.
michael
parents:
2839
diff
changeset
|
231 offset_t av_url_read_seek(URLContext *h, |
2778
50e2307414ee
Extend URLProtocol with new function pointers and api functions for
andoma
parents:
2757
diff
changeset
|
232 int stream_index, int64_t timestamp, int flags) |
50e2307414ee
Extend URLProtocol with new function pointers and api functions for
andoma
parents:
2757
diff
changeset
|
233 { |
50e2307414ee
Extend URLProtocol with new function pointers and api functions for
andoma
parents:
2757
diff
changeset
|
234 if (!h->prot->url_read_seek) |
50e2307414ee
Extend URLProtocol with new function pointers and api functions for
andoma
parents:
2757
diff
changeset
|
235 return AVERROR(ENOSYS); |
50e2307414ee
Extend URLProtocol with new function pointers and api functions for
andoma
parents:
2757
diff
changeset
|
236 return h->prot->url_read_seek(h, stream_index, timestamp, flags); |
50e2307414ee
Extend URLProtocol with new function pointers and api functions for
andoma
parents:
2757
diff
changeset
|
237 } |