diff --git a/libavcodec/pthread.c b/libavcodec/pthread.c index 0688d9d8f0..a4e3081272 100644 --- a/libavcodec/pthread.c +++ b/libavcodec/pthread.c @@ -413,7 +413,6 @@ static int update_context_from_thread(AVCodecContext *dst, AVCodecContext *src, dst->has_b_frames = src->has_b_frames; dst->idct_algo = src->idct_algo; - dst->slice_count = src->slice_count; dst->bits_per_coded_sample = src->bits_per_coded_sample; dst->sample_aspect_ratio = src->sample_aspect_ratio; @@ -447,8 +446,9 @@ static int update_context_from_thread(AVCodecContext *dst, AVCodecContext *src, * * @param dst The destination context. * @param src The source context. + * @return 0 on success, negative error code on failure */ -static void update_context_from_user(AVCodecContext *dst, AVCodecContext *src) +static int update_context_from_user(AVCodecContext *dst, AVCodecContext *src) { #define copy_fields(s, e) memcpy(&dst->s, &src->s, (char*)&dst->e - (char*)&dst->s); dst->flags = src->flags; @@ -469,6 +469,22 @@ static void update_context_from_user(AVCodecContext *dst, AVCodecContext *src) dst->frame_number = src->frame_number; dst->reordered_opaque = src->reordered_opaque; + + if (src->slice_count && src->slice_offset) { + if (dst->slice_count < src->slice_count) { + int *tmp = av_realloc(dst->slice_offset, src->slice_count * + sizeof(*dst->slice_offset)); + if (!tmp) { + av_free(dst->slice_offset); + return AVERROR(ENOMEM); + } + dst->slice_offset = tmp; + } + memcpy(dst->slice_offset, src->slice_offset, + src->slice_count * sizeof(*dst->slice_offset)); + } + dst->slice_count = src->slice_count; + return 0; #undef copy_fields } @@ -579,7 +595,8 @@ int ff_thread_decode_frame(AVCodecContext *avctx, */ p = &fctx->threads[fctx->next_decoding]; - update_context_from_user(p->avctx, avctx); + err = update_context_from_user(p->avctx, avctx); + if (err) return err; err = submit_packet(p, avpkt); if (err) return err; @@ -750,6 +767,7 @@ static void frame_thread_free(AVCodecContext *avctx, int thread_count) if (i) { av_freep(&p->avctx->priv_data); av_freep(&p->avctx->internal); + av_freep(&p->avctx->slice_offset); } av_freep(&p->avctx);