deps/media-playback: Fix lockup issues
Certain functions such as avformat_open_input and av_read_frame can block, causing the program to someone wait very long periods of time when a network URL is used with the media source. The interrupt_callback member variable in AVFormatContext allows safely canceling IO operations when trying to shut down or stop the media-playback interface.
This commit is contained in:
parent
daee6e0759
commit
88ae9aff6e
23
deps/media-playback/media-playback/media.c
vendored
23
deps/media-playback/media-playback/media.c
vendored
@ -486,6 +486,23 @@ static inline bool mp_media_eof(mp_media_t *m)
|
|||||||
return eof;
|
return eof;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int interrupt_callback(void *data)
|
||||||
|
{
|
||||||
|
mp_media_t *m = data;
|
||||||
|
bool stop = false;
|
||||||
|
uint64_t ts = os_gettime_ns();
|
||||||
|
|
||||||
|
if ((ts - m->interrupt_poll_ts) > 20000000) {
|
||||||
|
pthread_mutex_lock(&m->mutex);
|
||||||
|
stop = m->kill || m->stopping;
|
||||||
|
pthread_mutex_unlock(&m->mutex);
|
||||||
|
|
||||||
|
m->interrupt_poll_ts = ts;
|
||||||
|
}
|
||||||
|
|
||||||
|
return stop;
|
||||||
|
}
|
||||||
|
|
||||||
static bool init_avformat(mp_media_t *m)
|
static bool init_avformat(mp_media_t *m)
|
||||||
{
|
{
|
||||||
AVInputFormat *format = NULL;
|
AVInputFormat *format = NULL;
|
||||||
@ -501,6 +518,10 @@ static bool init_avformat(mp_media_t *m)
|
|||||||
if (m->buffering && m->is_network)
|
if (m->buffering && m->is_network)
|
||||||
av_dict_set_int(&opts, "buffer_size", m->buffering, 0);
|
av_dict_set_int(&opts, "buffer_size", m->buffering, 0);
|
||||||
|
|
||||||
|
m->fmt = avformat_alloc_context();
|
||||||
|
m->fmt->interrupt_callback.callback = interrupt_callback;
|
||||||
|
m->fmt->interrupt_callback.opaque = m;
|
||||||
|
|
||||||
int ret = avformat_open_input(&m->fmt, m->path, format,
|
int ret = avformat_open_input(&m->fmt, m->path, format,
|
||||||
opts ? &opts : NULL);
|
opts ? &opts : NULL);
|
||||||
av_dict_free(&opts);
|
av_dict_free(&opts);
|
||||||
@ -695,9 +716,9 @@ void mp_media_free(mp_media_t *media)
|
|||||||
mp_kill_thread(media);
|
mp_kill_thread(media);
|
||||||
mp_decode_free(&media->v);
|
mp_decode_free(&media->v);
|
||||||
mp_decode_free(&media->a);
|
mp_decode_free(&media->a);
|
||||||
|
avformat_close_input(&media->fmt);
|
||||||
pthread_mutex_destroy(&media->mutex);
|
pthread_mutex_destroy(&media->mutex);
|
||||||
os_sem_destroy(media->sem);
|
os_sem_destroy(media->sem);
|
||||||
avformat_close_input(&media->fmt);
|
|
||||||
sws_freeContext(media->swscale);
|
sws_freeContext(media->swscale);
|
||||||
av_freep(&media->scale_pic[0]);
|
av_freep(&media->scale_pic[0]);
|
||||||
bfree(media->path);
|
bfree(media->path);
|
||||||
|
2
deps/media-playback/media-playback/media.h
vendored
2
deps/media-playback/media-playback/media.h
vendored
@ -80,6 +80,8 @@ struct mp_media {
|
|||||||
int64_t start_ts;
|
int64_t start_ts;
|
||||||
int64_t base_ts;
|
int64_t base_ts;
|
||||||
|
|
||||||
|
uint64_t interrupt_poll_ts;
|
||||||
|
|
||||||
pthread_mutex_t mutex;
|
pthread_mutex_t mutex;
|
||||||
os_sem_t *sem;
|
os_sem_t *sem;
|
||||||
bool stopping;
|
bool stopping;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user