Also improves correctness in some ways.
---
 libavcodec/avcodec.h    |   11 +++++++++--
 libavcodec/beosthread.c |    2 +-
 libavcodec/os2thread.c  |    2 +-
 libavcodec/pthread.c    |   17 ++++++++---------
 libavcodec/thread.h     |    6 +++---
 libavcodec/utils.c      |    9 +++++----
 libavcodec/w32thread.c  |    2 +-
 7 files changed, 28 insertions(+), 21 deletions(-)
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 15b3e29..14a3bba 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -2257,14 +2257,21 @@ typedef struct AVCodecContext {
     int is_copy;
 
     /**
-     * Which multithreading method to use, for codecs that support more than one.
+     * Which multithreading methods to use, for codecs that support more than one.
      * - encoding: Set by user, otherwise the default is used.
      * - decoding: Set by user, otherwise the default is used.
      */
     int thread_algorithm;
-#define FF_THREAD_AUTO       0 //< Use the default. Will be changed by libavcodec after init.
 #define FF_THREAD_MULTIFRAME 1 //< Decode more than one frame at once
 #define FF_THREAD_MULTISLICE 2 //< Decode more than one part of a single frame at once
+#define FF_THREAD_DEFAULT    3 //< Use both if possible.
+
+    /**
+     * Which multithreading methods are actually active at the moment.
+     * - encoding: Set by libavcodec.
+     * - decoding: Set by libavcodec.
+     */
+    int active_thread_algorithm;
 } AVCodecContext;
 
 /**
diff --git a/libavcodec/beosthread.c b/libavcodec/beosthread.c
index fbe2168..376a9ac 100644
--- a/libavcodec/beosthread.c
+++ b/libavcodec/beosthread.c
@@ -124,7 +124,7 @@ int avcodec_thread_init(AVCodecContext *s, int thread_count){
     if(s->thread_opaque) return 0;
 
     s->thread_count= thread_count;
-    s->thread_algorithm= FF_THREAD_MULTISLICE;
+    s->active_thread_algorithm= FF_THREAD_MULTISLICE;
 
     assert(!s->thread_opaque);
     c= av_mallocz(sizeof(ThreadContext)*thread_count);
diff --git a/libavcodec/os2thread.c b/libavcodec/os2thread.c
index defc3bb..c7166b9 100644
--- a/libavcodec/os2thread.c
+++ b/libavcodec/os2thread.c
@@ -117,7 +117,7 @@ int avcodec_thread_init(AVCodecContext *s, int thread_count){
     if(s->thread_opaque) return 0;
 
     s->thread_count= thread_count;
-    s->thread_algorithm= FF_THREAD_MULTISLICE;
+    s->active_thread_algorithm= FF_THREAD_MULTISLICE;
 
     assert(!s->thread_opaque);
     c= av_mallocz(sizeof(ThreadContext)*thread_count);
diff --git a/libavcodec/pthread.c b/libavcodec/pthread.c
index 461724e..b4d9c7f 100644
--- a/libavcodec/pthread.c
+++ b/libavcodec/pthread.c
@@ -563,8 +563,6 @@ static void ff_frame_thread_free(AVCodecContext *avctx)
 
     av_freep(&fctx->threads);
     av_freep(&avctx->thread_opaque);
-
-    avctx->thread_algorithm = FF_THREAD_AUTO;
 }
 
 void ff_frame_thread_flush(AVCodecContext *avctx)
@@ -654,14 +652,15 @@ void ff_delayed_release_buffer(AVCodecContext *avctx, AVFrame *f)
 /// Set the threading algorithm used, or none if an algorithm was set but no thread count.
 static void ff_validate_thread_parameters(AVCodecContext *avctx)
 {
+    int frame_threading_supported = (avctx->codec->capabilities & CODEC_CAP_FRAME_THREADS)
+                                && !(avctx->flags & CODEC_FLAG_TRUNCATED) && !(avctx->flags & CODEC_FLAG_LOW_DELAY)
+                                && !(avctx->flags2 & CODEC_FLAG2_CHUNKS);
     if (avctx->thread_count <= 1)
-        avctx->thread_algorithm = 0;
-    else if (avctx->thread_algorithm == FF_THREAD_AUTO) {
-        if ((avctx->codec->capabilities & CODEC_CAP_FRAME_THREADS) && !(avctx->flags & CODEC_FLAG_TRUNCATED) &&
-           !(avctx->flags & CODEC_FLAG_LOW_DELAY) && !(avctx->flags2 & CODEC_FLAG2_CHUNKS))
-             avctx->thread_algorithm = FF_THREAD_MULTIFRAME;
-        else avctx->thread_algorithm = FF_THREAD_MULTISLICE;
-    }
+        avctx->active_thread_algorithm = 0;
+    else if (frame_threading_supported && (avctx->thread_algorithm & FF_THREAD_MULTIFRAME))
+        avctx->active_thread_algorithm = FF_THREAD_MULTIFRAME;
+    else
+        avctx->active_thread_algorithm = FF_THREAD_MULTISLICE;
 }
 
 int avcodec_thread_init(AVCodecContext *avctx, int thread_count)
diff --git a/libavcodec/thread.h b/libavcodec/thread.h
index 900de9c..0c33ad4 100644
--- a/libavcodec/thread.h
+++ b/libavcodec/thread.h
@@ -97,9 +97,9 @@ void ff_release_buffer(AVFrame *f);
 void ff_delayed_release_buffer(AVCodecContext *avctx, AVFrame *f);
 
 ///True if frame threading is active.
-#define USE_FRAME_THREADING(avctx) (avctx->thread_algorithm == FF_THREAD_MULTIFRAME)
+#define USE_FRAME_THREADING(avctx) (avctx->active_thread_algorithm == FF_THREAD_MULTIFRAME)
 ///True if calling AVCodecContext execute() will run in parallel.
-#define USE_AVCODEC_EXECUTE(avctx) (avctx->thread_algorithm == FF_THREAD_MULTISLICE)
+#define USE_AVCODEC_EXECUTE(avctx) (avctx->active_thread_algorithm == FF_THREAD_MULTISLICE)
 
 #else
 
@@ -125,7 +125,7 @@ static inline void ff_delayed_release_buffer(AVCodecContext *avctx, AVFrame *f)
 }
 
 #define USE_FRAME_THREADING(avctx) 0
-#define USE_AVCODEC_EXECUTE(avctx) (ENABLE_THREADS && avctx->thread_algorithm)
+#define USE_AVCODEC_EXECUTE(avctx) (ENABLE_THREADS && avctx->active_thread_algorithm)
 
 #endif
 
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index 560ecd9..d85d252 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -734,8 +734,7 @@ static const AVOption options[]={
 {"request_channels", "set desired number of audio channels", OFFSET(request_channels), FF_OPT_TYPE_INT, DEFAULT, 0, INT_MAX, A|D},
 {"drc_scale", "percentage of dynamic range compression to apply", OFFSET(drc_scale), FF_OPT_TYPE_FLOAT, 1.0, 0.0, 1.0, A|D},
 {"reservoir", "use bit reservoir", 0, FF_OPT_TYPE_CONST, CODEC_FLAG2_BIT_RESERVOIR, INT_MIN, INT_MAX, A|E, "flags2"},
-{"thread_algorithm", "select multithreading type", OFFSET(thread_algorithm), FF_OPT_TYPE_INT, DEFAULT, 0, INT_MAX, V|E|D, "thread_algorithm"},
-{"auto", NULL, 0, FF_OPT_TYPE_CONST, FF_THREAD_AUTO, INT_MIN, INT_MAX, V|E|D, "thread_algorithm"},
+{"thread_algorithm", "select multithreading type", OFFSET(thread_algorithm), FF_OPT_TYPE_INT, FF_THREAD_DEFAULT, 0, INT_MAX, V|E|D, "thread_algorithm"},
 {"slice", NULL, 0, FF_OPT_TYPE_CONST, FF_THREAD_MULTISLICE, INT_MIN, INT_MAX, V|E|D, "thread_algorithm"},
 {"frame", NULL, 0, FF_OPT_TYPE_CONST, FF_THREAD_MULTIFRAME, INT_MIN, INT_MAX, V|E|D, "thread_algorithm"},
 {NULL},
@@ -777,6 +776,8 @@ void avcodec_get_context_defaults2(AVCodecContext *s, enum CodecType codec_type)
 
     s->palctrl = NULL;
     s->reget_buffer= avcodec_default_reget_buffer;
+
+    s->active_thread_algorithm= FF_THREAD_DEFAULT;
 }
 
 AVCodecContext *avcodec_alloc_context2(enum CodecType codec_type){
@@ -997,7 +998,6 @@ int avcodec_decode_subtitle(AVCodecContext *avctx, AVSubtitle *sub,
 
 int avcodec_close(AVCodecContext *avctx)
 {
-    int threaded = USE_FRAME_THREADING(avctx);
     entangled_thread_counter++;
     if(entangled_thread_counter != 1){
         av_log(avctx, AV_LOG_ERROR, "insufficient thread locking around avcodec_open/close()\n");
@@ -1007,12 +1007,13 @@ int avcodec_close(AVCodecContext *avctx)
 
     if (ENABLE_THREADS && avctx->thread_opaque)
         avcodec_thread_free(avctx);
-    if (avctx->codec->close && !threaded)
+    if (avctx->codec->close && !USE_FRAME_THREADING(avctx))
         avctx->codec->close(avctx);
     avcodec_default_free_buffers(avctx);
     av_freep(&avctx->priv_data);
     av_freep(&avctx->rc_eq);
     avctx->codec = NULL;
+    avctx->active_thread_algorithm = 0;
     entangled_thread_counter--;
     return 0;
 }
diff --git a/libavcodec/w32thread.c b/libavcodec/w32thread.c
index dea42b4..74e53f1 100644
--- a/libavcodec/w32thread.c
+++ b/libavcodec/w32thread.c
@@ -107,7 +107,7 @@ int avcodec_thread_init(AVCodecContext *s, int thread_count){
     if(s->thread_opaque) return 0;
 
     s->thread_count= thread_count;
-    s->thread_algorithm= FF_THREAD_MULTISLICE;
+    s->active_thread_algorithm= FF_THREAD_MULTISLICE;
 
     assert(!s->thread_opaque);
     c= av_mallocz(sizeof(ThreadContext)*thread_count);
_______________________________________________
FFmpeg-soc mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/ffmpeg-soc

Reply via email to