[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