From 9241e1bf106f7ae5a6350fdbe602dda9aa390008 Mon Sep 17 00:00:00 2001 From: wm4 Date: Tue, 14 Oct 2014 21:01:30 +0200 Subject: [PATCH] demux_lavf: set stream network options if applicable Normally, we pass libavformat demuxers a wrapped mpv stream. But in some cases, such as HLS and RTSP, we let libavformat open the stream itself. In these cases, set typical network properties like useragent according to the mpv options. (We still don't set it for the cases where libavformat opens other streams on its own, e.g. when opening the companion .sub file for .idx files - not sure if we maybe should always set these options.) --- demux/demux_lavf.c | 5 ++-- stream/stream.h | 7 +++++ stream/stream_lavf.c | 69 +++++++++++++++++++++++++------------------- 3 files changed, 50 insertions(+), 31 deletions(-) diff --git a/demux/demux_lavf.c b/demux/demux_lavf.c index ddec27f66d..85db0692e8 100644 --- a/demux/demux_lavf.c +++ b/demux/demux_lavf.c @@ -706,10 +706,13 @@ static int demux_open_lavf(demuxer_t *demuxer, enum demux_check check) "analyzeduration to %f\n", analyze_duration); } + AVDictionary *dopts = NULL; + if ((priv->avif->flags & AVFMT_NOFILE) || demuxer->stream->type == STREAMTYPE_AVDEVICE || matches_avinputformat_name(priv, "hls")) { + mp_setup_av_network_options(&dopts, demuxer->global, demuxer->log, opts); // This might be incorrect. demuxer->seekable = true; } else { @@ -727,8 +730,6 @@ static int demux_open_lavf(demuxer_t *demuxer, enum demux_check check) avfc->pb = priv->pb; } - AVDictionary *dopts = NULL; - if (matches_avinputformat_name(priv, "rtsp")) { const char *transport = NULL; switch (opts->network_rtsp_transport) { diff --git a/stream/stream.h b/stream/stream.h index 28f9936fce..56c431ed46 100644 --- a/stream/stream.h +++ b/stream/stream.h @@ -268,6 +268,13 @@ void mp_cancel_reset(struct mp_cancel *c); char *mp_file_url_to_filename(void *talloc_ctx, bstr url); char *mp_file_get_path(void *talloc_ctx, bstr url); +// stream_lavf.c +struct AVDictionary; +void mp_setup_av_network_options(struct AVDictionary **dict, + struct mpv_global *global, + struct mp_log *log, + struct MPOpts *opts); + void stream_print_proto_list(struct mp_log *log); #endif /* MPLAYER_STREAM_H */ diff --git a/stream/stream_lavf.c b/stream/stream_lavf.c index 2441492229..02f23284b3 100644 --- a/stream/stream_lavf.c +++ b/stream/stream_lavf.c @@ -143,6 +143,45 @@ static int interrupt_cb(void *ctx) static const char * const prefix[] = { "lavf://", "ffmpeg://" }; +void mp_setup_av_network_options(AVDictionary **dict, struct mpv_global *global, + struct mp_log *log, struct MPOpts *opts) +{ + void *temp = talloc_new(NULL); + + // HTTP specific options (other protocols ignore them) + if (opts->network_useragent) + av_dict_set(dict, "user-agent", opts->network_useragent, 0); + if (opts->network_cookies_enabled) { + char *file = opts->network_cookies_file; + if (file && file[0]) + file = mp_get_user_path(temp, global, file); + char *cookies = cookies_lavf(temp, log, file); + if (cookies && cookies[0]) + av_dict_set(dict, "cookies", cookies, 0); + } + av_dict_set(dict, "tls_verify", opts->network_tls_verify ? "1" : "0", 0); + if (opts->network_tls_ca_file) + av_dict_set(dict, "ca_file", opts->network_tls_ca_file, 0); + char *cust_headers = talloc_strdup(temp, ""); + if (opts->network_referrer) { + cust_headers = talloc_asprintf_append(cust_headers, "Referer: %s\r\n", + opts->network_referrer); + } + if (opts->network_http_header_fields) { + for (int n = 0; opts->network_http_header_fields[n]; n++) { + cust_headers = talloc_asprintf_append(cust_headers, "%s\r\n", + opts->network_http_header_fields[n]); + } + } + if (strlen(cust_headers)) + av_dict_set(dict, "headers", cust_headers, 0); + av_dict_set(dict, "icy", "1", 0); + + mp_set_avdict(dict, opts->stream_lavf_opts->avopts); + + talloc_free(temp); +} + static int open_f(stream_t *stream) { struct MPOpts *opts = stream->opts; @@ -186,35 +225,7 @@ static int open_f(stream_t *stream) filename = talloc_asprintf(temp, "mmsh://%.*s", BSTR_P(b_filename)); } - // HTTP specific options (other protocols ignore them) - if (opts->network_useragent) - av_dict_set(&dict, "user-agent", opts->network_useragent, 0); - if (opts->network_cookies_enabled) { - char *file = opts->network_cookies_file; - if (file && file[0]) - file = mp_get_user_path(temp, stream->global, file); - char *cookies = cookies_lavf(temp, stream->log, file); - if (cookies && cookies[0]) - av_dict_set(&dict, "cookies", cookies, 0); - } - av_dict_set(&dict, "tls_verify", opts->network_tls_verify ? "1" : "0", 0); - if (opts->network_tls_ca_file) - av_dict_set(&dict, "ca_file", opts->network_tls_ca_file, 0); - char *cust_headers = talloc_strdup(temp, ""); - if (opts->network_referrer) { - cust_headers = talloc_asprintf_append(cust_headers, "Referer: %s\r\n", - opts->network_referrer); - } - if (opts->network_http_header_fields) { - for (int n = 0; opts->network_http_header_fields[n]; n++) { - cust_headers = talloc_asprintf_append(cust_headers, "%s\r\n", - opts->network_http_header_fields[n]); - } - } - if (strlen(cust_headers)) - av_dict_set(&dict, "headers", cust_headers, 0); - av_dict_set(&dict, "icy", "1", 0); - mp_set_avdict(&dict, opts->stream_lavf_opts->avopts); + mp_setup_av_network_options(&dict, stream->global, stream->log, opts); AVIOInterruptCB cb = { .callback = interrupt_cb,