ffmpeg / libavformat / aviobuf.c @ 6cc7f139
History | View | Annotate | Download (28.2 KB)
1 | de6d9b64 | Fabrice Bellard | /*
|
---|---|---|---|
2 | * Buffered I/O for ffmpeg system
|
||
3 | 19720f15 | Fabrice Bellard | * Copyright (c) 2000,2001 Fabrice Bellard
|
4 | de6d9b64 | Fabrice Bellard | *
|
5 | 2912e87a | Mans Rullgard | * This file is part of Libav.
|
6 | b78e7197 | Diego Biurrun | *
|
7 | 2912e87a | Mans Rullgard | * Libav is free software; you can redistribute it and/or
|
8 | 19720f15 | Fabrice Bellard | * modify it under the terms of the GNU Lesser General Public
|
9 | * License as published by the Free Software Foundation; either
|
||
10 | b78e7197 | Diego Biurrun | * version 2.1 of the License, or (at your option) any later version.
|
11 | de6d9b64 | Fabrice Bellard | *
|
12 | 2912e87a | Mans Rullgard | * Libav is distributed in the hope that it will be useful,
|
13 | de6d9b64 | Fabrice Bellard | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14 | 19720f15 | Fabrice Bellard | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
15 | * Lesser General Public License for more details.
|
||
16 | de6d9b64 | Fabrice Bellard | *
|
17 | 19720f15 | Fabrice Bellard | * You should have received a copy of the GNU Lesser General Public
|
18 | 2912e87a | Mans Rullgard | * License along with Libav; if not, write to the Free Software
|
19 | 5509bffa | Diego Biurrun | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
20 | de6d9b64 | Fabrice Bellard | */
|
21 | 245976da | Diego Biurrun | |
22 | #include "libavutil/crc.h" |
||
23 | aa805f94 | Reimar Döffinger | #include "libavutil/intreadwrite.h" |
24 | de6d9b64 | Fabrice Bellard | #include "avformat.h" |
25 | 5c91a675 | Zdenek Kabelac | #include "avio.h" |
26 | e731b8d8 | Anton Khirnov | #include "avio_internal.h" |
27 | 603e5c0b | Michael Chinen | #include "internal.h" |
28 | abba3dd1 | Fabrice Bellard | #include <stdarg.h> |
29 | de6d9b64 | Fabrice Bellard | |
30 | #define IO_BUFFER_SIZE 32768 |
||
31 | |||
32 | 7939d0ed | Martin Storsjö | /**
|
33 | * Do seeks within this distance ahead of the current buffer by skipping
|
||
34 | * data instead of calling the protocol seek function, for seekable
|
||
35 | * protocols.
|
||
36 | */
|
||
37 | #define SHORT_SEEK_THRESHOLD 4096 |
||
38 | |||
39 | ae628ec1 | Anton Khirnov | static void fill_buffer(AVIOContext *s); |
40 | 364cacc7 | Aurelien Jacobs | #if !FF_API_URL_RESETBUF
|
41 | ae628ec1 | Anton Khirnov | static int url_resetbuf(AVIOContext *s, int flags); |
42 | 08580cb0 | Benoit Fouet | #endif
|
43 | 398f5d3f | Michael Niedermayer | |
44 | e731b8d8 | Anton Khirnov | int ffio_init_context(AVIOContext *s,
|
45 | de6d9b64 | Fabrice Bellard | unsigned char *buffer, |
46 | int buffer_size,
|
||
47 | int write_flag,
|
||
48 | void *opaque,
|
||
49 | 0c1a9eda | Zdenek Kabelac | int (*read_packet)(void *opaque, uint8_t *buf, int buf_size), |
50 | 576ae256 | Michael Niedermayer | int (*write_packet)(void *opaque, uint8_t *buf, int buf_size), |
51 | bc5c918e | Diego Biurrun | int64_t (*seek)(void *opaque, int64_t offset, int whence)) |
52 | de6d9b64 | Fabrice Bellard | { |
53 | s->buffer = buffer; |
||
54 | s->buffer_size = buffer_size; |
||
55 | s->buf_ptr = buffer; |
||
56 | s->opaque = opaque; |
||
57 | 9daa4cea | Aurelien Jacobs | url_resetbuf(s, write_flag ? URL_WRONLY : URL_RDONLY); |
58 | de6d9b64 | Fabrice Bellard | s->write_packet = write_packet; |
59 | s->read_packet = read_packet; |
||
60 | s->seek = seek; |
||
61 | s->pos = 0;
|
||
62 | s->must_flush = 0;
|
||
63 | s->eof_reached = 0;
|
||
64 | 576ae256 | Michael Niedermayer | s->error = 0;
|
65 | 8978feda | Anton Khirnov | #if FF_API_OLD_AVIO
|
66 | de6d9b64 | Fabrice Bellard | s->is_streamed = 0;
|
67 | 8978feda | Anton Khirnov | #endif
|
68 | s->seekable = AVIO_SEEKABLE_NORMAL; |
||
69 | abba3dd1 | Fabrice Bellard | s->max_packet_size = 0;
|
70 | ee9f36a8 | Michael Niedermayer | s->update_checksum= NULL;
|
71 | 942f3bb5 | Michael Niedermayer | if(!read_packet && !write_flag){
|
72 | s->pos = buffer_size; |
||
73 | s->buf_end = s->buffer + buffer_size; |
||
74 | } |
||
75 | e7e4810a | Björn Axelsson | s->read_pause = NULL;
|
76 | s->read_seek = NULL;
|
||
77 | de6d9b64 | Fabrice Bellard | return 0; |
78 | } |
||
79 | 115329f1 | Diego Biurrun | |
80 | e731b8d8 | Anton Khirnov | #if FF_API_OLD_AVIO
|
81 | int init_put_byte(AVIOContext *s,
|
||
82 | unsigned char *buffer, |
||
83 | int buffer_size,
|
||
84 | int write_flag,
|
||
85 | void *opaque,
|
||
86 | int (*read_packet)(void *opaque, uint8_t *buf, int buf_size), |
||
87 | int (*write_packet)(void *opaque, uint8_t *buf, int buf_size), |
||
88 | int64_t (*seek)(void *opaque, int64_t offset, int whence)) |
||
89 | { |
||
90 | return ffio_init_context(s, buffer, buffer_size, write_flag, opaque,
|
||
91 | read_packet, write_packet, seek); |
||
92 | } |
||
93 | 8d9ac969 | Anton Khirnov | AVIOContext *av_alloc_put_byte( |
94 | unsigned char *buffer, |
||
95 | int buffer_size,
|
||
96 | int write_flag,
|
||
97 | void *opaque,
|
||
98 | int (*read_packet)(void *opaque, uint8_t *buf, int buf_size), |
||
99 | int (*write_packet)(void *opaque, uint8_t *buf, int buf_size), |
||
100 | int64_t (*seek)(void *opaque, int64_t offset, int whence)) |
||
101 | { |
||
102 | return avio_alloc_context(buffer, buffer_size, write_flag, opaque,
|
||
103 | read_packet, write_packet, seek); |
||
104 | } |
||
105 | e731b8d8 | Anton Khirnov | #endif
|
106 | |||
107 | 8d9ac969 | Anton Khirnov | AVIOContext *avio_alloc_context( |
108 | 1e0f3468 | Reimar Döffinger | unsigned char *buffer, |
109 | int buffer_size,
|
||
110 | int write_flag,
|
||
111 | void *opaque,
|
||
112 | int (*read_packet)(void *opaque, uint8_t *buf, int buf_size), |
||
113 | int (*write_packet)(void *opaque, uint8_t *buf, int buf_size), |
||
114 | 7f37f568 | Diego Biurrun | int64_t (*seek)(void *opaque, int64_t offset, int whence)) |
115 | { |
||
116 | ae628ec1 | Anton Khirnov | AVIOContext *s = av_mallocz(sizeof(AVIOContext));
|
117 | e731b8d8 | Anton Khirnov | ffio_init_context(s, buffer, buffer_size, write_flag, opaque, |
118 | 1e0f3468 | Reimar Döffinger | read_packet, write_packet, seek); |
119 | return s;
|
||
120 | } |
||
121 | |||
122 | ae628ec1 | Anton Khirnov | static void flush_buffer(AVIOContext *s) |
123 | de6d9b64 | Fabrice Bellard | { |
124 | if (s->buf_ptr > s->buffer) {
|
||
125 | 576ae256 | Michael Niedermayer | if (s->write_packet && !s->error){
|
126 | c66f53cf | Martin Storsjö | int ret= s->write_packet(s->opaque, s->buffer, s->buf_ptr - s->buffer);
|
127 | 576ae256 | Michael Niedermayer | if(ret < 0){ |
128 | s->error = ret; |
||
129 | } |
||
130 | } |
||
131 | 465e1dad | Michael Niedermayer | if(s->update_checksum){
|
132 | ee9f36a8 | Michael Niedermayer | s->checksum= s->update_checksum(s->checksum, s->checksum_ptr, s->buf_ptr - s->checksum_ptr); |
133 | s->checksum_ptr= s->buffer; |
||
134 | } |
||
135 | de6d9b64 | Fabrice Bellard | s->pos += s->buf_ptr - s->buffer; |
136 | } |
||
137 | s->buf_ptr = s->buffer; |
||
138 | } |
||
139 | |||
140 | 77eb5504 | Anton Khirnov | void avio_w8(AVIOContext *s, int b) |
141 | de6d9b64 | Fabrice Bellard | { |
142 | *(s->buf_ptr)++ = b; |
||
143 | 115329f1 | Diego Biurrun | if (s->buf_ptr >= s->buf_end)
|
144 | de6d9b64 | Fabrice Bellard | flush_buffer(s); |
145 | } |
||
146 | |||
147 | 0ac8e2bf | Anton Khirnov | void ffio_fill(AVIOContext *s, int b, int count) |
148 | 17ee8f66 | Anssi Hannula | { |
149 | while (count > 0) { |
||
150 | int len = FFMIN(s->buf_end - s->buf_ptr, count);
|
||
151 | memset(s->buf_ptr, b, len); |
||
152 | s->buf_ptr += len; |
||
153 | |||
154 | if (s->buf_ptr >= s->buf_end)
|
||
155 | flush_buffer(s); |
||
156 | |||
157 | count -= len; |
||
158 | } |
||
159 | } |
||
160 | |||
161 | 77eb5504 | Anton Khirnov | void avio_write(AVIOContext *s, const unsigned char *buf, int size) |
162 | de6d9b64 | Fabrice Bellard | { |
163 | while (size > 0) { |
||
164 | 90aa6ace | Reimar Döffinger | int len = FFMIN(s->buf_end - s->buf_ptr, size);
|
165 | de6d9b64 | Fabrice Bellard | memcpy(s->buf_ptr, buf, len); |
166 | s->buf_ptr += len; |
||
167 | |||
168 | 115329f1 | Diego Biurrun | if (s->buf_ptr >= s->buf_end)
|
169 | de6d9b64 | Fabrice Bellard | flush_buffer(s); |
170 | |||
171 | buf += len; |
||
172 | size -= len; |
||
173 | } |
||
174 | } |
||
175 | |||
176 | b7f2fdde | Anton Khirnov | void avio_flush(AVIOContext *s)
|
177 | de6d9b64 | Fabrice Bellard | { |
178 | flush_buffer(s); |
||
179 | s->must_flush = 0;
|
||
180 | } |
||
181 | |||
182 | 6b4aa5da | Anton Khirnov | int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
|
183 | de6d9b64 | Fabrice Bellard | { |
184 | bc5c918e | Diego Biurrun | int64_t offset1; |
185 | int64_t pos; |
||
186 | c6a5e087 | Tomas Härdin | int force = whence & AVSEEK_FORCE;
|
187 | whence &= ~AVSEEK_FORCE; |
||
188 | 899681cd | Björn Axelsson | |
189 | if(!s)
|
||
190 | return AVERROR(EINVAL);
|
||
191 | |||
192 | pos = s->pos - (s->write_flag ? 0 : (s->buf_end - s->buffer));
|
||
193 | de6d9b64 | Fabrice Bellard | |
194 | if (whence != SEEK_CUR && whence != SEEK_SET)
|
||
195 | 8fa36ae0 | François Revol | return AVERROR(EINVAL);
|
196 | 115329f1 | Diego Biurrun | |
197 | f40d1739 | Michael Niedermayer | if (whence == SEEK_CUR) {
|
198 | offset1 = pos + (s->buf_ptr - s->buffer); |
||
199 | if (offset == 0) |
||
200 | return offset1;
|
||
201 | offset += offset1; |
||
202 | } |
||
203 | offset1 = offset - pos; |
||
204 | if (!s->must_flush &&
|
||
205 | b3eab9fb | Baptiste Coudurier | offset1 >= 0 && offset1 <= (s->buf_end - s->buffer)) {
|
206 | f40d1739 | Michael Niedermayer | /* can do the seek inside the buffer */
|
207 | s->buf_ptr = s->buffer + offset1; |
||
208 | 8978feda | Anton Khirnov | } else if ((!s->seekable || |
209 | 7939d0ed | Martin Storsjö | offset1 <= s->buf_end + SHORT_SEEK_THRESHOLD - s->buffer) && |
210 | !s->write_flag && offset1 >= 0 &&
|
||
211 | 7a6fe01f | Tomas Härdin | (whence != SEEK_END || force)) { |
212 | 398f5d3f | Michael Niedermayer | while(s->pos < offset && !s->eof_reached)
|
213 | fill_buffer(s); |
||
214 | 5cb4b82a | Baptiste Coudurier | if (s->eof_reached)
|
215 | 8d5e638f | Stefano Sabatini | return AVERROR_EOF;
|
216 | 398f5d3f | Michael Niedermayer | s->buf_ptr = s->buf_end + offset - s->pos; |
217 | f40d1739 | Michael Niedermayer | } else {
|
218 | 9d30e068 | Stefano Sabatini | int64_t res; |
219 | 68fcdbf1 | Ronald S. Bultje | |
220 | b250f9c6 | Aurelien Jacobs | #if CONFIG_MUXERS || CONFIG_NETWORK
|
221 | f40d1739 | Michael Niedermayer | if (s->write_flag) {
|
222 | de6d9b64 | Fabrice Bellard | flush_buffer(s); |
223 | s->must_flush = 1;
|
||
224 | } |
||
225 | b250f9c6 | Aurelien Jacobs | #endif /* CONFIG_MUXERS || CONFIG_NETWORK */ |
226 | 9d30e068 | Stefano Sabatini | if (!s->seek)
|
227 | return AVERROR(EPIPE);
|
||
228 | if ((res = s->seek(s->opaque, offset, SEEK_SET)) < 0) |
||
229 | 68fcdbf1 | Ronald S. Bultje | return res;
|
230 | 39a127bf | Baptiste Coudurier | if (!s->write_flag)
|
231 | s->buf_end = s->buffer; |
||
232 | s->buf_ptr = s->buffer; |
||
233 | f40d1739 | Michael Niedermayer | s->pos = offset; |
234 | de6d9b64 | Fabrice Bellard | } |
235 | f40d1739 | Michael Niedermayer | s->eof_reached = 0;
|
236 | de6d9b64 | Fabrice Bellard | return offset;
|
237 | } |
||
238 | |||
239 | 0300db8a | Anton Khirnov | #if FF_API_OLD_AVIO
|
240 | ae628ec1 | Anton Khirnov | int url_fskip(AVIOContext *s, int64_t offset)
|
241 | de6d9b64 | Fabrice Bellard | { |
242 | 6b4aa5da | Anton Khirnov | int64_t ret = avio_seek(s, offset, SEEK_CUR); |
243 | d5e9ddeb | Martin Storsjö | return ret < 0 ? ret : 0; |
244 | de6d9b64 | Fabrice Bellard | } |
245 | |||
246 | ae628ec1 | Anton Khirnov | int64_t url_ftell(AVIOContext *s) |
247 | de6d9b64 | Fabrice Bellard | { |
248 | 6b4aa5da | Anton Khirnov | return avio_seek(s, 0, SEEK_CUR); |
249 | de6d9b64 | Fabrice Bellard | } |
250 | a2704c97 | Anton Khirnov | #endif
|
251 | de6d9b64 | Fabrice Bellard | |
252 | 76aa876e | Anton Khirnov | int64_t avio_size(AVIOContext *s) |
253 | a965c478 | Aurelien Jacobs | { |
254 | bc5c918e | Diego Biurrun | int64_t size; |
255 | 115329f1 | Diego Biurrun | |
256 | 899681cd | Björn Axelsson | if(!s)
|
257 | return AVERROR(EINVAL);
|
||
258 | |||
259 | a965c478 | Aurelien Jacobs | if (!s->seek)
|
260 | 4c4ef3db | Stefano Sabatini | return AVERROR(ENOSYS);
|
261 | 8e287af0 | Michael Niedermayer | size = s->seek(s->opaque, 0, AVSEEK_SIZE);
|
262 | if(size<0){ |
||
263 | 8f42f523 | Ronald S. Bultje | if ((size = s->seek(s->opaque, -1, SEEK_END)) < 0) |
264 | return size;
|
||
265 | size++; |
||
266 | 1ae2c5f2 | Michael Niedermayer | s->seek(s->opaque, s->pos, SEEK_SET); |
267 | 8e287af0 | Michael Niedermayer | } |
268 | a965c478 | Aurelien Jacobs | return size;
|
269 | } |
||
270 | |||
271 | 66e5b1df | Anton Khirnov | #if FF_API_OLD_AVIO
|
272 | ae628ec1 | Anton Khirnov | int url_feof(AVIOContext *s)
|
273 | de6d9b64 | Fabrice Bellard | { |
274 | 899681cd | Björn Axelsson | if(!s)
|
275 | return 0; |
||
276 | de6d9b64 | Fabrice Bellard | return s->eof_reached;
|
277 | } |
||
278 | |||
279 | ae628ec1 | Anton Khirnov | int url_ferror(AVIOContext *s)
|
280 | 576ae256 | Michael Niedermayer | { |
281 | 899681cd | Björn Axelsson | if(!s)
|
282 | return 0; |
||
283 | 576ae256 | Michael Niedermayer | return s->error;
|
284 | } |
||
285 | 3e68b3ba | Anton Khirnov | #endif
|
286 | 576ae256 | Michael Niedermayer | |
287 | 77eb5504 | Anton Khirnov | void avio_wl32(AVIOContext *s, unsigned int val) |
288 | de6d9b64 | Fabrice Bellard | { |
289 | 77eb5504 | Anton Khirnov | avio_w8(s, val); |
290 | avio_w8(s, val >> 8);
|
||
291 | avio_w8(s, val >> 16);
|
||
292 | avio_w8(s, val >> 24);
|
||
293 | de6d9b64 | Fabrice Bellard | } |
294 | |||
295 | 77eb5504 | Anton Khirnov | void avio_wb32(AVIOContext *s, unsigned int val) |
296 | de6d9b64 | Fabrice Bellard | { |
297 | 77eb5504 | Anton Khirnov | avio_w8(s, val >> 24);
|
298 | avio_w8(s, val >> 16);
|
||
299 | avio_w8(s, val >> 8);
|
||
300 | avio_w8(s, val); |
||
301 | de6d9b64 | Fabrice Bellard | } |
302 | |||
303 | 4efd5cf3 | Anton Khirnov | #if FF_API_OLD_AVIO
|
304 | ae628ec1 | Anton Khirnov | void put_strz(AVIOContext *s, const char *str) |
305 | 75bdb984 | Philip Gladstone | { |
306 | 4efd5cf3 | Anton Khirnov | avio_put_str(s, str); |
307 | } |
||
308 | b7effd4e | Anton Khirnov | |
309 | #define GET(name, type) \
|
||
310 | type get_be ##name(AVIOContext *s) \ |
||
311 | {\ |
||
312 | return avio_rb ##name(s);\ |
||
313 | }\ |
||
314 | type get_le ##name(AVIOContext *s) \ |
||
315 | {\ |
||
316 | return avio_rl ##name(s);\ |
||
317 | } |
||
318 | |||
319 | GET(16, unsigned int) |
||
320 | GET(24, unsigned int) |
||
321 | GET(32, unsigned int) |
||
322 | GET(64, uint64_t)
|
||
323 | |||
324 | #undef GET
|
||
325 | |||
326 | 77eb5504 | Anton Khirnov | #define PUT(name, type ) \
|
327 | void put_le ##name(AVIOContext *s, type val)\ |
||
328 | {\ |
||
329 | avio_wl ##name(s, val);\ |
||
330 | }\ |
||
331 | void put_be ##name(AVIOContext *s, type val)\ |
||
332 | {\ |
||
333 | avio_wb ##name(s, val);\ |
||
334 | } |
||
335 | |||
336 | PUT(16, unsigned int) |
||
337 | PUT(24, unsigned int) |
||
338 | PUT(32, unsigned int) |
||
339 | PUT(64, uint64_t)
|
||
340 | #undef PUT
|
||
341 | |||
342 | b7effd4e | Anton Khirnov | int get_byte(AVIOContext *s)
|
343 | { |
||
344 | return avio_r8(s);
|
||
345 | } |
||
346 | int get_buffer(AVIOContext *s, unsigned char *buf, int size) |
||
347 | { |
||
348 | return avio_read(s, buf, size);
|
||
349 | } |
||
350 | b3db9cee | Anton Khirnov | int get_partial_buffer(AVIOContext *s, unsigned char *buf, int size) |
351 | { |
||
352 | return ffio_read_partial(s, buf, size);
|
||
353 | } |
||
354 | 77eb5504 | Anton Khirnov | void put_byte(AVIOContext *s, int val) |
355 | { |
||
356 | avio_w8(s, val); |
||
357 | } |
||
358 | void put_buffer(AVIOContext *s, const unsigned char *buf, int size) |
||
359 | { |
||
360 | avio_write(s, buf, size); |
||
361 | } |
||
362 | 0ac8e2bf | Anton Khirnov | void put_nbyte(AVIOContext *s, int b, int count) |
363 | { |
||
364 | ffio_fill(s, b, count); |
||
365 | } |
||
366 | 22a3212e | Anton Khirnov | |
367 | int url_fopen(AVIOContext **s, const char *filename, int flags) |
||
368 | { |
||
369 | return avio_open(s, filename, flags);
|
||
370 | } |
||
371 | int url_fclose(AVIOContext *s)
|
||
372 | { |
||
373 | return avio_close(s);
|
||
374 | } |
||
375 | 6b4aa5da | Anton Khirnov | int64_t url_fseek(AVIOContext *s, int64_t offset, int whence)
|
376 | { |
||
377 | return avio_seek(s, offset, whence);
|
||
378 | } |
||
379 | 76aa876e | Anton Khirnov | int64_t url_fsize(AVIOContext *s) |
380 | { |
||
381 | return avio_size(s);
|
||
382 | } |
||
383 | 59f65d95 | Anton Khirnov | int url_setbufsize(AVIOContext *s, int buf_size) |
384 | { |
||
385 | return ffio_set_buf_size(s, buf_size);
|
||
386 | } |
||
387 | d9d86e00 | Anton Khirnov | int url_fprintf(AVIOContext *s, const char *fmt, ...) |
388 | { |
||
389 | va_list ap; |
||
390 | char buf[4096]; |
||
391 | int ret;
|
||
392 | |||
393 | va_start(ap, fmt); |
||
394 | ret = vsnprintf(buf, sizeof(buf), fmt, ap);
|
||
395 | va_end(ap); |
||
396 | avio_write(s, buf, strlen(buf)); |
||
397 | return ret;
|
||
398 | } |
||
399 | b7f2fdde | Anton Khirnov | void put_flush_packet(AVIOContext *s)
|
400 | { |
||
401 | avio_flush(s); |
||
402 | } |
||
403 | 933e90a6 | Anton Khirnov | int av_url_read_fpause(AVIOContext *s, int pause) |
404 | { |
||
405 | return ffio_read_pause(s, pause);
|
||
406 | } |
||
407 | int64_t av_url_read_fseek(AVIOContext *s, int stream_index,
|
||
408 | int64_t timestamp, int flags)
|
||
409 | { |
||
410 | return ffio_read_seek(s, stream_index, timestamp, flags);
|
||
411 | } |
||
412 | 4c4427a7 | Anton Khirnov | void init_checksum(AVIOContext *s,
|
413 | unsigned long (*update_checksum)(unsigned long c, const uint8_t *p, unsigned int len), |
||
414 | unsigned long checksum) |
||
415 | { |
||
416 | ffio_init_checksum(s, update_checksum, checksum); |
||
417 | } |
||
418 | b64030f2 | Anton Khirnov | unsigned long get_checksum(AVIOContext *s) |
419 | { |
||
420 | return ffio_get_checksum(s);
|
||
421 | } |
||
422 | b92c5452 | Anton Khirnov | int url_open_dyn_buf(AVIOContext **s)
|
423 | { |
||
424 | return avio_open_dyn_buf(s);
|
||
425 | } |
||
426 | 403ee835 | Anton Khirnov | int url_open_dyn_packet_buf(AVIOContext **s, int max_packet_size) |
427 | { |
||
428 | return ffio_open_dyn_packet_buf(s, max_packet_size);
|
||
429 | } |
||
430 | 6dc7d80d | Anton Khirnov | int url_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
|
431 | { |
||
432 | return avio_close_dyn_buf(s, pbuffer);
|
||
433 | } |
||
434 | 724f6a0f | Anton Khirnov | int url_fdopen(AVIOContext **s, URLContext *h)
|
435 | { |
||
436 | return ffio_fdopen(s, h);
|
||
437 | } |
||
438 | 4efd5cf3 | Anton Khirnov | #endif
|
439 | |||
440 | ae628ec1 | Anton Khirnov | int avio_put_str(AVIOContext *s, const char *str) |
441 | 4efd5cf3 | Anton Khirnov | { |
442 | int len = 1; |
||
443 | if (str) {
|
||
444 | len += strlen(str); |
||
445 | 77eb5504 | Anton Khirnov | avio_write(s, (const unsigned char *) str, len); |
446 | 4efd5cf3 | Anton Khirnov | } else
|
447 | 77eb5504 | Anton Khirnov | avio_w8(s, 0);
|
448 | 4efd5cf3 | Anton Khirnov | return len;
|
449 | 75bdb984 | Philip Gladstone | } |
450 | |||
451 | ae628ec1 | Anton Khirnov | int avio_put_str16le(AVIOContext *s, const char *str) |
452 | dccbd97d | Anton Khirnov | { |
453 | const uint8_t *q = str;
|
||
454 | int ret = 0; |
||
455 | |||
456 | while (*q) {
|
||
457 | uint32_t ch; |
||
458 | uint16_t tmp; |
||
459 | |||
460 | GET_UTF8(ch, *q++, break;)
|
||
461 | 77eb5504 | Anton Khirnov | PUT_UTF16(ch, tmp, avio_wl16(s, tmp);ret += 2;)
|
462 | dccbd97d | Anton Khirnov | } |
463 | 77eb5504 | Anton Khirnov | avio_wl16(s, 0);
|
464 | dccbd97d | Anton Khirnov | ret += 2;
|
465 | return ret;
|
||
466 | } |
||
467 | |||
468 | 603e5c0b | Michael Chinen | int ff_get_v_length(uint64_t val){
|
469 | int i=1; |
||
470 | |||
471 | while(val>>=7) |
||
472 | i++; |
||
473 | |||
474 | return i;
|
||
475 | } |
||
476 | |||
477 | ae628ec1 | Anton Khirnov | void ff_put_v(AVIOContext *bc, uint64_t val){
|
478 | 603e5c0b | Michael Chinen | int i= ff_get_v_length(val);
|
479 | |||
480 | while(--i>0) |
||
481 | 77eb5504 | Anton Khirnov | avio_w8(bc, 128 | (val>>(7*i))); |
482 | 603e5c0b | Michael Chinen | |
483 | 77eb5504 | Anton Khirnov | avio_w8(bc, val&127);
|
484 | 603e5c0b | Michael Chinen | } |
485 | |||
486 | 77eb5504 | Anton Khirnov | void avio_wl64(AVIOContext *s, uint64_t val)
|
487 | de6d9b64 | Fabrice Bellard | { |
488 | 77eb5504 | Anton Khirnov | avio_wl32(s, (uint32_t)(val & 0xffffffff));
|
489 | avio_wl32(s, (uint32_t)(val >> 32));
|
||
490 | de6d9b64 | Fabrice Bellard | } |
491 | |||
492 | 77eb5504 | Anton Khirnov | void avio_wb64(AVIOContext *s, uint64_t val)
|
493 | de6d9b64 | Fabrice Bellard | { |
494 | 77eb5504 | Anton Khirnov | avio_wb32(s, (uint32_t)(val >> 32));
|
495 | avio_wb32(s, (uint32_t)(val & 0xffffffff));
|
||
496 | de6d9b64 | Fabrice Bellard | } |
497 | |||
498 | 77eb5504 | Anton Khirnov | void avio_wl16(AVIOContext *s, unsigned int val) |
499 | de6d9b64 | Fabrice Bellard | { |
500 | 77eb5504 | Anton Khirnov | avio_w8(s, val); |
501 | avio_w8(s, val >> 8);
|
||
502 | de6d9b64 | Fabrice Bellard | } |
503 | |||
504 | 77eb5504 | Anton Khirnov | void avio_wb16(AVIOContext *s, unsigned int val) |
505 | de6d9b64 | Fabrice Bellard | { |
506 | 77eb5504 | Anton Khirnov | avio_w8(s, val >> 8);
|
507 | avio_w8(s, val); |
||
508 | de6d9b64 | Fabrice Bellard | } |
509 | |||
510 | 77eb5504 | Anton Khirnov | void avio_wl24(AVIOContext *s, unsigned int val) |
511 | ea395e8c | Aurelien Jacobs | { |
512 | 77eb5504 | Anton Khirnov | avio_wl16(s, val & 0xffff);
|
513 | avio_w8(s, val >> 16);
|
||
514 | ea395e8c | Aurelien Jacobs | } |
515 | |||
516 | 77eb5504 | Anton Khirnov | void avio_wb24(AVIOContext *s, unsigned int val) |
517 | a254c574 | Michael Niedermayer | { |
518 | 77eb5504 | Anton Khirnov | avio_wb16(s, val >> 8);
|
519 | avio_w8(s, val); |
||
520 | a254c574 | Michael Niedermayer | } |
521 | |||
522 | 61840b43 | Anton Khirnov | #if FF_API_OLD_AVIO
|
523 | ae628ec1 | Anton Khirnov | void put_tag(AVIOContext *s, const char *tag) |
524 | de6d9b64 | Fabrice Bellard | { |
525 | while (*tag) {
|
||
526 | 77eb5504 | Anton Khirnov | avio_w8(s, *tag++); |
527 | de6d9b64 | Fabrice Bellard | } |
528 | } |
||
529 | 61840b43 | Anton Khirnov | #endif
|
530 | de6d9b64 | Fabrice Bellard | |
531 | /* Input stream */
|
||
532 | |||
533 | ae628ec1 | Anton Khirnov | static void fill_buffer(AVIOContext *s) |
534 | de6d9b64 | Fabrice Bellard | { |
535 | e360ada2 | Martin Storsjö | uint8_t *dst= !s->max_packet_size && s->buf_end - s->buffer < s->buffer_size ? s->buf_end : s->buffer; |
536 | 4589dc5c | Michael Niedermayer | int len= s->buffer_size - (dst - s->buffer);
|
537 | 01d91b9b | Tomas Härdin | int max_buffer_size = s->max_packet_size ? s->max_packet_size : IO_BUFFER_SIZE;
|
538 | 4589dc5c | Michael Niedermayer | |
539 | abba3dd1 | Fabrice Bellard | /* no need to do anything if EOF already reached */
|
540 | if (s->eof_reached)
|
||
541 | return;
|
||
542 | ee9f36a8 | Michael Niedermayer | |
543 | 4589dc5c | Michael Niedermayer | if(s->update_checksum && dst == s->buffer){
|
544 | 0f0680c5 | Michael Niedermayer | if(s->buf_end > s->checksum_ptr)
|
545 | s->checksum= s->update_checksum(s->checksum, s->checksum_ptr, s->buf_end - s->checksum_ptr); |
||
546 | ee9f36a8 | Michael Niedermayer | s->checksum_ptr= s->buffer; |
547 | } |
||
548 | |||
549 | 01d91b9b | Tomas Härdin | /* make buffer smaller in case it ended up large after probing */
|
550 | if (s->buffer_size > max_buffer_size) {
|
||
551 | 59f65d95 | Anton Khirnov | ffio_set_buf_size(s, max_buffer_size); |
552 | 01d91b9b | Tomas Härdin | |
553 | s->checksum_ptr = dst = s->buffer; |
||
554 | len = s->buffer_size; |
||
555 | } |
||
556 | |||
557 | 602dd8f6 | Benoit Fouet | if(s->read_packet)
|
558 | c66f53cf | Martin Storsjö | len = s->read_packet(s->opaque, dst, len); |
559 | 4589dc5c | Michael Niedermayer | else
|
560 | len = 0;
|
||
561 | abba3dd1 | Fabrice Bellard | if (len <= 0) { |
562 | /* do not modify buffer if EOF reached so that a seek back can
|
||
563 | be done without rereading data */
|
||
564 | de6d9b64 | Fabrice Bellard | s->eof_reached = 1;
|
565 | 5f097703 | Alex Beregszaszi | if(len<0) |
566 | s->error= len; |
||
567 | abba3dd1 | Fabrice Bellard | } else {
|
568 | s->pos += len; |
||
569 | 4589dc5c | Michael Niedermayer | s->buf_ptr = dst; |
570 | s->buf_end = dst + len; |
||
571 | de6d9b64 | Fabrice Bellard | } |
572 | } |
||
573 | |||
574 | 7f37f568 | Diego Biurrun | unsigned long ff_crc04C11DB7_update(unsigned long checksum, const uint8_t *buf, |
575 | unsigned int len) |
||
576 | { |
||
577 | 3abe5fbd | Aurelien Jacobs | return av_crc(av_crc_get_table(AV_CRC_32_IEEE), checksum, buf, len);
|
578 | 992e78f5 | Baptiste Coudurier | } |
579 | |||
580 | b64030f2 | Anton Khirnov | unsigned long ffio_get_checksum(AVIOContext *s) |
581 | 7f37f568 | Diego Biurrun | { |
582 | ee9f36a8 | Michael Niedermayer | s->checksum= s->update_checksum(s->checksum, s->checksum_ptr, s->buf_ptr - s->checksum_ptr); |
583 | 465e1dad | Michael Niedermayer | s->update_checksum= NULL;
|
584 | ee9f36a8 | Michael Niedermayer | return s->checksum;
|
585 | } |
||
586 | |||
587 | 4c4427a7 | Anton Khirnov | void ffio_init_checksum(AVIOContext *s,
|
588 | 7f37f568 | Diego Biurrun | unsigned long (*update_checksum)(unsigned long c, const uint8_t *p, unsigned int len), |
589 | unsigned long checksum) |
||
590 | { |
||
591 | ee9f36a8 | Michael Niedermayer | s->update_checksum= update_checksum; |
592 | 465e1dad | Michael Niedermayer | if(s->update_checksum){
|
593 | ccb15994 | Michael Niedermayer | s->checksum= checksum; |
594 | 465e1dad | Michael Niedermayer | s->checksum_ptr= s->buf_ptr; |
595 | } |
||
596 | ee9f36a8 | Michael Niedermayer | } |
597 | |||
598 | abba3dd1 | Fabrice Bellard | /* XXX: put an inline version */
|
599 | b7effd4e | Anton Khirnov | int avio_r8(AVIOContext *s)
|
600 | de6d9b64 | Fabrice Bellard | { |
601 | 3aa13da9 | Reimar Döffinger | if (s->buf_ptr >= s->buf_end)
|
602 | de6d9b64 | Fabrice Bellard | fill_buffer(s); |
603 | 853a0fcc | Reimar Döffinger | if (s->buf_ptr < s->buf_end)
|
604 | return *s->buf_ptr++;
|
||
605 | return 0; |
||
606 | de6d9b64 | Fabrice Bellard | } |
607 | |||
608 | e5197539 | Anton Khirnov | #if FF_API_OLD_AVIO
|
609 | ae628ec1 | Anton Khirnov | int url_fgetc(AVIOContext *s)
|
610 | abba3dd1 | Fabrice Bellard | { |
611 | 3aa13da9 | Reimar Döffinger | if (s->buf_ptr >= s->buf_end)
|
612 | abba3dd1 | Fabrice Bellard | fill_buffer(s); |
613 | 853a0fcc | Reimar Döffinger | if (s->buf_ptr < s->buf_end)
|
614 | return *s->buf_ptr++;
|
||
615 | return URL_EOF;
|
||
616 | abba3dd1 | Fabrice Bellard | } |
617 | e5197539 | Anton Khirnov | #endif
|
618 | abba3dd1 | Fabrice Bellard | |
619 | b7effd4e | Anton Khirnov | int avio_read(AVIOContext *s, unsigned char *buf, int size) |
620 | de6d9b64 | Fabrice Bellard | { |
621 | int len, size1;
|
||
622 | |||
623 | size1 = size; |
||
624 | while (size > 0) { |
||
625 | len = s->buf_end - s->buf_ptr; |
||
626 | if (len > size)
|
||
627 | len = size; |
||
628 | if (len == 0) { |
||
629 | 3e2b6358 | Michael Niedermayer | if(size > s->buffer_size && !s->update_checksum){
|
630 | 602dd8f6 | Benoit Fouet | if(s->read_packet)
|
631 | c66f53cf | Martin Storsjö | len = s->read_packet(s->opaque, buf, size); |
632 | 3e2b6358 | Michael Niedermayer | if (len <= 0) { |
633 | /* do not modify buffer if EOF reached so that a seek back can
|
||
634 | be done without rereading data */
|
||
635 | s->eof_reached = 1;
|
||
636 | if(len<0) |
||
637 | s->error= len; |
||
638 | break;
|
||
639 | } else {
|
||
640 | s->pos += len; |
||
641 | size -= len; |
||
642 | buf += len; |
||
643 | s->buf_ptr = s->buffer; |
||
644 | s->buf_end = s->buffer/* + len*/;
|
||
645 | } |
||
646 | }else{
|
||
647 | fill_buffer(s); |
||
648 | len = s->buf_end - s->buf_ptr; |
||
649 | if (len == 0) |
||
650 | break;
|
||
651 | } |
||
652 | de6d9b64 | Fabrice Bellard | } else {
|
653 | memcpy(buf, s->buf_ptr, len); |
||
654 | buf += len; |
||
655 | s->buf_ptr += len; |
||
656 | size -= len; |
||
657 | } |
||
658 | } |
||
659 | 7f7686df | Reimar Döffinger | if (size1 == size) {
|
660 | 3e68b3ba | Anton Khirnov | if (s->error) return s->error; |
661 | 66e5b1df | Anton Khirnov | if (s->eof_reached) return AVERROR_EOF; |
662 | 7f7686df | Reimar Döffinger | } |
663 | de6d9b64 | Fabrice Bellard | return size1 - size;
|
664 | } |
||
665 | |||
666 | b3db9cee | Anton Khirnov | int ffio_read_partial(AVIOContext *s, unsigned char *buf, int size) |
667 | e15dec10 | Leon van Stuivenberg | { |
668 | int len;
|
||
669 | 115329f1 | Diego Biurrun | |
670 | 0ecca7a4 | Michael Niedermayer | if(size<0) |
671 | return -1; |
||
672 | e15dec10 | Leon van Stuivenberg | |
673 | len = s->buf_end - s->buf_ptr; |
||
674 | if (len == 0) { |
||
675 | fill_buffer(s); |
||
676 | len = s->buf_end - s->buf_ptr; |
||
677 | } |
||
678 | if (len > size)
|
||
679 | len = size; |
||
680 | memcpy(buf, s->buf_ptr, len); |
||
681 | s->buf_ptr += len; |
||
682 | 7f7686df | Reimar Döffinger | if (!len) {
|
683 | 3e68b3ba | Anton Khirnov | if (s->error) return s->error; |
684 | 66e5b1df | Anton Khirnov | if (s->eof_reached) return AVERROR_EOF; |
685 | 7f7686df | Reimar Döffinger | } |
686 | e15dec10 | Leon van Stuivenberg | return len;
|
687 | } |
||
688 | |||
689 | b7effd4e | Anton Khirnov | unsigned int avio_rl16(AVIOContext *s) |
690 | de6d9b64 | Fabrice Bellard | { |
691 | unsigned int val; |
||
692 | b7effd4e | Anton Khirnov | val = avio_r8(s); |
693 | val |= avio_r8(s) << 8;
|
||
694 | de6d9b64 | Fabrice Bellard | return val;
|
695 | } |
||
696 | |||
697 | b7effd4e | Anton Khirnov | unsigned int avio_rl24(AVIOContext *s) |
698 | ea395e8c | Aurelien Jacobs | { |
699 | unsigned int val; |
||
700 | b7effd4e | Anton Khirnov | val = avio_rl16(s); |
701 | val |= avio_r8(s) << 16;
|
||
702 | ea395e8c | Aurelien Jacobs | return val;
|
703 | } |
||
704 | |||
705 | b7effd4e | Anton Khirnov | unsigned int avio_rl32(AVIOContext *s) |
706 | de6d9b64 | Fabrice Bellard | { |
707 | unsigned int val; |
||
708 | b7effd4e | Anton Khirnov | val = avio_rl16(s); |
709 | val |= avio_rl16(s) << 16;
|
||
710 | de6d9b64 | Fabrice Bellard | return val;
|
711 | } |
||
712 | |||
713 | b7effd4e | Anton Khirnov | uint64_t avio_rl64(AVIOContext *s) |
714 | de6d9b64 | Fabrice Bellard | { |
715 | 0c1a9eda | Zdenek Kabelac | uint64_t val; |
716 | b7effd4e | Anton Khirnov | val = (uint64_t)avio_rl32(s); |
717 | val |= (uint64_t)avio_rl32(s) << 32;
|
||
718 | de6d9b64 | Fabrice Bellard | return val;
|
719 | } |
||
720 | |||
721 | b7effd4e | Anton Khirnov | unsigned int avio_rb16(AVIOContext *s) |
722 | de6d9b64 | Fabrice Bellard | { |
723 | unsigned int val; |
||
724 | b7effd4e | Anton Khirnov | val = avio_r8(s) << 8;
|
725 | val |= avio_r8(s); |
||
726 | de6d9b64 | Fabrice Bellard | return val;
|
727 | } |
||
728 | |||
729 | b7effd4e | Anton Khirnov | unsigned int avio_rb24(AVIOContext *s) |
730 | de6d9b64 | Fabrice Bellard | { |
731 | unsigned int val; |
||
732 | b7effd4e | Anton Khirnov | val = avio_rb16(s) << 8;
|
733 | val |= avio_r8(s); |
||
734 | de6d9b64 | Fabrice Bellard | return val;
|
735 | } |
||
736 | b7effd4e | Anton Khirnov | unsigned int avio_rb32(AVIOContext *s) |
737 | a254c574 | Michael Niedermayer | { |
738 | unsigned int val; |
||
739 | b7effd4e | Anton Khirnov | val = avio_rb16(s) << 16;
|
740 | val |= avio_rb16(s); |
||
741 | a254c574 | Michael Niedermayer | return val;
|
742 | } |
||
743 | de6d9b64 | Fabrice Bellard | |
744 | e16ead07 | Anton Khirnov | #if FF_API_OLD_AVIO
|
745 | ae628ec1 | Anton Khirnov | char *get_strz(AVIOContext *s, char *buf, int maxlen) |
746 | 75bdb984 | Philip Gladstone | { |
747 | e16ead07 | Anton Khirnov | avio_get_str(s, INT_MAX, buf, maxlen); |
748 | 75bdb984 | Philip Gladstone | return buf;
|
749 | } |
||
750 | e16ead07 | Anton Khirnov | #endif
|
751 | 75bdb984 | Philip Gladstone | |
752 | ae628ec1 | Anton Khirnov | int ff_get_line(AVIOContext *s, char *buf, int maxlen) |
753 | 7c892951 | Aurelien Jacobs | { |
754 | int i = 0; |
||
755 | char c;
|
||
756 | |||
757 | do {
|
||
758 | b7effd4e | Anton Khirnov | c = avio_r8(s); |
759 | a43416a5 | Aurelien Jacobs | if (c && i < maxlen-1) |
760 | 7c892951 | Aurelien Jacobs | buf[i++] = c; |
761 | } while (c != '\n' && c); |
||
762 | |||
763 | buf[i] = 0;
|
||
764 | a43416a5 | Aurelien Jacobs | return i;
|
765 | 7c892951 | Aurelien Jacobs | } |
766 | |||
767 | 41d8555f | Reimar Döffinger | int avio_get_str(AVIOContext *s, int maxlen, char *buf, int buflen) |
768 | { |
||
769 | int i;
|
||
770 | |||
771 | // reserve 1 byte for terminating 0
|
||
772 | buflen = FFMIN(buflen - 1, maxlen);
|
||
773 | for (i = 0; i < buflen; i++) |
||
774 | if (!(buf[i] = avio_r8(s)))
|
||
775 | return i + 1; |
||
776 | if (buflen)
|
||
777 | buf[i] = 0;
|
||
778 | for (; i < maxlen; i++)
|
||
779 | if (!avio_r8(s))
|
||
780 | return i + 1; |
||
781 | return maxlen;
|
||
782 | } |
||
783 | |||
784 | 93b78d12 | Anton Khirnov | #define GET_STR16(type, read) \
|
785 | ae628ec1 | Anton Khirnov | int avio_get_str16 ##type(AVIOContext *pb, int maxlen, char *buf, int buflen)\ |
786 | 93b78d12 | Anton Khirnov | {\ |
787 | char* q = buf;\
|
||
788 | int ret = 0;\ |
||
789 | while (ret + 1 < maxlen) {\ |
||
790 | uint8_t tmp;\ |
||
791 | uint32_t ch;\ |
||
792 | GET_UTF16(ch, (ret += 2) <= maxlen ? read(pb) : 0, break;)\ |
||
793 | if (!ch)\
|
||
794 | break;\
|
||
795 | PUT_UTF8(ch, tmp, if (q - buf < buflen - 1) *q++ = tmp;)\ |
||
796 | }\ |
||
797 | *q = 0;\
|
||
798 | return ret;\
|
||
799 | }\ |
||
800 | |||
801 | b7effd4e | Anton Khirnov | GET_STR16(le, avio_rl16) |
802 | GET_STR16(be, avio_rb16) |
||
803 | 93b78d12 | Anton Khirnov | |
804 | #undef GET_STR16
|
||
805 | |||
806 | b7effd4e | Anton Khirnov | uint64_t avio_rb64(AVIOContext *s) |
807 | de6d9b64 | Fabrice Bellard | { |
808 | 0c1a9eda | Zdenek Kabelac | uint64_t val; |
809 | b7effd4e | Anton Khirnov | val = (uint64_t)avio_rb32(s) << 32;
|
810 | val |= (uint64_t)avio_rb32(s); |
||
811 | de6d9b64 | Fabrice Bellard | return val;
|
812 | } |
||
813 | |||
814 | 4839c192 | Anton Khirnov | uint64_t ffio_read_varlen(AVIOContext *bc){ |
815 | 897d3eef | Kostya Shishkov | uint64_t val = 0;
|
816 | int tmp;
|
||
817 | |||
818 | do{
|
||
819 | b7effd4e | Anton Khirnov | tmp = avio_r8(bc); |
820 | 897d3eef | Kostya Shishkov | val= (val<<7) + (tmp&127); |
821 | }while(tmp&128); |
||
822 | return val;
|
||
823 | } |
||
824 | |||
825 | 724f6a0f | Anton Khirnov | int ffio_fdopen(AVIOContext **s, URLContext *h)
|
826 | de6d9b64 | Fabrice Bellard | { |
827 | 0c1a9eda | Zdenek Kabelac | uint8_t *buffer; |
828 | abba3dd1 | Fabrice Bellard | int buffer_size, max_packet_size;
|
829 | de6d9b64 | Fabrice Bellard | |
830 | abba3dd1 | Fabrice Bellard | max_packet_size = url_get_max_packet_size(h); |
831 | if (max_packet_size) {
|
||
832 | buffer_size = max_packet_size; /* no need to bufferize more than one packet */
|
||
833 | } else {
|
||
834 | buffer_size = IO_BUFFER_SIZE; |
||
835 | } |
||
836 | 1ea4f593 | Fabrice Bellard | buffer = av_malloc(buffer_size); |
837 | de6d9b64 | Fabrice Bellard | if (!buffer)
|
838 | 8fa36ae0 | François Revol | return AVERROR(ENOMEM);
|
839 | de6d9b64 | Fabrice Bellard | |
840 | ae628ec1 | Anton Khirnov | *s = av_mallocz(sizeof(AVIOContext));
|
841 | 899681cd | Björn Axelsson | if(!*s) {
|
842 | av_free(buffer); |
||
843 | return AVERROR(ENOMEM);
|
||
844 | } |
||
845 | |||
846 | e731b8d8 | Anton Khirnov | if (ffio_init_context(*s, buffer, buffer_size,
|
847 | ac9fe33d | Gildas Bazin | (h->flags & URL_WRONLY || h->flags & URL_RDWR), h, |
848 | 004050ee | Michael Niedermayer | url_read, url_write, url_seek) < 0) {
|
849 | 1ea4f593 | Fabrice Bellard | av_free(buffer); |
850 | 899681cd | Björn Axelsson | av_freep(s); |
851 | 6f3e0b21 | Panagiotis Issaris | return AVERROR(EIO);
|
852 | de6d9b64 | Fabrice Bellard | } |
853 | 8978feda | Anton Khirnov | #if FF_API_OLD_AVIO
|
854 | 899681cd | Björn Axelsson | (*s)->is_streamed = h->is_streamed; |
855 | 8978feda | Anton Khirnov | #endif
|
856 | (*s)->seekable = h->is_streamed ? 0 : AVIO_SEEKABLE_NORMAL;
|
||
857 | 899681cd | Björn Axelsson | (*s)->max_packet_size = max_packet_size; |
858 | e7e4810a | Björn Axelsson | if(h->prot) {
|
859 | 502bdf68 | Michael Niedermayer | (*s)->read_pause = (int (*)(void *, int))h->prot->url_read_pause; |
860 | bc5c918e | Diego Biurrun | (*s)->read_seek = (int64_t (*)(void *, int, int64_t, int))h->prot->url_read_seek; |
861 | e7e4810a | Björn Axelsson | } |
862 | de6d9b64 | Fabrice Bellard | return 0; |
863 | } |
||
864 | |||
865 | 59f65d95 | Anton Khirnov | int ffio_set_buf_size(AVIOContext *s, int buf_size) |
866 | de6d9b64 | Fabrice Bellard | { |
867 | 0c1a9eda | Zdenek Kabelac | uint8_t *buffer; |
868 | 1ea4f593 | Fabrice Bellard | buffer = av_malloc(buf_size); |
869 | de6d9b64 | Fabrice Bellard | if (!buffer)
|
870 | 8fa36ae0 | François Revol | return AVERROR(ENOMEM);
|
871 | de6d9b64 | Fabrice Bellard | |
872 | 1ea4f593 | Fabrice Bellard | av_free(s->buffer); |
873 | de6d9b64 | Fabrice Bellard | s->buffer = buffer; |
874 | s->buffer_size = buf_size; |
||
875 | s->buf_ptr = buffer; |
||
876 | 770d9daf | Björn Axelsson | url_resetbuf(s, s->write_flag ? URL_WRONLY : URL_RDONLY); |
877 | return 0; |
||
878 | } |
||
879 | |||
880 | 364cacc7 | Aurelien Jacobs | #if FF_API_URL_RESETBUF
|
881 | ae628ec1 | Anton Khirnov | int url_resetbuf(AVIOContext *s, int flags) |
882 | 08580cb0 | Benoit Fouet | #else
|
883 | ae628ec1 | Anton Khirnov | static int url_resetbuf(AVIOContext *s, int flags) |
884 | 08580cb0 | Benoit Fouet | #endif
|
885 | 770d9daf | Björn Axelsson | { |
886 | 364cacc7 | Aurelien Jacobs | #if FF_API_URL_RESETBUF
|
887 | 6fa197e2 | Eli Friedman | if (flags & URL_RDWR)
|
888 | 770d9daf | Björn Axelsson | return AVERROR(EINVAL);
|
889 | 08580cb0 | Benoit Fouet | #else
|
890 | assert(flags == URL_WRONLY || flags == URL_RDONLY); |
||
891 | #endif
|
||
892 | 770d9daf | Björn Axelsson | |
893 | if (flags & URL_WRONLY) {
|
||
894 | s->buf_end = s->buffer + s->buffer_size; |
||
895 | s->write_flag = 1;
|
||
896 | } else {
|
||
897 | s->buf_end = s->buffer; |
||
898 | s->write_flag = 0;
|
||
899 | } |
||
900 | de6d9b64 | Fabrice Bellard | return 0; |
901 | } |
||
902 | |||
903 | f1ef2cd9 | Anton Khirnov | int ffio_rewind_with_probe_data(AVIOContext *s, unsigned char *buf, int buf_size) |
904 | 01d91b9b | Tomas Härdin | { |
905 | int64_t buffer_start; |
||
906 | int buffer_size;
|
||
907 | 496c645d | Martin Storsjö | int overlap, new_size, alloc_size;
|
908 | 01d91b9b | Tomas Härdin | |
909 | if (s->write_flag)
|
||
910 | return AVERROR(EINVAL);
|
||
911 | |||
912 | buffer_size = s->buf_end - s->buffer; |
||
913 | |||
914 | /* the buffers must touch or overlap */
|
||
915 | if ((buffer_start = s->pos - buffer_size) > buf_size)
|
||
916 | return AVERROR(EINVAL);
|
||
917 | |||
918 | overlap = buf_size - buffer_start; |
||
919 | new_size = buf_size + buffer_size - overlap; |
||
920 | |||
921 | 496c645d | Martin Storsjö | alloc_size = FFMAX(s->buffer_size, new_size); |
922 | if (alloc_size > buf_size)
|
||
923 | if (!(buf = av_realloc(buf, alloc_size)))
|
||
924 | 01d91b9b | Tomas Härdin | return AVERROR(ENOMEM);
|
925 | |||
926 | 496c645d | Martin Storsjö | if (new_size > buf_size) {
|
927 | 01d91b9b | Tomas Härdin | memcpy(buf + buf_size, s->buffer + overlap, buffer_size - overlap); |
928 | buf_size = new_size; |
||
929 | } |
||
930 | |||
931 | av_free(s->buffer); |
||
932 | s->buf_ptr = s->buffer = buf; |
||
933 | 496c645d | Martin Storsjö | s->buffer_size = alloc_size; |
934 | s->pos = buf_size; |
||
935 | 01d91b9b | Tomas Härdin | s->buf_end = s->buf_ptr + buf_size; |
936 | s->eof_reached = 0;
|
||
937 | s->must_flush = 0;
|
||
938 | |||
939 | return 0; |
||
940 | } |
||
941 | |||
942 | 22a3212e | Anton Khirnov | int avio_open(AVIOContext **s, const char *filename, int flags) |
943 | de6d9b64 | Fabrice Bellard | { |
944 | URLContext *h; |
||
945 | int err;
|
||
946 | |||
947 | err = url_open(&h, filename, flags); |
||
948 | if (err < 0) |
||
949 | return err;
|
||
950 | 724f6a0f | Anton Khirnov | err = ffio_fdopen(s, h); |
951 | de6d9b64 | Fabrice Bellard | if (err < 0) { |
952 | url_close(h); |
||
953 | return err;
|
||
954 | } |
||
955 | return 0; |
||
956 | } |
||
957 | |||
958 | 22a3212e | Anton Khirnov | int avio_close(AVIOContext *s)
|
959 | de6d9b64 | Fabrice Bellard | { |
960 | URLContext *h = s->opaque; |
||
961 | 115329f1 | Diego Biurrun | |
962 | 1ea4f593 | Fabrice Bellard | av_free(s->buffer); |
963 | 899681cd | Björn Axelsson | av_free(s); |
964 | de6d9b64 | Fabrice Bellard | return url_close(h);
|
965 | } |
||
966 | |||
967 | 8d9769a7 | Anton Khirnov | #if FF_API_OLD_AVIO
|
968 | ae628ec1 | Anton Khirnov | URLContext *url_fileno(AVIOContext *s) |
969 | de6d9b64 | Fabrice Bellard | { |
970 | return s->opaque;
|
||
971 | } |
||
972 | 8d9769a7 | Anton Khirnov | #endif
|
973 | de6d9b64 | Fabrice Bellard | |
974 | d9d86e00 | Anton Khirnov | int avio_printf(AVIOContext *s, const char *fmt, ...) |
975 | abba3dd1 | Fabrice Bellard | { |
976 | va_list ap; |
||
977 | char buf[4096]; |
||
978 | int ret;
|
||
979 | |||
980 | va_start(ap, fmt); |
||
981 | ret = vsnprintf(buf, sizeof(buf), fmt, ap);
|
||
982 | va_end(ap); |
||
983 | 77eb5504 | Anton Khirnov | avio_write(s, buf, strlen(buf)); |
984 | abba3dd1 | Fabrice Bellard | return ret;
|
985 | } |
||
986 | |||
987 | 655e45e7 | Anton Khirnov | #if FF_API_OLD_AVIO
|
988 | ae628ec1 | Anton Khirnov | char *url_fgets(AVIOContext *s, char *buf, int buf_size) |
989 | abba3dd1 | Fabrice Bellard | { |
990 | int c;
|
||
991 | char *q;
|
||
992 | |||
993 | e5197539 | Anton Khirnov | c = avio_r8(s); |
994 | 66e5b1df | Anton Khirnov | if (s->eof_reached)
|
995 | abba3dd1 | Fabrice Bellard | return NULL; |
996 | q = buf; |
||
997 | for(;;) {
|
||
998 | 66e5b1df | Anton Khirnov | if (s->eof_reached || c == '\n') |
999 | abba3dd1 | Fabrice Bellard | break;
|
1000 | if ((q - buf) < buf_size - 1) |
||
1001 | *q++ = c; |
||
1002 | e5197539 | Anton Khirnov | c = avio_r8(s); |
1003 | abba3dd1 | Fabrice Bellard | } |
1004 | if (buf_size > 0) |
||
1005 | *q = '\0';
|
||
1006 | return buf;
|
||
1007 | } |
||
1008 | |||
1009 | ae628ec1 | Anton Khirnov | int url_fget_max_packet_size(AVIOContext *s)
|
1010 | abba3dd1 | Fabrice Bellard | { |
1011 | return s->max_packet_size;
|
||
1012 | } |
||
1013 | e8bb2e24 | Anton Khirnov | #endif
|
1014 | abba3dd1 | Fabrice Bellard | |
1015 | 933e90a6 | Anton Khirnov | int ffio_read_pause(AVIOContext *s, int pause) |
1016 | e7e4810a | Björn Axelsson | { |
1017 | if (!s->read_pause)
|
||
1018 | return AVERROR(ENOSYS);
|
||
1019 | 502bdf68 | Michael Niedermayer | return s->read_pause(s->opaque, pause);
|
1020 | e7e4810a | Björn Axelsson | } |
1021 | |||
1022 | 933e90a6 | Anton Khirnov | int64_t ffio_read_seek(AVIOContext *s, int stream_index,
|
1023 | int64_t timestamp, int flags)
|
||
1024 | e7e4810a | Björn Axelsson | { |
1025 | URLContext *h = s->opaque; |
||
1026 | bc5c918e | Diego Biurrun | int64_t ret; |
1027 | e7e4810a | Björn Axelsson | if (!s->read_seek)
|
1028 | return AVERROR(ENOSYS);
|
||
1029 | ret = s->read_seek(h, stream_index, timestamp, flags); |
||
1030 | if(ret >= 0) { |
||
1031 | c007c687 | Howard Chu | int64_t pos; |
1032 | e7e4810a | Björn Axelsson | s->buf_ptr = s->buf_end; // Flush buffer
|
1033 | c007c687 | Howard Chu | pos = s->seek(h, 0, SEEK_CUR);
|
1034 | if (pos >= 0) |
||
1035 | s->pos = pos; |
||
1036 | else if (pos != AVERROR(ENOSYS)) |
||
1037 | ret = pos; |
||
1038 | e7e4810a | Björn Axelsson | } |
1039 | return ret;
|
||
1040 | } |
||
1041 | |||
1042 | 6dc7d80d | Anton Khirnov | /* avio_open_dyn_buf and avio_close_dyn_buf are used in rtp.c to send a response
|
1043 | b250f9c6 | Aurelien Jacobs | * back to the server even if CONFIG_MUXERS is false. */
|
1044 | #if CONFIG_MUXERS || CONFIG_NETWORK
|
||
1045 | de6d9b64 | Fabrice Bellard | /* buffer handling */
|
1046 | 83fddaeb | Anton Khirnov | #if FF_API_OLD_AVIO
|
1047 | ae628ec1 | Anton Khirnov | int url_open_buf(AVIOContext **s, uint8_t *buf, int buf_size, int flags) |
1048 | de6d9b64 | Fabrice Bellard | { |
1049 | 899681cd | Björn Axelsson | int ret;
|
1050 | ae628ec1 | Anton Khirnov | *s = av_mallocz(sizeof(AVIOContext));
|
1051 | 899681cd | Björn Axelsson | if(!*s)
|
1052 | return AVERROR(ENOMEM);
|
||
1053 | e731b8d8 | Anton Khirnov | ret = ffio_init_context(*s, buf, buf_size, |
1054 | 899681cd | Björn Axelsson | (flags & URL_WRONLY || flags & URL_RDWR), |
1055 | NULL, NULL, NULL, NULL); |
||
1056 | if(ret != 0) |
||
1057 | av_freep(s); |
||
1058 | return ret;
|
||
1059 | de6d9b64 | Fabrice Bellard | } |
1060 | |||
1061 | ae628ec1 | Anton Khirnov | int url_close_buf(AVIOContext *s)
|
1062 | de6d9b64 | Fabrice Bellard | { |
1063 | b7f2fdde | Anton Khirnov | avio_flush(s); |
1064 | de6d9b64 | Fabrice Bellard | return s->buf_ptr - s->buffer;
|
1065 | } |
||
1066 | 35f10235 | Anton Khirnov | #endif
|
1067 | abba3dd1 | Fabrice Bellard | |
1068 | /* output in a dynamic buffer */
|
||
1069 | |||
1070 | typedef struct DynBuffer { |
||
1071 | int pos, size, allocated_size;
|
||
1072 | 0c1a9eda | Zdenek Kabelac | uint8_t *buffer; |
1073 | abba3dd1 | Fabrice Bellard | int io_buffer_size;
|
1074 | 0c1a9eda | Zdenek Kabelac | uint8_t io_buffer[1];
|
1075 | abba3dd1 | Fabrice Bellard | } DynBuffer; |
1076 | |||
1077 | 576ae256 | Michael Niedermayer | static int dyn_buf_write(void *opaque, uint8_t *buf, int buf_size) |
1078 | abba3dd1 | Fabrice Bellard | { |
1079 | DynBuffer *d = opaque; |
||
1080 | 6bc03a69 | Reimar Döffinger | unsigned new_size, new_allocated_size;
|
1081 | 115329f1 | Diego Biurrun | |
1082 | abba3dd1 | Fabrice Bellard | /* reallocate buffer if needed */
|
1083 | new_size = d->pos + buf_size; |
||
1084 | new_allocated_size = d->allocated_size; |
||
1085 | 568e18b1 | Michael Niedermayer | if(new_size < d->pos || new_size > INT_MAX/2) |
1086 | return -1; |
||
1087 | abba3dd1 | Fabrice Bellard | while (new_size > new_allocated_size) {
|
1088 | if (!new_allocated_size)
|
||
1089 | new_allocated_size = new_size; |
||
1090 | else
|
||
1091 | 115329f1 | Diego Biurrun | new_allocated_size += new_allocated_size / 2 + 1; |
1092 | abba3dd1 | Fabrice Bellard | } |
1093 | 115329f1 | Diego Biurrun | |
1094 | abba3dd1 | Fabrice Bellard | if (new_allocated_size > d->allocated_size) {
|
1095 | b88ba823 | Mark Hills | d->buffer = av_realloc(d->buffer, new_allocated_size); |
1096 | if(d->buffer == NULL) |
||
1097 | 7ce820ef | Reimar Döffinger | return AVERROR(ENOMEM);
|
1098 | abba3dd1 | Fabrice Bellard | d->allocated_size = new_allocated_size; |
1099 | } |
||
1100 | memcpy(d->buffer + d->pos, buf, buf_size); |
||
1101 | d->pos = new_size; |
||
1102 | if (d->pos > d->size)
|
||
1103 | d->size = d->pos; |
||
1104 | 576ae256 | Michael Niedermayer | return buf_size;
|
1105 | abba3dd1 | Fabrice Bellard | } |
1106 | |||
1107 | 576ae256 | Michael Niedermayer | static int dyn_packet_buf_write(void *opaque, uint8_t *buf, int buf_size) |
1108 | abba3dd1 | Fabrice Bellard | { |
1109 | unsigned char buf1[4]; |
||
1110 | 576ae256 | Michael Niedermayer | int ret;
|
1111 | abba3dd1 | Fabrice Bellard | |
1112 | /* packetized write: output the header */
|
||
1113 | aa805f94 | Reimar Döffinger | AV_WB32(buf1, buf_size); |
1114 | 576ae256 | Michael Niedermayer | ret= dyn_buf_write(opaque, buf1, 4);
|
1115 | if(ret < 0) |
||
1116 | return ret;
|
||
1117 | abba3dd1 | Fabrice Bellard | |
1118 | /* then the data */
|
||
1119 | 576ae256 | Michael Niedermayer | return dyn_buf_write(opaque, buf, buf_size);
|
1120 | abba3dd1 | Fabrice Bellard | } |
1121 | |||
1122 | bc5c918e | Diego Biurrun | static int64_t dyn_buf_seek(void *opaque, int64_t offset, int whence) |
1123 | abba3dd1 | Fabrice Bellard | { |
1124 | DynBuffer *d = opaque; |
||
1125 | |||
1126 | if (whence == SEEK_CUR)
|
||
1127 | offset += d->pos; |
||
1128 | else if (whence == SEEK_END) |
||
1129 | offset += d->size; |
||
1130 | if (offset < 0 || offset > 0x7fffffffLL) |
||
1131 | return -1; |
||
1132 | d->pos = offset; |
||
1133 | return 0; |
||
1134 | } |
||
1135 | |||
1136 | ae628ec1 | Anton Khirnov | static int url_open_dyn_buf_internal(AVIOContext **s, int max_packet_size) |
1137 | abba3dd1 | Fabrice Bellard | { |
1138 | DynBuffer *d; |
||
1139 | 0c5a43d6 | Reimar Döffinger | unsigned io_buffer_size = max_packet_size ? max_packet_size : 1024; |
1140 | 115329f1 | Diego Biurrun | |
1141 | 568e18b1 | Michael Niedermayer | if(sizeof(DynBuffer) + io_buffer_size < io_buffer_size) |
1142 | return -1; |
||
1143 | dc2c2eea | Reimar Döffinger | d = av_mallocz(sizeof(DynBuffer) + io_buffer_size);
|
1144 | abba3dd1 | Fabrice Bellard | if (!d)
|
1145 | 0e7ceb24 | Reimar Döffinger | return AVERROR(ENOMEM);
|
1146 | 8bea72f7 | Anton Khirnov | d->io_buffer_size = io_buffer_size; |
1147 | *s = avio_alloc_context(d->io_buffer, d->io_buffer_size, 1, d, NULL, |
||
1148 | max_packet_size ? dyn_packet_buf_write : dyn_buf_write, |
||
1149 | max_packet_size ? NULL : dyn_buf_seek);
|
||
1150 | 899681cd | Björn Axelsson | if(!*s) {
|
1151 | av_free(d); |
||
1152 | return AVERROR(ENOMEM);
|
||
1153 | } |
||
1154 | 8bea72f7 | Anton Khirnov | (*s)->max_packet_size = max_packet_size; |
1155 | return 0; |
||
1156 | abba3dd1 | Fabrice Bellard | } |
1157 | |||
1158 | b92c5452 | Anton Khirnov | int avio_open_dyn_buf(AVIOContext **s)
|
1159 | abba3dd1 | Fabrice Bellard | { |
1160 | return url_open_dyn_buf_internal(s, 0); |
||
1161 | } |
||
1162 | |||
1163 | 403ee835 | Anton Khirnov | int ffio_open_dyn_packet_buf(AVIOContext **s, int max_packet_size) |
1164 | abba3dd1 | Fabrice Bellard | { |
1165 | if (max_packet_size <= 0) |
||
1166 | return -1; |
||
1167 | return url_open_dyn_buf_internal(s, max_packet_size);
|
||
1168 | } |
||
1169 | |||
1170 | 6dc7d80d | Anton Khirnov | int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
|
1171 | abba3dd1 | Fabrice Bellard | { |
1172 | DynBuffer *d = s->opaque; |
||
1173 | int size;
|
||
1174 | de1807bb | Josh Allmann | static const char padbuf[FF_INPUT_BUFFER_PADDING_SIZE] = {0}; |
1175 | int padding = 0; |
||
1176 | |||
1177 | /* don't attempt to pad fixed-size packet buffers */
|
||
1178 | if (!s->max_packet_size) {
|
||
1179 | 77eb5504 | Anton Khirnov | avio_write(s, padbuf, sizeof(padbuf));
|
1180 | de1807bb | Josh Allmann | padding = FF_INPUT_BUFFER_PADDING_SIZE; |
1181 | } |
||
1182 | abba3dd1 | Fabrice Bellard | |
1183 | b7f2fdde | Anton Khirnov | avio_flush(s); |
1184 | abba3dd1 | Fabrice Bellard | |
1185 | *pbuffer = d->buffer; |
||
1186 | size = d->size; |
||
1187 | av_free(d); |
||
1188 | 899681cd | Björn Axelsson | av_free(s); |
1189 | de1807bb | Josh Allmann | return size - padding;
|
1190 | abba3dd1 | Fabrice Bellard | } |
1191 | 8fa641f8 | Loïc Le Loarer | #endif /* CONFIG_MUXERS || CONFIG_NETWORK */ |