[FFmpeg-devel] [PATCH v4 3/4] lavf/dashdec: Prevent cross-thread avio_opts modification
Lukas Fellechner
lukas.fellechner at gmx.net
Tue Sep 6 00:16:33 EEST 2022
open_url modifies the shared avio_opts dict (update cookies).
This can cause problems during multithreaded initialization.
To prevent this, I take a copy of avio_opts, use that in open_url,
and copy the updated dict back afterwards.
---
libavformat/dashdec.c | 34 ++++++++++++++++++++++++++++++++--
1 file changed, 32 insertions(+), 2 deletions(-)
diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c
index 0532e2c918..19e657d836 100644
--- a/libavformat/dashdec.c
+++ b/libavformat/dashdec.c
@@ -156,6 +156,11 @@ typedef struct DASHContext {
int init_threads;
+#if HAVE_THREADS
+ /* Set during parallel initialization, to allow locking of avio_opts */
+ pthread_mutex_t *init_mutex;
+#endif
+
/* Flags for init section*/
int is_init_section_common_video;
int is_init_section_common_audio;
@@ -1699,7 +1704,32 @@ static int open_input(DASHContext *c, struct representation *pls, struct fragmen
ff_make_absolute_url(url, c->max_url_size, c->base_url, seg->url);
av_log(pls->parent, AV_LOG_VERBOSE, "DASH request for url '%s', offset %"PRId64"\n",
url, seg->url_offset);
- ret = open_url(pls->parent, &pls->input, url, &c->avio_opts, opts, NULL);
+
+ AVDictionary *avio_opts = c->avio_opts;
+
+#if HAVE_THREADS
+ // If we are doing parallel initialization, take a snapshot of the avio_opts,
+ // and copy the modified dictionary ("cookies" updated) back, after the url is opened.
+ if (c->init_mutex) {
+ pthread_mutex_lock(c->init_mutex);
+ avio_opts = NULL;
+ ret = av_dict_copy(&avio_opts, c->avio_opts, 0);
+ pthread_mutex_unlock(c->init_mutex);
+ if (ret < 0)
+ goto cleanup;
+ }
+#endif
+
+ ret = open_url(pls->parent, &pls->input, url, &avio_opts, opts, NULL);
+
+#if HAVE_THREADS
+ if (c->init_mutex) {
+ pthread_mutex_lock(c->init_mutex);
+ av_dict_free(&c->avio_opts);
+ c->avio_opts = avio_opts;
+ pthread_mutex_unlock(c->init_mutex);
+ }
+#endif
cleanup:
av_free(url);
@@ -2192,7 +2222,7 @@ static int init_streams_multithreaded(AVFormatContext *s, int nstreams, int thre
if (!avpriv_slicethread_create(&slice_thread, (void*)work_pool, &thread_worker, NULL, threads)) {
av_free(work_pool);
return AVERROR(ENOMEM);
-}
+ }
// alloc mutex and conditions
c->init_mutex = create_mutex();
--
2.28.0.windows.1
More information about the ffmpeg-devel
mailing list