diff --git a/libavformat/concatdec.c b/libavformat/concatdec.c
index bd5174ada2..178fac86cb 100644
--- a/libavformat/concatdec.c
+++ b/libavformat/concatdec.c
@@ -126,10 +126,10 @@ static int add_file(AVFormatContext *avf, char *filename, ConcatFile **rfile,
         url = filename;
         filename = NULL;
     } else {
-        url_len = strlen(avf->filename) + strlen(filename) + 16;
+        url_len = strlen(avf->url) + strlen(filename) + 16;
         if (!(url = av_malloc(url_len)))
             FAIL(AVERROR(ENOMEM));
-        ff_make_absolute_url(url, url_len, avf->filename, filename);
+        ff_make_absolute_url(url, url_len, avf->url, filename);
         av_freep(&filename);
     }
 
diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 39d0afe350..b6b170c29f 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -685,7 +685,7 @@ static int write_manifest(AVFormatContext *s, int final)
     AVIOContext *out;
     char temp_filename[1024];
     int ret, i;
-    const char *proto = avio_find_protocol_name(s->filename);
+    const char *proto = avio_find_protocol_name(s->url);
     int use_rename = proto && !strcmp(proto, "file");
     static unsigned int warned_non_file = 0;
     AVDictionaryEntry *title = av_dict_get(s->metadata, "title", NULL, 0);
@@ -694,7 +694,7 @@ static int write_manifest(AVFormatContext *s, int final)
     if (!use_rename && !warned_non_file++)
         av_log(s, AV_LOG_ERROR, "Cannot use rename on non file protocol, this may lead to races and temporary partial files\n");
 
-    snprintf(temp_filename, sizeof(temp_filename), use_rename ? "%s.tmp" : "%s", s->filename);
+    snprintf(temp_filename, sizeof(temp_filename), use_rename ? "%s.tmp" : "%s", s->url);
     set_http_options(&opts, c);
     ret = dashenc_io_open(s, &c->mpd_out, temp_filename, &opts);
     if (ret < 0) {
@@ -771,7 +771,7 @@ static int write_manifest(AVFormatContext *s, int final)
     dashenc_io_close(s, &c->mpd_out, temp_filename);
 
     if (use_rename) {
-        if ((ret = avpriv_io_move(temp_filename, s->filename)) < 0)
+        if ((ret = avpriv_io_move(temp_filename, s->url)) < 0)
             return ret;
     }
 
@@ -852,14 +852,14 @@ static int dash_init(AVFormatContext *s)
     if (c->single_file)
         c->use_template = 0;
 
-    av_strlcpy(c->dirname, s->filename, sizeof(c->dirname));
+    av_strlcpy(c->dirname, s->url, sizeof(c->dirname));
     ptr = strrchr(c->dirname, '/');
     if (ptr) {
         av_strlcpy(basename, &ptr[1], sizeof(basename));
         ptr[1] = '\0';
     } else {
         c->dirname[0] = '\0';
-        av_strlcpy(basename, s->filename, sizeof(basename));
+        av_strlcpy(basename, s->url, sizeof(basename));
     }
 
     ptr = strrchr(basename, '.');
@@ -1018,7 +1018,7 @@ static int dash_write_header(AVFormatContext *s)
     }
     ret = write_manifest(s, 0);
     if (!ret)
-        av_log(s, AV_LOG_VERBOSE, "Manifest written to: %s\n", s->filename);
+        av_log(s, AV_LOG_VERBOSE, "Manifest written to: %s\n", s->url);
     return ret;
 }
 
@@ -1117,7 +1117,7 @@ static int dash_flush(AVFormatContext *s, int final, int stream)
     DASHContext *c = s->priv_data;
     int i, ret = 0;
 
-    const char *proto = avio_find_protocol_name(s->filename);
+    const char *proto = avio_find_protocol_name(s->url);
     int use_rename = proto && !strcmp(proto, "file");
 
     int cur_flush_segment_index = 0;
@@ -1325,7 +1325,7 @@ static int dash_write_trailer(AVFormatContext *s)
             snprintf(filename, sizeof(filename), "%s%s", c->dirname, os->initfile);
             unlink(filename);
         }
-        unlink(s->filename);
+        unlink(s->url);
     }
 
     return 0;
diff --git a/libavformat/fifo.c b/libavformat/fifo.c
index c881f31e94..145e2e2660 100644
--- a/libavformat/fifo.c
+++ b/libavformat/fifo.c
@@ -124,9 +124,9 @@ static int fifo_thread_write_header(FifoThreadContext *ctx)
     if (ret < 0)
         return ret;
 
-    ret = ff_format_output_open(avf2, avf->filename, &format_options);
+    ret = ff_format_output_open(avf2, avf->url, &format_options);
     if (ret < 0) {
-        av_log(avf, AV_LOG_ERROR, "Error opening %s: %s\n", avf->filename,
+        av_log(avf, AV_LOG_ERROR, "Error opening %s: %s\n", avf->url,
                av_err2str(ret));
         goto end;
     }
@@ -500,13 +500,13 @@ static int fifo_init(AVFormatContext *avf)
         }
     }
 
-    oformat = av_guess_format(fifo->format, avf->filename, NULL);
+    oformat = av_guess_format(fifo->format, avf->url, NULL);
     if (!oformat) {
         ret = AVERROR_MUXER_NOT_FOUND;
         return ret;
     }
 
-    ret = fifo_mux_init(avf, oformat, avf->filename);
+    ret = fifo_mux_init(avf, oformat, avf->url);
     if (ret < 0)
         return ret;
 
diff --git a/libavformat/flvenc.c b/libavformat/flvenc.c
index 899b07ea7b..e8af48cb64 100644
--- a/libavformat/flvenc.c
+++ b/libavformat/flvenc.c
@@ -610,10 +610,10 @@ static int shift_data(AVFormatContext *s)
      * writing, so we re-open the same output, but for reading. It also avoids
      * a read/seek/write/seek back and forth. */
     avio_flush(s->pb);
-    ret = s->io_open(s, &read_pb, s->filename, AVIO_FLAG_READ, NULL);
+    ret = s->io_open(s, &read_pb, s->url, AVIO_FLAG_READ, NULL);
     if (ret < 0) {
         av_log(s, AV_LOG_ERROR, "Unable to re-open %s output file for "
-               "the second pass (add_keyframe_index)\n", s->filename);
+               "the second pass (add_keyframe_index)\n", s->url);
         goto end;
     }
 
diff --git a/libavformat/gxfenc.c b/libavformat/gxfenc.c
index 0e0772b744..3507c00b40 100644
--- a/libavformat/gxfenc.c
+++ b/libavformat/gxfenc.c
@@ -311,7 +311,7 @@ static int gxf_write_material_data_section(AVFormatContext *s)
     AVIOContext *pb = s->pb;
     int64_t pos;
     int len;
-    const char *filename = strrchr(s->filename, '/');
+    const char *filename = strrchr(s->url, '/');
 
     pos = avio_tell(pb);
     avio_wb16(pb, 0); /* size */
@@ -320,7 +320,7 @@ static int gxf_write_material_data_section(AVFormatContext *s)
     if (filename)
         filename++;
     else
-        filename = s->filename;
+        filename = s->url;
     len = strlen(filename);
 
     avio_w8(pb, MAT_NAME);
diff --git a/libavformat/hdsenc.c b/libavformat/hdsenc.c
index 72829f7257..d82aee17b9 100644
--- a/libavformat/hdsenc.c
+++ b/libavformat/hdsenc.c
@@ -169,8 +169,8 @@ static int write_manifest(AVFormatContext *s, int final)
     if (c->nb_streams > 0)
         duration = c->streams[0].last_ts * av_q2d(s->streams[0]->time_base);
 
-    snprintf(filename, sizeof(filename), "%s/index.f4m", s->filename);
-    snprintf(temp_filename, sizeof(temp_filename), "%s/index.f4m.tmp", s->filename);
+    snprintf(filename, sizeof(filename), "%s/index.f4m", s->url);
+    snprintf(temp_filename, sizeof(temp_filename), "%s/index.f4m.tmp", s->url);
     ret = s->io_open(s, &out, temp_filename, AVIO_FLAG_WRITE, NULL);
     if (ret < 0) {
         av_log(s, AV_LOG_ERROR, "Unable to open %s for writing\n", temp_filename);
@@ -178,7 +178,7 @@ static int write_manifest(AVFormatContext *s, int final)
     }
     avio_printf(out, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
     avio_printf(out, "<manifest xmlns=\"http://ns.adobe.com/f4m/1.0\">\n");
-    avio_printf(out, "\t<id>%s</id>\n", av_basename(s->filename));
+    avio_printf(out, "\t<id>%s</id>\n", av_basename(s->url));
     avio_printf(out, "\t<streamType>%s</streamType>\n",
                      final ? "recorded" : "live");
     avio_printf(out, "\t<deliveryType>streaming</deliveryType>\n");
@@ -236,9 +236,9 @@ static int write_abst(AVFormatContext *s, OutputStream *os, int final)
         cur_media_time = os->fragments[os->nb_fragments - 1]->start_time;
 
     snprintf(filename, sizeof(filename),
-             "%s/stream%d.abst", s->filename, index);
+             "%s/stream%d.abst", s->url, index);
     snprintf(temp_filename, sizeof(temp_filename),
-             "%s/stream%d.abst.tmp", s->filename, index);
+             "%s/stream%d.abst.tmp", s->url, index);
     ret = s->io_open(s, &out, temp_filename, AVIO_FLAG_WRITE, NULL);
     if (ret < 0) {
         av_log(s, AV_LOG_ERROR, "Unable to open %s for writing\n", temp_filename);
@@ -317,9 +317,9 @@ static int hds_write_header(AVFormatContext *s)
     int ret = 0, i;
     AVOutputFormat *oformat;
 
-    if (mkdir(s->filename, 0777) == -1 && errno != EEXIST) {
+    if (mkdir(s->url, 0777) == -1 && errno != EEXIST) {
         ret = AVERROR(errno);
-        av_log(s, AV_LOG_ERROR , "Failed to create directory %s\n", s->filename);
+        av_log(s, AV_LOG_ERROR , "Failed to create directory %s\n", s->url);
         goto fail;
     }
 
@@ -412,7 +412,7 @@ static int hds_write_header(AVFormatContext *s)
             s->streams[os->first_stream + j]->time_base = os->ctx->streams[j]->time_base;
 
         snprintf(os->temp_filename, sizeof(os->temp_filename),
-                 "%s/stream%d_temp", s->filename, i);
+                 "%s/stream%d_temp", s->url, i);
         ret = init_file(s, os, 0);
         if (ret < 0)
             goto fail;
@@ -476,7 +476,7 @@ static int hds_flush(AVFormatContext *s, OutputStream *os, int final,
     close_file(s, os);
 
     snprintf(target_filename, sizeof(target_filename),
-             "%s/stream%dSeg1-Frag%d", s->filename, index, os->fragment_index);
+             "%s/stream%dSeg1-Frag%d", s->url, index, os->fragment_index);
     ret = ff_rename(os->temp_filename, target_filename, s);
     if (ret < 0)
         return ret;
@@ -549,13 +549,13 @@ static int hds_write_trailer(AVFormatContext *s)
 
     if (c->remove_at_exit) {
         char filename[1024];
-        snprintf(filename, sizeof(filename), "%s/index.f4m", s->filename);
+        snprintf(filename, sizeof(filename), "%s/index.f4m", s->url);
         unlink(filename);
         for (i = 0; i < c->nb_streams; i++) {
-            snprintf(filename, sizeof(filename), "%s/stream%d.abst", s->filename, i);
+            snprintf(filename, sizeof(filename), "%s/stream%d.abst", s->url, i);
             unlink(filename);
         }
-        rmdir(s->filename);
+        rmdir(s->url);
     }
 
     hds_free(s);
diff --git a/libavformat/img2dec.c b/libavformat/img2dec.c
index ecf64eaffa..62db0d92cf 100644
--- a/libavformat/img2dec.c
+++ b/libavformat/img2dec.c
@@ -198,7 +198,7 @@ int ff_img_read_header(AVFormatContext *s1)
         return AVERROR(EINVAL);
     }
 
-    av_strlcpy(s->path, s1->filename, sizeof(s->path));
+    av_strlcpy(s->path, s1->url, sizeof(s->path));
     s->img_number = 0;
     s->img_count  = 0;
 
@@ -338,7 +338,7 @@ int ff_img_read_header(AVFormatContext *s1)
 
             pd.buf = probe_buffer;
             pd.buf_size = probe_buffer_size;
-            pd.filename = s1->filename;
+            pd.filename = s1->url;
 
             while ((fmt = av_iformat_next(fmt))) {
                 if (fmt->read_header != ff_img_read_header ||
diff --git a/libavformat/img2enc.c b/libavformat/img2enc.c
index b680676bff..a09cc8ec50 100644
--- a/libavformat/img2enc.c
+++ b/libavformat/img2enc.c
@@ -53,7 +53,7 @@ static int write_header(AVFormatContext *s)
     AVStream *st = s->streams[0];
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(st->codecpar->format);
 
-    av_strlcpy(img->path, s->filename, sizeof(img->path));
+    av_strlcpy(img->path, s->url, sizeof(img->path));
 
     /* find format */
     if (s->oformat->flags & AVFMT_NOFILE)
@@ -156,7 +156,7 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt)
 
         av_assert0(!img->split_planes);
 
-        ret = avformat_alloc_output_context2(&fmt, NULL, img->muxer, s->filename);
+        ret = avformat_alloc_output_context2(&fmt, NULL, img->muxer, s->url);
         if (ret < 0)
             return ret;
         st = avformat_new_stream(fmt, NULL);
diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
index 158ce7ae1f..a45fe09743 100644
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@ -3953,8 +3953,8 @@ static int webm_dash_manifest_read_header(AVFormatContext *s)
     }
 
     // basename of the file
-    buf = strrchr(s->filename, '/');
-    av_dict_set(&s->streams[0]->metadata, FILENAME, buf ? ++buf : s->filename, 0);
+    buf = strrchr(s->url, '/');
+    av_dict_set(&s->streams[0]->metadata, FILENAME, buf ? ++buf : s->url, 0);
 
     // track number
     tracks = matroska->tracks.elem;
diff --git a/libavformat/mlvdec.c b/libavformat/mlvdec.c
index 319cd26de4..d387c871ee 100644
--- a/libavformat/mlvdec.c
+++ b/libavformat/mlvdec.c
@@ -342,9 +342,9 @@ static int read_header(AVFormatContext *avctx)
         return ret;
 
     /* scan secondary files */
-    if (strlen(avctx->filename) > 2) {
+    if (strlen(avctx->url) > 2) {
         int i;
-        char *filename = av_strdup(avctx->filename);
+        char *filename = av_strdup(avctx->url);
 
         if (!filename)
             return AVERROR(ENOMEM);
diff --git a/libavformat/mov.c b/libavformat/mov.c
index 22faecfc17..d16b431e03 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -4115,7 +4115,7 @@ static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
         MOVDref *dref = &sc->drefs[sc->dref_id - 1];
         if (c->enable_drefs) {
-            if (mov_open_dref(c, &sc->pb, c->fc->filename, dref) < 0)
+            if (mov_open_dref(c, &sc->pb, c->fc->url, dref) < 0)
                 av_log(c->fc, AV_LOG_ERROR,
                        "stream %d, error opening alias: path='%s', dir='%s', "
                        "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index a597b0853d..f7079f3df7 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -1556,9 +1556,9 @@ static int mov_find_codec_tag(AVFormatContext *s, MOVTrack *track)
     else if (track->mode == MODE_ISM)
         tag = track->par->codec_tag;
     else if (track->mode == MODE_IPOD) {
-        if (!av_match_ext(s->filename, "m4a") &&
-            !av_match_ext(s->filename, "m4v") &&
-            !av_match_ext(s->filename, "m4b"))
+        if (!av_match_ext(s->url, "m4a") &&
+            !av_match_ext(s->url, "m4v") &&
+            !av_match_ext(s->url, "m4b"))
             av_log(s, AV_LOG_WARNING, "Warning, extension is not .m4a nor .m4v "
                    "Quicktime/Ipod might not play the file\n");
         tag = track->par->codec_tag;
@@ -6400,10 +6400,10 @@ static int shift_data(AVFormatContext *s)
      * writing, so we re-open the same output, but for reading. It also avoids
      * a read/seek/write/seek back and forth. */
     avio_flush(s->pb);
-    ret = s->io_open(s, &read_pb, s->filename, AVIO_FLAG_READ, NULL);
+    ret = s->io_open(s, &read_pb, s->url, AVIO_FLAG_READ, NULL);
     if (ret < 0) {
         av_log(s, AV_LOG_ERROR, "Unable to re-open %s output file for "
-               "the second pass (faststart)\n", s->filename);
+               "the second pass (faststart)\n", s->url);
         goto end;
     }
 
diff --git a/libavformat/mpeg.c b/libavformat/mpeg.c
index 50fe7a1a76..abdc6a937c 100644
--- a/libavformat/mpeg.c
+++ b/libavformat/mpeg.c
@@ -703,7 +703,7 @@ static int vobsub_read_header(AVFormatContext *s)
 
     if (!vobsub->sub_name) {
         char *ext;
-        vobsub->sub_name = av_strdup(s->filename);
+        vobsub->sub_name = av_strdup(s->url);
         if (!vobsub->sub_name) {
             ret = AVERROR(ENOMEM);
             goto end;
@@ -718,7 +718,7 @@ static int vobsub_read_header(AVFormatContext *s)
             goto end;
         }
         memcpy(ext, !strncmp(ext, "IDX", 3) ? "SUB" : "sub", 3);
-        av_log(s, AV_LOG_VERBOSE, "IDX/SUB: %s -> %s\n", s->filename, vobsub->sub_name);
+        av_log(s, AV_LOG_VERBOSE, "IDX/SUB: %s -> %s\n", s->url, vobsub->sub_name);
     }
 
     if (!(iformat = av_find_input_format("mpeg"))) {
diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c
index fdfa544ee2..8b0736ac4e 100644
--- a/libavformat/mpegtsenc.c
+++ b/libavformat/mpegtsenc.c
@@ -1012,7 +1012,7 @@ static int mpegts_init(AVFormatContext *s)
            ts->sdt_packet_period, ts->pat_packet_period);
 
     if (ts->m2ts_mode == -1) {
-        if (av_match_ext(s->filename, "m2ts")) {
+        if (av_match_ext(s->url, "m2ts")) {
             ts->m2ts_mode = 1;
         } else {
             ts->m2ts_mode = 0;
diff --git a/libavformat/options.c b/libavformat/options.c
index 9371c72667..c188c23506 100644
--- a/libavformat/options.c
+++ b/libavformat/options.c
@@ -104,7 +104,7 @@ static int io_open_default(AVFormatContext *s, AVIOContext **pb,
 {
     int loglevel;
 
-    if (!strcmp(url, s->filename) ||
+    if (!strcmp(url, s->url) ||
         s->iformat && !strcmp(s->iformat->name, "image2") ||
         s->oformat && !strcmp(s->oformat->name, "image2")
     ) {
diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index cf7cdb2f2b..89fc1e293c 100644
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -1686,7 +1686,7 @@ int ff_rtsp_connect(AVFormatContext *s)
 redirect:
     /* extract hostname and port */
     av_url_split(proto, sizeof(proto), auth, sizeof(auth),
-                 host, sizeof(host), &port, path, sizeof(path), s->filename);
+                 host, sizeof(host), &port, path, sizeof(path), s->url);
 
     if (!strcmp(proto, "rtsps")) {
         lower_rtsp_proto         = "tls";
@@ -1717,7 +1717,7 @@ redirect:
         }
     }
 
-    /* Construct the URI used in request; this is similar to s->filename,
+    /* Construct the URI used in request; this is similar to s->url,
      * but with authentication credentials removed and RTSP specific options
      * stripped out. */
     ff_url_join(rt->control_uri, sizeof(rt->control_uri), proto, NULL,
@@ -1905,13 +1905,19 @@ redirect:
     ff_rtsp_close_streams(s);
     ff_rtsp_close_connections(s);
     if (reply->status_code >=300 && reply->status_code < 400 && s->iformat) {
-        av_strlcpy(s->filename, reply->location, sizeof(s->filename));
+        char *new_url = av_strdup(reply->location);
+        if (!new_url) {
+            err = AVERROR(ENOMEM);
+            goto fail2;
+        }
+        ff_format_set_url(s, new_url);
         rt->session_id[0] = '\0';
         av_log(s, AV_LOG_INFO, "Status %d: Redirecting to %s\n",
                reply->status_code,
-               s->filename);
+               s->url);
         goto redirect;
     }
+ fail2:
     ff_network_close();
     return err;
 }
@@ -2425,7 +2431,7 @@ static int rtp_read_header(AVFormatContext *s)
     if (!ff_network_init())
         return AVERROR(EIO);
 
-    ret = ffurl_open_whitelist(&in, s->filename, AVIO_FLAG_READ,
+    ret = ffurl_open_whitelist(&in, s->url, AVIO_FLAG_READ,
                      &s->interrupt_callback, NULL, s->protocol_whitelist, s->protocol_blacklist, NULL);
     if (ret)
         goto fail;
@@ -2476,7 +2482,7 @@ static int rtp_read_header(AVFormatContext *s)
     }
 
     av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port,
-                 NULL, 0, s->filename);
+                 NULL, 0, s->url);
 
     snprintf(sdp, sizeof(sdp),
              "v=0\r\nc=IN IP%d %s\r\nm=%s %d RTP/AVP %d\r\n",
diff --git a/libavformat/rtspdec.c b/libavformat/rtspdec.c
index fdf75a0979..32dff2319c 100644
--- a/libavformat/rtspdec.c
+++ b/libavformat/rtspdec.c
@@ -644,7 +644,7 @@ static int rtsp_listen(AVFormatContext *s)
 
     /* extract hostname and port */
     av_url_split(proto, sizeof(proto), auth, sizeof(auth), host, sizeof(host),
-                 &port, path, sizeof(path), s->filename);
+                 &port, path, sizeof(path), s->url);
 
     /* ff_url_join. No authorization by now (NULL) */
     ff_url_join(rt->control_uri, sizeof(rt->control_uri), proto, NULL, host,
@@ -804,7 +804,7 @@ static int resetup_tcp(AVFormatContext *s)
     int port;
 
     av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port, NULL, 0,
-                 s->filename);
+                 s->url);
     ff_rtsp_undo_setup(s, 0);
     return ff_rtsp_make_setup_request(s, host, port, RTSP_LOWER_TRANSPORT_TCP,
                                       rt->real_challenge);
diff --git a/libavformat/rtspenc.c b/libavformat/rtspenc.c
index e7707bb5fb..97e3ef6da3 100644
--- a/libavformat/rtspenc.c
+++ b/libavformat/rtspenc.c
@@ -50,6 +50,7 @@ int ff_rtsp_setup_output_streams(AVFormatContext *s, const char *addr)
     int i;
     char *sdp;
     AVFormatContext sdp_ctx, *ctx_array[1];
+    char url[1024];
 
     if (s->start_time_realtime == 0  ||  s->start_time_realtime == AV_NOPTS_VALUE)
         s->start_time_realtime = av_gettime();
@@ -71,7 +72,8 @@ int ff_rtsp_setup_output_streams(AVFormatContext *s, const char *addr)
      * flexible SDP creation interface.
      */
     sdp_ctx = *s;
-    ff_url_join(sdp_ctx.filename, sizeof(sdp_ctx.filename),
+    sdp_ctx.url = url;
+    ff_url_join(url, sizeof(url),
                 "rtsp", NULL, addr, -1, NULL);
     ctx_array[0] = &sdp_ctx;
     if (av_sdp_create(ctx_array, 1, sdp, SDP_MAX_SIZE)) {
diff --git a/libavformat/sapdec.c b/libavformat/sapdec.c
index 522b38d10a..7a6c8bf176 100644
--- a/libavformat/sapdec.c
+++ b/libavformat/sapdec.c
@@ -74,7 +74,7 @@ static int sap_read_header(AVFormatContext *s)
         return AVERROR(EIO);
 
     av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port,
-                 path, sizeof(path), s->filename);
+                 path, sizeof(path), s->url);
     if (port < 0)
         port = 9875;
 
diff --git a/libavformat/sapenc.c b/libavformat/sapenc.c
index 3098e340ca..f9afab0c33 100644
--- a/libavformat/sapenc.c
+++ b/libavformat/sapenc.c
@@ -84,7 +84,7 @@ static int sap_write_header(AVFormatContext *s)
 
     /* extract hostname and port */
     av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &base_port,
-                 path, sizeof(path), s->filename);
+                 path, sizeof(path), s->url);
     if (base_port < 0)
         base_port = 5004;
 
@@ -144,6 +144,7 @@ static int sap_write_header(AVFormatContext *s)
         s->start_time_realtime = av_gettime();
     for (i = 0; i < s->nb_streams; i++) {
         URLContext *fd;
+        char *new_url;
 
         ff_url_join(url, sizeof(url), "rtp", NULL, host, base_port,
                     "?ttl=%d", ttl);
@@ -161,7 +162,12 @@ static int sap_write_header(AVFormatContext *s)
             goto fail;
         s->streams[i]->priv_data = contexts[i];
         s->streams[i]->time_base = contexts[i]->streams[0]->time_base;
-        av_strlcpy(contexts[i]->filename, url, sizeof(contexts[i]->filename));
+        new_url = av_strdup(url);
+        if (!new_url) {
+            ret = AVERROR(ENOMEM);
+            goto fail;
+        }
+        ff_format_set_url(contexts[i], new_url);
     }
 
     if (s->nb_streams > 0 && title)
diff --git a/libavformat/sdp.c b/libavformat/sdp.c
index e7149167a1..a5d202e99c 100644
--- a/libavformat/sdp.c
+++ b/libavformat/sdp.c
@@ -784,7 +784,7 @@ int av_sdp_create(AVFormatContext *ac[], int n_files, char *buf, int size)
     port = 0;
     ttl = 0;
     if (n_files == 1) {
-        port = sdp_get_address(dst, sizeof(dst), &ttl, ac[0]->filename);
+        port = sdp_get_address(dst, sizeof(dst), &ttl, ac[0]->url ? ac[0]->url : "");
         is_multicast = resolve_destination(dst, sizeof(dst), dst_type,
                                            sizeof(dst_type));
         if (!is_multicast)
@@ -804,7 +804,7 @@ int av_sdp_create(AVFormatContext *ac[], int n_files, char *buf, int size)
     dst[0] = 0;
     for (i = 0; i < n_files; i++) {
         if (n_files != 1) {
-            port = sdp_get_address(dst, sizeof(dst), &ttl, ac[i]->filename);
+            port = sdp_get_address(dst, sizeof(dst), &ttl, ac[i]->url ? ac[i]->url : "");
             is_multicast = resolve_destination(dst, sizeof(dst), dst_type,
                                                sizeof(dst_type));
             if (!is_multicast)
diff --git a/libavformat/segment.c b/libavformat/segment.c
index 81d3f1d940..8da4fca512 100644
--- a/libavformat/segment.c
+++ b/libavformat/segment.c
@@ -192,6 +192,8 @@ static int set_segment_filename(AVFormatContext *s)
     AVFormatContext *oc = seg->avf;
     size_t size;
     int ret;
+    char buf[1024];
+    char *new_name;
 
     if (seg->segment_idx_wrap)
         seg->segment_idx %= seg->segment_idx_wrap;
@@ -200,18 +202,22 @@ static int set_segment_filename(AVFormatContext *s)
         struct tm *tm, tmpbuf;
         time(&now0);
         tm = localtime_r(&now0, &tmpbuf);
-        if (!strftime(oc->filename, sizeof(oc->filename), s->filename, tm)) {
+        if (!strftime(buf, sizeof(buf), s->url, tm)) {
             av_log(oc, AV_LOG_ERROR, "Could not get segment filename with strftime\n");
             return AVERROR(EINVAL);
         }
-    } else if (av_get_frame_filename(oc->filename, sizeof(oc->filename),
-                                     s->filename, seg->segment_idx) < 0) {
-        av_log(oc, AV_LOG_ERROR, "Invalid segment filename template '%s'\n", s->filename);
+    } else if (av_get_frame_filename(buf, sizeof(buf),
+                                     s->url, seg->segment_idx) < 0) {
+        av_log(oc, AV_LOG_ERROR, "Invalid segment filename template '%s'\n", s->url);
         return AVERROR(EINVAL);
     }
+    new_name = av_strdup(buf);
+    if (!new_name)
+        return AVERROR(ENOMEM);
+    ff_format_set_url(oc, new_name);
 
     /* copy modified name in list entry */
-    size = strlen(av_basename(oc->filename)) + 1;
+    size = strlen(av_basename(oc->url)) + 1;
     if (seg->entry_prefix)
         size += strlen(seg->entry_prefix);
 
@@ -219,7 +225,7 @@ static int set_segment_filename(AVFormatContext *s)
         return ret;
     snprintf(seg->cur_entry.filename, size, "%s%s",
              seg->entry_prefix ? seg->entry_prefix : "",
-             av_basename(oc->filename));
+             av_basename(oc->url));
 
     return 0;
 }
@@ -245,8 +251,8 @@ static int segment_start(AVFormatContext *s, int write_header)
     if ((err = set_segment_filename(s)) < 0)
         return err;
 
-    if ((err = s->io_open(s, &oc->pb, oc->filename, AVIO_FLAG_WRITE, NULL)) < 0) {
-        av_log(s, AV_LOG_ERROR, "Failed to open segment '%s'\n", oc->filename);
+    if ((err = s->io_open(s, &oc->pb, oc->url, AVIO_FLAG_WRITE, NULL)) < 0) {
+        av_log(s, AV_LOG_ERROR, "Failed to open segment '%s'\n", oc->url);
         return err;
     }
     if (!seg->individual_header_trailer)
@@ -360,7 +366,7 @@ static int segment_end(AVFormatContext *s, int write_trailer, int is_last)
 
     if (ret < 0)
         av_log(s, AV_LOG_ERROR, "Failure occurred when ending segment '%s'\n",
-               oc->filename);
+               oc->url);
 
     if (seg->list) {
         if (seg->list_size || seg->list_type == LIST_TYPE_M3U8) {
@@ -403,7 +409,7 @@ static int segment_end(AVFormatContext *s, int write_trailer, int is_last)
     }
 
     av_log(s, AV_LOG_VERBOSE, "segment:'%s' count:%d ended\n",
-           seg->avf->filename, seg->segment_count);
+           seg->avf->url, seg->segment_count);
     seg->segment_count++;
 
     if (seg->increment_tc) {
@@ -726,7 +732,7 @@ static int seg_init(AVFormatContext *s)
            seg->reference_stream_index,
            av_get_media_type_string(s->streams[seg->reference_stream_index]->codecpar->codec_type));
 
-    seg->oformat = av_guess_format(seg->format, s->filename, NULL);
+    seg->oformat = av_guess_format(seg->format, s->url, NULL);
 
     if (!seg->oformat)
         return AVERROR_MUXER_NOT_FOUND;
@@ -745,9 +751,9 @@ static int seg_init(AVFormatContext *s)
 
     if (seg->write_header_trailer) {
         if ((ret = s->io_open(s, &oc->pb,
-                              seg->header_filename ? seg->header_filename : oc->filename,
+                              seg->header_filename ? seg->header_filename : oc->url,
                               AVIO_FLAG_WRITE, NULL)) < 0) {
-            av_log(s, AV_LOG_ERROR, "Failed to open segment '%s'\n", oc->filename);
+            av_log(s, AV_LOG_ERROR, "Failed to open segment '%s'\n", oc->url);
             return ret;
         }
         if (!seg->individual_header_trailer)
@@ -830,7 +836,7 @@ static int seg_write_header(AVFormatContext *s)
         } else {
             close_null_ctxp(&oc->pb);
         }
-        if ((ret = oc->io_open(oc, &oc->pb, oc->filename, AVIO_FLAG_WRITE, NULL)) < 0)
+        if ((ret = oc->io_open(oc, &oc->pb, oc->url, AVIO_FLAG_WRITE, NULL)) < 0)
             return ret;
         if (!seg->individual_header_trailer)
             oc->pb->seekable = 0;
@@ -917,7 +923,7 @@ calc_times:
 
     if (seg->segment_frame_count == 0) {
         av_log(s, AV_LOG_VERBOSE, "segment:'%s' starts with packet stream:%d pts:%s pts_time:%s frame:%d\n",
-               seg->avf->filename, pkt->stream_index,
+               seg->avf->url, pkt->stream_index,
                av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &st->time_base), seg->frame_count);
     }
 
diff --git a/libavformat/smoothstreamingenc.c b/libavformat/smoothstreamingenc.c
index 54a1c49caa..094712af27 100644
--- a/libavformat/smoothstreamingenc.c
+++ b/libavformat/smoothstreamingenc.c
@@ -221,8 +221,8 @@ static int write_manifest(AVFormatContext *s, int final)
     int ret, i, video_chunks = 0, audio_chunks = 0, video_streams = 0, audio_streams = 0;
     int64_t duration = 0;
 
-    snprintf(filename, sizeof(filename), "%s/Manifest", s->filename);
-    snprintf(temp_filename, sizeof(temp_filename), "%s/Manifest.tmp", s->filename);
+    snprintf(filename, sizeof(filename), "%s/Manifest", s->url);
+    snprintf(temp_filename, sizeof(temp_filename), "%s/Manifest.tmp", s->url);
     ret = s->io_open(s, &out, temp_filename, AVIO_FLAG_WRITE, NULL);
     if (ret < 0) {
         av_log(s, AV_LOG_ERROR, "Unable to open %s for writing\n", temp_filename);
@@ -295,7 +295,7 @@ static int ism_write_header(AVFormatContext *s)
     int ret = 0, i;
     AVOutputFormat *oformat;
 
-    if (mkdir(s->filename, 0777) == -1 && errno != EEXIST) {
+    if (mkdir(s->url, 0777) == -1 && errno != EEXIST) {
         ret = AVERROR(errno);
         av_log(s, AV_LOG_ERROR, "mkdir failed\n");
         goto fail;
@@ -324,7 +324,7 @@ static int ism_write_header(AVFormatContext *s)
             ret = AVERROR(EINVAL);
             goto fail;
         }
-        snprintf(os->dirname, sizeof(os->dirname), "%s/QualityLevels(%"PRId64")", s->filename, s->streams[i]->codecpar->bit_rate);
+        snprintf(os->dirname, sizeof(os->dirname), "%s/QualityLevels(%"PRId64")", s->url, s->streams[i]->codecpar->bit_rate);
         if (mkdir(os->dirname, 0777) == -1 && errno != EEXIST) {
             ret = AVERROR(errno);
             av_log(s, AV_LOG_ERROR, "mkdir failed\n");
@@ -609,9 +609,9 @@ static int ism_write_trailer(AVFormatContext *s)
 
     if (c->remove_at_exit) {
         char filename[1024];
-        snprintf(filename, sizeof(filename), "%s/Manifest", s->filename);
+        snprintf(filename, sizeof(filename), "%s/Manifest", s->url);
         unlink(filename);
-        rmdir(s->filename);
+        rmdir(s->url);
     }
 
     ism_free(s);
diff --git a/libavformat/tee.c b/libavformat/tee.c
index dd1844ac0e..ef3b113a47 100644
--- a/libavformat/tee.c
+++ b/libavformat/tee.c
@@ -406,7 +406,7 @@ static void log_slave(TeeSlave *slave, void *log_ctx, int log_level)
 {
     int i;
     av_log(log_ctx, log_level, "filename:'%s' format:%s\n",
-           slave->avf->filename, slave->avf->oformat->name);
+           slave->avf->url, slave->avf->oformat->name);
     for (i = 0; i < slave->avf->nb_streams; i++) {
         AVStream *st = slave->avf->streams[i];
         AVBSFContext *bsf = slave->bsfs[i];
@@ -448,7 +448,7 @@ static int tee_write_header(AVFormatContext *avf)
 {
     TeeContext *tee = avf->priv_data;
     unsigned nb_slaves = 0, i;
-    const char *filename = avf->filename;
+    const char *filename = avf->url;
     char **slaves = NULL;
     int ret;
 
diff --git a/libavformat/utils.c b/libavformat/utils.c
index 8bf27c3b35..0b777186e1 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -2059,7 +2059,7 @@ void ff_configure_buffers_for_index(AVFormatContext *s, int64_t time_tolerance)
     int64_t pos_delta = 0;
     int64_t skip = 0;
     //We could use URLProtocol flags here but as many user applications do not use URLProtocols this would be unreliable
-    const char *proto = avio_find_protocol_name(s->filename);
+    const char *proto = avio_find_protocol_name(s->url);
 
     if (!proto) {
         av_log(s, AV_LOG_INFO,
diff --git a/libavformat/webm_chunk.c b/libavformat/webm_chunk.c
index f8dbaa3339..549ec2879a 100644
--- a/libavformat/webm_chunk.c
+++ b/libavformat/webm_chunk.c
@@ -99,8 +99,8 @@ static int get_chunk_filename(AVFormatContext *s, int is_header, char *filename)
         av_strlcpy(filename, wc->header_filename, strlen(wc->header_filename) + 1);
     } else {
         if (av_get_frame_filename(filename, MAX_FILENAME_SIZE,
-                                  s->filename, wc->chunk_index - 1) < 0) {
-            av_log(oc, AV_LOG_ERROR, "Invalid chunk filename template '%s'\n", s->filename);
+                                  s->url, wc->chunk_index - 1) < 0) {
+            av_log(oc, AV_LOG_ERROR, "Invalid chunk filename template '%s'\n", s->url);
             return AVERROR(EINVAL);
         }
     }
@@ -119,7 +119,7 @@ static int webm_chunk_write_header(AVFormatContext *s)
     if (s->nb_streams != 1) { return AVERROR_INVALIDDATA; }
 
     wc->chunk_index = wc->chunk_start_index;
-    wc->oformat = av_guess_format("webm", s->filename, "video/webm");
+    wc->oformat = av_guess_format("webm", s->url, "video/webm");
     if (!wc->oformat)
         return AVERROR_MUXER_NOT_FOUND;
 
@@ -127,12 +127,12 @@ static int webm_chunk_write_header(AVFormatContext *s)
     if (ret < 0)
         return ret;
     oc = wc->avf;
-    ret = get_chunk_filename(s, 1, oc->filename);
+    ret = get_chunk_filename(s, 1, oc->url);
     if (ret < 0)
         return ret;
     if (wc->http_method)
         av_dict_set(&options, "method", wc->http_method, 0);
-    ret = s->io_open(s, &oc->pb, oc->filename, AVIO_FLAG_WRITE, &options);
+    ret = s->io_open(s, &oc->pb, oc->url, AVIO_FLAG_WRITE, &options);
     av_dict_free(&options);
     if (ret < 0)
         return ret;
