5cb733d3d8ac44a62e665dc66752b6652c9ab2fb
[libav.git] / libavformat / aviobuf.c
1 /*
2 * buffered I/O
3 * Copyright (c) 2000,2001 Fabrice Bellard
4 *
5 * This file is part of Libav.
6 *
7 * Libav 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.
11 *
12 * Libav 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.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with Libav; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #include "libavutil/crc.h"
23 #include "libavutil/dict.h"
24 #include "libavutil/intreadwrite.h"
25 #include "libavutil/log.h"
26 #include "libavutil/opt.h"
27 #include "avformat.h"
28 #include "avio.h"
29 #include "avio_internal.h"
30 #include "internal.h"
31 #include "url.h"
32 #include <stdarg.h>
33
34 #define IO_BUFFER_SIZE 32768
35
36 /**
37 * Do seeks within this distance ahead of the current buffer by skipping
38 * data instead of calling the protocol seek function, for seekable
39 * protocols.
40 */
41 #define SHORT_SEEK_THRESHOLD 4096
42
43 typedef struct AVIOInternal {
44 const AVClass *class;
45
46 char *protocol_whitelist;
47 char *protocol_blacklist;
48
49 URLContext *h;
50 const URLProtocol **protocols;
51 } AVIOInternal;
52
53 static void *io_priv_child_next(void *obj, void *prev)
54 {
55 AVIOInternal *internal = obj;
56 return prev ? NULL : internal->h;
57 }
58
59 static const AVClass *io_priv_child_class_next(const AVClass *prev)
60 {
61 return prev ? NULL : &ffurl_context_class;
62 }
63
64 #define OFFSET(x) offsetof(AVIOInternal, x)
65 static const AVOption io_priv_options[] = {
66 { "protocol_whitelist", "A comma-separated list of allowed protocols",
67 OFFSET(protocol_whitelist), AV_OPT_TYPE_STRING },
68 { "protocol_blacklist", "A comma-separated list of forbidden protocols",
69 OFFSET(protocol_whitelist), AV_OPT_TYPE_STRING },
70 { NULL },
71 };
72
73 static const AVClass io_priv_class = {
74 .class_name = "AVIOContext",
75 .item_name = av_default_item_name,
76 .version = LIBAVUTIL_VERSION_INT,
77 .option = io_priv_options,
78 .child_next = io_priv_child_next,
79 .child_class_next = io_priv_child_class_next,
80 };
81
82 static void *ff_avio_child_next(void *obj, void *prev)
83 {
84 AVIOContext *s = obj;
85 return prev ? NULL : s->opaque;
86 }
87
88 static const AVClass *ff_avio_child_class_next(const AVClass *prev)
89 {
90 return prev ? NULL : &io_priv_class;
91 }
92
93 static const AVOption ff_avio_options[] = {
94 { NULL },
95 };
96
97 const AVClass ff_avio_class = {
98 .class_name = "AVIOContext",
99 .item_name = av_default_item_name,
100 .version = LIBAVUTIL_VERSION_INT,
101 .option = ff_avio_options,
102 .child_next = ff_avio_child_next,
103 .child_class_next = ff_avio_child_class_next,
104 };
105
106 static void fill_buffer(AVIOContext *s);
107 static int url_resetbuf(AVIOContext *s, int flags);
108
109 int ffio_init_context(AVIOContext *s,
110 unsigned char *buffer,
111 int buffer_size,
112 int write_flag,
113 void *opaque,
114 int (*read_packet)(void *opaque, uint8_t *buf, int buf_size),
115 int (*write_packet)(void *opaque, uint8_t *buf, int buf_size),
116 int64_t (*seek)(void *opaque, int64_t offset, int whence))
117 {
118 s->buffer = buffer;
119 s->buffer_size = buffer_size;
120 s->buf_ptr = buffer;
121 s->opaque = opaque;
122
123 url_resetbuf(s, write_flag ? AVIO_FLAG_WRITE : AVIO_FLAG_READ);
124
125 s->write_packet = write_packet;
126 s->read_packet = read_packet;
127 s->seek = seek;
128 s->pos = 0;
129 s->must_flush = 0;
130 s->eof_reached = 0;
131 s->error = 0;
132 s->seekable = seek ? AVIO_SEEKABLE_NORMAL : 0;
133 s->max_packet_size = 0;
134 s->update_checksum = NULL;
135
136 if (!read_packet && !write_flag) {
137 s->pos = buffer_size;
138 s->buf_end = s->buffer + buffer_size;
139 }
140 s->read_pause = NULL;
141 s->read_seek = NULL;
142
143 s->write_data_type = NULL;
144 s->ignore_boundary_point = 0;
145 s->current_type = AVIO_DATA_MARKER_UNKNOWN;
146 s->last_time = AV_NOPTS_VALUE;
147
148 return 0;
149 }
150
151 AVIOContext *avio_alloc_context(
152 unsigned char *buffer,
153 int buffer_size,
154 int write_flag,
155 void *opaque,
156 int (*read_packet)(void *opaque, uint8_t *buf, int buf_size),
157 int (*write_packet)(void *opaque, uint8_t *buf, int buf_size),
158 int64_t (*seek)(void *opaque, int64_t offset, int whence))
159 {
160 AVIOContext *s = av_mallocz(sizeof(AVIOContext));
161 if (!s)
162 return NULL;
163 ffio_init_context(s, buffer, buffer_size, write_flag, opaque,
164 read_packet, write_packet, seek);
165 return s;
166 }
167
168 static void flush_buffer(AVIOContext *s)
169 {
170 if (s->buf_ptr > s->buffer) {
171 if (!s->error) {
172 int ret = 0;
173 if (s->write_data_type)
174 ret = s->write_data_type(s->opaque, s->buffer,
175 s->buf_ptr - s->buffer,
176 s->current_type,
177 s->last_time);
178 else if (s->write_packet)
179 ret = s->write_packet(s->opaque, s->buffer,
180 s->buf_ptr - s->buffer);
181 if (ret < 0) {
182 s->error = ret;
183 }
184 }
185 if (s->current_type == AVIO_DATA_MARKER_SYNC_POINT ||
186 s->current_type == AVIO_DATA_MARKER_BOUNDARY_POINT) {
187 s->current_type = AVIO_DATA_MARKER_UNKNOWN;
188 }
189 s->last_time = AV_NOPTS_VALUE;
190 if (s->update_checksum) {
191 s->checksum = s->update_checksum(s->checksum, s->checksum_ptr,
192 s->buf_ptr - s->checksum_ptr);
193 s->checksum_ptr = s->buffer;
194 }
195 s->pos += s->buf_ptr - s->buffer;
196 }
197 s->buf_ptr = s->buffer;
198 }
199
200 void avio_w8(AVIOContext *s, int b)
201 {
202 *s->buf_ptr++ = b;
203 if (s->buf_ptr >= s->buf_end)
204 flush_buffer(s);
205 }
206
207 void ffio_fill(AVIOContext *s, int b, int count)
208 {
209 while (count > 0) {
210 int len = FFMIN(s->buf_end - s->buf_ptr, count);
211 memset(s->buf_ptr, b, len);
212 s->buf_ptr += len;
213
214 if (s->buf_ptr >= s->buf_end)
215 flush_buffer(s);
216
217 count -= len;
218 }
219 }
220
221 void avio_write(AVIOContext *s, const unsigned char *buf, int size)
222 {
223 while (size > 0) {
224 int len = FFMIN(s->buf_end - s->buf_ptr, size);
225 memcpy(s->buf_ptr, buf, len);
226 s->buf_ptr += len;
227
228 if (s->buf_ptr >= s->buf_end)
229 flush_buffer(s);
230
231 buf += len;
232 size -= len;
233 }
234 }
235
236 void avio_flush(AVIOContext *s)
237 {
238 flush_buffer(s);
239 s->must_flush = 0;
240 }
241
242 int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
243 {
244 int64_t offset1;
245 int64_t pos;
246 int force = whence & AVSEEK_FORCE;
247 whence &= ~AVSEEK_FORCE;
248
249 if(!s)
250 return AVERROR(EINVAL);
251
252 pos = s->pos - (s->write_flag ? 0 : (s->buf_end - s->buffer));
253
254 if (whence != SEEK_CUR && whence != SEEK_SET)
255 return AVERROR(EINVAL);
256
257 if (whence == SEEK_CUR) {
258 offset1 = pos + (s->buf_ptr - s->buffer);
259 if (offset == 0)
260 return offset1;
261 offset += offset1;
262 }
263 offset1 = offset - pos;
264 if (!s->must_flush &&
265 offset1 >= 0 && offset1 < (s->buf_end - s->buffer)) {
266 /* can do the seek inside the buffer */
267 s->buf_ptr = s->buffer + offset1;
268 } else if ((!(s->seekable & AVIO_SEEKABLE_NORMAL) ||
269 offset1 <= s->buf_end + SHORT_SEEK_THRESHOLD - s->buffer) &&
270 !s->write_flag && offset1 >= 0 &&
271 (whence != SEEK_END || force)) {
272 while(s->pos < offset && !s->eof_reached)
273 fill_buffer(s);
274 if (s->eof_reached)
275 return AVERROR_EOF;
276 s->buf_ptr = s->buf_end + offset - s->pos;
277 } else {
278 int64_t res;
279
280 if (s->write_flag) {
281 flush_buffer(s);
282 s->must_flush = 1;
283 }
284 if (!s->seek)
285 return AVERROR(EPIPE);
286 if ((res = s->seek(s->opaque, offset, SEEK_SET)) < 0)
287 return res;
288 if (!s->write_flag)
289 s->buf_end = s->buffer;
290 s->buf_ptr = s->buffer;
291 s->pos = offset;
292 }
293 s->eof_reached = 0;
294 return offset;
295 }
296
297 int64_t avio_size(AVIOContext *s)
298 {
299 int64_t size;
300
301 if (!s)
302 return AVERROR(EINVAL);
303
304 if (!s->seek)
305 return AVERROR(ENOSYS);
306 size = s->seek(s->opaque, 0, AVSEEK_SIZE);
307 if (size < 0) {
308 if ((size = s->seek(s->opaque, -1, SEEK_END)) < 0)
309 return size;
310 size++;
311 s->seek(s->opaque, s->pos, SEEK_SET);
312 }
313 return size;
314 }
315
316 void avio_wl32(AVIOContext *s, unsigned int val)
317 {
318 avio_w8(s, val);
319 avio_w8(s, val >> 8);
320 avio_w8(s, val >> 16);
321 avio_w8(s, val >> 24);
322 }
323
324 void avio_wb32(AVIOContext *s, unsigned int val)
325 {
326 avio_w8(s, val >> 24);
327 avio_w8(s, val >> 16);
328 avio_w8(s, val >> 8);
329 avio_w8(s, val);
330 }
331
332 int avio_put_str(AVIOContext *s, const char *str)
333 {
334 int len = 1;
335 if (str) {
336 len += strlen(str);
337 avio_write(s, (const unsigned char *) str, len);
338 } else
339 avio_w8(s, 0);
340 return len;
341 }
342
343 #define PUT_STR16(type, write) \
344 int avio_put_str16 ## type(AVIOContext * s, const char *str) \
345 { \
346 const uint8_t *q = str; \
347 int ret = 0; \
348 \
349 while (*q) { \
350 uint32_t ch; \
351 uint16_t tmp; \
352 \
353 GET_UTF8(ch, *q++, break; ) \
354 PUT_UTF16(ch, tmp, write(s, tmp); ret += 2; ) \
355 } \
356 write(s, 0); \
357 ret += 2; \
358 return ret; \
359 }
360
361 PUT_STR16(le, avio_wl16)
362 PUT_STR16(be, avio_wb16)
363
364 #undef PUT_STR16
365
366 int ff_get_v_length(uint64_t val)
367 {
368 int i = 1;
369
370 while (val >>= 7)
371 i++;
372
373 return i;
374 }
375
376 void ff_put_v(AVIOContext *bc, uint64_t val)
377 {
378 int i = ff_get_v_length(val);
379
380 while (--i > 0)
381 avio_w8(bc, 128 | (val >> (7 * i)));
382
383 avio_w8(bc, val & 127);
384 }
385
386 void avio_wl64(AVIOContext *s, uint64_t val)
387 {
388 avio_wl32(s, (uint32_t)(val & 0xffffffff));
389 avio_wl32(s, (uint32_t)(val >> 32));
390 }
391
392 void avio_wb64(AVIOContext *s, uint64_t val)
393 {
394 avio_wb32(s, (uint32_t)(val >> 32));
395 avio_wb32(s, (uint32_t)(val & 0xffffffff));
396 }
397
398 void avio_wl16(AVIOContext *s, unsigned int val)
399 {
400 avio_w8(s, val);
401 avio_w8(s, val >> 8);
402 }
403
404 void avio_wb16(AVIOContext *s, unsigned int val)
405 {
406 avio_w8(s, val >> 8);
407 avio_w8(s, val);
408 }
409
410 void avio_wl24(AVIOContext *s, unsigned int val)
411 {
412 avio_wl16(s, val & 0xffff);
413 avio_w8(s, val >> 16);
414 }
415
416 void avio_wb24(AVIOContext *s, unsigned int val)
417 {
418 avio_wb16(s, val >> 8);
419 avio_w8(s, val);
420 }
421
422 void avio_write_marker(AVIOContext *s, int64_t time, enum AVIODataMarkerType type)
423 {
424 if (!s->write_data_type)
425 return;
426 // If ignoring boundary points, just treat it as unknown
427 if (type == AVIO_DATA_MARKER_BOUNDARY_POINT && s->ignore_boundary_point)
428 type = AVIO_DATA_MARKER_UNKNOWN;
429 // Avoid unnecessary flushes if we are already in non-header/trailer
430 // data and setting the type to unknown
431 if (type == AVIO_DATA_MARKER_UNKNOWN &&
432 (s->current_type != AVIO_DATA_MARKER_HEADER &&
433 s->current_type != AVIO_DATA_MARKER_TRAILER))
434 return;
435
436 switch (type) {
437 case AVIO_DATA_MARKER_HEADER:
438 case AVIO_DATA_MARKER_TRAILER:
439 // For header/trailer, ignore a new marker of the same type;
440 // consecutive header/trailer markers can be merged.
441 if (type == s->current_type)
442 return;
443 break;
444 }
445
446 // If we've reached here, we have a new, noteworthy marker.
447 // Flush the previous data and mark the start of the new data.
448 avio_flush(s);
449 s->current_type = type;
450 s->last_time = time;
451 }
452
453 /* Input stream */
454
455 static void fill_buffer(AVIOContext *s)
456 {
457 uint8_t *dst = !s->max_packet_size &&
458 s->buf_end - s->buffer < s->buffer_size ?
459 s->buf_end : s->buffer;
460 int len = s->buffer_size - (dst - s->buffer);
461 int max_buffer_size = s->max_packet_size ?
462 s->max_packet_size : IO_BUFFER_SIZE;
463
464 /* can't fill the buffer without read_packet, just set EOF if appropriate */
465 if (!s->read_packet && s->buf_ptr >= s->buf_end)
466 s->eof_reached = 1;
467
468 /* no need to do anything if EOF already reached */
469 if (s->eof_reached)
470 return;
471
472 if (s->update_checksum && dst == s->buffer) {
473 if (s->buf_end > s->checksum_ptr)
474 s->checksum = s->update_checksum(s->checksum, s->checksum_ptr,
475 s->buf_end - s->checksum_ptr);
476 s->checksum_ptr = s->buffer;
477 }
478
479 /* make buffer smaller in case it ended up large after probing */
480 if (s->buffer_size > max_buffer_size) {
481 ffio_set_buf_size(s, max_buffer_size);
482
483 s->checksum_ptr = dst = s->buffer;
484 len = s->buffer_size;
485 }
486
487 if (s->read_packet)
488 len = s->read_packet(s->opaque, dst, len);
489 else
490 len = 0;
491 if (len <= 0) {
492 /* do not modify buffer if EOF reached so that a seek back can
493 be done without rereading data */
494 s->eof_reached = 1;
495 if (len < 0)
496 s->error = len;
497 } else {
498 s->pos += len;
499 s->buf_ptr = dst;
500 s->buf_end = dst + len;
501 }
502 }
503
504 unsigned long ff_crc04C11DB7_update(unsigned long checksum, const uint8_t *buf,
505 unsigned int len)
506 {
507 return av_crc(av_crc_get_table(AV_CRC_32_IEEE), checksum, buf, len);
508 }
509
510 unsigned long ff_crcA001_update(unsigned long checksum, const uint8_t *buf,
511 unsigned int len)
512 {
513 return av_crc(av_crc_get_table(AV_CRC_16_ANSI_LE), checksum, buf, len);
514 }
515
516 unsigned long ffio_get_checksum(AVIOContext *s)
517 {
518 s->checksum = s->update_checksum(s->checksum, s->checksum_ptr,
519 s->buf_ptr - s->checksum_ptr);
520 s->update_checksum = NULL;
521 return s->checksum;
522 }
523
524 void ffio_init_checksum(AVIOContext *s,
525 unsigned long (*update_checksum)(unsigned long c, const uint8_t *p, unsigned int len),
526 unsigned long checksum)
527 {
528 s->update_checksum = update_checksum;
529 if (s->update_checksum) {
530 s->checksum = checksum;
531 s->checksum_ptr = s->buf_ptr;
532 }
533 }
534
535 /* XXX: put an inline version */
536 int avio_r8(AVIOContext *s)
537 {
538 if (s->buf_ptr >= s->buf_end)
539 fill_buffer(s);
540 if (s->buf_ptr < s->buf_end)
541 return *s->buf_ptr++;
542 return 0;
543 }
544
545 int avio_read(AVIOContext *s, unsigned char *buf, int size)
546 {
547 int len, size1;
548
549 size1 = size;
550 while (size > 0) {
551 len = s->buf_end - s->buf_ptr;
552 if (len > size)
553 len = size;
554 if (len == 0 || s->write_flag) {
555 if(size > s->buffer_size && !s->update_checksum){
556 if(s->read_packet)
557 len = s->read_packet(s->opaque, buf, size);
558 if (len <= 0) {
559 /* do not modify buffer if EOF reached so that a seek back can
560 be done without rereading data */
561 s->eof_reached = 1;
562 if(len<0)
563 s->error= len;
564 break;
565 } else {
566 s->pos += len;
567 size -= len;
568 buf += len;
569 s->buf_ptr = s->buffer;
570 s->buf_end = s->buffer/* + len*/;
571 }
572 } else {
573 fill_buffer(s);
574 len = s->buf_end - s->buf_ptr;
575 if (len == 0)
576 break;
577 }
578 } else {
579 memcpy(buf, s->buf_ptr, len);
580 buf += len;
581 s->buf_ptr += len;
582 size -= len;
583 }
584 }
585 if (size1 == size) {
586 if (s->error) return s->error;
587 if (s->eof_reached) return AVERROR_EOF;
588 }
589 return size1 - size;
590 }
591
592 int ffio_read_size(AVIOContext *s, unsigned char *buf, int size)
593 {
594 int ret = avio_read(s, buf, size);
595 if (ret != size)
596 return AVERROR_INVALIDDATA;
597 return ret;
598 }
599
600 int ffio_read_indirect(AVIOContext *s, unsigned char *buf, int size, const unsigned char **data)
601 {
602 if (s->buf_end - s->buf_ptr >= size && !s->write_flag) {
603 *data = s->buf_ptr;
604 s->buf_ptr += size;
605 return size;
606 } else {
607 *data = buf;
608 return avio_read(s, buf, size);
609 }
610 }
611
612 int ffio_read_partial(AVIOContext *s, unsigned char *buf, int size)
613 {
614 int len;
615
616 if (size < 0)
617 return -1;
618
619 if (s->read_packet && s->write_flag) {
620 len = s->read_packet(s->opaque, buf, size);
621 if (len > 0)
622 s->pos += len;
623 return len;
624 }
625
626 len = s->buf_end - s->buf_ptr;
627 if (len == 0) {
628 /* Reset the buf_end pointer to the start of the buffer, to make sure
629 * the fill_buffer call tries to read as much data as fits into the
630 * full buffer, instead of just what space is left after buf_end.
631 * This avoids returning partial packets at the end of the buffer,
632 * for packet based inputs.
633 */
634 s->buf_end = s->buf_ptr = s->buffer;
635 fill_buffer(s);
636 len = s->buf_end - s->buf_ptr;
637 }
638 if (len > size)
639 len = size;
640 memcpy(buf, s->buf_ptr, len);
641 s->buf_ptr += len;
642 if (!len) {
643 if (s->error) return s->error;
644 if (s->eof_reached) return AVERROR_EOF;
645 }
646 return len;
647 }
648
649 unsigned int avio_rl16(AVIOContext *s)
650 {
651 unsigned int val;
652 val = avio_r8(s);
653 val |= avio_r8(s) << 8;
654 return val;
655 }
656
657 unsigned int avio_rl24(AVIOContext *s)
658 {
659 unsigned int val;
660 val = avio_rl16(s);
661 val |= avio_r8(s) << 16;
662 return val;
663 }
664
665 unsigned int avio_rl32(AVIOContext *s)
666 {
667 unsigned int val;
668 val = avio_rl16(s);
669 val |= avio_rl16(s) << 16;
670 return val;
671 }
672
673 uint64_t avio_rl64(AVIOContext *s)
674 {
675 uint64_t val;
676 val = (uint64_t)avio_rl32(s);
677 val |= (uint64_t)avio_rl32(s) << 32;
678 return val;
679 }
680
681 unsigned int avio_rb16(AVIOContext *s)
682 {
683 unsigned int val;
684 val = avio_r8(s) << 8;
685 val |= avio_r8(s);
686 return val;
687 }
688
689 unsigned int avio_rb24(AVIOContext *s)
690 {
691 unsigned int val;
692 val = avio_rb16(s) << 8;
693 val |= avio_r8(s);
694 return val;
695 }
696 unsigned int avio_rb32(AVIOContext *s)
697 {
698 unsigned int val;
699 val = avio_rb16(s) << 16;
700 val |= avio_rb16(s);
701 return val;
702 }
703
704 int ff_get_line(AVIOContext *s, char *buf, int maxlen)
705 {
706 int i = 0;
707 char c;
708
709 do {
710 c = avio_r8(s);
711 if (c && i < maxlen-1)
712 buf[i++] = c;
713 } while (c != '\n' && c);
714
715 buf[i] = 0;
716 return i;
717 }
718
719 int avio_get_str(AVIOContext *s, int maxlen, char *buf, int buflen)
720 {
721 int i;
722
723 if (buflen <= 0)
724 return AVERROR(EINVAL);
725 // reserve 1 byte for terminating 0
726 buflen = FFMIN(buflen - 1, maxlen);
727 for (i = 0; i < buflen; i++)
728 if (!(buf[i] = avio_r8(s)))
729 return i + 1;
730 buf[i] = 0;
731 for (; i < maxlen; i++)
732 if (!avio_r8(s))
733 return i + 1;
734 return maxlen;
735 }
736
737 #define GET_STR16(type, read) \
738 int avio_get_str16 ##type(AVIOContext *pb, int maxlen, char *buf, int buflen)\
739 {\
740 char* q = buf;\
741 int ret = 0;\
742 if (buflen <= 0) \
743 return AVERROR(EINVAL); \
744 while (ret + 1 < maxlen) {\
745 uint8_t tmp;\
746 uint32_t ch;\
747 GET_UTF16(ch, (ret += 2) <= maxlen ? read(pb) : 0, break;)\
748 if (!ch)\
749 break;\
750 PUT_UTF8(ch, tmp, if (q - buf < buflen - 1) *q++ = tmp;)\
751 }\
752 *q = 0;\
753 return ret;\
754 }\
755
756 GET_STR16(le, avio_rl16)
757 GET_STR16(be, avio_rb16)
758
759 #undef GET_STR16
760
761 uint64_t avio_rb64(AVIOContext *s)
762 {
763 uint64_t val;
764 val = (uint64_t)avio_rb32(s) << 32;
765 val |= (uint64_t)avio_rb32(s);
766 return val;
767 }
768
769 uint64_t ffio_read_varlen(AVIOContext *bc){
770 uint64_t val = 0;
771 int tmp;
772
773 do{
774 tmp = avio_r8(bc);
775 val= (val<<7) + (tmp&127);
776 }while(tmp&128);
777 return val;
778 }
779
780 static int io_read_packet(void *opaque, uint8_t *buf, int buf_size)
781 {
782 AVIOInternal *internal = opaque;
783 return ffurl_read(internal->h, buf, buf_size);
784 }
785
786 static int io_write_packet(void *opaque, uint8_t *buf, int buf_size)
787 {
788 AVIOInternal *internal = opaque;
789 return ffurl_write(internal->h, buf, buf_size);
790 }
791
792 static int64_t io_seek(void *opaque, int64_t offset, int whence)
793 {
794 AVIOInternal *internal = opaque;
795 return ffurl_seek(internal->h, offset, whence);
796 }
797
798 static int io_read_pause(void *opaque, int pause)
799 {
800 AVIOInternal *internal = opaque;
801 if (!internal->h->prot->url_read_pause)
802 return AVERROR(ENOSYS);
803 return internal->h->prot->url_read_pause(internal->h, pause);
804 }
805
806 static int64_t io_read_seek(void *opaque, int stream_index, int64_t timestamp, int flags)
807 {
808 AVIOInternal *internal = opaque;
809 if (!internal->h->prot->url_read_seek)
810 return AVERROR(ENOSYS);
811 return internal->h->prot->url_read_seek(internal->h, stream_index, timestamp, flags);
812 }
813
814 int ffio_fdopen(AVIOContext **s, URLContext *h)
815 {
816 AVIOInternal *internal = NULL;
817 uint8_t *buffer = NULL;
818 int buffer_size, max_packet_size;
819
820 max_packet_size = h->max_packet_size;
821 if (max_packet_size) {
822 buffer_size = max_packet_size; /* no need to bufferize more than one packet */
823 } else {
824 buffer_size = IO_BUFFER_SIZE;
825 }
826 buffer = av_malloc(buffer_size);
827 if (!buffer)
828 return AVERROR(ENOMEM);
829
830 internal = av_mallocz(sizeof(*internal));
831 if (!internal)
832 goto fail;
833
834 internal->class = &io_priv_class;
835 internal->h = h;
836
837 av_opt_set_defaults(internal);
838
839 *s = avio_alloc_context(buffer, buffer_size, h->flags & AVIO_FLAG_WRITE,
840 internal, io_read_packet, io_write_packet, io_seek);
841 if (!*s)
842 goto fail;
843
844 (*s)->seekable = h->is_streamed ? 0 : AVIO_SEEKABLE_NORMAL;
845 (*s)->max_packet_size = max_packet_size;
846 if(h->prot) {
847 (*s)->read_pause = io_read_pause;
848 (*s)->read_seek = io_read_seek;
849
850 if (h->prot->url_read_seek)
851 (*s)->seekable |= AVIO_SEEKABLE_TIME;
852 }
853 (*s)->av_class = &ff_avio_class;
854 return 0;
855 fail:
856 if (internal)
857 av_opt_free(internal);
858 av_freep(&internal);
859 av_freep(&buffer);
860 return AVERROR(ENOMEM);
861 }
862
863 int ffio_set_buf_size(AVIOContext *s, int buf_size)
864 {
865 uint8_t *buffer;
866 buffer = av_malloc(buf_size);
867 if (!buffer)
868 return AVERROR(ENOMEM);
869
870 av_free(s->buffer);
871 s->buffer = buffer;
872 s->buffer_size = buf_size;
873 s->buf_ptr = buffer;
874 url_resetbuf(s, s->write_flag ? AVIO_FLAG_WRITE : AVIO_FLAG_READ);
875 return 0;
876 }
877
878 static int url_resetbuf(AVIOContext *s, int flags)
879 {
880 assert(flags == AVIO_FLAG_WRITE || flags == AVIO_FLAG_READ);
881
882 if (flags & AVIO_FLAG_WRITE) {
883 s->buf_end = s->buffer + s->buffer_size;
884 s->write_flag = 1;
885 } else {
886 s->buf_end = s->buffer;
887 s->write_flag = 0;
888 }
889 return 0;
890 }
891
892 int ffio_rewind_with_probe_data(AVIOContext *s, unsigned char *buf, int buf_size)
893 {
894 int64_t buffer_start;
895 int buffer_size;
896 int overlap, new_size, alloc_size;
897
898 if (s->write_flag)
899 return AVERROR(EINVAL);
900
901 buffer_size = s->buf_end - s->buffer;
902
903 /* the buffers must touch or overlap */
904 if ((buffer_start = s->pos - buffer_size) > buf_size)
905 return AVERROR(EINVAL);
906
907 overlap = buf_size - buffer_start;
908 new_size = buf_size + buffer_size - overlap;
909
910 alloc_size = FFMAX(s->buffer_size, new_size);
911 if (alloc_size > buf_size)
912 if (!(buf = av_realloc(buf, alloc_size)))
913 return AVERROR(ENOMEM);
914
915 if (new_size > buf_size) {
916 memcpy(buf + buf_size, s->buffer + overlap, buffer_size - overlap);
917 buf_size = new_size;
918 }
919
920 av_free(s->buffer);
921 s->buf_ptr = s->buffer = buf;
922 s->buffer_size = alloc_size;
923 s->pos = buf_size;
924 s->buf_end = s->buf_ptr + buf_size;
925 s->eof_reached = 0;
926 s->must_flush = 0;
927
928 return 0;
929 }
930
931 int avio_open(AVIOContext **s, const char *filename, int flags)
932 {
933 return avio_open2(s, filename, flags, NULL, NULL);
934 }
935
936 int avio_open2(AVIOContext **s, const char *filename, int flags,
937 const AVIOInterruptCB *int_cb, AVDictionary **options)
938 {
939 AVIOInternal *internal;
940 const URLProtocol **protocols;
941 char *proto_whitelist = NULL, *proto_blacklist = NULL;
942 AVDictionaryEntry *e;
943 URLContext *h;
944 int err;
945
946 if (options) {
947 e = av_dict_get(*options, "protocol_whitelist", NULL, 0);
948 if (e)
949 proto_whitelist = e->value;
950 e = av_dict_get(*options, "protocol_blacklist", NULL, 0);
951 if (e)
952 proto_blacklist = e->value;
953 }
954
955 protocols = ffurl_get_protocols(proto_whitelist, proto_blacklist);
956 if (!protocols)
957 return AVERROR(ENOMEM);
958
959 err = ffurl_open(&h, filename, flags, int_cb, options, protocols, NULL);
960 if (err < 0) {
961 av_freep(&protocols);
962 return err;
963 }
964
965 err = ffio_fdopen(s, h);
966 if (err < 0) {
967 ffurl_close(h);
968 av_freep(&protocols);
969 return err;
970 }
971
972 internal = (*s)->opaque;
973 internal->protocols = protocols;
974
975 if (options) {
976 err = av_opt_set_dict(internal, options);
977 if (err < 0) {
978 avio_closep(s);
979 return err;
980 }
981 }
982
983 return 0;
984 }
985
986 int avio_close(AVIOContext *s)
987 {
988 AVIOInternal *internal;
989 URLContext *h;
990
991 if (!s)
992 return 0;
993
994 avio_flush(s);
995 internal = s->opaque;
996 h = internal->h;
997
998 av_opt_free(internal);
999
1000 av_freep(&internal->protocols);
1001 av_freep(&s->opaque);
1002 av_freep(&s->buffer);
1003 av_free(s);
1004 return ffurl_close(h);
1005 }
1006
1007 int avio_closep(AVIOContext **s)
1008 {
1009 int ret = avio_close(*s);
1010 *s = NULL;
1011 return ret;
1012 }
1013
1014 int avio_printf(AVIOContext *s, const char *fmt, ...)
1015 {
1016 va_list ap;
1017 char buf[4096];
1018 int ret;
1019
1020 va_start(ap, fmt);
1021 ret = vsnprintf(buf, sizeof(buf), fmt, ap);
1022 va_end(ap);
1023 avio_write(s, buf, strlen(buf));
1024 return ret;
1025 }
1026
1027 int avio_pause(AVIOContext *s, int pause)
1028 {
1029 if (!s->read_pause)
1030 return AVERROR(ENOSYS);
1031 return s->read_pause(s->opaque, pause);
1032 }
1033
1034 int64_t avio_seek_time(AVIOContext *s, int stream_index,
1035 int64_t timestamp, int flags)
1036 {
1037 int64_t ret;
1038 if (!s->read_seek)
1039 return AVERROR(ENOSYS);
1040 ret = s->read_seek(s->opaque, stream_index, timestamp, flags);
1041 if (ret >= 0) {
1042 int64_t pos;
1043 s->buf_ptr = s->buf_end; // Flush buffer
1044 pos = s->seek(s->opaque, 0, SEEK_CUR);
1045 if (pos >= 0)
1046 s->pos = pos;
1047 else if (pos != AVERROR(ENOSYS))
1048 ret = pos;
1049 }
1050 return ret;
1051 }
1052
1053 /* output in a dynamic buffer */
1054
1055 typedef struct DynBuffer {
1056 int pos, size, allocated_size;
1057 uint8_t *buffer;
1058 int io_buffer_size;
1059 uint8_t io_buffer[1];
1060 } DynBuffer;
1061
1062 static int dyn_buf_write(void *opaque, uint8_t *buf, int buf_size)
1063 {
1064 DynBuffer *d = opaque;
1065 unsigned new_size, new_allocated_size;
1066
1067 /* reallocate buffer if needed */
1068 new_size = d->pos + buf_size;
1069 new_allocated_size = d->allocated_size;
1070 if (new_size < d->pos || new_size > INT_MAX/2)
1071 return -1;
1072 while (new_size > new_allocated_size) {
1073 if (!new_allocated_size)
1074 new_allocated_size = new_size;
1075 else
1076 new_allocated_size += new_allocated_size / 2 + 1;
1077 }
1078
1079 if (new_allocated_size > d->allocated_size) {
1080 int err;
1081 if ((err = av_reallocp(&d->buffer, new_allocated_size)) < 0) {
1082 d->allocated_size = 0;
1083 d->size = 0;
1084 return err;
1085 }
1086 d->allocated_size = new_allocated_size;
1087 }
1088 memcpy(d->buffer + d->pos, buf, buf_size);
1089 d->pos = new_size;
1090 if (d->pos > d->size)
1091 d->size = d->pos;
1092 return buf_size;
1093 }
1094
1095 static int dyn_packet_buf_write(void *opaque, uint8_t *buf, int buf_size)
1096 {
1097 unsigned char buf1[4];
1098 int ret;
1099
1100 /* packetized write: output the header */
1101 AV_WB32(buf1, buf_size);
1102 ret = dyn_buf_write(opaque, buf1, 4);
1103 if (ret < 0)
1104 return ret;
1105
1106 /* then the data */
1107 return dyn_buf_write(opaque, buf, buf_size);
1108 }
1109
1110 static int64_t dyn_buf_seek(void *opaque, int64_t offset, int whence)
1111 {
1112 DynBuffer *d = opaque;
1113
1114 if (whence == SEEK_CUR)
1115 offset += d->pos;
1116 else if (whence == SEEK_END)
1117 offset += d->size;
1118 if (offset < 0 || offset > 0x7fffffffLL)
1119 return -1;
1120 d->pos = offset;
1121 return 0;
1122 }
1123
1124 static int url_open_dyn_buf_internal(AVIOContext **s, int max_packet_size)
1125 {
1126 DynBuffer *d;
1127 unsigned io_buffer_size = max_packet_size ? max_packet_size : 1024;
1128
1129 if (sizeof(DynBuffer) + io_buffer_size < io_buffer_size)
1130 return -1;
1131 d = av_mallocz(sizeof(DynBuffer) + io_buffer_size);
1132 if (!d)
1133 return AVERROR(ENOMEM);
1134 d->io_buffer_size = io_buffer_size;
1135 *s = avio_alloc_context(d->io_buffer, d->io_buffer_size, 1, d, NULL,
1136 max_packet_size ? dyn_packet_buf_write : dyn_buf_write,
1137 max_packet_size ? NULL : dyn_buf_seek);
1138 if(!*s) {
1139 av_free(d);
1140 return AVERROR(ENOMEM);
1141 }
1142 (*s)->max_packet_size = max_packet_size;
1143 return 0;
1144 }
1145
1146 int avio_open_dyn_buf(AVIOContext **s)
1147 {
1148 return url_open_dyn_buf_internal(s, 0);
1149 }
1150
1151 int ffio_open_dyn_packet_buf(AVIOContext **s, int max_packet_size)
1152 {
1153 if (max_packet_size <= 0)
1154 return -1;
1155 return url_open_dyn_buf_internal(s, max_packet_size);
1156 }
1157
1158 int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
1159 {
1160 DynBuffer *d;
1161 int size;
1162 static const char padbuf[AV_INPUT_BUFFER_PADDING_SIZE] = {0};
1163 int padding = 0;
1164
1165 if (!s) {
1166 *pbuffer = NULL;
1167 return 0;
1168 }
1169
1170 /* don't attempt to pad fixed-size packet buffers */
1171 if (!s->max_packet_size) {
1172 avio_write(s, padbuf, sizeof(padbuf));
1173 padding = AV_INPUT_BUFFER_PADDING_SIZE;
1174 }
1175
1176 avio_flush(s);
1177
1178 d = s->opaque;
1179 *pbuffer = d->buffer;
1180 size = d->size;
1181 av_free(d);
1182 av_free(s);
1183 return size - padding;
1184 }
1185
1186 void ffio_free_dyn_buf(AVIOContext **s)
1187 {
1188 uint8_t *tmp;
1189 if (!*s)
1190 return;
1191 avio_close_dyn_buf(*s, &tmp);
1192 av_free(tmp);
1193 *s = NULL;
1194 }
1195
1196 static int null_buf_write(void *opaque, uint8_t *buf, int buf_size)
1197 {
1198 DynBuffer *d = opaque;
1199
1200 d->pos += buf_size;
1201 if (d->pos > d->size)
1202 d->size = d->pos;
1203 return buf_size;
1204 }
1205
1206 int ffio_open_null_buf(AVIOContext **s)
1207 {
1208 int ret = url_open_dyn_buf_internal(s, 0);
1209 if (ret >= 0) {
1210 AVIOContext *pb = *s;
1211 pb->write_packet = null_buf_write;
1212 }
1213 return ret;
1214 }
1215
1216 int ffio_close_null_buf(AVIOContext *s)
1217 {
1218 DynBuffer *d = s->opaque;
1219 int size;
1220
1221 avio_flush(s);
1222
1223 size = d->size;
1224 av_free(d);
1225 av_free(s);
1226 return size;
1227 }