deps/media-playback: Init avformat in thread

Prevents the media playback object from locking the render thread.
This commit is contained in:
jp9000 2017-05-16 01:55:58 -07:00
parent 3b091b1668
commit 2b3d619c31
2 changed files with 48 additions and 29 deletions

View File

@ -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);
}

View File

@ -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;