aviobuf.c
Go to the documentation of this file.
1 /*
2  * buffered I/O
3  * Copyright (c) 2000,2001 Fabrice Bellard
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
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 "libavutil/avassert.h"
28 #include "avformat.h"
29 #include "avio.h"
30 #include "avio_internal.h"
31 #include "internal.h"
32 #include "url.h"
33 #include <stdarg.h>
34 
35 #define IO_BUFFER_SIZE 32768
36 
37 /**
38  * Do seeks within this distance ahead of the current buffer by skipping
39  * data instead of calling the protocol seek function, for seekable
40  * protocols.
41  */
42 #define SHORT_SEEK_THRESHOLD 4096
43 
44 static void *ffio_url_child_next(void *obj, void *prev)
45 {
46  AVIOContext *s = obj;
47  return prev ? NULL : s->opaque;
48 }
49 
50 static const AVClass *ffio_url_child_class_next(const AVClass *prev)
51 {
52  return prev ? NULL : &ffurl_context_class;
53 }
54 
55 static const AVOption ffio_url_options[] = {
56  { NULL },
57 };
58 
60  .class_name = "AVIOContext",
61  .item_name = av_default_item_name,
62  .version = LIBAVUTIL_VERSION_INT,
63  .option = ffio_url_options,
64  .child_next = ffio_url_child_next,
65  .child_class_next = ffio_url_child_class_next,
66 };
67 
68 static void fill_buffer(AVIOContext *s);
69 static int url_resetbuf(AVIOContext *s, int flags);
70 
72  unsigned char *buffer,
73  int buffer_size,
74  int write_flag,
75  void *opaque,
76  int (*read_packet)(void *opaque, uint8_t *buf, int buf_size),
77  int (*write_packet)(void *opaque, uint8_t *buf, int buf_size),
78  int64_t (*seek)(void *opaque, int64_t offset, int whence))
79 {
80  s->buffer = buffer;
81  s->buffer_size = buffer_size;
82  s->buf_ptr = buffer;
83  s->opaque = opaque;
84  s->direct = 0;
85 
86  url_resetbuf(s, write_flag ? AVIO_FLAG_WRITE : AVIO_FLAG_READ);
87 
90  s->seek = seek;
91  s->pos = 0;
92  s->must_flush = 0;
93  s->eof_reached = 0;
94  s->error = 0;
96  s->max_packet_size = 0;
97  s->update_checksum = NULL;
98 
99  if (!read_packet && !write_flag) {
100  s->pos = buffer_size;
101  s->buf_end = s->buffer + buffer_size;
102  }
103  s->read_pause = NULL;
104  s->read_seek = NULL;
105 
106  return 0;
107 }
108 
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  AVIOContext *s = av_mallocz(sizeof(AVIOContext));
119  if (!s)
120  return NULL;
121  ffio_init_context(s, buffer, buffer_size, write_flag, opaque,
122  read_packet, write_packet, seek);
123  return s;
124 }
125 
126 static void writeout(AVIOContext *s, const uint8_t *data, int len)
127 {
128  if (s->write_packet && !s->error) {
129  int ret = s->write_packet(s->opaque, (uint8_t *)data, len);
130  if (ret < 0) {
131  s->error = ret;
132  }
133  }
134  s->writeout_count ++;
135  s->pos += len;
136 }
137 
138 static void flush_buffer(AVIOContext *s)
139 {
140  if (s->buf_ptr > s->buffer) {
141  writeout(s, s->buffer, s->buf_ptr - s->buffer);
142  if (s->update_checksum) {
144  s->buf_ptr - s->checksum_ptr);
145  s->checksum_ptr = s->buffer;
146  }
147  }
148  s->buf_ptr = s->buffer;
149 }
150 
151 void avio_w8(AVIOContext *s, int b)
152 {
153  av_assert2(b>=-128 && b<=255);
154  *s->buf_ptr++ = b;
155  if (s->buf_ptr >= s->buf_end)
156  flush_buffer(s);
157 }
158 
159 void ffio_fill(AVIOContext *s, int b, int count)
160 {
161  while (count > 0) {
162  int len = FFMIN(s->buf_end - s->buf_ptr, count);
163  memset(s->buf_ptr, b, len);
164  s->buf_ptr += len;
165 
166  if (s->buf_ptr >= s->buf_end)
167  flush_buffer(s);
168 
169  count -= len;
170  }
171 }
172 
173 void avio_write(AVIOContext *s, const unsigned char *buf, int size)
174 {
175  if (s->direct && !s->update_checksum) {
176  avio_flush(s);
177  writeout(s, buf, size);
178  return;
179  }
180  while (size > 0) {
181  int len = FFMIN(s->buf_end - s->buf_ptr, size);
182  memcpy(s->buf_ptr, buf, len);
183  s->buf_ptr += len;
184 
185  if (s->buf_ptr >= s->buf_end)
186  flush_buffer(s);
187 
188  buf += len;
189  size -= len;
190  }
191 }
192 
194 {
195  flush_buffer(s);
196  s->must_flush = 0;
197 }
198 
199 int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
200 {
201  int64_t offset1;
202  int64_t pos;
203  int force = whence & AVSEEK_FORCE;
204  whence &= ~AVSEEK_FORCE;
205 
206  if(!s)
207  return AVERROR(EINVAL);
208 
209  pos = s->pos - (s->write_flag ? 0 : (s->buf_end - s->buffer));
210 
211  if (whence != SEEK_CUR && whence != SEEK_SET)
212  return AVERROR(EINVAL);
213 
214  if (whence == SEEK_CUR) {
215  offset1 = pos + (s->buf_ptr - s->buffer);
216  if (offset == 0)
217  return offset1;
218  offset += offset1;
219  }
220  offset1 = offset - pos;
221  if (!s->must_flush && (!s->direct || !s->seek) &&
222  offset1 >= 0 && offset1 <= (s->buf_end - s->buffer)) {
223  /* can do the seek inside the buffer */
224  s->buf_ptr = s->buffer + offset1;
225  } else if ((!s->seekable ||
226  offset1 <= s->buf_end + SHORT_SEEK_THRESHOLD - s->buffer) &&
227  !s->write_flag && offset1 >= 0 &&
228  (!s->direct || !s->seek) &&
229  (whence != SEEK_END || force)) {
230  while(s->pos < offset && !s->eof_reached)
231  fill_buffer(s);
232  if (s->eof_reached)
233  return AVERROR_EOF;
234  s->buf_ptr = s->buf_end + offset - s->pos;
235  } else {
236  int64_t res;
237 
238  if (s->write_flag) {
239  flush_buffer(s);
240  s->must_flush = 1;
241  }
242  if (!s->seek)
243  return AVERROR(EPIPE);
244  if ((res = s->seek(s->opaque, offset, SEEK_SET)) < 0)
245  return res;
246  s->seek_count ++;
247  if (!s->write_flag)
248  s->buf_end = s->buffer;
249  s->buf_ptr = s->buffer;
250  s->pos = offset;
251  }
252  s->eof_reached = 0;
253  return offset;
254 }
255 
256 int64_t avio_skip(AVIOContext *s, int64_t offset)
257 {
258  return avio_seek(s, offset, SEEK_CUR);
259 }
260 
262 {
263  int64_t size;
264 
265  if (!s)
266  return AVERROR(EINVAL);
267 
268  if (!s->seek)
269  return AVERROR(ENOSYS);
270  size = s->seek(s->opaque, 0, AVSEEK_SIZE);
271  if (size < 0) {
272  if ((size = s->seek(s->opaque, -1, SEEK_END)) < 0)
273  return size;
274  size++;
275  s->seek(s->opaque, s->pos, SEEK_SET);
276  }
277  return size;
278 }
279 
281 {
282  if(!s)
283  return 0;
284  if(s->eof_reached){
285  s->eof_reached=0;
286  fill_buffer(s);
287  }
288  return s->eof_reached;
289 }
290 
291 void avio_wl32(AVIOContext *s, unsigned int val)
292 {
293  avio_w8(s, (uint8_t) val );
294  avio_w8(s, (uint8_t)(val >> 8 ));
295  avio_w8(s, (uint8_t)(val >> 16));
296  avio_w8(s, val >> 24 );
297 }
298 
299 void avio_wb32(AVIOContext *s, unsigned int val)
300 {
301  avio_w8(s, val >> 24 );
302  avio_w8(s, (uint8_t)(val >> 16));
303  avio_w8(s, (uint8_t)(val >> 8 ));
304  avio_w8(s, (uint8_t) val );
305 }
306 
307 int avio_put_str(AVIOContext *s, const char *str)
308 {
309  int len = 1;
310  if (str) {
311  len += strlen(str);
312  avio_write(s, (const unsigned char *) str, len);
313  } else
314  avio_w8(s, 0);
315  return len;
316 }
317 
318 int avio_put_str16le(AVIOContext *s, const char *str)
319 {
320  const uint8_t *q = str;
321  int ret = 0;
322 
323  while (*q) {
324  uint32_t ch;
325  uint16_t tmp;
326 
327  GET_UTF8(ch, *q++, break;)
328  PUT_UTF16(ch, tmp, avio_wl16(s, tmp); ret += 2;)
329  }
330  avio_wl16(s, 0);
331  ret += 2;
332  return ret;
333 }
334 
335 int ff_get_v_length(uint64_t val)
336 {
337  int i = 1;
338 
339  while (val >>= 7)
340  i++;
341 
342  return i;
343 }
344 
345 void ff_put_v(AVIOContext *bc, uint64_t val)
346 {
347  int i = ff_get_v_length(val);
348 
349  while (--i > 0)
350  avio_w8(bc, 128 | (uint8_t)(val >> (7*i)));
351 
352  avio_w8(bc, val & 127);
353 }
354 
355 void avio_wl64(AVIOContext *s, uint64_t val)
356 {
357  avio_wl32(s, (uint32_t)(val & 0xffffffff));
358  avio_wl32(s, (uint32_t)(val >> 32));
359 }
360 
361 void avio_wb64(AVIOContext *s, uint64_t val)
362 {
363  avio_wb32(s, (uint32_t)(val >> 32));
364  avio_wb32(s, (uint32_t)(val & 0xffffffff));
365 }
366 
367 void avio_wl16(AVIOContext *s, unsigned int val)
368 {
369  avio_w8(s, (uint8_t)val);
370  avio_w8(s, (int)val >> 8);
371 }
372 
373 void avio_wb16(AVIOContext *s, unsigned int val)
374 {
375  avio_w8(s, (int)val >> 8);
376  avio_w8(s, (uint8_t)val);
377 }
378 
379 void avio_wl24(AVIOContext *s, unsigned int val)
380 {
381  avio_wl16(s, val & 0xffff);
382  avio_w8(s, (int)val >> 16);
383 }
384 
385 void avio_wb24(AVIOContext *s, unsigned int val)
386 {
387  avio_wb16(s, (int)val >> 8);
388  avio_w8(s, (uint8_t)val);
389 }
390 
391 /* Input stream */
392 
393 static void fill_buffer(AVIOContext *s)
394 {
395  uint8_t *dst = !s->max_packet_size &&
396  s->buf_end - s->buffer < s->buffer_size ?
397  s->buf_end : s->buffer;
398  int len = s->buffer_size - (dst - s->buffer);
399  int max_buffer_size = s->max_packet_size ?
401 
402  /* can't fill the buffer without read_packet, just set EOF if appropriate */
403  if (!s->read_packet && s->buf_ptr >= s->buf_end)
404  s->eof_reached = 1;
405 
406  /* no need to do anything if EOF already reached */
407  if (s->eof_reached)
408  return;
409 
410  if (s->update_checksum && dst == s->buffer) {
411  if (s->buf_end > s->checksum_ptr)
413  s->buf_end - s->checksum_ptr);
414  s->checksum_ptr = s->buffer;
415  }
416 
417  /* make buffer smaller in case it ended up large after probing */
418  if (s->read_packet && s->buffer_size > max_buffer_size) {
419  ffio_set_buf_size(s, max_buffer_size);
420 
421  s->checksum_ptr = dst = s->buffer;
422  len = s->buffer_size;
423  }
424 
425  if (s->read_packet)
426  len = s->read_packet(s->opaque, dst, len);
427  else
428  len = 0;
429  if (len <= 0) {
430  /* do not modify buffer if EOF reached so that a seek back can
431  be done without rereading data */
432  s->eof_reached = 1;
433  if (len < 0)
434  s->error = len;
435  } else {
436  s->pos += len;
437  s->buf_ptr = dst;
438  s->buf_end = dst + len;
439  s->bytes_read += len;
440  }
441 }
442 
443 unsigned long ff_crc04C11DB7_update(unsigned long checksum, const uint8_t *buf,
444  unsigned int len)
445 {
446  return av_crc(av_crc_get_table(AV_CRC_32_IEEE), checksum, buf, len);
447 }
448 
450 {
452  s->buf_ptr - s->checksum_ptr);
453  s->update_checksum = NULL;
454  return s->checksum;
455 }
456 
458  unsigned long (*update_checksum)(unsigned long c, const uint8_t *p, unsigned int len),
459  unsigned long checksum)
460 {
461  s->update_checksum = update_checksum;
462  if (s->update_checksum) {
463  s->checksum = checksum;
464  s->checksum_ptr = s->buf_ptr;
465  }
466 }
467 
468 /* XXX: put an inline version */
470 {
471  if (s->buf_ptr >= s->buf_end)
472  fill_buffer(s);
473  if (s->buf_ptr < s->buf_end)
474  return *s->buf_ptr++;
475  return 0;
476 }
477 
478 int avio_read(AVIOContext *s, unsigned char *buf, int size)
479 {
480  int len, size1;
481 
482  size1 = size;
483  while (size > 0) {
484  len = s->buf_end - s->buf_ptr;
485  if (len > size)
486  len = size;
487  if (len == 0 || s->write_flag) {
488  if((s->direct || size > s->buffer_size) && !s->update_checksum){
489  if(s->read_packet)
490  len = s->read_packet(s->opaque, buf, size);
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  break;
498  } else {
499  s->pos += len;
500  s->bytes_read += len;
501  size -= len;
502  buf += len;
503  s->buf_ptr = s->buffer;
504  s->buf_end = s->buffer/* + len*/;
505  }
506  } else {
507  fill_buffer(s);
508  len = s->buf_end - s->buf_ptr;
509  if (len == 0)
510  break;
511  }
512  } else {
513  memcpy(buf, s->buf_ptr, len);
514  buf += len;
515  s->buf_ptr += len;
516  size -= len;
517  }
518  }
519  if (size1 == size) {
520  if (s->error) return s->error;
521  if (url_feof(s)) return AVERROR_EOF;
522  }
523  return size1 - size;
524 }
525 
526 int ffio_read_partial(AVIOContext *s, unsigned char *buf, int size)
527 {
528  int len;
529 
530  if (size < 0)
531  return -1;
532 
533  if (s->read_packet && s->write_flag) {
534  len = s->read_packet(s->opaque, buf, size);
535  if (len > 0)
536  s->pos += len;
537  return len;
538  }
539 
540  len = s->buf_end - s->buf_ptr;
541  if (len == 0) {
542  /* Reset the buf_end pointer to the start of the buffer, to make sure
543  * the fill_buffer call tries to read as much data as fits into the
544  * full buffer, instead of just what space is left after buf_end.
545  * This avoids returning partial packets at the end of the buffer,
546  * for packet based inputs.
547  */
548  s->buf_end = s->buf_ptr = s->buffer;
549  fill_buffer(s);
550  len = s->buf_end - s->buf_ptr;
551  }
552  if (len > size)
553  len = size;
554  memcpy(buf, s->buf_ptr, len);
555  s->buf_ptr += len;
556  if (!len) {
557  if (s->error) return s->error;
558  if (url_feof(s)) return AVERROR_EOF;
559  }
560  return len;
561 }
562 
563 unsigned int avio_rl16(AVIOContext *s)
564 {
565  unsigned int val;
566  val = avio_r8(s);
567  val |= avio_r8(s) << 8;
568  return val;
569 }
570 
571 unsigned int avio_rl24(AVIOContext *s)
572 {
573  unsigned int val;
574  val = avio_rl16(s);
575  val |= avio_r8(s) << 16;
576  return val;
577 }
578 
579 unsigned int avio_rl32(AVIOContext *s)
580 {
581  unsigned int val;
582  val = avio_rl16(s);
583  val |= avio_rl16(s) << 16;
584  return val;
585 }
586 
587 uint64_t avio_rl64(AVIOContext *s)
588 {
589  uint64_t val;
590  val = (uint64_t)avio_rl32(s);
591  val |= (uint64_t)avio_rl32(s) << 32;
592  return val;
593 }
594 
595 unsigned int avio_rb16(AVIOContext *s)
596 {
597  unsigned int val;
598  val = avio_r8(s) << 8;
599  val |= avio_r8(s);
600  return val;
601 }
602 
603 unsigned int avio_rb24(AVIOContext *s)
604 {
605  unsigned int val;
606  val = avio_rb16(s) << 8;
607  val |= avio_r8(s);
608  return val;
609 }
610 unsigned int avio_rb32(AVIOContext *s)
611 {
612  unsigned int val;
613  val = avio_rb16(s) << 16;
614  val |= avio_rb16(s);
615  return val;
616 }
617 
618 int ff_get_line(AVIOContext *s, char *buf, int maxlen)
619 {
620  int i = 0;
621  char c;
622 
623  do {
624  c = avio_r8(s);
625  if (c && i < maxlen-1)
626  buf[i++] = c;
627  } while (c != '\n' && c);
628 
629  buf[i] = 0;
630  return i;
631 }
632 
633 int avio_get_str(AVIOContext *s, int maxlen, char *buf, int buflen)
634 {
635  int i;
636 
637  if (buflen <= 0)
638  return AVERROR(EINVAL);
639  // reserve 1 byte for terminating 0
640  buflen = FFMIN(buflen - 1, maxlen);
641  for (i = 0; i < buflen; i++)
642  if (!(buf[i] = avio_r8(s)))
643  return i + 1;
644  buf[i] = 0;
645  for (; i < maxlen; i++)
646  if (!avio_r8(s))
647  return i + 1;
648  return maxlen;
649 }
650 
651 #define GET_STR16(type, read) \
652  int avio_get_str16 ##type(AVIOContext *pb, int maxlen, char *buf, int buflen)\
653 {\
654  char* q = buf;\
655  int ret = 0;\
656  if (buflen <= 0) \
657  return AVERROR(EINVAL); \
658  while (ret + 1 < maxlen) {\
659  uint8_t tmp;\
660  uint32_t ch;\
661  GET_UTF16(ch, (ret += 2) <= maxlen ? read(pb) : 0, break;)\
662  if (!ch)\
663  break;\
664  PUT_UTF8(ch, tmp, if (q - buf < buflen - 1) *q++ = tmp;)\
665  }\
666  *q = 0;\
667  return ret;\
668 }\
669 
671 GET_STR16(be, avio_rb16)
672 
673 #undef GET_STR16
674 
675 uint64_t avio_rb64(AVIOContext *s)
676 {
677  uint64_t val;
678  val = (uint64_t)avio_rb32(s) << 32;
679  val |= (uint64_t)avio_rb32(s);
680  return val;
681 }
682 
684  uint64_t val = 0;
685  int tmp;
686 
687  do{
688  tmp = avio_r8(bc);
689  val= (val<<7) + (tmp&127);
690  }while(tmp&128);
691  return val;
692 }
693 
695 {
696  uint8_t *buffer;
697  int buffer_size, max_packet_size;
698 
699  max_packet_size = h->max_packet_size;
700  if (max_packet_size) {
701  buffer_size = max_packet_size; /* no need to bufferize more than one packet */
702  } else {
703  buffer_size = IO_BUFFER_SIZE;
704  }
705  buffer = av_malloc(buffer_size);
706  if (!buffer)
707  return AVERROR(ENOMEM);
708 
709  *s = avio_alloc_context(buffer, buffer_size, h->flags & AVIO_FLAG_WRITE, h,
710  (void*)ffurl_read, (void*)ffurl_write, (void*)ffurl_seek);
711  if (!*s) {
712  av_free(buffer);
713  return AVERROR(ENOMEM);
714  }
715  (*s)->direct = h->flags & AVIO_FLAG_DIRECT;
716  (*s)->seekable = h->is_streamed ? 0 : AVIO_SEEKABLE_NORMAL;
717  (*s)->max_packet_size = max_packet_size;
718  if(h->prot) {
719  (*s)->read_pause = (int (*)(void *, int))h->prot->url_read_pause;
720  (*s)->read_seek = (int64_t (*)(void *, int, int64_t, int))h->prot->url_read_seek;
721  }
722  (*s)->av_class = &ffio_url_class;
723  return 0;
724 }
725 
726 int ffio_set_buf_size(AVIOContext *s, int buf_size)
727 {
728  uint8_t *buffer;
729  buffer = av_malloc(buf_size);
730  if (!buffer)
731  return AVERROR(ENOMEM);
732 
733  av_free(s->buffer);
734  s->buffer = buffer;
735  s->buffer_size = buf_size;
736  s->buf_ptr = buffer;
738  return 0;
739 }
740 
741 static int url_resetbuf(AVIOContext *s, int flags)
742 {
743  av_assert1(flags == AVIO_FLAG_WRITE || flags == AVIO_FLAG_READ);
744 
745  if (flags & AVIO_FLAG_WRITE) {
746  s->buf_end = s->buffer + s->buffer_size;
747  s->write_flag = 1;
748  } else {
749  s->buf_end = s->buffer;
750  s->write_flag = 0;
751  }
752  return 0;
753 }
754 
755 int ffio_rewind_with_probe_data(AVIOContext *s, unsigned char **bufp, int buf_size)
756 {
757  int64_t buffer_start;
758  int buffer_size;
759  int overlap, new_size, alloc_size;
760  uint8_t *buf = *bufp;
761 
762  if (s->write_flag) {
763  av_freep(bufp);
764  return AVERROR(EINVAL);
765  }
766 
767  buffer_size = s->buf_end - s->buffer;
768 
769  /* the buffers must touch or overlap */
770  if ((buffer_start = s->pos - buffer_size) > buf_size) {
771  av_freep(bufp);
772  return AVERROR(EINVAL);
773  }
774 
775  overlap = buf_size - buffer_start;
776  new_size = buf_size + buffer_size - overlap;
777 
778  alloc_size = FFMAX(s->buffer_size, new_size);
779  if (alloc_size > buf_size)
780  if (!(buf = (*bufp) = av_realloc_f(buf, 1, alloc_size)))
781  return AVERROR(ENOMEM);
782 
783  if (new_size > buf_size) {
784  memcpy(buf + buf_size, s->buffer + overlap, buffer_size - overlap);
785  buf_size = new_size;
786  }
787 
788  av_free(s->buffer);
789  s->buf_ptr = s->buffer = buf;
790  s->buffer_size = alloc_size;
791  s->pos = buf_size;
792  s->buf_end = s->buf_ptr + buf_size;
793  s->eof_reached = 0;
794  s->must_flush = 0;
795 
796  return 0;
797 }
798 
799 int avio_open(AVIOContext **s, const char *filename, int flags)
800 {
801  return avio_open2(s, filename, flags, NULL, NULL);
802 }
803 
804 int avio_open2(AVIOContext **s, const char *filename, int flags,
806 {
807  URLContext *h;
808  int err;
809 
810  err = ffurl_open(&h, filename, flags, int_cb, options);
811  if (err < 0)
812  return err;
813  err = ffio_fdopen(s, h);
814  if (err < 0) {
815  ffurl_close(h);
816  return err;
817  }
818  return 0;
819 }
820 
822 {
823  URLContext *h;
824 
825  if (!s)
826  return 0;
827 
828  avio_flush(s);
829  h = s->opaque;
830  av_freep(&s->buffer);
831  if (s->write_flag)
832  av_log(s, AV_LOG_DEBUG, "Statistics: %d seeks, %d writeouts\n", s->seek_count, s->writeout_count);
833  else
834  av_log(s, AV_LOG_DEBUG, "Statistics: %"PRId64" bytes read, %d seeks\n", s->bytes_read, s->seek_count);
835  av_free(s);
836  return ffurl_close(h);
837 }
838 
840 {
841  int ret = avio_close(*s);
842  *s = NULL;
843  return ret;
844 }
845 
846 int avio_printf(AVIOContext *s, const char *fmt, ...)
847 {
848  va_list ap;
849  char buf[4096];
850  int ret;
851 
852  va_start(ap, fmt);
853  ret = vsnprintf(buf, sizeof(buf), fmt, ap);
854  va_end(ap);
855  avio_write(s, buf, strlen(buf));
856  return ret;
857 }
858 
860 {
861  if (!s->read_pause)
862  return AVERROR(ENOSYS);
863  return s->read_pause(s->opaque, pause);
864 }
865 
866 int64_t avio_seek_time(AVIOContext *s, int stream_index,
867  int64_t timestamp, int flags)
868 {
869  URLContext *h = s->opaque;
870  int64_t ret;
871  if (!s->read_seek)
872  return AVERROR(ENOSYS);
873  ret = s->read_seek(h, stream_index, timestamp, flags);
874  if (ret >= 0) {
875  int64_t pos;
876  s->buf_ptr = s->buf_end; // Flush buffer
877  pos = s->seek(h, 0, SEEK_CUR);
878  if (pos >= 0)
879  s->pos = pos;
880  else if (pos != AVERROR(ENOSYS))
881  ret = pos;
882  }
883  return ret;
884 }
885 
886 /* output in a dynamic buffer */
887 
888 typedef struct DynBuffer {
893 } DynBuffer;
894 
895 static int dyn_buf_write(void *opaque, uint8_t *buf, int buf_size)
896 {
897  DynBuffer *d = opaque;
898  unsigned new_size, new_allocated_size;
899 
900  /* reallocate buffer if needed */
901  new_size = d->pos + buf_size;
902  new_allocated_size = d->allocated_size;
903  if (new_size < d->pos || new_size > INT_MAX/2)
904  return -1;
905  while (new_size > new_allocated_size) {
906  if (!new_allocated_size)
907  new_allocated_size = new_size;
908  else
909  new_allocated_size += new_allocated_size / 2 + 1;
910  }
911 
912  if (new_allocated_size > d->allocated_size) {
913  d->buffer = av_realloc_f(d->buffer, 1, new_allocated_size);
914  if(d->buffer == NULL)
915  return AVERROR(ENOMEM);
916  d->allocated_size = new_allocated_size;
917  }
918  memcpy(d->buffer + d->pos, buf, buf_size);
919  d->pos = new_size;
920  if (d->pos > d->size)
921  d->size = d->pos;
922  return buf_size;
923 }
924 
925 static int dyn_packet_buf_write(void *opaque, uint8_t *buf, int buf_size)
926 {
927  unsigned char buf1[4];
928  int ret;
929 
930  /* packetized write: output the header */
931  AV_WB32(buf1, buf_size);
932  ret = dyn_buf_write(opaque, buf1, 4);
933  if (ret < 0)
934  return ret;
935 
936  /* then the data */
937  return dyn_buf_write(opaque, buf, buf_size);
938 }
939 
940 static int64_t dyn_buf_seek(void *opaque, int64_t offset, int whence)
941 {
942  DynBuffer *d = opaque;
943 
944  if (whence == SEEK_CUR)
945  offset += d->pos;
946  else if (whence == SEEK_END)
947  offset += d->size;
948  if (offset < 0 || offset > 0x7fffffffLL)
949  return -1;
950  d->pos = offset;
951  return 0;
952 }
953 
954 static int url_open_dyn_buf_internal(AVIOContext **s, int max_packet_size)
955 {
956  DynBuffer *d;
957  unsigned io_buffer_size = max_packet_size ? max_packet_size : 1024;
958 
959  if (sizeof(DynBuffer) + io_buffer_size < io_buffer_size)
960  return -1;
961  d = av_mallocz(sizeof(DynBuffer) + io_buffer_size);
962  if (!d)
963  return AVERROR(ENOMEM);
965  *s = avio_alloc_context(d->io_buffer, d->io_buffer_size, 1, d, NULL,
966  max_packet_size ? dyn_packet_buf_write : dyn_buf_write,
967  max_packet_size ? NULL : dyn_buf_seek);
968  if(!*s) {
969  av_free(d);
970  return AVERROR(ENOMEM);
971  }
972  (*s)->max_packet_size = max_packet_size;
973  return 0;
974 }
975 
977 {
978  return url_open_dyn_buf_internal(s, 0);
979 }
980 
981 int ffio_open_dyn_packet_buf(AVIOContext **s, int max_packet_size)
982 {
983  if (max_packet_size <= 0)
984  return -1;
985  return url_open_dyn_buf_internal(s, max_packet_size);
986 }
987 
989 {
990  DynBuffer *d = s->opaque;
991  int size;
992  static const char padbuf[FF_INPUT_BUFFER_PADDING_SIZE] = {0};
993  int padding = 0;
994 
995  /* don't attempt to pad fixed-size packet buffers */
996  if (!s->max_packet_size) {
997  avio_write(s, padbuf, sizeof(padbuf));
999  }
1000 
1001  avio_flush(s);
1002 
1003  *pbuffer = d->buffer;
1004  size = d->size;
1005  av_free(d);
1006  av_free(s);
1007  return size - padding;
1008 }
void avio_wl64(AVIOContext *s, uint64_t val)
Definition: aviobuf.c:355
int url_feof(AVIOContext *s)
feof() equivalent for AVIOContext.
Definition: aviobuf.c:280
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:205
AVIOContext * avio_alloc_context(unsigned char *buffer, int buffer_size, int write_flag, void *opaque, int(*read_packet)(void *opaque, uint8_t *buf, int buf_size), int(*write_packet)(void *opaque, uint8_t *buf, int buf_size), int64_t(*seek)(void *opaque, int64_t offset, int whence))
Allocate and initialize an AVIOContext for buffered I/O.
Definition: aviobuf.c:109
static int64_t dyn_buf_seek(void *opaque, int64_t offset, int whence)
Definition: aviobuf.c:940
const char * s
Definition: avisynth_c.h:668
Bytestream IO Context.
Definition: avio.h:68
Buffered I/O operations.
uint64_t avio_rb64(AVIOContext *s)
Definition: aviobuf.c:675
int avio_open_dyn_buf(AVIOContext **s)
Open a write only memory stream.
Definition: aviobuf.c:976
#define GET_UTF8(val, GET_BYTE, ERROR)
Convert a UTF-8 character (up to 4 bytes) to its 32-bit UCS-4 encoded form.
Definition: common.h:296
uint8_t io_buffer[1]
Definition: aviobuf.c:892
void avio_wb16(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:373
uint32_t av_crc(const AVCRC *ctx, uint32_t crc, const uint8_t *buffer, size_t length)
Calculate the CRC of a block.
Definition: crc.c:275
AVOption.
Definition: opt.h:251
av_default_item_name
const char * fmt
Definition: avisynth_c.h:669
void * av_realloc_f(void *ptr, size_t nelem, size_t elsize)
Allocate or reallocate a block of memory.
Definition: mem.c:168
unsigned char * buf_ptr
Current position in the buffer.
Definition: avio.h:84
int writeout_count
writeout statistic This field is internal to libavformat and access from outside is not allowed...
Definition: avio.h:148
unsigned char * buf_end
End of the data, may be less than buffer+buffer_size if the read function returned less data than req...
Definition: avio.h:85
int ffurl_write(URLContext *h, const unsigned char *buf, int size)
Write size bytes from buf to the resource accessed by h.
Definition: avio.c:317
int write_flag
true if open for writing
Definition: avio.h:97
int is_streamed
true if streamed (no seek possible), default = false
Definition: url.h:48
static int write_packet(AVFormatContext *s, AVPacket *pkt)
#define vsnprintf
Definition: snprintf.h:36
int ffio_read_partial(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:526
void ffio_fill(AVIOContext *s, int b, int count)
Definition: aviobuf.c:159
#define AVIO_FLAG_READ
read-only
Definition: avio.h:332
unsigned int avio_rl24(AVIOContext *s)
Definition: aviobuf.c:571
struct URLProtocol * prot
Definition: url.h:43
#define AVIO_FLAG_WRITE
write-only
Definition: avio.h:333
unsigned char * buffer
Start of the buffer.
Definition: avio.h:82
void avio_wl24(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:379
void avio_w8(AVIOContext *s, int b)
Definition: aviobuf.c:151
int flags
Definition: url.h:46
int avio_closep(AVIOContext **s)
Close the resource accessed by the AVIOContext *s, free it and set the pointer pointing to it to NULL...
Definition: aviobuf.c:839
void * opaque
A private pointer, passed to the read/write/seek/...
Definition: avio.h:89
static const AVOption ffio_url_options[]
Definition: aviobuf.c:55
static const AVClass * ffio_url_child_class_next(const AVClass *prev)
Definition: aviobuf.c:50
void avio_wb32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:299
#define IO_BUFFER_SIZE
Definition: aviobuf.c:35
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:198
set threshold d
#define AV_WB32(p, darg)
Definition: intreadwrite.h:265
int avio_put_str(AVIOContext *s, const char *str)
Write a NULL-terminated string.
Definition: aviobuf.c:307
void avio_wl32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:291
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:55
Public dictionary API.
uint8_t
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition: avassert.h:63
AVOptions.
static void fill_buffer(AVIOContext *s)
Definition: aviobuf.c:393
const AVCRC * av_crc_get_table(AVCRCId crc_id)
Get an initialized standard CRC table.
Definition: crc.c:261
#define b
Definition: input.c:42
unsigned long ffio_get_checksum(AVIOContext *s)
Definition: aviobuf.c:449
void avio_flush(AVIOContext *s)
Force flushing of buffered data to the output s.
Definition: aviobuf.c:193
int ffio_init_context(AVIOContext *s, unsigned char *buffer, int buffer_size, int write_flag, void *opaque, int(*read_packet)(void *opaque, uint8_t *buf, int buf_size), int(*write_packet)(void *opaque, uint8_t *buf, int buf_size), int64_t(*seek)(void *opaque, int64_t offset, int whence))
Definition: aviobuf.c:71
int64_t bytes_read
Bytes read statistic This field is internal to libavformat and access from outside is not allowed...
Definition: avio.h:136
#define AVERROR_EOF
End of file.
Definition: error.h:55
int ffio_set_buf_size(AVIOContext *s, int buf_size)
Definition: aviobuf.c:726
void avio_wb24(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:385
void avio_wl16(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:367
const OptionDef options[]
Definition: ffserver.c:4697
static void flush_buffer(AVIOContext *s)
Definition: aviobuf.c:138
int max_packet_size
Definition: avio.h:98
Callback for checking whether to abort blocking functions.
Definition: avio.h:51
void av_free(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). ...
Definition: mem.c:183
int io_buffer_size
Definition: aviobuf.c:891
unsigned int avio_rb24(AVIOContext *s)
Definition: aviobuf.c:603
const AVIOInterruptCB int_cb
Definition: ffmpeg.c:422
static int dyn_packet_buf_write(void *opaque, uint8_t *buf, int buf_size)
Definition: aviobuf.c:925
Spectrum Plot time data
simple assert() macros that are a bit more flexible than ISO C assert().
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
unsigned long checksum
Definition: avio.h:99
#define SHORT_SEEK_THRESHOLD
Do seeks within this distance ahead of the current buffer by skipping data instead of calling the pro...
Definition: aviobuf.c:42
static const uint8_t offset[127][2]
Definition: vf_spp.c:70
#define FFMAX(a, b)
Definition: common.h:56
int direct
avio_read and avio_write should if possible be satisfied directly instead of going through a buffer...
Definition: avio.h:130
unsigned int avio_rl16(AVIOContext *s)
Definition: aviobuf.c:563
int size
int seek_count
seek statistic This field is internal to libavformat and access from outside is not allowed...
Definition: avio.h:142
int avio_pause(AVIOContext *s, int pause)
Pause and resume playing - only meaningful if using a network streaming protocol (e.g.
Definition: aviobuf.c:859
#define FF_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding...
unsigned int avio_rl32(AVIOContext *s)
Definition: aviobuf.c:579
int size
Definition: aviobuf.c:889
int(* read_packet)(void *opaque, uint8_t *buf, int buf_size)
Definition: avio.h:91
int seekable
A combination of AVIO_SEEKABLE_ flags or 0 when the stream is not seekable.
Definition: avio.h:117
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:199
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition: avassert.h:53
#define FFMIN(a, b)
Definition: common.h:58
int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
Return the written size and a pointer to the buffer.
Definition: aviobuf.c:988
unsigned char * checksum_ptr
Definition: avio.h:100
struct DynBuffer DynBuffer
ret
Definition: avfilter.c:821
int avio_printf(AVIOContext *s, const char *fmt,...)
Definition: aviobuf.c:846
int64_t(* seek)(void *opaque, int64_t offset, int whence)
Definition: avio.h:93
int allocated_size
Definition: aviobuf.c:889
int must_flush
true if the next seek should flush
Definition: avio.h:95
static int dyn_buf_write(void *opaque, uint8_t *buf, int buf_size)
Definition: aviobuf.c:895
int ff_get_line(AVIOContext *s, char *buf, int maxlen)
Read a whole line of text from AVIOContext.
Definition: aviobuf.c:618
#define GET_STR16(type, read)
Definition: aviobuf.c:651
int buffer_size
Maximum buffer size.
Definition: avio.h:83
LIBAVUTIL_VERSION_INT
Definition: eval.c:55
void avio_wb64(AVIOContext *s, uint64_t val)
Definition: aviobuf.c:361
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:478
uint8_t le
Definition: crc.c:215
#define AVIO_SEEKABLE_NORMAL
Seeking works like for a local file.
Definition: avio.h:38
NULL
Definition: eval.c:55
int ffio_open_dyn_packet_buf(AVIOContext **s, int max_packet_size)
Open a write only packetized memory stream with a maximum packet size of &#39;max_packet_size&#39;.
Definition: aviobuf.c:981
int avio_open(AVIOContext **s, const char *filename, int flags)
Create and initialize a AVIOContext for accessing the resource indicated by url.
Definition: aviobuf.c:799
int ffio_rewind_with_probe_data(AVIOContext *s, unsigned char **bufp, int buf_size)
Rewind the AVIOContext using the specified buffer containing the first buf_size bytes of the file...
Definition: aviobuf.c:755
static int url_resetbuf(AVIOContext *s, int flags)
Definition: aviobuf.c:741
int(* url_read_pause)(URLContext *h, int pause)
Definition: url.h:81
uint64_t avio_rl64(AVIOContext *s)
Definition: aviobuf.c:587
int avio_close(AVIOContext *s)
Close the resource accessed by the AVIOContext s and free it.
Definition: aviobuf.c:821
int(* write_packet)(void *opaque, uint8_t *buf, int buf_size)
Definition: avio.h:92
void * buf
Definition: avisynth_c.h:594
Definition: url.h:41
static int read_packet(AVFormatContext *ctx, AVPacket *pkt)
Definition: libcdio.c:114
void * av_malloc(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:73
Describe the class of an AVClass context structure.
Definition: log.h:50
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition: aviobuf.c:173
#define AVSEEK_FORCE
Oring this flag as into the "whence" parameter to a seek function causes it to seek by any means (lik...
Definition: avio.h:230
synthesis window for stochastic i
#define AVIO_FLAG_DIRECT
Use direct mode.
Definition: avio.h:359
unsigned int avio_rb16(AVIOContext *s)
Definition: aviobuf.c:595
int pos
Definition: aviobuf.c:889
pause
Definition: plot_peaks.m:14
#define PUT_UTF16(val, tmp, PUT_16BIT)
Convert a 32-bit Unicode character to its UTF-16 encoded form (2 or 4 bytes).
Definition: common.h:383
int error
contains the error code or 0 if no error happened
Definition: avio.h:102
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Buffer references ownership and permissions
int ff_get_v_length(uint64_t val)
Get the length in bytes which is needed to store val as v.
Definition: aviobuf.c:335
static int flags
Definition: cpu.c:23
int ffurl_close(URLContext *h)
Definition: avio.c:359
const AVClass ffurl_context_class
Definition: avio.c:75
int avio_open2(AVIOContext **s, const char *filename, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options)
Create and initialize a AVIOContext for accessing the resource indicated by url.
Definition: aviobuf.c:804
int(* read_pause)(void *opaque, int pause)
Pause or resume playback for network streaming protocols - e.g.
Definition: avio.h:106
int64_t avio_size(AVIOContext *s)
Get the filesize.
Definition: aviobuf.c:261
Main libavformat public API header.
const AVClass ffio_url_class
Definition: aviobuf.c:59
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:162
int avio_get_str(AVIOContext *s, int maxlen, char *buf, int buflen)
Read a string from pb into buf.
Definition: aviobuf.c:633
int64_t ffurl_seek(URLContext *h, int64_t pos, int whence)
Change the position that will be used by the next read/write operation on the resource accessed by h...
Definition: avio.c:328
static void * ffio_url_child_next(void *obj, void *prev)
Definition: aviobuf.c:44
int ffurl_open(URLContext **puc, const char *filename, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options)
Create an URLContext for accessing to the resource indicated by url, and open it. ...
Definition: avio.c:247
unsigned long(* update_checksum)(unsigned long checksum, const uint8_t *buf, unsigned int size)
Definition: avio.h:101
int ffio_fdopen(AVIOContext **s, URLContext *h)
Create and initialize a AVIOContext for accessing the resource referenced by the URLContext h...
Definition: aviobuf.c:694
void ffio_init_checksum(AVIOContext *s, unsigned long(*update_checksum)(unsigned long c, const uint8_t *p, unsigned int len), unsigned long checksum)
Definition: aviobuf.c:457
static double c[64]
int64_t pos
position in the file of the current buffer
Definition: avio.h:94
the buffer and buffer reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFilterBuffer structures They must not be accessed but through references stored in AVFilterBufferRef structures Several references can point to the same buffer
#define AVSEEK_SIZE
Passing this as the "whence" parameter to a seek function causes it to return the filesize without se...
Definition: avio.h:222
uint64_t ffio_read_varlen(AVIOContext *bc)
Definition: aviobuf.c:683
unsigned int avio_rb32(AVIOContext *s)
Definition: aviobuf.c:610
uint8_t * buffer
Definition: aviobuf.c:890
int eof_reached
true if eof reached
Definition: avio.h:96
void ff_put_v(AVIOContext *bc, uint64_t val)
Put val using a variable number of bytes.
Definition: aviobuf.c:345
int len
else dst[i][x+y *dst_stride[i]]
Definition: vf_mcdeint.c:160
static void writeout(AVIOContext *s, const uint8_t *data, int len)
Definition: aviobuf.c:126
static int url_open_dyn_buf_internal(AVIOContext **s, int max_packet_size)
Definition: aviobuf.c:954
int max_packet_size
if non zero, the stream is packetized with this max packet size
Definition: url.h:47
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition: aviobuf.c:256
void INT64 INT64 count
Definition: avisynth_c.h:594
unbuffered private I/O API
int avio_put_str16le(AVIOContext *s, const char *str)
Convert an UTF-8 string to UTF-16LE and write it.
Definition: aviobuf.c:318
unsigned long ff_crc04C11DB7_update(unsigned long checksum, const uint8_t *buf, unsigned int len)
Definition: aviobuf.c:443
int avio_r8(AVIOContext *s)
Definition: aviobuf.c:469
int ffurl_read(URLContext *h, unsigned char *buf, int size)
Read up to size bytes from the resource accessed by h, and store the read bytes in buf...
Definition: avio.c:303
int64_t(* read_seek)(void *opaque, int stream_index, int64_t timestamp, int flags)
Seek to a given timestamp in stream with the specified stream_index.
Definition: avio.h:112
int64_t avio_seek_time(AVIOContext *s, int stream_index, int64_t timestamp, int flags)
Seek to a given timestamp relative to some component stream.
Definition: aviobuf.c:866
int64_t(* url_read_seek)(URLContext *h, int stream_index, int64_t timestamp, int flags)
Definition: url.h:82