Browse code

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.

Janne Grunau authored on 2012/01/02 04:24:24
Showing 7 changed files
... ...
@@ -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