[03/13] avio: introduce an AVIOContext.seekable field

Message ID 1300131546-2880-3-git-send-email-anton@khirnov.net
State Superseded
Headers show

Commit Message

Anton Khirnov March 14, 2011, 7:38 p.m.
Use it instead of url_is_streamed and AVIOContext.is_streamed.
---
 ffserver.c                 |    8 ++++----
 libavformat/aiffdec.c      |    2 +-
 libavformat/aiffenc.c      |    2 +-
 libavformat/ape.c          |    2 +-
 libavformat/asfenc.c       |    4 ++--
 libavformat/au.c           |    2 +-
 libavformat/avidec.c       |    4 ++--
 libavformat/avienc.c       |   18 +++++++++---------
 libavformat/avio.h         |   20 +++++++++++++++++---
 libavformat/aviobuf.c      |    8 +++++++-
 libavformat/bink.c         |    2 +-
 libavformat/cafdec.c       |    4 ++--
 libavformat/ffmdec.c       |    2 +-
 libavformat/filmstripdec.c |    2 +-
 libavformat/flacenc.c      |    2 +-
 libavformat/flvdec.c       |    4 ++--
 libavformat/gxfenc.c       |    2 +-
 libavformat/id3v1.c        |    2 +-
 libavformat/matroskadec.c  |    2 +-
 libavformat/matroskaenc.c  |   12 ++++++------
 libavformat/mmf.c          |    2 +-
 libavformat/mov.c          |   12 ++++++------
 libavformat/movenc.c       |    4 ++--
 libavformat/mpc.c          |    2 +-
 libavformat/mpeg.c         |    2 +-
 libavformat/mxfenc.c       |    2 +-
 libavformat/nutdec.c       |    2 +-
 libavformat/oggdec.c       |    2 +-
 libavformat/r3d.c          |    2 +-
 libavformat/rmdec.c        |    2 +-
 libavformat/rmenc.c        |    6 +++---
 libavformat/rsoenc.c       |    2 +-
 libavformat/soxenc.c       |    2 +-
 libavformat/swfenc.c       |    2 +-
 libavformat/tty.c          |    2 +-
 libavformat/utils.c        |    2 +-
 libavformat/vc1testenc.c   |    2 +-
 libavformat/vocdec.c       |    2 +-
 libavformat/wav.c          |    4 ++--
 libavformat/wv.c           |    4 ++--
 40 files changed, 92 insertions(+), 72 deletions(-)

Comments

Ronald Bultje March 17, 2011, 2:39 a.m. | #1
Hi,

On Mon, Mar 14, 2011 at 3:38 PM, Anton Khirnov <anton@khirnov.net> wrote:
> Use it instead of url_is_streamed and AVIOContext.is_streamed.
[..]
> +enum AVIOSeekable {
> +    AVIO_SEEK_NONE = 0, /**< Seeking isn't possible (e.g. pipe) */
> +    AVIO_SEEK_SLOW,     /**< Seeking is slow (e.g. HTTP/1.1 with RangeRequest) */
> +    AVIO_SEEK_FAST,     /**< Seeking is fast (e.g. a local file) */
> +};

So this assumes that there's merely 3 types of I/O resources:
unseekable, streams that are seekable and local files. I think flags
make more sense here. An I/O resource is either seekable or not, and
it is either a stream or not. Some streams are seekable (HTTP/1.1),
some are not (HTTP/1.0). Some resources are not streams but are
seekable (file), and others are not (pipe).

Basically seekable is a functional attribute whereas is_stream is more
like a latency-type attribute (if seekable && stream, I can seek in
the movie to skip ads, but not quickly skip video frames throughout
the whole file for fast index generation, since downloading the file
will take forever). I think flags are more appropriate. One for
is_stream (slow/latency), and one for seekable.

Ronald
Anton Khirnov March 17, 2011, 6:59 a.m. | #2
On Wed, Mar 16, 2011 at 10:39:12PM -0400, Ronald S. Bultje wrote:
> Hi,
> 
> On Mon, Mar 14, 2011 at 3:38 PM, Anton Khirnov <anton@khirnov.net> wrote:
> > Use it instead of url_is_streamed and AVIOContext.is_streamed.
> [..]
> > +enum AVIOSeekable {
> > +    AVIO_SEEK_NONE = 0, /**< Seeking isn't possible (e.g. pipe) */
> > +    AVIO_SEEK_SLOW,     /**< Seeking is slow (e.g. HTTP/1.1 with RangeRequest) */
> > +    AVIO_SEEK_FAST,     /**< Seeking is fast (e.g. a local file) */
> > +};
> 
> So this assumes that there's merely 3 types of I/O resources:
> unseekable, streams that are seekable and local files. I think flags
> make more sense here. An I/O resource is either seekable or not, and
> it is either a stream or not. Some streams are seekable (HTTP/1.1),
> some are not (HTTP/1.0). Some resources are not streams but are
> seekable (file), and others are not (pipe).
> 
> Basically seekable is a functional attribute whereas is_stream is more
> like a latency-type attribute (if seekable && stream, I can seek in
> the movie to skip ads, but not quickly skip video frames throughout
> the whole file for fast index generation, since downloading the file
> will take forever). I think flags are more appropriate. One for
> is_stream (slow/latency), and one for seekable.
> 

I don't really see the advantage in that -- what would be the use case
where it's useful to know that something is a stream (how do you define
a stream anyway), but you're not interested in seeking properties?

Besides I'd argue that a pipe is a stream.
Luca Barbato March 18, 2011, 1:07 p.m. | #3
On 3/14/11 8:38 PM, Anton Khirnov wrote:
> Use it instead of url_is_streamed and AVIOContext.is_streamed.

seekable is a better defintion, I'm not sure about fast and slow as 
well. I'd change it state how precise it could be not how fast.

(binary search over http is slow, offset lookup on an index is fast)

lu

Patch

diff --git a/ffserver.c b/ffserver.c
index e5c4ac2..11833e9 100644
--- a/ffserver.c
+++ b/ffserver.c
@@ -2260,7 +2260,7 @@  static int http_prepare_data(HTTPContext *c)
             /* XXX: potential leak */
             return -1;
         }
-        c->fmt_ctx.pb->is_streamed = 1;
+        c->fmt_ctx.pb->seekable = AVIO_SEEK_NONE;
 
         /*
          * HACK to avoid mpeg ps muxer to spit many underflow errors
@@ -2399,7 +2399,7 @@  static int http_prepare_data(HTTPContext *c)
                     }
                     ost = ctx->streams[pkt.stream_index];
 
-                    ctx->pb->is_streamed = 1;
+                    ctx->pb->seekable = AVIO_SEEK_NONE;
                     if (pkt.dts != AV_NOPTS_VALUE)
                         pkt.dts = av_rescale_q(pkt.dts, ist->time_base, ost->time_base);
                     if (pkt.pts != AV_NOPTS_VALUE)
@@ -2436,7 +2436,7 @@  static int http_prepare_data(HTTPContext *c)
             /* XXX: potential leak */
             return -1;
         }
-        c->fmt_ctx.pb->is_streamed = 1;
+        c->fmt_ctx.pb->seekable = AVIO_SEEK_NONE;
         av_write_trailer(ctx);
         len = url_close_dyn_buf(ctx->pb, &c->pb_buffer);
         c->buffer_ptr = c->pb_buffer;
@@ -2722,7 +2722,7 @@  static int http_receive_data(HTTPContext *c)
                 goto fail;
 
             url_open_buf(&pb, c->buffer, c->buffer_end - c->buffer, URL_RDONLY);
-            pb->is_streamed = 1;
+            pb->seekable = AVIO_SEEK_NONE;
 
             if (av_open_input_stream(&s, pb, c->stream->feed_filename, fmt_in, NULL) < 0) {
                 av_free(pb);
diff --git a/libavformat/aiffdec.c b/libavformat/aiffdec.c
index 8506d8b..c3dadcb 100644
--- a/libavformat/aiffdec.c
+++ b/libavformat/aiffdec.c
@@ -238,7 +238,7 @@  static int aiff_read_header(AVFormatContext *s,
             offset += avio_tell(pb);    /* Compute absolute data offset */
             if (st->codec->block_align)    /* Assume COMM already parsed */
                 goto got_sound;
-            if (url_is_streamed(pb)) {
+            if (!pb->seekable) {
                 av_log(s, AV_LOG_ERROR, "file is not seekable\n");
                 return -1;
             }
diff --git a/libavformat/aiffenc.c b/libavformat/aiffenc.c
index 3e59362..387020d 100644
--- a/libavformat/aiffenc.c
+++ b/libavformat/aiffenc.c
@@ -124,7 +124,7 @@  static int aiff_write_trailer(AVFormatContext *s)
         end_size++;
     }
 
-    if (!url_is_streamed(s->pb)) {
+    if (s->pb->seekable) {
         /* File length */
         avio_seek(pb, aiff->form, SEEK_SET);
         avio_wb32(pb, file_size - aiff->form - 4);
diff --git a/libavformat/ape.c b/libavformat/ape.c
index 6c26984..6b226e2 100644
--- a/libavformat/ape.c
+++ b/libavformat/ape.c
@@ -287,7 +287,7 @@  static int ape_read_header(AVFormatContext * s, AVFormatParameters * ap)
     ape_dumpinfo(s, ape);
 
     /* try to read APE tags */
-    if (!url_is_streamed(pb)) {
+    if (pb->seekable) {
         ff_ape_parse_tag(s);
         avio_seek(pb, 0, SEEK_SET);
     }
diff --git a/libavformat/asfenc.c b/libavformat/asfenc.c
index 3a06044..4dc1ca0 100644
--- a/libavformat/asfenc.c
+++ b/libavformat/asfenc.c
@@ -347,7 +347,7 @@  static int asf_write_header1(AVFormatContext *s, int64_t file_size, int64_t data
     avio_wl64(pb, duration); /* end time stamp (in 100ns units) */
     avio_wl64(pb, asf->duration); /* duration (in 100ns units) */
     avio_wl64(pb, PREROLL_TIME); /* start time stamp */
-    avio_wl32(pb, (asf->is_streamed || url_is_streamed(pb)) ? 3 : 2); /* ??? */
+    avio_wl32(pb, (asf->is_streamed || !pb->seekable ) ? 3 : 2); /* ??? */
     avio_wl32(pb, s->packet_size); /* packet size */
     avio_wl32(pb, s->packet_size); /* packet size */
     avio_wl32(pb, bit_rate); /* Nominal data rate in bps */
@@ -866,7 +866,7 @@  static int asf_write_trailer(AVFormatContext *s)
     }
     put_flush_packet(s->pb);
 
-    if (asf->is_streamed || url_is_streamed(s->pb)) {
+    if (asf->is_streamed || !s->pb->seekable) {
         put_chunk(s, 0x4524, 0, 0); /* end of stream */
     } else {
         /* rewrite an updated header */
diff --git a/libavformat/au.c b/libavformat/au.c
index 9ea4010..cddd03a 100644
--- a/libavformat/au.c
+++ b/libavformat/au.c
@@ -91,7 +91,7 @@  static int au_write_trailer(AVFormatContext *s)
     AVIOContext *pb = s->pb;
     int64_t file_size;
 
-    if (!url_is_streamed(s->pb)) {
+    if (s->pb->seekable) {
 
         /* update file size */
         file_size = avio_tell(pb);
diff --git a/libavformat/avidec.c b/libavformat/avidec.c
index 8181298..e4ae22c 100644
--- a/libavformat/avidec.c
+++ b/libavformat/avidec.c
@@ -665,7 +665,7 @@  static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
             break;
         case MKTAG('i', 'n', 'd', 'x'):
             i= avio_tell(pb);
-            if(!url_is_streamed(pb) && !(s->flags & AVFMT_FLAG_IGNIDX)){
+            if(pb->seekable && !(s->flags & AVFMT_FLAG_IGNIDX)){
                 read_braindead_odml_indx(s, 0);
             }
             avio_seek(pb, i+size, SEEK_SET);
@@ -721,7 +721,7 @@  static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
         return -1;
     }
 
-    if(!avi->index_loaded && !url_is_streamed(pb))
+    if(!avi->index_loaded && pb->seekable)
         avi_load_index(s);
     avi->index_loaded = 1;
     avi->non_interleaved |= guess_ni_flag(s);
diff --git a/libavformat/avienc.c b/libavformat/avienc.c
index 8d9980c..0b4ba4c 100644
--- a/libavformat/avienc.c
+++ b/libavformat/avienc.c
@@ -197,7 +197,7 @@  static int avi_write_header(AVFormatContext *s)
     }
     avio_wl32(pb, bitrate / 8); /* XXX: not quite exact */
     avio_wl32(pb, 0); /* padding */
-    if (url_is_streamed(pb))
+    if (!pb->seekable)
         avio_wl32(pb, AVIF_TRUSTCKTYPE | AVIF_ISINTERLEAVED); /* flags */
     else
         avio_wl32(pb, AVIF_TRUSTCKTYPE | AVIF_HASINDEX | AVIF_ISINTERLEAVED); /* flags */
@@ -259,7 +259,7 @@  static int avi_write_header(AVFormatContext *s)
 
         avio_wl32(pb, 0); /* start */
         avist->frames_hdr_strm = avio_tell(pb); /* remember this offset to fill later */
-        if (url_is_streamed(pb))
+        if (!pb->seekable)
             avio_wl32(pb, AVI_MAX_RIFF_SIZE); /* FIXME: this may be broken, but who cares */
         else
             avio_wl32(pb, 0); /* length, XXX: filled later */
@@ -303,7 +303,7 @@  static int avi_write_header(AVFormatContext *s)
         }
       }
 
-        if (!url_is_streamed(pb)) {
+        if (pb->seekable) {
             unsigned char tag[5];
             int j;
 
@@ -362,7 +362,7 @@  static int avi_write_header(AVFormatContext *s)
         ff_end_tag(pb, list2);
     }
 
-    if (!url_is_streamed(pb)) {
+    if (pb->seekable) {
         /* AVI could become an OpenDML one, if it grows beyond 2Gb range */
         avi->odml_list = ff_start_tag(pb, "JUNK");
         ffio_wfourcc(pb, "odml");
@@ -406,7 +406,7 @@  static int avi_write_ix(AVFormatContext *s)
     char ix_tag[] = "ix00";
     int i, j;
 
-    assert(!url_is_streamed(pb));
+    assert(pb->seekable);
 
     if (avi->riff_id > AVI_MASTER_INDEX_SIZE)
         return -1;
@@ -464,7 +464,7 @@  static int avi_write_idx1(AVFormatContext *s)
     int i;
     char tag[5];
 
-    if (!url_is_streamed(pb)) {
+    if (pb->seekable) {
         AVIStream *avist;
         AVIIentry* ie = 0, *tie;
         int empty, stream_id = -1;
@@ -532,7 +532,7 @@  static int avi_write_packet(AVFormatContext *s, AVPacket *pkt)
     avist->packet_count++;
 
     // Make sure to put an OpenDML chunk when the file size exceeds the limits
-    if (!url_is_streamed(pb) &&
+    if (pb->seekable &&
         (avio_tell(pb) - avi->riff_start > AVI_MAX_RIFF_SIZE)) {
 
         avi_write_ix(s);
@@ -552,7 +552,7 @@  static int avi_write_packet(AVFormatContext *s, AVPacket *pkt)
        avist->audio_strm_length += size;
     }
 
-    if (!url_is_streamed(s->pb)) {
+    if (s->pb->seekable) {
         AVIIndex* idx = &avist->indexes;
         int cl = idx->entry / AVI_INDEX_CLUSTER_SIZE;
         int id = idx->entry % AVI_INDEX_CLUSTER_SIZE;
@@ -590,7 +590,7 @@  static int avi_write_trailer(AVFormatContext *s)
     int i, j, n, nb_frames;
     int64_t file_size;
 
-    if (!url_is_streamed(pb)){
+    if (pb->seekable){
         if (avi->riff_id == 1) {
             ff_end_tag(pb, avi->movi_list);
             res = avi_write_idx1(s);
diff --git a/libavformat/avio.h b/libavformat/avio.h
index b8f9c58..4b4c0b6 100644
--- a/libavformat/avio.h
+++ b/libavformat/avio.h
@@ -332,6 +332,12 @@  attribute_deprecated int av_register_protocol(URLProtocol *protocol);
  */
 int av_register_protocol2(URLProtocol *protocol, int size);
 
+enum AVIOSeekable {
+    AVIO_SEEK_NONE = 0, /**< Seeking isn't possible (e.g. pipe) */
+    AVIO_SEEK_SLOW,     /**< Seeking is slow (e.g. HTTP/1.1 with RangeRequest) */
+    AVIO_SEEK_FAST,     /**< Seeking is fast (e.g. a local file) */
+};
+
 /**
  * Bytestream IO Context.
  * New fields can be added to the end with minor version bumps.
@@ -351,7 +357,9 @@  typedef struct {
     int must_flush; /**< true if the next seek should flush */
     int eof_reached; /**< true if eof reached */
     int write_flag;  /**< true if open for writing */
-    int is_streamed;
+#if FF_API_OLD_AVIO
+    attribute_deprecated int is_streamed;
+#endif
     int max_packet_size;
     unsigned long checksum;
     unsigned char *checksum_ptr;
@@ -360,6 +368,7 @@  typedef struct {
     int (*read_pause)(void *opaque, int pause);
     int64_t (*read_seek)(void *opaque, int stream_index,
                          int64_t timestamp, int flags);
+    enum AVIOSeekable seekable;     /**< specifies whether it's possible to seek */
 } AVIOContext;
 
 #if FF_API_OLD_AVIO
@@ -570,10 +579,15 @@  uint64_t     avio_rb64(AVIOContext *s);
 
 uint64_t ff_get_v(AVIOContext *bc);
 
-static inline int url_is_streamed(AVIOContext *s)
+#if FF_API_OLD_AVIO
+/**
+ * @deprecated Use AVIOContext.seekable field directly.
+ */
+attribute_deprecated static inline int url_is_streamed(AVIOContext *s)
 {
-    return s->is_streamed;
+    return s->seekable == AVIO_SEEK_NONE;
 }
+#endif
 
 /**
  * Create and initialize a AVIOContext for accessing the
diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c
index 4f39fe3..edb6e5b 100644
--- a/libavformat/aviobuf.c
+++ b/libavformat/aviobuf.c
@@ -62,7 +62,10 @@  int ffio_init_context(AVIOContext *s,
     s->must_flush = 0;
     s->eof_reached = 0;
     s->error = 0;
+#if FF_API_OLD_AVIO
     s->is_streamed = 0;
+#endif
+    s->seekable = AVIO_SEEK_FAST;
     s->max_packet_size = 0;
     s->update_checksum= NULL;
     if(!read_packet && !write_flag){
@@ -202,7 +205,7 @@  int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
         offset1 >= 0 && offset1 <= (s->buf_end - s->buffer)) {
         /* can do the seek inside the buffer */
         s->buf_ptr = s->buffer + offset1;
-    } else if ((s->is_streamed ||
+    } else if ((!s->seekable ||
                offset1 <= s->buf_end + SHORT_SEEK_THRESHOLD - s->buffer) &&
                !s->write_flag && offset1 >= 0 &&
               (whence != SEEK_END || force)) {
@@ -792,7 +795,10 @@  int url_fdopen(AVIOContext **s, URLContext *h)
         av_freep(s);
         return AVERROR(EIO);
     }
+#if FF_API_OLD_AVIO
     (*s)->is_streamed = h->is_streamed;
+#endif
+    (*s)->seekable = h->is_streamed ? AVIO_SEEK_NONE : AVIO_SEEK_FAST;
     (*s)->max_packet_size = max_packet_size;
     if(h->prot) {
         (*s)->read_pause = (int (*)(void *, int))h->prot->url_read_pause;
diff --git a/libavformat/bink.c b/libavformat/bink.c
index 22beb4c..c739050 100644
--- a/libavformat/bink.c
+++ b/libavformat/bink.c
@@ -247,7 +247,7 @@  static int read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, in
     BinkDemuxContext *bink = s->priv_data;
     AVStream *vst = s->streams[0];
 
-    if (url_is_streamed(s->pb))
+    if (!s->pb->seekable)
         return -1;
 
     /* seek to the first frame */
diff --git a/libavformat/cafdec.c b/libavformat/cafdec.c
index ec3054f..30462ba 100644
--- a/libavformat/cafdec.c
+++ b/libavformat/cafdec.c
@@ -223,7 +223,7 @@  static int read_header(AVFormatContext *s,
 
         /* stop at data chunk if seeking is not supported or
            data chunk size is unknown */
-        if (found_data && (caf->data_size < 0 || url_is_streamed(pb)))
+        if (found_data && (caf->data_size < 0 || !pb->seekable))
             break;
 
         tag  = avio_rb32(pb);
@@ -236,7 +236,7 @@  static int read_header(AVFormatContext *s,
             avio_seek(pb, 4, SEEK_CUR); /* edit count */
             caf->data_start = avio_tell(pb);
             caf->data_size  = size < 0 ? -1 : size - 4;
-            if (caf->data_size > 0 && !url_is_streamed(pb))
+            if (caf->data_size > 0 && pb->seekable)
                 avio_seek(pb, caf->data_size, SEEK_CUR);
             found_data = 1;
             break;
diff --git a/libavformat/ffmdec.c b/libavformat/ffmdec.c
index 1b5be16..22f719d 100644
--- a/libavformat/ffmdec.c
+++ b/libavformat/ffmdec.c
@@ -281,7 +281,7 @@  static int ffm_read_header(AVFormatContext *s, AVFormatParameters *ap)
         goto fail;
     ffm->write_index = avio_rb64(pb);
     /* get also filesize */
-    if (!url_is_streamed(pb)) {
+    if (pb->seekable) {
         ffm->file_size = avio_size(pb);
         if (ffm->write_index)
             adjust_write_index(s);
diff --git a/libavformat/filmstripdec.c b/libavformat/filmstripdec.c
index 568bc0d..49c795a 100644
--- a/libavformat/filmstripdec.c
+++ b/libavformat/filmstripdec.c
@@ -40,7 +40,7 @@  static int read_header(AVFormatContext *s,
     AVIOContext *pb = s->pb;
     AVStream *st;
 
-    if (url_is_streamed(s->pb))
+    if (!s->pb->seekable)
         return AVERROR(EIO);
 
     avio_seek(pb, avio_size(pb) - 36, SEEK_SET);
diff --git a/libavformat/flacenc.c b/libavformat/flacenc.c
index 079e6dd..576398d 100644
--- a/libavformat/flacenc.c
+++ b/libavformat/flacenc.c
@@ -98,7 +98,7 @@  static int flac_write_trailer(struct AVFormatContext *s)
     if (!ff_flac_is_extradata_valid(s->streams[0]->codec, &format, &streaminfo))
         return -1;
 
-    if (!url_is_streamed(pb)) {
+    if (pb->seekable) {
         /* rewrite the STREAMINFO header block data */
         file_size = avio_tell(pb);
         avio_seek(pb, 8, SEEK_SET);
diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c
index bb27131..b62c550 100644
--- a/libavformat/flvdec.c
+++ b/libavformat/flvdec.c
@@ -370,7 +370,7 @@  static int flv_read_packet(AVFormatContext *s, AVPacket *pkt)
  }
 
     // if not streamed and no duration from metadata then seek to end to find the duration from the timestamps
-    if(!url_is_streamed(s->pb) && (!s->duration || s->duration==AV_NOPTS_VALUE)){
+    if(s->pb->seekable && (!s->duration || s->duration==AV_NOPTS_VALUE)){
         int size;
         const int64_t pos= avio_tell(s->pb);
         const int64_t fsize= avio_size(s->pb);
@@ -472,7 +472,7 @@  static int flv_read_seek2(AVFormatContext *s, int stream_index,
 
     if (ts - min_ts > (uint64_t)(max_ts - ts)) flags |= AVSEEK_FLAG_BACKWARD;
 
-    if (url_is_streamed(s->pb)) {
+    if (!s->pb->seekable) {
         if (stream_index < 0) {
             stream_index = av_find_default_stream_index(s);
             if (stream_index < 0)
diff --git a/libavformat/gxfenc.c b/libavformat/gxfenc.c
index 44b5020..962b10d 100644
--- a/libavformat/gxfenc.c
+++ b/libavformat/gxfenc.c
@@ -634,7 +634,7 @@  static int gxf_write_header(AVFormatContext *s)
     uint8_t tracks[255] = {0};
     int i, media_info = 0;
 
-    if (url_is_streamed(pb)) {
+    if (!pb->seekable) {
         av_log(s, AV_LOG_ERROR, "gxf muxer does not support streamed output, patch welcome");
         return -1;
     }
diff --git a/libavformat/id3v1.c b/libavformat/id3v1.c
index 0152e39..4be4581 100644
--- a/libavformat/id3v1.c
+++ b/libavformat/id3v1.c
@@ -228,7 +228,7 @@  void ff_id3v1_read(AVFormatContext *s)
     int ret, filesize;
     uint8_t buf[ID3v1_TAG_SIZE];
 
-    if (!url_is_streamed(s->pb)) {
+    if (s->pb->seekable) {
         /* XXX: change that */
         filesize = avio_size(s->pb);
         if (filesize > 128) {
diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
index a356611..1da8c8d 100644
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@ -1117,7 +1117,7 @@  static void matroska_execute_seekhead(MatroskaDemuxContext *matroska)
     int i;
 
     // we should not do any seeking in the streaming case
-    if (url_is_streamed(matroska->ctx->pb) ||
+    if (!matroska->ctx->pb->seekable ||
         (matroska->ctx->flags & AVFMT_FLAG_IGNIDX))
         return;
 
diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c
index 4c4f009..222d991 100644
--- a/libavformat/matroskaenc.c
+++ b/libavformat/matroskaenc.c
@@ -862,7 +862,7 @@  static int mkv_write_header(AVFormatContext *s)
         if (ret < 0) return ret;
     }
 
-    if (url_is_streamed(s->pb))
+    if (!s->pb->seekable)
         mkv_write_seekhead(pb, mkv->main_seekhead);
 
     mkv->cues = mkv_start_cues(mkv->segment_offset);
@@ -1038,7 +1038,7 @@  static int mkv_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
         return AVERROR(EINVAL);
     }
 
-    if (url_is_streamed(s->pb)) {
+    if (!s->pb->seekable) {
         if (!mkv->dyn_bc)
             url_open_dyn_buf(&mkv->dyn_bc);
         pb = mkv->dyn_bc;
@@ -1090,16 +1090,16 @@  static int mkv_copy_packet(MatroskaMuxContext *mkv, const AVPacket *pkt)
 static int mkv_write_packet(AVFormatContext *s, AVPacket *pkt)
 {
     MatroskaMuxContext *mkv = s->priv_data;
-    AVIOContext *pb = url_is_streamed(s->pb) ? mkv->dyn_bc : s->pb;
+    AVIOContext *pb = s->pb->seekable ? s->pb : mkv->dyn_bc;
     AVCodecContext *codec = s->streams[pkt->stream_index]->codec;
     int ret, keyframe = !!(pkt->flags & AV_PKT_FLAG_KEY);
     int64_t ts = mkv->tracks[pkt->stream_index].write_dts ? pkt->dts : pkt->pts;
-    int cluster_size = avio_tell(pb) - (url_is_streamed(s->pb) ? 0 : mkv->cluster_pos);
+    int cluster_size = avio_tell(pb) - (s->pb->seekable ? mkv->cluster_pos : 0);
 
     // start a new cluster every 5 MB or 5 sec, or 32k / 1 sec for streaming or
     // after 4k and on a keyframe
     if (mkv->cluster_pos &&
-        ((url_is_streamed(s->pb) && (cluster_size > 32*1024 || ts > mkv->cluster_pts + 1000))
+        ((!s->pb->seekable && (cluster_size > 32*1024 || ts > mkv->cluster_pts + 1000))
          ||                      cluster_size > 5*1024*1024 || ts > mkv->cluster_pts + 5000
          || (codec->codec_type == AVMEDIA_TYPE_VIDEO && keyframe && cluster_size > 4*1024))) {
         av_log(s, AV_LOG_DEBUG, "Starting new cluster at offset %" PRIu64
@@ -1153,7 +1153,7 @@  static int mkv_write_trailer(AVFormatContext *s)
         end_ebml_master(pb, mkv->cluster);
     }
 
-    if (!url_is_streamed(pb)) {
+    if (pb->seekable) {
         cuespos = mkv_write_cues(pb, mkv->cues, s->nb_streams);
 
         ret = mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_CUES    , cuespos);
diff --git a/libavformat/mmf.c b/libavformat/mmf.c
index be3f649..efa1223 100644
--- a/libavformat/mmf.c
+++ b/libavformat/mmf.c
@@ -133,7 +133,7 @@  static int mmf_write_trailer(AVFormatContext *s)
     int64_t pos, size;
     int gatetime;
 
-    if (!url_is_streamed(s->pb)) {
+    if (s->pb->seekable) {
         /* Fill in length fields */
         end_tag_be(pb, mmf->awapos);
         end_tag_be(pb, mmf->atrpos);
diff --git a/libavformat/mov.c b/libavformat/mov.c
index db79815..77b7abb 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -304,7 +304,7 @@  static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
             if (err < 0)
                 return err;
             if (c->found_moov && c->found_mdat &&
-                (url_is_streamed(pb) || start_pos + a.size == avio_size(pb)))
+                (!pb->seekable || start_pos + a.size == avio_size(pb)))
                 return 0;
             left = a.size - avio_tell(pb) + start_pos;
             if (left > 0) /* skip garbage at atom end */
@@ -2350,7 +2350,7 @@  static int mov_read_header(AVFormatContext *s, AVFormatParameters *ap)
 
     mov->fc = s;
     /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
-    if(!url_is_streamed(pb))
+    if(pb->seekable)
         atom.size = avio_size(pb);
     else
         atom.size = INT64_MAX;
@@ -2366,7 +2366,7 @@  static int mov_read_header(AVFormatContext *s, AVFormatParameters *ap)
     }
     av_dlog(mov->fc, "on_parse_exit_offset=%lld\n", avio_tell(pb));
 
-    if (!url_is_streamed(pb) && mov->chapter_track > 0)
+    if (pb->seekable && mov->chapter_track > 0)
         mov_read_chapters(s);
 
     return 0;
@@ -2384,8 +2384,8 @@  static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
             AVIndexEntry *current_sample = &avst->index_entries[msc->current_sample];
             int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
             av_dlog(s, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
-            if (!sample || (url_is_streamed(s->pb) && current_sample->pos < sample->pos) ||
-                (!url_is_streamed(s->pb) &&
+            if (!sample || (!s->pb->seekable && current_sample->pos < sample->pos) ||
+                (s->pb->seekable &&
                  ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb &&
                  ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
                   (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
@@ -2409,7 +2409,7 @@  static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
     sample = mov_find_next_sample(s, &st);
     if (!sample) {
         mov->found_mdat = 0;
-        if (!url_is_streamed(s->pb) ||
+        if (s->pb->seekable||
             mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX }) < 0 ||
             s->pb->eof_reached)
             return AVERROR_EOF;
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index e1fd79d..085df4c 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -1955,7 +1955,7 @@  int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
     unsigned int samplesInChunk = 0;
     int size= pkt->size;
 
-    if (url_is_streamed(s->pb)) return 0; /* Can't handle that */
+    if (!s->pb->seekable) return 0; /* Can't handle that */
     if (!size) return 0; /* Discard 0 sized packets */
 
     if (enc->codec_id == CODEC_ID_AMR_NB) {
@@ -2090,7 +2090,7 @@  static int mov_write_header(AVFormatContext *s)
     MOVMuxContext *mov = s->priv_data;
     int i, hint_track = 0;
 
-    if (url_is_streamed(s->pb)) {
+    if (!s->pb->seekable) {
         av_log(s, AV_LOG_ERROR, "muxer does not support non seekable output\n");
         return -1;
     }
diff --git a/libavformat/mpc.c b/libavformat/mpc.c
index b9c5dc9..3544cf1 100644
--- a/libavformat/mpc.c
+++ b/libavformat/mpc.c
@@ -93,7 +93,7 @@  static int mpc_read_header(AVFormatContext *s, AVFormatParameters *ap)
     st->duration = c->fcount;
 
     /* try to read APE tags */
-    if (!url_is_streamed(s->pb)) {
+    if (s->pb->seekable) {
         int64_t pos = avio_tell(s->pb);
         ff_ape_parse_tag(s);
         if (!av_metadata_get(s->metadata, "", NULL, AV_METADATA_IGNORE_SUFFIX))
diff --git a/libavformat/mpeg.c b/libavformat/mpeg.c
index 7a93c63..131d16c 100644
--- a/libavformat/mpeg.c
+++ b/libavformat/mpeg.c
@@ -402,7 +402,7 @@  static int mpegps_read_pes_header(AVFormatContext *s,
         int i;
         for(i=0; i<s->nb_streams; i++){
             if(startcode == s->streams[i]->id &&
-               !url_is_streamed(s->pb) /* index useless on streams anyway */) {
+               s->pb->seekable /* index useless on streams anyway */) {
                 ff_reduce_index(s, i);
                 av_add_index_entry(s->streams[i], *ppos, dts, 0, 0, AVINDEX_KEYFRAME /* FIXME keyframe? */);
             }
diff --git a/libavformat/mxfenc.c b/libavformat/mxfenc.c
index 8e1cfc7..caeae8a 100644
--- a/libavformat/mxfenc.c
+++ b/libavformat/mxfenc.c
@@ -1784,7 +1784,7 @@  static int mxf_write_footer(AVFormatContext *s)
     mxf_write_klv_fill(s);
     mxf_write_random_index_pack(s);
 
-    if (!url_is_streamed(s->pb)) {
+    if (s->pb->seekable) {
         avio_seek(pb, 0, SEEK_SET);
         if (mxf->edit_unit_byte_count) {
             mxf_write_partition(s, 1, 2, header_closed_partition_key, 1);
diff --git a/libavformat/nutdec.c b/libavformat/nutdec.c
index d31040e..926a4b3 100644
--- a/libavformat/nutdec.c
+++ b/libavformat/nutdec.c
@@ -652,7 +652,7 @@  static int nut_read_header(AVFormatContext *s, AVFormatParameters *ap)
 
     s->data_offset= pos-8;
 
-    if(!url_is_streamed(bc)){
+    if(bc->seekable){
         int64_t orig_pos= avio_tell(bc);
         find_and_decode_index(nut);
         avio_seek(bc, orig_pos, SEEK_SET);
diff --git a/libavformat/oggdec.c b/libavformat/oggdec.c
index 76ef19a..cd866d4 100644
--- a/libavformat/oggdec.c
+++ b/libavformat/oggdec.c
@@ -455,7 +455,7 @@  ogg_get_length (AVFormatContext * s)
     int i;
     int64_t size, end;
 
-    if(url_is_streamed(s->pb))
+    if(!s->pb->seekable)
         return 0;
 
 // already set
diff --git a/libavformat/r3d.c b/libavformat/r3d.c
index 39f97ff..537b7c1 100644
--- a/libavformat/r3d.c
+++ b/libavformat/r3d.c
@@ -177,7 +177,7 @@  static int r3d_read_header(AVFormatContext *s, AVFormatParameters *ap)
 
     s->data_offset = avio_tell(s->pb);
     av_dlog(s, "data offset %#llx\n", s->data_offset);
-    if (url_is_streamed(s->pb))
+    if (!s->pb->seekable)
         return 0;
     // find REOB/REOF/REOS to load index
     avio_seek(s->pb, avio_size(s->pb)-48-8, SEEK_SET);
diff --git a/libavformat/rmdec.c b/libavformat/rmdec.c
index 4fd2e86..8bdf4ea 100644
--- a/libavformat/rmdec.c
+++ b/libavformat/rmdec.c
@@ -481,7 +481,7 @@  static int rm_read_header(AVFormatContext *s, AVFormatParameters *ap)
 
     if (!data_off)
         data_off = avio_tell(pb) - 18;
-    if (indx_off && !url_is_streamed(pb) && !(s->flags & AVFMT_FLAG_IGNIDX) &&
+    if (indx_off && pb->seekable && !(s->flags & AVFMT_FLAG_IGNIDX) &&
         avio_seek(pb, indx_off, SEEK_SET) >= 0) {
         rm_read_index(s);
         avio_seek(pb, data_off + 18, SEEK_SET);
diff --git a/libavformat/rmenc.c b/libavformat/rmenc.c
index 8a60886..fc44590 100644
--- a/libavformat/rmenc.c
+++ b/libavformat/rmenc.c
@@ -118,7 +118,7 @@  static int rv10_write_header(AVFormatContext *ctx,
     avio_wb32(s, 0);           /* data offset : will be patched after */
     avio_wb16(s, ctx->nb_streams);    /* num streams */
     flags = 1 | 2; /* save allowed & perfect play */
-    if (url_is_streamed(s))
+    if (!s->seekable)
         flags |= 4; /* live broadcast */
     avio_wb16(s, flags);
 
@@ -170,7 +170,7 @@  static int rv10_write_header(AVFormatContext *ctx,
         avio_wb32(s, 0);           /* start time */
         avio_wb32(s, BUFFER_DURATION);           /* preroll */
         /* duration */
-        if (url_is_streamed(s) || !stream->total_frames)
+        if (!s->seekable || !stream->total_frames)
             avio_wb32(s, (int)(3600 * 1000));
         else
             avio_wb32(s, (int)(stream->total_frames * 1000 / stream->frame_rate));
@@ -434,7 +434,7 @@  static int rm_write_trailer(AVFormatContext *s)
     int data_size, index_pos, i;
     AVIOContext *pb = s->pb;
 
-    if (!url_is_streamed(s->pb)) {
+    if (s->pb->seekable) {
         /* end of file: finish to write header */
         index_pos = avio_seek(pb, 0, SEEK_CUR);
         data_size = index_pos - rm->data_pos;
diff --git a/libavformat/rsoenc.c b/libavformat/rsoenc.c
index fc7df76..231daba 100644
--- a/libavformat/rsoenc.c
+++ b/libavformat/rsoenc.c
@@ -38,7 +38,7 @@  static int rso_write_header(AVFormatContext *s)
         return AVERROR_INVALIDDATA;
     }
 
-    if (url_is_streamed(s->pb)) {
+    if (!s->pb->seekable) {
         av_log(s, AV_LOG_ERROR, "muxer does not support non seekable output\n");
         return AVERROR_INVALIDDATA;
     }
diff --git a/libavformat/soxenc.c b/libavformat/soxenc.c
index fb68d0b..298cd9b 100644
--- a/libavformat/soxenc.c
+++ b/libavformat/soxenc.c
@@ -96,7 +96,7 @@  static int sox_write_trailer(AVFormatContext *s)
     AVIOContext *pb = s->pb;
     AVCodecContext *enc = s->streams[0]->codec;
 
-    if (!url_is_streamed(s->pb)) {
+    if (s->pb->seekable) {
         /* update number of samples */
         int64_t file_size = avio_tell(pb);
         int64_t num_samples = (file_size - sox->header_size - 4LL) >> 2LL;
diff --git a/libavformat/swfenc.c b/libavformat/swfenc.c
index 182cb65..6754a97 100644
--- a/libavformat/swfenc.c
+++ b/libavformat/swfenc.c
@@ -492,7 +492,7 @@  static int swf_write_trailer(AVFormatContext *s)
     put_flush_packet(s->pb);
 
     /* patch file size and number of frames if not streamed */
-    if (!url_is_streamed(s->pb) && video_enc) {
+    if (s->pb->seekable && video_enc) {
         file_size = avio_tell(pb);
         avio_seek(pb, 4, SEEK_SET);
         avio_wl32(pb, file_size);
diff --git a/libavformat/tty.c b/libavformat/tty.c
index 8af245a..5072298 100644
--- a/libavformat/tty.c
+++ b/libavformat/tty.c
@@ -88,7 +88,7 @@  static int read_header(AVFormatContext *avctx,
     /* simulate tty display speed */
     s->chars_per_frame = FFMAX(av_q2d(st->time_base) * (ap->sample_rate ? ap->sample_rate : LINE_RATE), 1);
 
-    if (!url_is_streamed(avctx->pb)) {
+    if (avctx->pb->seekable) {
         s->fsize = avio_size(avctx->pb);
         st->duration = (s->fsize + s->chars_per_frame - 1) / s->chars_per_frame;
 
diff --git a/libavformat/utils.c b/libavformat/utils.c
index 902a170..ce2fb4d 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -2016,7 +2016,7 @@  static void av_estimate_timings(AVFormatContext *ic, int64_t old_offset)
 
     if ((!strcmp(ic->iformat->name, "mpeg") ||
          !strcmp(ic->iformat->name, "mpegts")) &&
-        file_size && !url_is_streamed(ic->pb)) {
+        file_size && ic->pb->seekable) {
         /* get accurate estimate from the PTSes */
         av_estimate_timings_from_pts(ic, old_offset);
     } else if (av_has_duration(ic)) {
diff --git a/libavformat/vc1testenc.c b/libavformat/vc1testenc.c
index 65ac602..b1113b5 100644
--- a/libavformat/vc1testenc.c
+++ b/libavformat/vc1testenc.c
@@ -73,7 +73,7 @@  static int vc1test_write_trailer(AVFormatContext *s)
     RCVContext *ctx = s->priv_data;
     AVIOContext *pb = s->pb;
 
-    if (!url_is_streamed(s->pb)) {
+    if (s->pb->seekable) {
         avio_seek(pb, 0, SEEK_SET);
         avio_wl24(pb, ctx->frames);
         put_flush_packet(pb);
diff --git a/libavformat/vocdec.c b/libavformat/vocdec.c
index f4fb8cc..f34592f 100644
--- a/libavformat/vocdec.c
+++ b/libavformat/vocdec.c
@@ -78,7 +78,7 @@  voc_get_packet(AVFormatContext *s, AVPacket *pkt, AVStream *st, int max_size)
             return AVERROR(EIO);
         voc->remaining_size = avio_rl24(pb);
         if (!voc->remaining_size) {
-            if (url_is_streamed(s->pb))
+            if (!s->pb->seekable)
                 return AVERROR(EIO);
             voc->remaining_size = avio_size(pb) - avio_tell(pb);
         }
diff --git a/libavformat/wav.c b/libavformat/wav.c
index d51c012..ed54244 100644
--- a/libavformat/wav.c
+++ b/libavformat/wav.c
@@ -58,7 +58,7 @@  static int wav_write_header(AVFormatContext *s)
     ff_end_tag(pb, fmt);
 
     if (s->streams[0]->codec->codec_tag != 0x01 /* hence for all other than PCM */
-        && !url_is_streamed(s->pb)) {
+        && s->pb->seekable) {
         fact = ff_start_tag(pb, "fact");
         avio_wl32(pb, 0);
         ff_end_tag(pb, fact);
@@ -98,7 +98,7 @@  static int wav_write_trailer(AVFormatContext *s)
 
     put_flush_packet(pb);
 
-    if (!url_is_streamed(s->pb)) {
+    if (s->pb->seekable) {
         ff_end_tag(pb, wav->data);
 
         /* update file size */
diff --git a/libavformat/wv.c b/libavformat/wv.c
index 12aaef9..097f249 100644
--- a/libavformat/wv.c
+++ b/libavformat/wv.c
@@ -121,7 +121,7 @@  static int wv_read_block_header(AVFormatContext *ctx, AVIOContext *pb, int appen
     }
     if((rate == -1 || !chan) && !wc->block_parsed){
         int64_t block_end = avio_tell(pb) + wc->blksize - 24;
-        if(url_is_streamed(pb)){
+        if(!pb->seekable){
             av_log(ctx, AV_LOG_ERROR, "Cannot determine additional parameters\n");
             return -1;
         }
@@ -223,7 +223,7 @@  static int wv_read_header(AVFormatContext *s,
     st->start_time = 0;
     st->duration = wc->samples;
 
-    if(!url_is_streamed(s->pb)) {
+    if(s->pb->seekable) {
         int64_t cur = avio_tell(s->pb);
         ff_ape_parse_tag(s);
         if(!av_metadata_get(s->metadata, "", NULL, AV_METADATA_IGNORE_SUFFIX))