diff --git a/src/dvr/dvr_rec.c b/src/dvr/dvr_rec.c index 3b61430c..4929a738 100644 --- a/src/dvr/dvr_rec.c +++ b/src/dvr/dvr_rec.c @@ -253,7 +253,7 @@ dvr_rec_start(dvr_entry_t *de, htsmsg_t *m) enum CodecType codec_type; const char *codec_name; char urlname[512]; - int err; + int err, r; htsmsg_field_t *f; htsmsg_t *sub, *streams; const char *type, *lang; @@ -356,7 +356,11 @@ dvr_rec_start(dvr_entry_t *de, htsmsg_t *m) ctx->codec_id = codec_id; ctx->codec_type = codec_type; - if(avcodec_open(ctx, codec) < 0) { + pthread_mutex_lock(&ffmpeg_lock); + r = avcodec_open(ctx, codec); + pthread_mutex_unlock(&ffmpeg_lock); + + if(r < 0) { tvhlog(LOG_ERR, "dvr", "%s - Cannot open codec for %s, ignoring stream", de->de_ititle, codec_name); @@ -703,7 +707,9 @@ dvr_thread_epilog(dvr_entry_t *de) for(i = 0; i < fctx->nb_streams; i++) { st = fctx->streams[i]; + pthread_mutex_lock(&ffmpeg_lock); avcodec_close(st->codec); + pthread_mutex_unlock(&ffmpeg_lock); free(st->codec); free(st); } diff --git a/src/main.c b/src/main.c index 3ab2347b..f4e03916 100644 --- a/src/main.c +++ b/src/main.c @@ -60,6 +60,7 @@ extern const char *htsversion_full; time_t dispatch_clock; static LIST_HEAD(, gtimer) gtimers; pthread_mutex_t global_lock; +pthread_mutex_t ffmpeg_lock; static void handle_sigpipe(int x) @@ -290,6 +291,8 @@ main(int argc, char **argv) hts_settings_init("tvheadend", homedir); + pthread_mutex_init(&ffmpeg_lock, NULL); + pthread_mutex_init(&global_lock, NULL); pthread_mutex_lock(&global_lock); diff --git a/src/transports.c b/src/transports.c index 7f8fcd1f..fd86e163 100644 --- a/src/transports.c +++ b/src/transports.c @@ -86,8 +86,11 @@ transport_stop(th_transport_t *t) if(st->st_parser != NULL) av_parser_close(st->st_parser); - if(st->st_ctx != NULL) + if(st->st_ctx != NULL) { + pthread_mutex_lock(&ffmpeg_lock); avcodec_close(st->st_ctx); + pthread_mutex_unlock(&ffmpeg_lock); + } av_free(st->st_ctx); @@ -244,8 +247,10 @@ transport_start(th_transport_t *t, unsigned int weight, int force_start) c = avcodec_find_decoder(id); if(c != NULL) { st->st_ctx = avcodec_alloc_context(); + pthread_mutex_lock(&ffmpeg_lock); avcodec_open(st->st_ctx, c); - st->st_parser = av_parser_init(id); + pthread_mutex_unlock(&ffmpeg_lock); + st->st_parser = av_parser_init(id); } else { abort(); } diff --git a/src/tvhead.h b/src/tvhead.h index dfe3dc5f..597252ec 100644 --- a/src/tvhead.h +++ b/src/tvhead.h @@ -37,6 +37,7 @@ #include "redblack.h" extern pthread_mutex_t global_lock; +extern pthread_mutex_t ffmpeg_lock; static inline void lock_assert0(pthread_mutex_t *l, const char *file, int line)