LCOV - code coverage report
Current view: top level - libavformat - aviobuf.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 710 829 85.6 %
Date: 2018-05-20 11:54:08 Functions: 88 94 93.6 %

          Line data    Source code
       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/bprint.h"
      23             : #include "libavutil/crc.h"
      24             : #include "libavutil/dict.h"
      25             : #include "libavutil/intreadwrite.h"
      26             : #include "libavutil/log.h"
      27             : #include "libavutil/opt.h"
      28             : #include "libavutil/avassert.h"
      29             : #include "avformat.h"
      30             : #include "avio.h"
      31             : #include "avio_internal.h"
      32             : #include "internal.h"
      33             : #include "url.h"
      34             : #include <stdarg.h>
      35             : 
      36             : #define IO_BUFFER_SIZE 32768
      37             : 
      38             : /**
      39             :  * Do seeks within this distance ahead of the current buffer by skipping
      40             :  * data instead of calling the protocol seek function, for seekable
      41             :  * protocols.
      42             :  */
      43             : #define SHORT_SEEK_THRESHOLD 4096
      44             : 
      45             : typedef struct AVIOInternal {
      46             :     URLContext *h;
      47             : } AVIOInternal;
      48             : 
      49      876018 : static void *ff_avio_child_next(void *obj, void *prev)
      50             : {
      51      876018 :     AVIOContext *s = obj;
      52      876018 :     AVIOInternal *internal = s->opaque;
      53      876018 :     return prev ? NULL : internal->h;
      54             : }
      55             : 
      56      116972 : static const AVClass *ff_avio_child_class_next(const AVClass *prev)
      57             : {
      58      116972 :     return prev ? NULL : &ffurl_context_class;
      59             : }
      60             : 
      61             : #define OFFSET(x) offsetof(AVIOContext,x)
      62             : #define E AV_OPT_FLAG_ENCODING_PARAM
      63             : #define D AV_OPT_FLAG_DECODING_PARAM
      64             : static const AVOption ff_avio_options[] = {
      65             :     {"protocol_whitelist", "List of protocols that are allowed to be used", OFFSET(protocol_whitelist), AV_OPT_TYPE_STRING, { .str = NULL },  CHAR_MIN, CHAR_MAX, D },
      66             :     { NULL },
      67             : };
      68             : 
      69             : const AVClass ff_avio_class = {
      70             :     .class_name = "AVIOContext",
      71             :     .item_name  = av_default_item_name,
      72             :     .version    = LIBAVUTIL_VERSION_INT,
      73             :     .option     = ff_avio_options,
      74             :     .child_next = ff_avio_child_next,
      75             :     .child_class_next = ff_avio_child_class_next,
      76             : };
      77             : 
      78             : static void fill_buffer(AVIOContext *s);
      79             : static int url_resetbuf(AVIOContext *s, int flags);
      80             : 
      81      161397 : int ffio_init_context(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      161397 :     memset(s, 0, sizeof(AVIOContext));
      91             : 
      92      161397 :     s->buffer      = buffer;
      93      161397 :     s->orig_buffer_size =
      94      161397 :     s->buffer_size = buffer_size;
      95      161397 :     s->buf_ptr     = buffer;
      96      161397 :     s->buf_ptr_max = buffer;
      97      161397 :     s->opaque      = opaque;
      98      161397 :     s->direct      = 0;
      99             : 
     100      161397 :     url_resetbuf(s, write_flag ? AVIO_FLAG_WRITE : AVIO_FLAG_READ);
     101             : 
     102      161397 :     s->write_packet    = write_packet;
     103      161397 :     s->read_packet     = read_packet;
     104      161397 :     s->seek            = seek;
     105      161397 :     s->pos             = 0;
     106      161397 :     s->eof_reached     = 0;
     107      161397 :     s->error           = 0;
     108      161397 :     s->seekable        = seek ? AVIO_SEEKABLE_NORMAL : 0;
     109      161397 :     s->min_packet_size = 0;
     110      161397 :     s->max_packet_size = 0;
     111      161397 :     s->update_checksum = NULL;
     112      161397 :     s->short_seek_threshold = SHORT_SEEK_THRESHOLD;
     113             : 
     114      161397 :     if (!read_packet && !write_flag) {
     115       59438 :         s->pos     = buffer_size;
     116       59438 :         s->buf_end = s->buffer + buffer_size;
     117             :     }
     118      161397 :     s->read_pause = NULL;
     119      161397 :     s->read_seek  = NULL;
     120             : 
     121      161397 :     s->write_data_type       = NULL;
     122      161397 :     s->ignore_boundary_point = 0;
     123      161397 :     s->current_type          = AVIO_DATA_MARKER_UNKNOWN;
     124      161397 :     s->last_time             = AV_NOPTS_VALUE;
     125      161397 :     s->short_seek_get        = NULL;
     126      161397 :     s->written               = 0;
     127             : 
     128      161397 :     return 0;
     129             : }
     130             : 
     131      101747 : AVIOContext *avio_alloc_context(
     132             :                   unsigned char *buffer,
     133             :                   int buffer_size,
     134             :                   int write_flag,
     135             :                   void *opaque,
     136             :                   int (*read_packet)(void *opaque, uint8_t *buf, int buf_size),
     137             :                   int (*write_packet)(void *opaque, uint8_t *buf, int buf_size),
     138             :                   int64_t (*seek)(void *opaque, int64_t offset, int whence))
     139             : {
     140      101747 :     AVIOContext *s = av_malloc(sizeof(AVIOContext));
     141      101747 :     if (!s)
     142           0 :         return NULL;
     143      101747 :     ffio_init_context(s, buffer, buffer_size, write_flag, opaque,
     144             :                   read_packet, write_packet, seek);
     145      101747 :     return s;
     146             : }
     147             : 
     148      101749 : void avio_context_free(AVIOContext **ps)
     149             : {
     150      101749 :     av_freep(ps);
     151      101749 : }
     152             : 
     153      284576 : static void writeout(AVIOContext *s, const uint8_t *data, int len)
     154             : {
     155      284576 :     if (!s->error) {
     156      284576 :         int ret = 0;
     157      284576 :         if (s->write_data_type)
     158         119 :             ret = s->write_data_type(s->opaque, (uint8_t *)data,
     159             :                                      len,
     160             :                                      s->current_type,
     161             :                                      s->last_time);
     162      284457 :         else if (s->write_packet)
     163      284457 :             ret = s->write_packet(s->opaque, (uint8_t *)data, len);
     164      284576 :         if (ret < 0) {
     165           0 :             s->error = ret;
     166             :         } else {
     167      284576 :             if (s->pos + len > s->written)
     168      282531 :                 s->written = s->pos + len;
     169             :         }
     170             :     }
     171      569107 :     if (s->current_type == AVIO_DATA_MARKER_SYNC_POINT ||
     172      284531 :         s->current_type == AVIO_DATA_MARKER_BOUNDARY_POINT) {
     173          48 :         s->current_type = AVIO_DATA_MARKER_UNKNOWN;
     174             :     }
     175      284576 :     s->last_time = AV_NOPTS_VALUE;
     176      284576 :     s->writeout_count ++;
     177      284576 :     s->pos += len;
     178      284576 : }
     179             : 
     180      393519 : static void flush_buffer(AVIOContext *s)
     181             : {
     182      393519 :     s->buf_ptr_max = FFMAX(s->buf_ptr, s->buf_ptr_max);
     183      393519 :     if (s->write_flag && s->buf_ptr_max > s->buffer) {
     184      284576 :         writeout(s, s->buffer, s->buf_ptr_max - s->buffer);
     185      284576 :         if (s->update_checksum) {
     186        1628 :             s->checksum     = s->update_checksum(s->checksum, s->checksum_ptr,
     187         814 :                                                  s->buf_ptr_max - s->checksum_ptr);
     188         814 :             s->checksum_ptr = s->buffer;
     189             :         }
     190             :     }
     191      393519 :     s->buf_ptr = s->buf_ptr_max = s->buffer;
     192      393519 :     if (!s->write_flag)
     193       75851 :         s->buf_end = s->buffer;
     194      393519 : }
     195             : 
     196     4347805 : void avio_w8(AVIOContext *s, int b)
     197             : {
     198             :     av_assert2(b>=-128 && b<=255);
     199     4347805 :     *s->buf_ptr++ = b;
     200     4347805 :     if (s->buf_ptr >= s->buf_end)
     201          29 :         flush_buffer(s);
     202     4347805 : }
     203             : 
     204        1203 : void ffio_fill(AVIOContext *s, int b, int count)
     205             : {
     206        3542 :     while (count > 0) {
     207        1136 :         int len = FFMIN(s->buf_end - s->buf_ptr, count);
     208        1136 :         memset(s->buf_ptr, b, len);
     209        1136 :         s->buf_ptr += len;
     210             : 
     211        1136 :         if (s->buf_ptr >= s->buf_end)
     212           0 :             flush_buffer(s);
     213             : 
     214        1136 :         count -= len;
     215             :     }
     216        1203 : }
     217             : 
     218      571134 : void avio_write(AVIOContext *s, const unsigned char *buf, int size)
     219             : {
     220      571134 :     if (s->direct && !s->update_checksum) {
     221           0 :         avio_flush(s);
     222           0 :         writeout(s, buf, size);
     223           0 :         return;
     224             :     }
     225     1763393 :     while (size > 0) {
     226      621125 :         int len = FFMIN(s->buf_end - s->buf_ptr, size);
     227      621125 :         memcpy(s->buf_ptr, buf, len);
     228      621125 :         s->buf_ptr += len;
     229             : 
     230      621125 :         if (s->buf_ptr >= s->buf_end)
     231       55606 :             flush_buffer(s);
     232             : 
     233      621125 :         buf += len;
     234      621125 :         size -= len;
     235             :     }
     236             : }
     237             : 
     238      334402 : void avio_flush(AVIOContext *s)
     239             : {
     240      334402 :     int seekback = s->write_flag ? FFMIN(0, s->buf_ptr - s->buf_ptr_max) : 0;
     241      334402 :     flush_buffer(s);
     242      334402 :     if (seekback)
     243           7 :         avio_seek(s, seekback, SEEK_CUR);
     244      334402 : }
     245             : 
     246     4975332 : int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
     247             : {
     248             :     int64_t offset1;
     249             :     int64_t pos;
     250     4975332 :     int force = whence & AVSEEK_FORCE;
     251             :     int buffer_size;
     252             :     int short_seek;
     253     4975332 :     whence &= ~AVSEEK_FORCE;
     254             : 
     255     4975332 :     if(!s)
     256        4680 :         return AVERROR(EINVAL);
     257             : 
     258     4970652 :     buffer_size = s->buf_end - s->buffer;
     259             :     // pos is the absolute position that the beginning of s->buffer corresponds to in the file
     260     4970652 :     pos = s->pos - (s->write_flag ? 0 : buffer_size);
     261             : 
     262     4970652 :     if (whence != SEEK_CUR && whence != SEEK_SET)
     263           1 :         return AVERROR(EINVAL);
     264             : 
     265     4970651 :     if (whence == SEEK_CUR) {
     266     4787761 :         offset1 = pos + (s->buf_ptr - s->buffer);
     267     4787761 :         if (offset == 0)
     268     4542728 :             return offset1;
     269      245033 :         if (offset > INT64_MAX - offset1)
     270           3 :             return AVERROR(EINVAL);
     271      245030 :         offset += offset1;
     272             :     }
     273      427920 :     if (offset < 0)
     274          58 :         return AVERROR(EINVAL);
     275             : 
     276      427862 :     if (s->short_seek_get) {
     277      417536 :         short_seek = s->short_seek_get(s->opaque);
     278             :         /* fallback to default short seek */
     279      417536 :         if (short_seek <= 0)
     280      417536 :             short_seek = s->short_seek_threshold;
     281             :     } else
     282       10326 :         short_seek = s->short_seek_threshold;
     283             : 
     284      427862 :     offset1 = offset - pos; // "offset1" is the relative offset from the beginning of s->buffer
     285      427862 :     s->buf_ptr_max = FFMAX(s->buf_ptr_max, s->buf_ptr);
     286      427862 :     if ((!s->direct || !s->seek) &&
     287      419893 :         offset1 >= 0 && offset1 <= (s->write_flag ? s->buf_ptr_max - s->buffer : buffer_size)) {
     288             :         /* can do the seek inside the buffer */
     289      413010 :         s->buf_ptr = s->buffer + offset1;
     290       29699 :     } else if ((!(s->seekable & AVIO_SEEKABLE_NORMAL) ||
     291       25566 :                offset1 <= buffer_size + short_seek) &&
     292       20967 :                !s->write_flag && offset1 >= 0 &&
     293        2162 :                (!s->direct || !s->seek) &&
     294           0 :               (whence != SEEK_END || force)) {
     295        6140 :         while(s->pos < offset && !s->eof_reached)
     296        1848 :             fill_buffer(s);
     297        2146 :         if (s->eof_reached)
     298         322 :             return AVERROR_EOF;
     299        1824 :         s->buf_ptr = s->buf_end - (s->pos - offset);
     300       12706 :     } else if(!s->write_flag && offset1 < 0 && -offset1 < buffer_size>>1 && s->seek && offset > 0) {
     301             :         int64_t res;
     302             : 
     303         451 :         pos -= FFMIN(buffer_size>>1, pos);
     304         451 :         if ((res = s->seek(s->opaque, pos, SEEK_SET)) < 0)
     305           0 :             return res;
     306         451 :         s->buf_end =
     307         451 :         s->buf_ptr = s->buffer;
     308         451 :         s->pos = pos;
     309         451 :         s->eof_reached = 0;
     310         451 :         fill_buffer(s);
     311         451 :         return avio_seek(s, offset, SEEK_SET | force);
     312             :     } else {
     313             :         int64_t res;
     314       12255 :         if (s->write_flag) {
     315        3482 :             flush_buffer(s);
     316             :         }
     317       12255 :         if (!s->seek)
     318           0 :             return AVERROR(EPIPE);
     319       12255 :         if ((res = s->seek(s->opaque, offset, SEEK_SET)) < 0)
     320           4 :             return res;
     321       12251 :         s->seek_count ++;
     322       12251 :         if (!s->write_flag)
     323        8773 :             s->buf_end = s->buffer;
     324       12251 :         s->buf_ptr = s->buf_ptr_max = s->buffer;
     325       12251 :         s->pos = offset;
     326             :     }
     327      427085 :     s->eof_reached = 0;
     328      427085 :     return offset;
     329             : }
     330             : 
     331      246372 : int64_t avio_skip(AVIOContext *s, int64_t offset)
     332             : {
     333      246372 :     return avio_seek(s, offset, SEEK_CUR);
     334             : }
     335             : 
     336       95521 : int64_t avio_size(AVIOContext *s)
     337             : {
     338             :     int64_t size;
     339             : 
     340       95521 :     if (!s)
     341          48 :         return AVERROR(EINVAL);
     342             : 
     343       95473 :     if (s->written)
     344        5576 :         return s->written;
     345             : 
     346       89897 :     if (!s->seek)
     347           1 :         return AVERROR(ENOSYS);
     348       89896 :     size = s->seek(s->opaque, 0, AVSEEK_SIZE);
     349       89896 :     if (size < 0) {
     350           5 :         if ((size = s->seek(s->opaque, -1, SEEK_END)) < 0)
     351           0 :             return size;
     352           5 :         size++;
     353           5 :         s->seek(s->opaque, s->pos, SEEK_SET);
     354             :     }
     355       89896 :     return size;
     356             : }
     357             : 
     358     5822766 : int avio_feof(AVIOContext *s)
     359             : {
     360     5822766 :     if(!s)
     361           0 :         return 0;
     362     5822766 :     if(s->eof_reached){
     363        6572 :         s->eof_reached=0;
     364        6572 :         fill_buffer(s);
     365             :     }
     366     5822766 :     return s->eof_reached;
     367             : }
     368             : 
     369      867643 : void avio_wl32(AVIOContext *s, unsigned int val)
     370             : {
     371      867643 :     avio_w8(s, (uint8_t) val       );
     372      867643 :     avio_w8(s, (uint8_t)(val >> 8 ));
     373      867643 :     avio_w8(s, (uint8_t)(val >> 16));
     374      867643 :     avio_w8(s,           val >> 24 );
     375      867643 : }
     376             : 
     377       94882 : void avio_wb32(AVIOContext *s, unsigned int val)
     378             : {
     379       94882 :     avio_w8(s,           val >> 24 );
     380       94882 :     avio_w8(s, (uint8_t)(val >> 16));
     381       94882 :     avio_w8(s, (uint8_t)(val >> 8 ));
     382       94882 :     avio_w8(s, (uint8_t) val       );
     383       94882 : }
     384             : 
     385         333 : int avio_put_str(AVIOContext *s, const char *str)
     386             : {
     387         333 :     int len = 1;
     388         333 :     if (str) {
     389         333 :         len += strlen(str);
     390         333 :         avio_write(s, (const unsigned char *) str, len);
     391             :     } else
     392           0 :         avio_w8(s, 0);
     393         333 :     return len;
     394             : }
     395             : 
     396          92 : static inline int put_str16(AVIOContext *s, const char *str, const int be)
     397             : {
     398          92 :     const uint8_t *q = str;
     399          92 :     int ret = 0;
     400          92 :     int err = 0;
     401             : 
     402         933 :     while (*q) {
     403             :         uint32_t ch;
     404             :         uint16_t tmp;
     405             : 
     406        1498 :         GET_UTF8(ch, *q++, goto invalid;)
     407         749 :         PUT_UTF16(ch, tmp, be ? avio_wb16(s, tmp) : avio_wl16(s, tmp);
     408             :                   ret += 2;)
     409         749 :         continue;
     410           0 : invalid:
     411           0 :         av_log(s, AV_LOG_ERROR, "Invalid UTF8 sequence in avio_put_str16%s\n", be ? "be" : "le");
     412           0 :         err = AVERROR(EINVAL);
     413           0 :         if (!*(q-1))
     414           0 :             break;
     415             :     }
     416          92 :     if (be)
     417          68 :         avio_wb16(s, 0);
     418             :     else
     419          24 :         avio_wl16(s, 0);
     420          92 :     if (err)
     421           0 :         return err;
     422          92 :     ret += 2;
     423          92 :     return ret;
     424             : }
     425             : 
     426             : #define PUT_STR16(type, big_endian)                          \
     427             : int avio_put_str16 ## type(AVIOContext *s, const char *str)  \
     428             : {                                                            \
     429             : return put_str16(s, str, big_endian);                        \
     430             : }
     431             : 
     432          24 : PUT_STR16(le, 0)
     433          68 : PUT_STR16(be, 1)
     434             : 
     435             : #undef PUT_STR16
     436             : 
     437      209461 : int ff_get_v_length(uint64_t val)
     438             : {
     439      209461 :     int i = 1;
     440             : 
     441      487579 :     while (val >>= 7)
     442       68657 :         i++;
     443             : 
     444      209461 :     return i;
     445             : }
     446             : 
     447      190047 : void ff_put_v(AVIOContext *bc, uint64_t val)
     448             : {
     449      190047 :     int i = ff_get_v_length(val);
     450             : 
     451      428785 :     while (--i > 0)
     452       48691 :         avio_w8(bc, 128 | (uint8_t)(val >> (7*i)));
     453             : 
     454      190047 :     avio_w8(bc, val & 127);
     455      190047 : }
     456             : 
     457      135408 : void avio_wl64(AVIOContext *s, uint64_t val)
     458             : {
     459      135408 :     avio_wl32(s, (uint32_t)(val & 0xffffffff));
     460      135408 :     avio_wl32(s, (uint32_t)(val >> 32));
     461      135408 : }
     462             : 
     463       18479 : void avio_wb64(AVIOContext *s, uint64_t val)
     464             : {
     465       18479 :     avio_wb32(s, (uint32_t)(val >> 32));
     466       18479 :     avio_wb32(s, (uint32_t)(val & 0xffffffff));
     467       18479 : }
     468             : 
     469        5700 : void avio_wl16(AVIOContext *s, unsigned int val)
     470             : {
     471        5700 :     avio_w8(s, (uint8_t)val);
     472        5700 :     avio_w8(s, (int)val >> 8);
     473        5700 : }
     474             : 
     475       33690 : void avio_wb16(AVIOContext *s, unsigned int val)
     476             : {
     477       33690 :     avio_w8(s, (int)val >> 8);
     478       33690 :     avio_w8(s, (uint8_t)val);
     479       33690 : }
     480             : 
     481          88 : void avio_wl24(AVIOContext *s, unsigned int val)
     482             : {
     483          88 :     avio_wl16(s, val & 0xffff);
     484          88 :     avio_w8(s, (int)val >> 16);
     485          88 : }
     486             : 
     487        8519 : void avio_wb24(AVIOContext *s, unsigned int val)
     488             : {
     489        8519 :     avio_wb16(s, (int)val >> 8);
     490        8519 :     avio_w8(s, (uint8_t)val);
     491        8519 : }
     492             : 
     493      442525 : void avio_write_marker(AVIOContext *s, int64_t time, enum AVIODataMarkerType type)
     494             : {
     495      442525 :     if (type == AVIO_DATA_MARKER_FLUSH_POINT) {
     496      426274 :         if (s->buf_ptr - s->buffer >= s->min_packet_size)
     497      213663 :             avio_flush(s);
     498      426274 :         return;
     499             :     }
     500       16251 :     if (!s->write_data_type)
     501       16076 :         return;
     502             :     // If ignoring boundary points, just treat it as unknown
     503         175 :     if (type == AVIO_DATA_MARKER_BOUNDARY_POINT && s->ignore_boundary_point)
     504           0 :         type = AVIO_DATA_MARKER_UNKNOWN;
     505             :     // Avoid unnecessary flushes if we are already in non-header/trailer
     506             :     // data and setting the type to unknown
     507         202 :     if (type == AVIO_DATA_MARKER_UNKNOWN &&
     508          27 :         (s->current_type != AVIO_DATA_MARKER_HEADER &&
     509           0 :          s->current_type != AVIO_DATA_MARKER_TRAILER))
     510           0 :         return;
     511             : 
     512         175 :     switch (type) {
     513         100 :     case AVIO_DATA_MARKER_HEADER:
     514             :     case AVIO_DATA_MARKER_TRAILER:
     515             :         // For header/trailer, ignore a new marker of the same type;
     516             :         // consecutive header/trailer markers can be merged.
     517         100 :         if (type == s->current_type)
     518          11 :             return;
     519          89 :         break;
     520             :     }
     521             : 
     522             :     // If we've reached here, we have a new, noteworthy marker.
     523             :     // Flush the previous data and mark the start of the new data.
     524         164 :     avio_flush(s);
     525         164 :     s->current_type = type;
     526         164 :     s->last_time = time;
     527             : }
     528             : 
     529      170130 : static int read_packet_wrapper(AVIOContext *s, uint8_t *buf, int size)
     530             : {
     531             :     int ret;
     532             : 
     533      170130 :     if (!s->read_packet)
     534           0 :         return AVERROR(EINVAL);
     535      170130 :     ret = s->read_packet(s->opaque, buf, size);
     536             : #if FF_API_OLD_AVIO_EOF_0
     537      170130 :     if (!ret && !s->max_packet_size) {
     538           1 :         av_log(NULL, AV_LOG_WARNING, "Invalid return value 0 for stream protocol\n");
     539           1 :         ret = AVERROR_EOF;
     540             :     }
     541             : #else
     542             :     av_assert2(ret || s->max_packet_size);
     543             : #endif
     544      170130 :     return ret;
     545             : }
     546             : 
     547             : /* Input stream */
     548             : 
     549       81696 : static void fill_buffer(AVIOContext *s)
     550             : {
     551      163392 :     int max_buffer_size = s->max_packet_size ?
     552       81696 :                           s->max_packet_size : IO_BUFFER_SIZE;
     553       81696 :     uint8_t *dst        = s->buf_end - s->buffer + max_buffer_size < s->buffer_size ?
     554             :                           s->buf_end : s->buffer;
     555       81696 :     int len             = s->buffer_size - (dst - s->buffer);
     556             : 
     557             :     /* can't fill the buffer without read_packet, just set EOF if appropriate */
     558       81696 :     if (!s->read_packet && s->buf_ptr >= s->buf_end)
     559           6 :         s->eof_reached = 1;
     560             : 
     561             :     /* no need to do anything if EOF already reached */
     562       81696 :     if (s->eof_reached)
     563        9560 :         return;
     564             : 
     565       72136 :     if (s->update_checksum && dst == s->buffer) {
     566          85 :         if (s->buf_end > s->checksum_ptr)
     567          76 :             s->checksum = s->update_checksum(s->checksum, s->checksum_ptr,
     568          38 :                                              s->buf_end - s->checksum_ptr);
     569          85 :         s->checksum_ptr = s->buffer;
     570             :     }
     571             : 
     572             :     /* make buffer smaller in case it ended up large after probing */
     573       72136 :     if (s->read_packet && s->orig_buffer_size && s->buffer_size > s->orig_buffer_size) {
     574         457 :         if (dst == s->buffer && s->buf_ptr != dst) {
     575           7 :             int ret = ffio_set_buf_size(s, s->orig_buffer_size);
     576           7 :             if (ret < 0)
     577           0 :                 av_log(s, AV_LOG_WARNING, "Failed to decrease buffer size\n");
     578             : 
     579           7 :             s->checksum_ptr = dst = s->buffer;
     580             :         }
     581         457 :         av_assert0(len >= s->orig_buffer_size);
     582         457 :         len = s->orig_buffer_size;
     583             :     }
     584             : 
     585       72136 :     len = read_packet_wrapper(s, dst, len);
     586       72136 :     if (len == AVERROR_EOF) {
     587             :         /* do not modify buffer if EOF reached so that a seek back can
     588             :            be done without rereading data */
     589       10499 :         s->eof_reached = 1;
     590       61637 :     } else if (len < 0) {
     591           0 :         s->eof_reached = 1;
     592           0 :         s->error= len;
     593             :     } else {
     594       61637 :         s->pos += len;
     595       61637 :         s->buf_ptr = dst;
     596       61637 :         s->buf_end = dst + len;
     597       61637 :         s->bytes_read += len;
     598             :     }
     599             : }
     600             : 
     601       23012 : unsigned long ff_crc04C11DB7_update(unsigned long checksum, const uint8_t *buf,
     602             :                                     unsigned int len)
     603             : {
     604       23012 :     return av_crc(av_crc_get_table(AV_CRC_32_IEEE), checksum, buf, len);
     605             : }
     606             : 
     607          14 : unsigned long ff_crcEDB88320_update(unsigned long checksum, const uint8_t *buf,
     608             :                                     unsigned int len)
     609             : {
     610          14 :     return av_crc(av_crc_get_table(AV_CRC_32_IEEE_LE), checksum, buf, len);
     611             : }
     612             : 
     613          49 : unsigned long ff_crcA001_update(unsigned long checksum, const uint8_t *buf,
     614             :                                 unsigned int len)
     615             : {
     616          49 :     return av_crc(av_crc_get_table(AV_CRC_16_ANSI_LE), checksum, buf, len);
     617             : }
     618             : 
     619       21350 : unsigned long ffio_get_checksum(AVIOContext *s)
     620             : {
     621       42700 :     s->checksum = s->update_checksum(s->checksum, s->checksum_ptr,
     622       21350 :                                      s->buf_ptr - s->checksum_ptr);
     623       21350 :     s->update_checksum = NULL;
     624       21350 :     return s->checksum;
     625             : }
     626             : 
     627       21386 : void ffio_init_checksum(AVIOContext *s,
     628             :                    unsigned long (*update_checksum)(unsigned long c, const uint8_t *p, unsigned int len),
     629             :                    unsigned long checksum)
     630             : {
     631       21386 :     s->update_checksum = update_checksum;
     632       21386 :     if (s->update_checksum) {
     633       21363 :         s->checksum     = checksum;
     634       21363 :         s->checksum_ptr = s->buf_ptr;
     635             :     }
     636       21386 : }
     637             : 
     638             : /* XXX: put an inline version */
     639     9530804 : int avio_r8(AVIOContext *s)
     640             : {
     641     9530804 :     if (s->buf_ptr >= s->buf_end)
     642       21295 :         fill_buffer(s);
     643     9530804 :     if (s->buf_ptr < s->buf_end)
     644     9520715 :         return *s->buf_ptr++;
     645       10089 :     return 0;
     646             : }
     647             : 
     648      644632 : int avio_read(AVIOContext *s, unsigned char *buf, int size)
     649             : {
     650             :     int len, size1;
     651             : 
     652      644632 :     size1 = size;
     653     1990626 :     while (size > 0) {
     654      703060 :         len = FFMIN(s->buf_end - s->buf_ptr, size);
     655      703060 :         if (len == 0 || s->write_flag) {
     656      262900 :             if((s->direct || size > s->buffer_size) && !s->update_checksum) {
     657             :                 // bypass the buffer and read data directly into buf
     658       97994 :                 len = read_packet_wrapper(s, buf, size);
     659      195526 :                 if (len == AVERROR_EOF) {
     660             :                     /* do not modify buffer if EOF reached so that a seek back can
     661             :                     be done without rereading data */
     662         462 :                     s->eof_reached = 1;
     663         462 :                     break;
     664       97532 :                 } else if (len < 0) {
     665           0 :                     s->eof_reached = 1;
     666           0 :                     s->error= len;
     667           0 :                     break;
     668             :                 } else {
     669       97532 :                     s->pos += len;
     670       97532 :                     s->bytes_read += len;
     671       97532 :                     size -= len;
     672       97532 :                     buf += len;
     673             :                     // reset the buffer
     674       97532 :                     s->buf_ptr = s->buffer;
     675       97532 :                     s->buf_end = s->buffer/* + len*/;
     676             :                 }
     677             :             } else {
     678       34305 :                 fill_buffer(s);
     679       34305 :                 len = s->buf_end - s->buf_ptr;
     680       34305 :                 if (len == 0)
     681        1236 :                     break;
     682             :             }
     683             :         } else {
     684      570761 :             memcpy(buf, s->buf_ptr, len);
     685      570761 :             buf += len;
     686      570761 :             s->buf_ptr += len;
     687      570761 :             size -= len;
     688             :         }
     689             :     }
     690      644632 :     if (size1 == size) {
     691        2862 :         if (s->error)      return s->error;
     692        2862 :         if (avio_feof(s))  return AVERROR_EOF;
     693             :     }
     694      643461 :     return size1 - size;
     695             : }
     696             : 
     697        2080 : int ffio_read_size(AVIOContext *s, unsigned char *buf, int size)
     698             : {
     699        2080 :     int ret = avio_read(s, buf, size);
     700        2080 :     if (ret != size)
     701           0 :         return AVERROR_INVALIDDATA;
     702        2080 :     return ret;
     703             : }
     704             : 
     705      275351 : int ffio_read_indirect(AVIOContext *s, unsigned char *buf, int size, const unsigned char **data)
     706             : {
     707      275351 :     if (s->buf_end - s->buf_ptr >= size && !s->write_flag) {
     708      273462 :         *data = s->buf_ptr;
     709      273462 :         s->buf_ptr += size;
     710      273462 :         return size;
     711             :     } else {
     712        1889 :         *data = buf;
     713        1889 :         return avio_read(s, buf, size);
     714             :     }
     715             : }
     716             : 
     717      492621 : int avio_read_partial(AVIOContext *s, unsigned char *buf, int size)
     718             : {
     719             :     int len;
     720             : 
     721      492621 :     if (size < 0)
     722           0 :         return -1;
     723             : 
     724      492621 :     if (s->read_packet && s->write_flag) {
     725           0 :         len = read_packet_wrapper(s, buf, size);
     726           0 :         if (len > 0)
     727           0 :             s->pos += len;
     728           0 :         return len;
     729             :     }
     730             : 
     731      492621 :     len = s->buf_end - s->buf_ptr;
     732      492621 :     if (len == 0) {
     733             :         /* Reset the buf_end pointer to the start of the buffer, to make sure
     734             :          * the fill_buffer call tries to read as much data as fits into the
     735             :          * full buffer, instead of just what space is left after buf_end.
     736             :          * This avoids returning partial packets at the end of the buffer,
     737             :          * for packet based inputs.
     738             :          */
     739       17225 :         s->buf_end = s->buf_ptr = s->buffer;
     740       17225 :         fill_buffer(s);
     741       17225 :         len = s->buf_end - s->buf_ptr;
     742             :     }
     743      492621 :     if (len > size)
     744      474993 :         len = size;
     745      492621 :     memcpy(buf, s->buf_ptr, len);
     746      492621 :     s->buf_ptr += len;
     747      492621 :     if (!len) {
     748        2138 :         if (s->error)      return s->error;
     749        2138 :         if (avio_feof(s))  return AVERROR_EOF;
     750             :     }
     751      490483 :     return len;
     752             : }
     753             : 
     754      800249 : unsigned int avio_rl16(AVIOContext *s)
     755             : {
     756             :     unsigned int val;
     757      800249 :     val = avio_r8(s);
     758      800249 :     val |= avio_r8(s) << 8;
     759      800249 :     return val;
     760             : }
     761             : 
     762         379 : unsigned int avio_rl24(AVIOContext *s)
     763             : {
     764             :     unsigned int val;
     765         379 :     val = avio_rl16(s);
     766         379 :     val |= avio_r8(s) << 16;
     767         379 :     return val;
     768             : }
     769             : 
     770      384816 : unsigned int avio_rl32(AVIOContext *s)
     771             : {
     772             :     unsigned int val;
     773      384816 :     val = avio_rl16(s);
     774      384816 :     val |= avio_rl16(s) << 16;
     775      384816 :     return val;
     776             : }
     777             : 
     778        4516 : uint64_t avio_rl64(AVIOContext *s)
     779             : {
     780             :     uint64_t val;
     781        4516 :     val = (uint64_t)avio_rl32(s);
     782        4516 :     val |= (uint64_t)avio_rl32(s) << 32;
     783        4516 :     return val;
     784             : }
     785             : 
     786      438109 : unsigned int avio_rb16(AVIOContext *s)
     787             : {
     788             :     unsigned int val;
     789      438109 :     val = avio_r8(s) << 8;
     790      438109 :     val |= avio_r8(s);
     791      438109 :     return val;
     792             : }
     793             : 
     794       16125 : unsigned int avio_rb24(AVIOContext *s)
     795             : {
     796             :     unsigned int val;
     797       16125 :     val = avio_rb16(s) << 8;
     798       16125 :     val |= avio_r8(s);
     799       16125 :     return val;
     800             : }
     801      172858 : unsigned int avio_rb32(AVIOContext *s)
     802             : {
     803             :     unsigned int val;
     804      172858 :     val = avio_rb16(s) << 16;
     805      172858 :     val |= avio_rb16(s);
     806      172858 :     return val;
     807             : }
     808             : 
     809         588 : int ff_get_line(AVIOContext *s, char *buf, int maxlen)
     810             : {
     811         588 :     int i = 0;
     812             :     char c;
     813             : 
     814             :     do {
     815       14083 :         c = avio_r8(s);
     816       14083 :         if (c && i < maxlen-1)
     817       14066 :             buf[i++] = c;
     818       14083 :     } while (c != '\n' && c != '\r' && c);
     819         588 :     if (c == '\r' && avio_r8(s) != '\n' && !avio_feof(s))
     820           0 :         avio_skip(s, -1);
     821             : 
     822         588 :     buf[i] = 0;
     823         588 :     return i;
     824             : }
     825             : 
     826          67 : int ff_get_chomp_line(AVIOContext *s, char *buf, int maxlen)
     827             : {
     828          67 :     int len = ff_get_line(s, buf, maxlen);
     829         196 :     while (len > 0 && av_isspace(buf[len - 1]))
     830          62 :         buf[--len] = '\0';
     831          67 :     return len;
     832             : }
     833             : 
     834         276 : int64_t ff_read_line_to_bprint(AVIOContext *s, AVBPrint *bp)
     835             : {
     836             :     int len, end;
     837         276 :     int64_t read = 0;
     838             :     char tmp[1024];
     839             :     char c;
     840             : 
     841             :     do {
     842         276 :         len = 0;
     843             :         do {
     844        4509 :             c = avio_r8(s);
     845        4509 :             end = (c == '\r' || c == '\n' || c == '\0');
     846        4509 :             if (!end)
     847        4233 :                 tmp[len++] = c;
     848        4509 :         } while (!end && len < sizeof(tmp));
     849         276 :         av_bprint_append_data(bp, tmp, len);
     850         276 :         read += len;
     851         276 :     } while (!end);
     852             : 
     853         276 :     if (c == '\r' && avio_r8(s) != '\n' && !avio_feof(s))
     854           0 :         avio_skip(s, -1);
     855             : 
     856         276 :     if (!c && s->error)
     857           0 :         return s->error;
     858             : 
     859         276 :     if (!c && !read && avio_feof(s))
     860           5 :         return AVERROR_EOF;
     861             : 
     862         271 :     return read;
     863             : }
     864             : 
     865         276 : int64_t ff_read_line_to_bprint_overwrite(AVIOContext *s, AVBPrint *bp)
     866             : {
     867             :     int64_t ret;
     868             : 
     869         276 :     av_bprint_clear(bp);
     870         276 :     ret = ff_read_line_to_bprint(s, bp);
     871         276 :     if (ret < 0)
     872           5 :         return ret;
     873             : 
     874         271 :     if (!av_bprint_is_complete(bp))
     875           0 :         return AVERROR(ENOMEM);
     876             : 
     877         271 :     return bp->len;
     878             : }
     879             : 
     880         365 : int avio_get_str(AVIOContext *s, int maxlen, char *buf, int buflen)
     881             : {
     882             :     int i;
     883             : 
     884         365 :     if (buflen <= 0)
     885           0 :         return AVERROR(EINVAL);
     886             :     // reserve 1 byte for terminating 0
     887         365 :     buflen = FFMIN(buflen - 1, maxlen);
     888        5991 :     for (i = 0; i < buflen; i++)
     889        5769 :         if (!(buf[i] = avio_r8(s)))
     890         143 :             return i + 1;
     891         222 :     buf[i] = 0;
     892         319 :     for (; i < maxlen; i++)
     893          99 :         if (!avio_r8(s))
     894           2 :             return i + 1;
     895         220 :     return maxlen;
     896             : }
     897             : 
     898             : #define GET_STR16(type, read) \
     899             :     int avio_get_str16 ##type(AVIOContext *pb, int maxlen, char *buf, int buflen)\
     900             : {\
     901             :     char* q = buf;\
     902             :     int ret = 0;\
     903             :     if (buflen <= 0) \
     904             :         return AVERROR(EINVAL); \
     905             :     while (ret + 1 < maxlen) {\
     906             :         uint8_t tmp;\
     907             :         uint32_t ch;\
     908             :         GET_UTF16(ch, (ret += 2) <= maxlen ? read(pb) : 0, break;)\
     909             :         if (!ch)\
     910             :             break;\
     911             :         PUT_UTF8(ch, tmp, if (q - buf < buflen - 1) *q++ = tmp;)\
     912             :     }\
     913             :     *q = 0;\
     914             :     return ret;\
     915             : }\
     916             : 
     917         599 : GET_STR16(le, avio_rl16)
     918         435 : GET_STR16(be, avio_rb16)
     919             : 
     920             : #undef GET_STR16
     921             : 
     922        6668 : uint64_t avio_rb64(AVIOContext *s)
     923             : {
     924             :     uint64_t val;
     925        6668 :     val = (uint64_t)avio_rb32(s) << 32;
     926        6668 :     val |= (uint64_t)avio_rb32(s);
     927        6668 :     return val;
     928             : }
     929             : 
     930       12782 : uint64_t ffio_read_varlen(AVIOContext *bc){
     931       12782 :     uint64_t val = 0;
     932             :     int tmp;
     933             : 
     934             :     do{
     935       22614 :         tmp = avio_r8(bc);
     936       22614 :         val= (val<<7) + (tmp&127);
     937       22614 :     }while(tmp&128);
     938       12782 :     return val;
     939             : }
     940             : 
     941      169747 : static int io_read_packet(void *opaque, uint8_t *buf, int buf_size)
     942             : {
     943      169747 :     AVIOInternal *internal = opaque;
     944      169747 :     return ffurl_read(internal->h, buf, buf_size);
     945             : }
     946             : 
     947      259586 : static int io_write_packet(void *opaque, uint8_t *buf, int buf_size)
     948             : {
     949      259586 :     AVIOInternal *internal = opaque;
     950      259586 :     return ffurl_write(internal->h, buf, buf_size);
     951             : }
     952             : 
     953      102151 : static int64_t io_seek(void *opaque, int64_t offset, int whence)
     954             : {
     955      102151 :     AVIOInternal *internal = opaque;
     956      102151 :     return ffurl_seek(internal->h, offset, whence);
     957             : }
     958             : 
     959      417536 : static int io_short_seek(void *opaque)
     960             : {
     961      417536 :     AVIOInternal *internal = opaque;
     962      417536 :     return ffurl_get_short_seek(internal->h);
     963             : }
     964             : 
     965           0 : static int io_read_pause(void *opaque, int pause)
     966             : {
     967           0 :     AVIOInternal *internal = opaque;
     968           0 :     if (!internal->h->prot->url_read_pause)
     969           0 :         return AVERROR(ENOSYS);
     970           0 :     return internal->h->prot->url_read_pause(internal->h, pause);
     971             : }
     972             : 
     973         311 : static int64_t io_read_seek(void *opaque, int stream_index, int64_t timestamp, int flags)
     974             : {
     975         311 :     AVIOInternal *internal = opaque;
     976         311 :     if (!internal->h->prot->url_read_seek)
     977         311 :         return AVERROR(ENOSYS);
     978           0 :     return internal->h->prot->url_read_seek(internal->h, stream_index, timestamp, flags);
     979             : }
     980             : 
     981       81895 : int ffio_fdopen(AVIOContext **s, URLContext *h)
     982             : {
     983       81895 :     AVIOInternal *internal = NULL;
     984       81895 :     uint8_t *buffer = NULL;
     985             :     int buffer_size, max_packet_size;
     986             : 
     987       81895 :     max_packet_size = h->max_packet_size;
     988       81895 :     if (max_packet_size) {
     989        1959 :         buffer_size = max_packet_size; /* no need to bufferize more than one packet */
     990             :     } else {
     991       79936 :         buffer_size = IO_BUFFER_SIZE;
     992             :     }
     993       81895 :     buffer = av_malloc(buffer_size);
     994       81895 :     if (!buffer)
     995           0 :         return AVERROR(ENOMEM);
     996             : 
     997       81895 :     internal = av_mallocz(sizeof(*internal));
     998       81895 :     if (!internal)
     999           0 :         goto fail;
    1000             : 
    1001       81895 :     internal->h = h;
    1002             : 
    1003       81895 :     *s = avio_alloc_context(buffer, buffer_size, h->flags & AVIO_FLAG_WRITE,
    1004             :                             internal, io_read_packet, io_write_packet, io_seek);
    1005       81895 :     if (!*s)
    1006           0 :         goto fail;
    1007             : 
    1008       81895 :     (*s)->protocol_whitelist = av_strdup(h->protocol_whitelist);
    1009       81895 :     if (!(*s)->protocol_whitelist && h->protocol_whitelist) {
    1010           0 :         avio_closep(s);
    1011           0 :         goto fail;
    1012             :     }
    1013       81895 :     (*s)->protocol_blacklist = av_strdup(h->protocol_blacklist);
    1014       81895 :     if (!(*s)->protocol_blacklist && h->protocol_blacklist) {
    1015           0 :         avio_closep(s);
    1016           0 :         goto fail;
    1017             :     }
    1018       81895 :     (*s)->direct = h->flags & AVIO_FLAG_DIRECT;
    1019             : 
    1020       81895 :     (*s)->seekable = h->is_streamed ? 0 : AVIO_SEEKABLE_NORMAL;
    1021       81895 :     (*s)->max_packet_size = max_packet_size;
    1022       81895 :     (*s)->min_packet_size = h->min_packet_size;
    1023       81895 :     if(h->prot) {
    1024       81895 :         (*s)->read_pause = io_read_pause;
    1025       81895 :         (*s)->read_seek  = io_read_seek;
    1026             : 
    1027       81895 :         if (h->prot->url_read_seek)
    1028           0 :             (*s)->seekable |= AVIO_SEEKABLE_TIME;
    1029             :     }
    1030       81895 :     (*s)->short_seek_get = io_short_seek;
    1031       81895 :     (*s)->av_class = &ff_avio_class;
    1032       81895 :     return 0;
    1033           0 : fail:
    1034           0 :     av_freep(&internal);
    1035           0 :     av_freep(&buffer);
    1036           0 :     return AVERROR(ENOMEM);
    1037             : }
    1038             : 
    1039           0 : URLContext* ffio_geturlcontext(AVIOContext *s)
    1040             : {
    1041             :     AVIOInternal *internal;
    1042           0 :     if (!s)
    1043           0 :         return NULL;
    1044             : 
    1045           0 :     internal = s->opaque;
    1046           0 :     if (internal && s->read_packet == io_read_packet)
    1047           0 :         return internal->h;
    1048             :     else
    1049           0 :         return NULL;
    1050             : }
    1051             : 
    1052        9747 : int ffio_ensure_seekback(AVIOContext *s, int64_t buf_size)
    1053             : {
    1054             :     uint8_t *buffer;
    1055       19494 :     int max_buffer_size = s->max_packet_size ?
    1056        9747 :                           s->max_packet_size : IO_BUFFER_SIZE;
    1057        9747 :     int filled = s->buf_end - s->buffer;
    1058        9747 :     ptrdiff_t checksum_ptr_offset = s->checksum_ptr ? s->checksum_ptr - s->buffer : -1;
    1059             : 
    1060        9747 :     buf_size += s->buf_ptr - s->buffer + max_buffer_size;
    1061             : 
    1062        9747 :     if (buf_size < filled || s->seekable || !s->read_packet)
    1063        9740 :         return 0;
    1064           7 :     av_assert0(!s->write_flag);
    1065             : 
    1066           7 :     buffer = av_malloc(buf_size);
    1067           7 :     if (!buffer)
    1068           0 :         return AVERROR(ENOMEM);
    1069             : 
    1070           7 :     memcpy(buffer, s->buffer, filled);
    1071           7 :     av_free(s->buffer);
    1072           7 :     s->buf_ptr = buffer + (s->buf_ptr - s->buffer);
    1073           7 :     s->buf_end = buffer + (s->buf_end - s->buffer);
    1074           7 :     s->buffer = buffer;
    1075           7 :     s->buffer_size = buf_size;
    1076           7 :     if (checksum_ptr_offset >= 0)
    1077           0 :         s->checksum_ptr = s->buffer + checksum_ptr_offset;
    1078           7 :     return 0;
    1079             : }
    1080             : 
    1081           7 : int ffio_set_buf_size(AVIOContext *s, int buf_size)
    1082             : {
    1083             :     uint8_t *buffer;
    1084           7 :     buffer = av_malloc(buf_size);
    1085           7 :     if (!buffer)
    1086           0 :         return AVERROR(ENOMEM);
    1087             : 
    1088           7 :     av_free(s->buffer);
    1089           7 :     s->buffer = buffer;
    1090           7 :     s->orig_buffer_size =
    1091           7 :     s->buffer_size = buf_size;
    1092           7 :     s->buf_ptr = s->buf_ptr_max = buffer;
    1093           7 :     url_resetbuf(s, s->write_flag ? AVIO_FLAG_WRITE : AVIO_FLAG_READ);
    1094           7 :     return 0;
    1095             : }
    1096             : 
    1097      161404 : static int url_resetbuf(AVIOContext *s, int flags)
    1098             : {
    1099             :     av_assert1(flags == AVIO_FLAG_WRITE || flags == AVIO_FLAG_READ);
    1100             : 
    1101      161404 :     if (flags & AVIO_FLAG_WRITE) {
    1102       26092 :         s->buf_end = s->buffer + s->buffer_size;
    1103       26092 :         s->write_flag = 1;
    1104             :     } else {
    1105      135312 :         s->buf_end = s->buffer;
    1106      135312 :         s->write_flag = 0;
    1107             :     }
    1108      161404 :     return 0;
    1109             : }
    1110             : 
    1111        3126 : int ffio_rewind_with_probe_data(AVIOContext *s, unsigned char **bufp, int buf_size)
    1112             : {
    1113             :     int64_t buffer_start;
    1114             :     int buffer_size;
    1115             :     int overlap, new_size, alloc_size;
    1116        3126 :     uint8_t *buf = *bufp;
    1117             : 
    1118        3126 :     if (s->write_flag) {
    1119           0 :         av_freep(bufp);
    1120           0 :         return AVERROR(EINVAL);
    1121             :     }
    1122             : 
    1123        3126 :     buffer_size = s->buf_end - s->buffer;
    1124             : 
    1125             :     /* the buffers must touch or overlap */
    1126        3126 :     if ((buffer_start = s->pos - buffer_size) > buf_size) {
    1127           0 :         av_freep(bufp);
    1128           0 :         return AVERROR(EINVAL);
    1129             :     }
    1130             : 
    1131        3126 :     overlap = buf_size - buffer_start;
    1132        3126 :     new_size = buf_size + buffer_size - overlap;
    1133             : 
    1134        3126 :     alloc_size = FFMAX(s->buffer_size, new_size);
    1135        3126 :     if (alloc_size > buf_size)
    1136        3089 :         if (!(buf = (*bufp) = av_realloc_f(buf, 1, alloc_size)))
    1137           0 :             return AVERROR(ENOMEM);
    1138             : 
    1139        3126 :     if (new_size > buf_size) {
    1140        2963 :         memcpy(buf + buf_size, s->buffer + overlap, buffer_size - overlap);
    1141        2963 :         buf_size = new_size;
    1142             :     }
    1143             : 
    1144        3126 :     av_free(s->buffer);
    1145        3126 :     s->buf_ptr = s->buffer = buf;
    1146        3126 :     s->buffer_size = alloc_size;
    1147        3126 :     s->pos = buf_size;
    1148        3126 :     s->buf_end = s->buf_ptr + buf_size;
    1149        3126 :     s->eof_reached = 0;
    1150             : 
    1151        3126 :     return 0;
    1152             : }
    1153             : 
    1154          33 : int avio_open(AVIOContext **s, const char *filename, int flags)
    1155             : {
    1156          33 :     return avio_open2(s, filename, flags, NULL, NULL);
    1157             : }
    1158             : 
    1159       81896 : int ffio_open_whitelist(AVIOContext **s, const char *filename, int flags,
    1160             :                          const AVIOInterruptCB *int_cb, AVDictionary **options,
    1161             :                          const char *whitelist, const char *blacklist
    1162             :                         )
    1163             : {
    1164             :     URLContext *h;
    1165             :     int err;
    1166             : 
    1167       81896 :     err = ffurl_open_whitelist(&h, filename, flags, int_cb, options, whitelist, blacklist, NULL);
    1168       81896 :     if (err < 0)
    1169           1 :         return err;
    1170       81895 :     err = ffio_fdopen(s, h);
    1171       81895 :     if (err < 0) {
    1172           0 :         ffurl_close(h);
    1173           0 :         return err;
    1174             :     }
    1175       81895 :     return 0;
    1176             : }
    1177             : 
    1178        5608 : int avio_open2(AVIOContext **s, const char *filename, int flags,
    1179             :                const AVIOInterruptCB *int_cb, AVDictionary **options)
    1180             : {
    1181        5608 :     return ffio_open_whitelist(s, filename, flags, int_cb, options, NULL, NULL);
    1182             : }
    1183             : 
    1184           0 : int ffio_open2_wrapper(struct AVFormatContext *s, AVIOContext **pb, const char *url, int flags,
    1185             :                        const AVIOInterruptCB *int_cb, AVDictionary **options)
    1186             : {
    1187           0 :     return ffio_open_whitelist(pb, url, flags, int_cb, options, s->protocol_whitelist, s->protocol_blacklist);
    1188             : }
    1189             : 
    1190       84110 : int avio_close(AVIOContext *s)
    1191             : {
    1192             :     AVIOInternal *internal;
    1193             :     URLContext *h;
    1194             : 
    1195       84110 :     if (!s)
    1196        2215 :         return 0;
    1197             : 
    1198       81895 :     avio_flush(s);
    1199       81895 :     internal = s->opaque;
    1200       81895 :     h        = internal->h;
    1201             : 
    1202       81895 :     av_freep(&s->opaque);
    1203       81895 :     av_freep(&s->buffer);
    1204       81895 :     if (s->write_flag)
    1205        6044 :         av_log(s, AV_LOG_DEBUG, "Statistics: %d seeks, %d writeouts\n", s->seek_count, s->writeout_count);
    1206             :     else
    1207       75851 :         av_log(s, AV_LOG_DEBUG, "Statistics: %"PRId64" bytes read, %d seeks\n", s->bytes_read, s->seek_count);
    1208       81895 :     av_opt_free(s);
    1209             : 
    1210       81895 :     avio_context_free(&s);
    1211             : 
    1212       81895 :     return ffurl_close(h);
    1213             : }
    1214             : 
    1215        5608 : int avio_closep(AVIOContext **s)
    1216             : {
    1217        5608 :     int ret = avio_close(*s);
    1218        5608 :     *s = NULL;
    1219        5608 :     return ret;
    1220             : }
    1221             : 
    1222       20332 : int avio_printf(AVIOContext *s, const char *fmt, ...)
    1223             : {
    1224             :     va_list ap;
    1225             :     char buf[4096]; /* update doc entry in avio.h if changed */
    1226             :     int ret;
    1227             : 
    1228       20332 :     va_start(ap, fmt);
    1229       20332 :     ret = vsnprintf(buf, sizeof(buf), fmt, ap);
    1230       20332 :     va_end(ap);
    1231       20332 :     avio_write(s, buf, strlen(buf));
    1232       20332 :     return ret;
    1233             : }
    1234             : 
    1235           0 : int avio_pause(AVIOContext *s, int pause)
    1236             : {
    1237           0 :     if (!s->read_pause)
    1238           0 :         return AVERROR(ENOSYS);
    1239           0 :     return s->read_pause(s->opaque, pause);
    1240             : }
    1241             : 
    1242         311 : int64_t avio_seek_time(AVIOContext *s, int stream_index,
    1243             :                        int64_t timestamp, int flags)
    1244             : {
    1245             :     int64_t ret;
    1246         311 :     if (!s->read_seek)
    1247           0 :         return AVERROR(ENOSYS);
    1248         311 :     ret = s->read_seek(s->opaque, stream_index, timestamp, flags);
    1249         311 :     if (ret >= 0) {
    1250             :         int64_t pos;
    1251           0 :         s->buf_ptr = s->buf_end; // Flush buffer
    1252           0 :         pos = s->seek(s->opaque, 0, SEEK_CUR);
    1253           0 :         if (pos >= 0)
    1254           0 :             s->pos = pos;
    1255           0 :         else if (pos != AVERROR(ENOSYS))
    1256           0 :             ret = pos;
    1257             :     }
    1258         311 :     return ret;
    1259             : }
    1260             : 
    1261           1 : int avio_read_to_bprint(AVIOContext *h, AVBPrint *pb, size_t max_size)
    1262             : {
    1263             :     int ret;
    1264             :     char buf[1024];
    1265           3 :     while (max_size) {
    1266           2 :         ret = avio_read(h, buf, FFMIN(max_size, sizeof(buf)));
    1267           2 :         if (ret == AVERROR_EOF)
    1268           1 :             return 0;
    1269           1 :         if (ret <= 0)
    1270           0 :             return ret;
    1271           1 :         av_bprint_append_data(pb, buf, ret);
    1272           1 :         if (!av_bprint_is_complete(pb))
    1273           0 :             return AVERROR(ENOMEM);
    1274           1 :         max_size -= ret;
    1275             :     }
    1276           0 :     return 0;
    1277             : }
    1278             : 
    1279           0 : int avio_accept(AVIOContext *s, AVIOContext **c)
    1280             : {
    1281             :     int ret;
    1282           0 :     AVIOInternal *internal = s->opaque;
    1283           0 :     URLContext *sc = internal->h;
    1284           0 :     URLContext *cc = NULL;
    1285           0 :     ret = ffurl_accept(sc, &cc);
    1286           0 :     if (ret < 0)
    1287           0 :         return ret;
    1288           0 :     return ffio_fdopen(c, cc);
    1289             : }
    1290             : 
    1291           0 : int avio_handshake(AVIOContext *c)
    1292             : {
    1293           0 :     AVIOInternal *internal = c->opaque;
    1294           0 :     URLContext *cc = internal->h;
    1295           0 :     return ffurl_handshake(cc);
    1296             : }
    1297             : 
    1298             : /* output in a dynamic buffer */
    1299             : 
    1300             : typedef struct DynBuffer {
    1301             :     int pos, size, allocated_size;
    1302             :     uint8_t *buffer;
    1303             :     int io_buffer_size;
    1304             :     uint8_t io_buffer[1];
    1305             : } DynBuffer;
    1306             : 
    1307       24864 : static int dyn_buf_write(void *opaque, uint8_t *buf, int buf_size)
    1308             : {
    1309       24864 :     DynBuffer *d = opaque;
    1310             :     unsigned new_size, new_allocated_size;
    1311             : 
    1312             :     /* reallocate buffer if needed */
    1313       24864 :     new_size = d->pos + buf_size;
    1314       24864 :     new_allocated_size = d->allocated_size;
    1315       24864 :     if (new_size < d->pos || new_size > INT_MAX/2)
    1316           0 :         return -1;
    1317       71412 :     while (new_size > new_allocated_size) {
    1318       21684 :         if (!new_allocated_size)
    1319       19707 :             new_allocated_size = new_size;
    1320             :         else
    1321        1977 :             new_allocated_size += new_allocated_size / 2 + 1;
    1322             :     }
    1323             : 
    1324       24864 :     if (new_allocated_size > d->allocated_size) {
    1325             :         int err;
    1326       20691 :         if ((err = av_reallocp(&d->buffer, new_allocated_size)) < 0) {
    1327           0 :             d->allocated_size = 0;
    1328           0 :             d->size = 0;
    1329           0 :             return err;
    1330             :         }
    1331       20691 :         d->allocated_size = new_allocated_size;
    1332             :     }
    1333       24864 :     memcpy(d->buffer + d->pos, buf, buf_size);
    1334       24864 :     d->pos = new_size;
    1335       24864 :     if (d->pos > d->size)
    1336       24781 :         d->size = d->pos;
    1337       24864 :     return buf_size;
    1338             : }
    1339             : 
    1340         276 : static int dyn_packet_buf_write(void *opaque, uint8_t *buf, int buf_size)
    1341             : {
    1342             :     unsigned char buf1[4];
    1343             :     int ret;
    1344             : 
    1345             :     /* packetized write: output the header */
    1346         276 :     AV_WB32(buf1, buf_size);
    1347         276 :     ret = dyn_buf_write(opaque, buf1, 4);
    1348         276 :     if (ret < 0)
    1349           0 :         return ret;
    1350             : 
    1351             :     /* then the data */
    1352         276 :     return dyn_buf_write(opaque, buf, buf_size);
    1353             : }
    1354             : 
    1355         404 : static int64_t dyn_buf_seek(void *opaque, int64_t offset, int whence)
    1356             : {
    1357         404 :     DynBuffer *d = opaque;
    1358             : 
    1359         404 :     if (whence == SEEK_CUR)
    1360           0 :         offset += d->pos;
    1361         404 :     else if (whence == SEEK_END)
    1362           0 :         offset += d->size;
    1363         404 :     if (offset < 0 || offset > 0x7fffffffLL)
    1364           0 :         return -1;
    1365         404 :     d->pos = offset;
    1366         404 :     return 0;
    1367             : }
    1368             : 
    1369       19809 : static int url_open_dyn_buf_internal(AVIOContext **s, int max_packet_size)
    1370             : {
    1371             :     DynBuffer *d;
    1372       19809 :     unsigned io_buffer_size = max_packet_size ? max_packet_size : 1024;
    1373             : 
    1374             :     if (sizeof(DynBuffer) + io_buffer_size < io_buffer_size)
    1375             :         return -1;
    1376       19809 :     d = av_mallocz(sizeof(DynBuffer) + io_buffer_size);
    1377       19809 :     if (!d)
    1378           0 :         return AVERROR(ENOMEM);
    1379       19809 :     d->io_buffer_size = io_buffer_size;
    1380       19809 :     *s = avio_alloc_context(d->io_buffer, d->io_buffer_size, 1, d, NULL,
    1381             :                             max_packet_size ? dyn_packet_buf_write : dyn_buf_write,
    1382             :                             max_packet_size ? NULL : dyn_buf_seek);
    1383       19809 :     if(!*s) {
    1384           0 :         av_free(d);
    1385           0 :         return AVERROR(ENOMEM);
    1386             :     }
    1387       19809 :     (*s)->max_packet_size = max_packet_size;
    1388       19809 :     return 0;
    1389             : }
    1390             : 
    1391       19638 : int avio_open_dyn_buf(AVIOContext **s)
    1392             : {
    1393       19638 :     return url_open_dyn_buf_internal(s, 0);
    1394             : }
    1395             : 
    1396          71 : int ffio_open_dyn_packet_buf(AVIOContext **s, int max_packet_size)
    1397             : {
    1398          71 :     if (max_packet_size <= 0)
    1399           0 :         return -1;
    1400          71 :     return url_open_dyn_buf_internal(s, max_packet_size);
    1401             : }
    1402             : 
    1403          15 : int avio_get_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
    1404             : {
    1405             :     DynBuffer *d;
    1406             : 
    1407          15 :     if (!s) {
    1408           0 :         *pbuffer = NULL;
    1409           0 :         return 0;
    1410             :     }
    1411             : 
    1412          15 :     avio_flush(s);
    1413             : 
    1414          15 :     d = s->opaque;
    1415          15 :     *pbuffer = d->buffer;
    1416             : 
    1417          15 :     return d->size;
    1418             : }
    1419             : 
    1420       19709 : int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
    1421             : {
    1422             :     DynBuffer *d;
    1423             :     int size;
    1424             :     static const char padbuf[AV_INPUT_BUFFER_PADDING_SIZE] = {0};
    1425       19709 :     int padding = 0;
    1426             : 
    1427       19709 :     if (!s) {
    1428           0 :         *pbuffer = NULL;
    1429           0 :         return 0;
    1430             :     }
    1431             : 
    1432             :     /* don't attempt to pad fixed-size packet buffers */
    1433       19709 :     if (!s->max_packet_size) {
    1434       19638 :         avio_write(s, padbuf, sizeof(padbuf));
    1435       19638 :         padding = AV_INPUT_BUFFER_PADDING_SIZE;
    1436             :     }
    1437             : 
    1438       19709 :     avio_flush(s);
    1439             : 
    1440       19709 :     d = s->opaque;
    1441       19709 :     *pbuffer = d->buffer;
    1442       19709 :     size = d->size;
    1443       19709 :     av_free(d);
    1444             : 
    1445       19709 :     avio_context_free(&s);
    1446             : 
    1447       19709 :     return size - padding;
    1448             : }
    1449             : 
    1450           2 : void ffio_free_dyn_buf(AVIOContext **s)
    1451             : {
    1452             :     uint8_t *tmp;
    1453           2 :     if (!*s)
    1454           0 :         return;
    1455           2 :     avio_close_dyn_buf(*s, &tmp);
    1456           2 :     av_free(tmp);
    1457           2 :     *s = NULL;
    1458             : }
    1459             : 
    1460         283 : static int null_buf_write(void *opaque, uint8_t *buf, int buf_size)
    1461             : {
    1462         283 :     DynBuffer *d = opaque;
    1463             : 
    1464         283 :     d->pos += buf_size;
    1465         283 :     if (d->pos > d->size)
    1466         162 :         d->size = d->pos;
    1467         283 :     return buf_size;
    1468             : }
    1469             : 
    1470         100 : int ffio_open_null_buf(AVIOContext **s)
    1471             : {
    1472         100 :     int ret = url_open_dyn_buf_internal(s, 0);
    1473         100 :     if (ret >= 0) {
    1474         100 :         AVIOContext *pb = *s;
    1475         100 :         pb->write_packet = null_buf_write;
    1476             :     }
    1477         100 :     return ret;
    1478             : }
    1479             : 
    1480         100 : int ffio_close_null_buf(AVIOContext *s)
    1481             : {
    1482         100 :     DynBuffer *d = s->opaque;
    1483             :     int size;
    1484             : 
    1485         100 :     avio_flush(s);
    1486             : 
    1487         100 :     size = d->size;
    1488         100 :     av_free(d);
    1489             : 
    1490         100 :     avio_context_free(&s);
    1491             : 
    1492         100 :     return size;
    1493             : }

Generated by: LCOV version 1.13