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