[FFmpeg-devel] [PATCH 1/2] avcodec: add execute3() api to utilize the main function of avpriv_slicethread_create().
Ilia Valiakhmetov
zakne0ne at gmail.com
Sun Aug 27 22:22:16 EEST 2017
Signed-off-by: Ilia Valiakhmetov <zakne0ne at gmail.com>
---
libavcodec/avcodec.h | 7 ++++++-
libavcodec/options.c | 1 +
libavcodec/pthread_slice.c | 27 +++++++++++++++++++++++++--
libavcodec/utils.c | 13 +++++++++++++
4 files changed, 45 insertions(+), 3 deletions(-)
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 6555550..712f40c 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -1089,6 +1089,10 @@ typedef struct RcOverride{
*/
#define AV_CODEC_CAP_AVOID_PROBING (1 << 17)
/**
+ * Codec initializes slice-based threading with a main function
+ */
+#define AV_CODEC_SLICE_THREAD_HAS_MF (1 << 18)
+/**
* Codec is intra only.
*/
#define AV_CODEC_CAP_INTRA_ONLY 0x40000000
@@ -3233,7 +3237,7 @@ typedef struct AVCodecContext {
* - decoding: Set by libavcodec, user can override.
*/
int (*execute2)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg, int jobnr, int threadnr), void *arg2, int *ret, int count);
-
+ int (*execute3)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg, int jobnr, int threadnr), int (*m_func)(struct AVCodecContext *c3), void *arg2, int *ret, int count);
/**
* noise vs. sse weight for the nsse comparison function
* - encoding: Set by user.
@@ -5774,6 +5778,7 @@ const char *avcodec_profile_name(enum AVCodecID codec_id, int profile);
int avcodec_default_execute(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2),void *arg, int *ret, int count, int size);
int avcodec_default_execute2(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2, int, int),void *arg, int *ret, int count);
+int avcodec_default_execute3(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2, int jobnr, int threadnr), int (*m_func)(struct AVCodecContext *c3), void *arg, int *ret, int count);
//FIXME func typedef
/**
diff --git a/libavcodec/options.c b/libavcodec/options.c
index 82e1217..6d63bdb 100644
--- a/libavcodec/options.c
+++ b/libavcodec/options.c
@@ -117,6 +117,7 @@ static int init_context_defaults(AVCodecContext *s, const AVCodec *codec)
s->get_format = avcodec_default_get_format;
s->execute = avcodec_default_execute;
s->execute2 = avcodec_default_execute2;
+ s->execute3 = avcodec_default_execute3;
s->sample_aspect_ratio = (AVRational){0,1};
s->pix_fmt = AV_PIX_FMT_NONE;
s->sw_pix_fmt = AV_PIX_FMT_NONE;
diff --git a/libavcodec/pthread_slice.c b/libavcodec/pthread_slice.c
index c781d35..08d19b9 100644
--- a/libavcodec/pthread_slice.c
+++ b/libavcodec/pthread_slice.c
@@ -38,11 +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;
+ main_func *m_func;
void *args;
int *rets;
int job_size;
@@ -54,6 +56,12 @@ typedef struct SliceThreadContext {
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)
{
AVCodecContext *avctx = priv;
@@ -99,7 +107,8 @@ 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;
}
@@ -110,10 +119,20 @@ static int thread_execute2(AVCodecContext *avctx, action_func2* func2, void *arg
return thread_execute(avctx, NULL, arg, ret, job_count, 0);
}
+static int thread_execute3(AVCodecContext *avctx, action_func2* func2, main_func* m_func, void *arg, int *ret, int job_count)
+{
+ SliceThreadContext *c = avctx->internal->thread_ctx;
+ c->func2 = func2;
+ c->m_func = m_func;
+ return 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 (*m_f)(void *);
#if HAVE_W32THREADS
w32thread_init();
@@ -142,7 +161,9 @@ 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) {
+ m_f = avctx->codec->capabilities & AV_CODEC_SLICE_THREAD_HAS_MF ? &main_function : NULL;
+
+ if (!c || (thread_count = avpriv_slicethread_create(&c->thread, avctx, worker_func, m_f, thread_count)) <= 1) {
if (c)
avpriv_slicethread_free(&c->thread);
av_freep(&avctx->internal->thread_ctx);
@@ -150,10 +171,12 @@ 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->execute2 = thread_execute2;
+ avctx->execute3 = thread_execute3;
return 0;
}
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index baf4992..b7a9f56 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -558,6 +558,19 @@ int avcodec_default_execute2(AVCodecContext *c, int (*func)(AVCodecContext *c2,
return 0;
}
+int avcodec_default_execute3(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2, int jobnr, int threadnr), int (*m_func)(struct AVCodecContext *c3), void *arg, int *ret, int count)
+{
+ int i;
+ m_func(c);
+ for (i = 0; i < count; i++) {
+ int r = func(c, arg, i, 0);
+ if (ret)
+ ret[i] = r;
+ }
+ emms_c();
+ return 0;
+}
+
enum AVPixelFormat avpriv_find_pix_fmt(const PixelFormatTag *tags,
unsigned int fourcc)
{
--
2.8.3
More information about the ffmpeg-devel
mailing list