Browse Source

deps/media-playback: Init avformat in thread

Prevents the media playback object from locking the render thread.
jp9000 8 years ago
parent
commit
2b3d619c31

+ 44 - 29
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);
 }

+ 4 - 0
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;