From 9d6785d426be1ac045c0b6a13b7447459389c40b Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Tue, 17 Jan 2017 16:28:30 +0100 Subject: lavc: do not implicitly share the frame pool between threads Currently the frame pool used by the default get_buffer2() implementation is a single struct, allocated when opening the decoder. A pointer to it is simply copied to each frame thread and we assume that no thread attempts to modify it at an unexpected time. This is rather fragile and potentially dangerous. With this commit, the frame pool is made refcounted, with the reference being propagated across threads along with other context variables. The frame pool is now also immutable - when the stream parameters change we drop the old reference and create a new one. --- libavcodec/pthread_frame.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'libavcodec/pthread_frame.c') diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index f0a162bc92..4cd890b295 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -296,6 +296,17 @@ static int update_context_from_thread(AVCodecContext *dst, AVCodecContext *src, } dst->hwaccel_flags = src->hwaccel_flags; + + if (!!dst->internal->pool != !!src->internal->pool || + (dst->internal->pool && dst->internal->pool->data != src->internal->pool->data)) { + av_buffer_unref(&dst->internal->pool); + + if (src->internal->pool) { + dst->internal->pool = av_buffer_ref(src->internal->pool); + if (!dst->internal->pool) + return AVERROR(ENOMEM); + } + } } if (for_user) { @@ -714,6 +725,7 @@ void ff_frame_thread_free(AVCodecContext *avctx, int thread_count) } if (p->avctx) { + av_buffer_unref(&p->avctx->internal->pool); av_freep(&p->avctx->internal); av_buffer_unref(&p->avctx->hw_frames_ctx); } -- cgit v1.2.3