[FFmpeg-devel] [PATCH 2/2] avcodec/pthread_slice: add main function support for avpriv_slicethread_create()

Ilia Valiakhmetov zakne0ne at gmail.com
Thu Sep 7 20:55:29 EEST 2017


---
 libavcodec/internal.h      |  4 ++++
 libavcodec/pthread_slice.c | 33 ++++++++++++++-------------------
 libavcodec/thread.h        |  1 +
 libavutil/slicethread.h    | 18 ++++++++++++++++++
 4 files changed, 37 insertions(+), 19 deletions(-)

diff --git a/libavcodec/internal.h b/libavcodec/internal.h
index 64120ea..4668952 100644
--- a/libavcodec/internal.h
+++ b/libavcodec/internal.h
@@ -64,6 +64,10 @@
  * dimensions to coded rather than display values.
  */
 #define FF_CODEC_CAP_EXPORTS_CROPPING       (1 << 4)
+/**
+ * Codec initializes slice-based threading with a main function
+ */
+#define FF_CODEC_CAP_SLICE_THREAD_HAS_MF    (1 << 5)
 
 #ifdef TRACE
 #   define ff_tlog(ctx, ...) av_log(ctx, AV_LOG_TRACE, __VA_ARGS__)
diff --git a/libavcodec/pthread_slice.c b/libavcodec/pthread_slice.c
index c781d35..65e5abf 100644
--- a/libavcodec/pthread_slice.c
+++ b/libavcodec/pthread_slice.c
@@ -38,21 +38,13 @@
 
 typedef int (action_func)(AVCodecContext *c, void *arg);
 typedef int (action_func2)(AVCodecContext *c, void *arg, int jobnr, int threadnr);
+typedef int (main_func)(AVCodecContext *c);
 
-typedef struct SliceThreadContext {
-    AVSliceThread *thread;
-    action_func *func;
-    action_func2 *func2;
-    void *args;
-    int *rets;
-    int job_size;
-
-    int *entries;
-    int entries_count;
-    int thread_count;
-    pthread_cond_t *progress_cond;
-    pthread_mutex_t *progress_mutex;
-} SliceThreadContext;
+static void main_function(void *priv) {
+    AVCodecContext *avctx = priv;
+    SliceThreadContext *c = avctx->internal->thread_ctx;
+    c->m_func(avctx);
+}
 
 static void worker_func(void *priv, int jobnr, int threadnr, int nb_jobs, int nb_threads)
 {
@@ -84,7 +76,7 @@ void ff_slice_thread_free(AVCodecContext *avctx)
     av_freep(&avctx->internal->thread_ctx);
 }
 
-static int thread_execute(AVCodecContext *avctx, action_func* func, void *arg, int *ret, int job_count, int job_size)
+int ff_thread_execute(AVCodecContext *avctx, action_func* func, void *arg, int *ret, int job_count, int job_size)
 {
     SliceThreadContext *c = avctx->internal->thread_ctx;
 
@@ -99,7 +91,7 @@ static int thread_execute(AVCodecContext *avctx, action_func* func, void *arg, i
     c->func = func;
     c->rets = ret;
 
-    avpriv_slicethread_execute(c->thread, job_count, 0);
+    avpriv_slicethread_execute(c->thread, job_count, !!c->m_func);
     return 0;
 }
 
@@ -107,13 +99,14 @@ static int thread_execute2(AVCodecContext *avctx, action_func2* func2, void *arg
 {
     SliceThreadContext *c = avctx->internal->thread_ctx;
     c->func2 = func2;
-    return thread_execute(avctx, NULL, arg, ret, job_count, 0);
+    return ff_thread_execute(avctx, NULL, arg, ret, job_count, 0);
 }
 
 int ff_slice_thread_init(AVCodecContext *avctx)
 {
     SliceThreadContext *c;
     int thread_count = avctx->thread_count;
+    static void (*main_f)(void *);
 
 #if HAVE_W32THREADS
     w32thread_init();
@@ -142,7 +135,8 @@ int ff_slice_thread_init(AVCodecContext *avctx)
     }
 
     avctx->internal->thread_ctx = c = av_mallocz(sizeof(*c));
-    if (!c || (thread_count = avpriv_slicethread_create(&c->thread, avctx, worker_func, NULL, thread_count)) <= 1) {
+    main_f = avctx->codec->caps_internal & FF_CODEC_CAP_SLICE_THREAD_HAS_MF ? &main_function : NULL;
+    if (!c || (thread_count = avpriv_slicethread_create(&c->thread, avctx, worker_func, main_f, thread_count)) <= 1) {
         if (c)
             avpriv_slicethread_free(&c->thread);
         av_freep(&avctx->internal->thread_ctx);
@@ -150,9 +144,10 @@ int ff_slice_thread_init(AVCodecContext *avctx)
         avctx->active_thread_type = 0;
         return 0;
     }
+    c->m_func = NULL;
     avctx->thread_count = thread_count;
 
-    avctx->execute = thread_execute;
+    avctx->execute = ff_thread_execute;
     avctx->execute2 = thread_execute2;
     return 0;
 }
diff --git a/libavcodec/thread.h b/libavcodec/thread.h
index 90864b5..dd8f5fe 100644
--- a/libavcodec/thread.h
+++ b/libavcodec/thread.h
@@ -133,6 +133,7 @@ void ff_thread_release_buffer(AVCodecContext *avctx, ThreadFrame *f);
 int ff_thread_ref_frame(ThreadFrame *dst, ThreadFrame *src);
 
 int ff_thread_init(AVCodecContext *s);
+int ff_thread_execute(AVCodecContext *avctx, int (*func)(AVCodecContext *c, void *arg), void *arg, int *ret, int job_count, int job_size);
 void ff_thread_free(AVCodecContext *s);
 
 int ff_alloc_entries(AVCodecContext *avctx, int count);
diff --git a/libavutil/slicethread.h b/libavutil/slicethread.h
index f6f6f30..9d15c96 100644
--- a/libavutil/slicethread.h
+++ b/libavutil/slicethread.h
@@ -16,11 +16,29 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "libavcodec/avcodec.h"
+
 #ifndef AVUTIL_SLICETHREAD_H
 #define AVUTIL_SLICETHREAD_H
 
 typedef struct AVSliceThread AVSliceThread;
 
+typedef struct SliceThreadContext {
+    AVSliceThread *thread;
+    int (*func)(AVCodecContext *c, void *arg);
+    int (*func2)(AVCodecContext *c, void *arg, int jobnr, int threadnr);
+    int (*m_func)(AVCodecContext *c);
+    void *args;
+    int *rets;
+    int job_size;
+
+    int *entries;
+    int entries_count;
+    int thread_count;
+    pthread_cond_t *progress_cond;
+    pthread_mutex_t *progress_mutex;
+} SliceThreadContext;
+
 /**
  * Create slice threading context.
  * @param pctx slice threading context returned here
-- 
2.8.3



More information about the ffmpeg-devel mailing list