if (!buffer)
return AVERROR(ENOMEM);
- *s = avio_alloc_context(buffer, buffer_size, h->flags & AVIO_FLAG_WRITE, h,
- (int (*)(void *, uint8_t *, int)) ffurl_read,
- (int (*)(void *, uint8_t *, int)) ffurl_write,
- (int64_t (*)(void *, int64_t, int)) ffurl_seek);
- if (!*s) {
- av_free(buffer);
- return AVERROR(ENOMEM);
- }
+ internal = av_mallocz(sizeof(*internal));
+ if (!internal)
+ goto fail;
+
+ internal->h = h;
+
+ *s = avio_alloc_context(buffer, buffer_size, h->flags & AVIO_FLAG_WRITE,
+ internal, io_read_packet, io_write_packet, io_seek);
+ if (!*s)
+ goto fail;
+
+ (*s)->protocol_whitelist = av_strdup(h->protocol_whitelist);
+ if (!(*s)->protocol_whitelist && h->protocol_whitelist) {
+ avio_closep(s);
- return AVERROR(ENOMEM);
++ goto fail;
+ }
+ (*s)->direct = h->flags & AVIO_FLAG_DIRECT;
++
(*s)->seekable = h->is_streamed ? 0 : AVIO_SEEKABLE_NORMAL;
(*s)->max_packet_size = max_packet_size;
if(h->prot) {
}
(*s)->av_class = &ff_avio_class;
return 0;
+ fail:
+ av_freep(&internal);
+ av_freep(&buffer);
+ return AVERROR(ENOMEM);
}
+int ffio_ensure_seekback(AVIOContext *s, int64_t buf_size)
+{
+ uint8_t *buffer;
+ int max_buffer_size = s->max_packet_size ?
+ s->max_packet_size : IO_BUFFER_SIZE;
+ int filled = s->buf_end - s->buffer;
+ ptrdiff_t checksum_ptr_offset = s->checksum_ptr ? s->checksum_ptr - s->buffer : -1;
+
+ buf_size += s->buf_ptr - s->buffer + max_buffer_size;
+
+ if (buf_size < filled || s->seekable || !s->read_packet)
+ return 0;
+ av_assert0(!s->write_flag);
+
+ buffer = av_malloc(buf_size);
+ if (!buffer)
+ return AVERROR(ENOMEM);
+
+ memcpy(buffer, s->buffer, filled);
+ av_free(s->buffer);
+ s->buf_ptr = buffer + (s->buf_ptr - s->buffer);
+ s->buf_end = buffer + (s->buf_end - s->buffer);
+ s->buffer = buffer;
+ s->buffer_size = buf_size;
+ if (checksum_ptr_offset >= 0)
+ s->checksum_ptr = s->buffer + checksum_ptr_offset;
+ return 0;
+}
+
int ffio_set_buf_size(AVIOContext *s, int buf_size)
{
uint8_t *buffer;
return 0;
}
+int avio_open2(AVIOContext **s, const char *filename, int flags,
+ const AVIOInterruptCB *int_cb, AVDictionary **options)
+{
+ return ffio_open_whitelist(s, filename, flags, int_cb, options, NULL);
+}
+
+int ffio_open2_wrapper(struct AVFormatContext *s, AVIOContext **pb, const char *url, int flags,
+ const AVIOInterruptCB *int_cb, AVDictionary **options)
+{
+ return ffio_open_whitelist(pb, url, flags, int_cb, options, s->protocol_whitelist);
+}
+
int avio_close(AVIOContext *s)
{
+ AVIOInternal *internal;
URLContext *h;
if (!s)
return 0;
avio_flush(s);
- h = s->opaque;
+ internal = s->opaque;
+ h = internal->h;
+
+ av_freep(&s->opaque);
av_freep(&s->buffer);
+ if (s->write_flag)
+ av_log(s, AV_LOG_DEBUG, "Statistics: %d seeks, %d writeouts\n", s->seek_count, s->writeout_count);
+ else
+ av_log(s, AV_LOG_DEBUG, "Statistics: %"PRId64" bytes read, %d seeks\n", s->bytes_read, s->seek_count);
+ av_opt_free(s);
av_free(s);
return ffurl_close(h);
}