From 2b3d619c319a18abcf9e1994d24079cea7af717a Mon Sep 17 00:00:00 2001 From: jp9000 Date: Tue, 16 May 2017 01:55:58 -0700 Subject: [PATCH] deps/media-playback: Init avformat in thread Prevents the media playback object from locking the render thread. --- deps/media-playback/media-playback/media.c | 73 +++++++++++++--------- deps/media-playback/media-playback/media.h | 4 ++ 2 files changed, 48 insertions(+), 29 deletions(-) diff --git a/deps/media-playback/media-playback/media.c b/deps/media-playback/media-playback/media.c index 8c65f7edd..b9f11610e 100644 --- a/deps/media-playback/media-playback/media.c +++ b/deps/media-playback/media-playback/media.c @@ -470,12 +470,51 @@ static inline bool mp_media_eof(mp_media_t *m) return eof; } +static bool init_avformat(mp_media_t *m) +{ + AVInputFormat *format = NULL; + + if (m->format_name && *m->format_name) { + format = av_find_input_format(m->format_name); + if (!format) + blog(LOG_INFO, "MP: Unable to find input format for " + "'%s'", m->path); + } + + int ret = avformat_open_input(&m->fmt, m->path, format, NULL); + if (ret < 0) { + blog(LOG_WARNING, "MP: Failed to open media: '%s'", m->path); + return false; + } + + if (avformat_find_stream_info(m->fmt, NULL) < 0) { + blog(LOG_WARNING, "MP: Failed to find stream info for '%s'", + m->path); + return false; + } + + m->has_video = mp_decode_init(m, AVMEDIA_TYPE_VIDEO, m->hw); + m->has_audio = mp_decode_init(m, AVMEDIA_TYPE_AUDIO, m->hw); + + if (!m->has_video && !m->has_audio) { + blog(LOG_WARNING, "MP: Could not initialize audio or video: " + "'%s'", m->path); + return false; + } + + return true; +} + static void *mp_media_thread(void *opaque) { mp_media_t *m = opaque; os_set_thread_name("mp_media_thread"); + if (!init_avformat(m)) { + return NULL; + } + mp_media_reset(m); for (;;) { @@ -533,8 +572,6 @@ static inline bool mp_media_init_internal(mp_media_t *m, const char *format_name, bool hw) { - AVInputFormat *format = NULL; - if (pthread_mutex_init(&m->mutex, NULL) != 0) { blog(LOG_WARNING, "MP: Failed to init mutex"); return false; @@ -544,33 +581,9 @@ static inline bool mp_media_init_internal(mp_media_t *m, return false; } - if (format_name && *format_name) { - format = av_find_input_format(format_name); - if (!format) - blog(LOG_INFO, "MP: Unable to find input format for " - "'%s'", path); - } - - int ret = avformat_open_input(&m->fmt, path, format, NULL); - if (ret < 0) { - blog(LOG_WARNING, "MP: Failed to open media: '%s'", path); - return false; - } - - if (avformat_find_stream_info(m->fmt, NULL) < 0) { - blog(LOG_WARNING, "MP: Failed to find stream info for '%s'", - path); - return false; - } - - m->has_video = mp_decode_init(m, AVMEDIA_TYPE_VIDEO, hw); - m->has_audio = mp_decode_init(m, AVMEDIA_TYPE_AUDIO, hw); - - if (!m->has_video && !m->has_audio) { - blog(LOG_WARNING, "MP: Could not initialize audio or video: " - "'%s'", path); - return false; - } + m->path = path ? bstrdup(path) : NULL; + m->format_name = format_name ? bstrdup(format_name) : NULL; + m->hw = hw; if (pthread_create(&m->thread, NULL, mp_media_thread, m) != 0) { blog(LOG_WARNING, "MP: Could not create media thread"); @@ -650,6 +663,8 @@ void mp_media_free(mp_media_t *media) avformat_close_input(&media->fmt); sws_freeContext(media->swscale); av_freep(&media->scale_pic[0]); + bfree(media->path); + bfree(media->format_name); memset(media, 0, sizeof(*media)); pthread_mutex_init_value(&media->mutex); } diff --git a/deps/media-playback/media-playback/media.h b/deps/media-playback/media-playback/media.h index 81868ba9d..e8dd58bee 100644 --- a/deps/media-playback/media-playback/media.h +++ b/deps/media-playback/media-playback/media.h @@ -51,6 +51,9 @@ struct mp_media { mp_audio_cb a_cb; void *opaque; + char *path; + char *format_name; + enum AVPixelFormat scale_format; struct SwsContext *swscale; int scale_linesizes[4]; @@ -63,6 +66,7 @@ struct mp_media { bool has_audio; bool is_file; bool eof; + bool hw; struct obs_source_frame obsframe; enum video_colorspace cur_space;