From 881a5e047dc78ec9ab771817497dffec503d77ee Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Sun, 1 Jan 2012 20:24:24 +0100 Subject: mpegenc: use avctx->slices as number of slices Adds a new member to MpegEncContext to hold the number of used slice contexts. Fixes segfaults with '-threads 17 -thread_type slice' and fate-vsynth{1,2}-mpeg{2,4}thread{,_ilace} with --disable-pthreads. --- libavcodec/mpegvideo.c | 53 ++++++++++++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 25 deletions(-) (limited to 'libavcodec/mpegvideo.c') diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c index 214b64ec3b..a2aa257f89 100644 --- a/libavcodec/mpegvideo.c +++ b/libavcodec/mpegvideo.c @@ -637,6 +637,8 @@ void MPV_common_defaults(MpegEncContext *s) s->picture_range_start = 0; s->picture_range_end = MAX_PICTURE_COUNT; + + s->slice_context_count = 1; } /** @@ -655,11 +657,13 @@ void MPV_decode_defaults(MpegEncContext *s) */ av_cold int MPV_common_init(MpegEncContext *s) { - int y_size, c_size, yc_size, i, mb_array_size, mv_table_size, x, y, - threads = (s->encoding || - (HAVE_THREADS && - s->avctx->active_thread_type & FF_THREAD_SLICE)) ? - s->avctx->thread_count : 1; + int y_size, c_size, yc_size, i, mb_array_size, mv_table_size, x, y; + int nb_slices = (HAVE_THREADS && + s->avctx->active_thread_type & FF_THREAD_SLICE) ? + s->avctx->thread_count : 1; + + if (s->encoding && s->avctx->slices) + nb_slices = s->avctx->slices; if (s->codec_id == CODEC_ID_MPEG2VIDEO && !s->progressive_sequence) s->mb_height = (s->height + 31) / 32 * 2; @@ -672,14 +676,15 @@ av_cold int MPV_common_init(MpegEncContext *s) return -1; } - if ((s->encoding || (s->avctx->active_thread_type & FF_THREAD_SLICE)) && - (s->avctx->thread_count > MAX_THREADS || - (s->avctx->thread_count > s->mb_height && s->mb_height))) { - int max_threads = FFMIN(MAX_THREADS, s->mb_height); - av_log(s->avctx, AV_LOG_WARNING, - "too many threads (%d), reducing to %d\n", - s->avctx->thread_count, max_threads); - threads = max_threads; + if (nb_slices > MAX_THREADS || (nb_slices > s->mb_height && s->mb_height)) { + int max_slices; + if (s->mb_height) + max_slices = FFMIN(MAX_THREADS, s->mb_height); + else + max_slices = MAX_THREADS; + av_log(s->avctx, AV_LOG_WARNING, "too many threads/slices (%d)," + " reducing to %d\n", nb_slices, max_slices); + nb_slices = max_slices; } if ((s->width || s->height) && @@ -885,22 +890,19 @@ av_cold int MPV_common_init(MpegEncContext *s) s->thread_context[0] = s; if (s->width && s->height) { - if (s->encoding || (HAVE_THREADS && - s->avctx->active_thread_type&FF_THREAD_SLICE)) { - for (i = 1; i < threads; i++) { + if (nb_slices > 1) { + for (i = 1; i < nb_slices; i++) { s->thread_context[i] = av_malloc(sizeof(MpegEncContext)); memcpy(s->thread_context[i], s, sizeof(MpegEncContext)); } - for (i = 0; i < threads; i++) { + for (i = 0; i < nb_slices; i++) { if (init_duplicate_context(s->thread_context[i], s) < 0) goto fail; s->thread_context[i]->start_mb_y = - (s->mb_height * (i) + s->avctx->thread_count / 2) / - s->avctx->thread_count; + (s->mb_height * (i) + nb_slices / 2) / nb_slices; s->thread_context[i]->end_mb_y = - (s->mb_height * (i + 1) + s->avctx->thread_count / 2) / - s->avctx->thread_count; + (s->mb_height * (i + 1) + nb_slices / 2) / nb_slices; } } else { if (init_duplicate_context(s, s) < 0) @@ -908,6 +910,7 @@ av_cold int MPV_common_init(MpegEncContext *s) s->start_mb_y = 0; s->end_mb_y = s->mb_height; } + s->slice_context_count = nb_slices; } return 0; @@ -921,14 +924,14 @@ void MPV_common_end(MpegEncContext *s) { int i, j, k; - if (s->encoding || (HAVE_THREADS && - s->avctx->active_thread_type & FF_THREAD_SLICE)) { - for (i = 0; i < s->avctx->thread_count; i++) { + if (s->slice_context_count > 1) { + for (i = 0; i < s->slice_context_count; i++) { free_duplicate_context(s->thread_context[i]); } - for (i = 1; i < s->avctx->thread_count; i++) { + for (i = 1; i < s->slice_context_count; i++) { av_freep(&s->thread_context[i]); } + s->slice_context_count = 1; } else free_duplicate_context(s); av_freep(&s->parse_context.buffer); -- cgit v1.2.3