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.
| ... | ... |
@@ -1280,7 +1280,6 @@ int ff_h264_frame_start(H264Context *h){
|
| 1280 | 1280 |
MpegEncContext * const s = &h->s; |
| 1281 | 1281 |
int i; |
| 1282 | 1282 |
const int pixel_shift = h->pixel_shift; |
| 1283 |
- int thread_count = (s->avctx->active_thread_type & FF_THREAD_SLICE) ? s->avctx->thread_count : 1; |
|
| 1284 | 1283 |
|
| 1285 | 1284 |
if(MPV_frame_start(s, s->avctx) < 0) |
| 1286 | 1285 |
return -1; |
| ... | ... |
@@ -1309,7 +1308,7 @@ int ff_h264_frame_start(H264Context *h){
|
| 1309 | 1309 |
|
| 1310 | 1310 |
/* can't be in alloc_tables because linesize isn't known there. |
| 1311 | 1311 |
* FIXME: redo bipred weight to not require extra buffer? */ |
| 1312 |
- for(i = 0; i < thread_count; i++) |
|
| 1312 |
+ for(i = 0; i < s->slice_context_count; i++) |
|
| 1313 | 1313 |
if(h->thread_context[i] && !h->thread_context[i]->s.obmc_scratchpad) |
| 1314 | 1314 |
h->thread_context[i]->s.obmc_scratchpad = av_malloc(16*6*s->linesize); |
| 1315 | 1315 |
|
| ... | ... |
@@ -2826,7 +2825,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0){
|
| 2826 | 2826 |
return -1; |
| 2827 | 2827 |
} |
| 2828 | 2828 |
} else {
|
| 2829 |
- for(i = 1; i < s->avctx->thread_count; i++) {
|
|
| 2829 |
+ for(i = 1; i < s->slice_context_count; i++) {
|
|
| 2830 | 2830 |
H264Context *c; |
| 2831 | 2831 |
c = h->thread_context[i] = av_malloc(sizeof(H264Context)); |
| 2832 | 2832 |
memcpy(c, h->s.thread_context[i], sizeof(MpegEncContext)); |
| ... | ... |
@@ -2839,7 +2838,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0){
|
| 2839 | 2839 |
clone_tables(c, h, i); |
| 2840 | 2840 |
} |
| 2841 | 2841 |
|
| 2842 |
- for(i = 0; i < s->avctx->thread_count; i++) |
|
| 2842 |
+ for(i = 0; i < s->slice_context_count; i++) |
|
| 2843 | 2843 |
if (context_init(h->thread_context[i]) < 0) {
|
| 2844 | 2844 |
av_log(h->s.avctx, AV_LOG_ERROR, "context_init() failed.\n"); |
| 2845 | 2845 |
return -1; |
| ... | ... |
@@ -3742,7 +3741,7 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size){
|
| 3742 | 3742 |
int nals_needed=0; ///< number of NALs that need decoding before the next frame thread starts |
| 3743 | 3743 |
int nal_index; |
| 3744 | 3744 |
|
| 3745 |
- h->max_contexts = (HAVE_THREADS && (s->avctx->active_thread_type&FF_THREAD_SLICE)) ? avctx->thread_count : 1; |
|
| 3745 |
+ h->max_contexts = s->slice_context_count; |
|
| 3746 | 3746 |
if(!(s->flags2 & CODEC_FLAG2_CHUNKS)){
|
| 3747 | 3747 |
h->current_slice = 0; |
| 3748 | 3748 |
if (!s->first_field) |
| ... | ... |
@@ -2428,7 +2428,9 @@ static int decode_chunks(AVCodecContext *avctx, |
| 2428 | 2428 |
} |
| 2429 | 2429 |
|
| 2430 | 2430 |
if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_SLICE)) {
|
| 2431 |
- int threshold= (s2->mb_height * s->slice_count + avctx->thread_count / 2) / avctx->thread_count; |
|
| 2431 |
+ int threshold = (s2->mb_height * s->slice_count + |
|
| 2432 |
+ s2->slice_context_count / 2) / |
|
| 2433 |
+ s2->slice_context_count; |
|
| 2432 | 2434 |
if (threshold <= mb_y) {
|
| 2433 | 2435 |
MpegEncContext *thread_context = s2->thread_context[s->slice_count]; |
| 2434 | 2436 |
|
| ... | ... |
@@ -637,6 +637,8 @@ void MPV_common_defaults(MpegEncContext *s) |
| 637 | 637 |
|
| 638 | 638 |
s->picture_range_start = 0; |
| 639 | 639 |
s->picture_range_end = MAX_PICTURE_COUNT; |
| 640 |
+ |
|
| 641 |
+ s->slice_context_count = 1; |
|
| 640 | 642 |
} |
| 641 | 643 |
|
| 642 | 644 |
/** |
| ... | ... |
@@ -655,11 +657,13 @@ void MPV_decode_defaults(MpegEncContext *s) |
| 655 | 655 |
*/ |
| 656 | 656 |
av_cold int MPV_common_init(MpegEncContext *s) |
| 657 | 657 |
{
|
| 658 |
- int y_size, c_size, yc_size, i, mb_array_size, mv_table_size, x, y, |
|
| 659 |
- threads = (s->encoding || |
|
| 660 |
- (HAVE_THREADS && |
|
| 661 |
- s->avctx->active_thread_type & FF_THREAD_SLICE)) ? |
|
| 662 |
- s->avctx->thread_count : 1; |
|
| 658 |
+ int y_size, c_size, yc_size, i, mb_array_size, mv_table_size, x, y; |
|
| 659 |
+ int nb_slices = (HAVE_THREADS && |
|
| 660 |
+ s->avctx->active_thread_type & FF_THREAD_SLICE) ? |
|
| 661 |
+ s->avctx->thread_count : 1; |
|
| 662 |
+ |
|
| 663 |
+ if (s->encoding && s->avctx->slices) |
|
| 664 |
+ nb_slices = s->avctx->slices; |
|
| 663 | 665 |
|
| 664 | 666 |
if (s->codec_id == CODEC_ID_MPEG2VIDEO && !s->progressive_sequence) |
| 665 | 667 |
s->mb_height = (s->height + 31) / 32 * 2; |
| ... | ... |
@@ -672,14 +676,15 @@ av_cold int MPV_common_init(MpegEncContext *s) |
| 672 | 672 |
return -1; |
| 673 | 673 |
} |
| 674 | 674 |
|
| 675 |
- if ((s->encoding || (s->avctx->active_thread_type & FF_THREAD_SLICE)) && |
|
| 676 |
- (s->avctx->thread_count > MAX_THREADS || |
|
| 677 |
- (s->avctx->thread_count > s->mb_height && s->mb_height))) {
|
|
| 678 |
- int max_threads = FFMIN(MAX_THREADS, s->mb_height); |
|
| 679 |
- av_log(s->avctx, AV_LOG_WARNING, |
|
| 680 |
- "too many threads (%d), reducing to %d\n", |
|
| 681 |
- s->avctx->thread_count, max_threads); |
|
| 682 |
- threads = max_threads; |
|
| 675 |
+ if (nb_slices > MAX_THREADS || (nb_slices > s->mb_height && s->mb_height)) {
|
|
| 676 |
+ int max_slices; |
|
| 677 |
+ if (s->mb_height) |
|
| 678 |
+ max_slices = FFMIN(MAX_THREADS, s->mb_height); |
|
| 679 |
+ else |
|
| 680 |
+ max_slices = MAX_THREADS; |
|
| 681 |
+ av_log(s->avctx, AV_LOG_WARNING, "too many threads/slices (%d)," |
|
| 682 |
+ " reducing to %d\n", nb_slices, max_slices); |
|
| 683 |
+ nb_slices = max_slices; |
|
| 683 | 684 |
} |
| 684 | 685 |
|
| 685 | 686 |
if ((s->width || s->height) && |
| ... | ... |
@@ -885,22 +890,19 @@ av_cold int MPV_common_init(MpegEncContext *s) |
| 885 | 885 |
s->thread_context[0] = s; |
| 886 | 886 |
|
| 887 | 887 |
if (s->width && s->height) {
|
| 888 |
- if (s->encoding || (HAVE_THREADS && |
|
| 889 |
- s->avctx->active_thread_type&FF_THREAD_SLICE)) {
|
|
| 890 |
- for (i = 1; i < threads; i++) {
|
|
| 888 |
+ if (nb_slices > 1) {
|
|
| 889 |
+ for (i = 1; i < nb_slices; i++) {
|
|
| 891 | 890 |
s->thread_context[i] = av_malloc(sizeof(MpegEncContext)); |
| 892 | 891 |
memcpy(s->thread_context[i], s, sizeof(MpegEncContext)); |
| 893 | 892 |
} |
| 894 | 893 |
|
| 895 |
- for (i = 0; i < threads; i++) {
|
|
| 894 |
+ for (i = 0; i < nb_slices; i++) {
|
|
| 896 | 895 |
if (init_duplicate_context(s->thread_context[i], s) < 0) |
| 897 | 896 |
goto fail; |
| 898 | 897 |
s->thread_context[i]->start_mb_y = |
| 899 |
- (s->mb_height * (i) + s->avctx->thread_count / 2) / |
|
| 900 |
- s->avctx->thread_count; |
|
| 898 |
+ (s->mb_height * (i) + nb_slices / 2) / nb_slices; |
|
| 901 | 899 |
s->thread_context[i]->end_mb_y = |
| 902 |
- (s->mb_height * (i + 1) + s->avctx->thread_count / 2) / |
|
| 903 |
- s->avctx->thread_count; |
|
| 900 |
+ (s->mb_height * (i + 1) + nb_slices / 2) / nb_slices; |
|
| 904 | 901 |
} |
| 905 | 902 |
} else {
|
| 906 | 903 |
if (init_duplicate_context(s, s) < 0) |
| ... | ... |
@@ -908,6 +910,7 @@ av_cold int MPV_common_init(MpegEncContext *s) |
| 908 | 908 |
s->start_mb_y = 0; |
| 909 | 909 |
s->end_mb_y = s->mb_height; |
| 910 | 910 |
} |
| 911 |
+ s->slice_context_count = nb_slices; |
|
| 911 | 912 |
} |
| 912 | 913 |
|
| 913 | 914 |
return 0; |
| ... | ... |
@@ -921,14 +924,14 @@ void MPV_common_end(MpegEncContext *s) |
| 921 | 921 |
{
|
| 922 | 922 |
int i, j, k; |
| 923 | 923 |
|
| 924 |
- if (s->encoding || (HAVE_THREADS && |
|
| 925 |
- s->avctx->active_thread_type & FF_THREAD_SLICE)) {
|
|
| 926 |
- for (i = 0; i < s->avctx->thread_count; i++) {
|
|
| 924 |
+ if (s->slice_context_count > 1) {
|
|
| 925 |
+ for (i = 0; i < s->slice_context_count; i++) {
|
|
| 927 | 926 |
free_duplicate_context(s->thread_context[i]); |
| 928 | 927 |
} |
| 929 |
- for (i = 1; i < s->avctx->thread_count; i++) {
|
|
| 928 |
+ for (i = 1; i < s->slice_context_count; i++) {
|
|
| 930 | 929 |
av_freep(&s->thread_context[i]); |
| 931 | 930 |
} |
| 931 |
+ s->slice_context_count = 1; |
|
| 932 | 932 |
} else free_duplicate_context(s); |
| 933 | 933 |
|
| 934 | 934 |
av_freep(&s->parse_context.buffer); |
| ... | ... |
@@ -268,6 +268,7 @@ typedef struct MpegEncContext {
|
| 268 | 268 |
int start_mb_y; ///< start mb_y of this thread (so current thread should process start_mb_y <= row < end_mb_y) |
| 269 | 269 |
int end_mb_y; ///< end mb_y of this thread (so current thread should process start_mb_y <= row < end_mb_y) |
| 270 | 270 |
struct MpegEncContext *thread_context[MAX_THREADS]; |
| 271 |
+ int slice_context_count; ///< number of used thread_contexts |
|
| 271 | 272 |
|
| 272 | 273 |
/** |
| 273 | 274 |
* copy of the previous picture structure. |
| ... | ... |
@@ -1428,7 +1428,8 @@ int MPV_encode_picture(AVCodecContext *avctx, |
| 1428 | 1428 |
{
|
| 1429 | 1429 |
MpegEncContext *s = avctx->priv_data; |
| 1430 | 1430 |
AVFrame *pic_arg = data; |
| 1431 |
- int i, stuffing_count, context_count = avctx->thread_count; |
|
| 1431 |
+ int i, stuffing_count; |
|
| 1432 |
+ int context_count = s->slice_context_count; |
|
| 1432 | 1433 |
|
| 1433 | 1434 |
for (i = 0; i < context_count; i++) {
|
| 1434 | 1435 |
int start_y = s->thread_context[i]->start_mb_y; |
| ... | ... |
@@ -3059,7 +3060,7 @@ static int encode_picture(MpegEncContext *s, int picture_number) |
| 3059 | 3059 |
{
|
| 3060 | 3060 |
int i; |
| 3061 | 3061 |
int bits; |
| 3062 |
- int context_count = s->avctx->thread_count; |
|
| 3062 |
+ int context_count = s->slice_context_count; |
|
| 3063 | 3063 |
|
| 3064 | 3064 |
s->picture_number = picture_number; |
| 3065 | 3065 |
|
| ... | ... |
@@ -506,7 +506,7 @@ static const AVOption options[]={
|
| 506 | 506 |
{"cholesky", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = AV_LPC_TYPE_CHOLESKY }, INT_MIN, INT_MAX, A|E, "lpc_type"},
|
| 507 | 507 |
{"lpc_passes", "deprecated, use flac-specific options", OFFSET(lpc_passes), AV_OPT_TYPE_INT, {.dbl = -1 }, INT_MIN, INT_MAX, A|E},
|
| 508 | 508 |
#endif |
| 509 |
-{"slices", "number of slices, used in parallelized decoding", OFFSET(slices), AV_OPT_TYPE_INT, {.dbl = 0 }, 0, INT_MAX, V|E},
|
|
| 509 |
+{"slices", "number of slices, used in parallelized encoding", OFFSET(slices), AV_OPT_TYPE_INT, {.dbl = 0 }, 0, INT_MAX, V|E},
|
|
| 510 | 510 |
{"thread_type", "select multithreading type", OFFSET(thread_type), AV_OPT_TYPE_FLAGS, {.dbl = FF_THREAD_SLICE|FF_THREAD_FRAME }, 0, INT_MAX, V|E|D, "thread_type"},
|
| 511 | 511 |
{"slice", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_THREAD_SLICE }, INT_MIN, INT_MAX, V|E|D, "thread_type"},
|
| 512 | 512 |
{"frame", NULL, 0, AV_OPT_TYPE_CONST, {.dbl = FF_THREAD_FRAME }, INT_MIN, INT_MAX, V|E|D, "thread_type"},
|
| ... | ... |
@@ -62,13 +62,13 @@ fi |
| 62 | 62 |
|
| 63 | 63 |
if [ -n "$do_mpeg2thread" ] ; then |
| 64 | 64 |
# mpeg2 encoding interlaced |
| 65 |
-do_video_encoding mpeg2thread.mpg "-qscale 10 -vcodec mpeg2video -f mpeg1video -bf 2 -flags +ildct+ilme -threads 2" |
|
| 65 |
+do_video_encoding mpeg2thread.mpg "-qscale 10 -vcodec mpeg2video -f mpeg1video -bf 2 -flags +ildct+ilme -threads 2 -slices 2" |
|
| 66 | 66 |
do_video_decoding |
| 67 | 67 |
fi |
| 68 | 68 |
|
| 69 | 69 |
if [ -n "$do_mpeg2thread_ilace" ]; then |
| 70 | 70 |
# mpeg2 encoding interlaced using intra vlc |
| 71 |
-do_video_encoding mpeg2threadivlc.mpg "-qscale 10 -vcodec mpeg2video -f mpeg1video -bf 2 -flags +ildct+ilme -flags2 +ivlc -threads 2" |
|
| 71 |
+do_video_encoding mpeg2threadivlc.mpg "-qscale 10 -vcodec mpeg2video -f mpeg1video -bf 2 -flags +ildct+ilme -flags2 +ivlc -threads 2 -slices 2" |
|
| 72 | 72 |
do_video_decoding |
| 73 | 73 |
fi |
| 74 | 74 |
|
| ... | ... |
@@ -143,7 +143,7 @@ do_video_decoding |
| 143 | 143 |
fi |
| 144 | 144 |
|
| 145 | 145 |
if [ -n "$do_mpeg4thread" ] ; then |
| 146 |
-do_video_encoding mpeg4-thread.avi "-b 500k -flags +mv4+part+aic -trellis 1 -mbd bits -ps 200 -bf 2 -an -vcodec mpeg4 -threads 2" |
|
| 146 |
+do_video_encoding mpeg4-thread.avi "-b 500k -flags +mv4+part+aic -trellis 1 -mbd bits -ps 200 -bf 2 -an -vcodec mpeg4 -threads 2 -slices 2" |
|
| 147 | 147 |
do_video_decoding |
| 148 | 148 |
fi |
| 149 | 149 |
|