27#define MAX_AUTO_THREADS 16
29#if HAVE_PTHREADS || HAVE_W32THREADS || HAVE_OS2THREADS
31typedef struct WorkerContext {
40 WorkerContext *workers;
42 int nb_active_threads;
54 int (*
worker_func)(
void *priv,
int jobnr,
int threadnr,
int nb_jobs,
int nb_threads);
57#if LIBAVUTIL_VERSION_MAJOR < 62
58 void (*worker_func_v1)(
void *priv,
int jobnr,
int threadnr,
int nb_jobs,
int nb_threads);
59 void (*main_func_v1)(
void *priv);
66 unsigned nb_jobs =
ctx->nb_jobs;
67 unsigned nb_active_threads =
ctx->nb_active_threads;
69 unsigned current_job = first_job;
75 ret =
ctx->worker_func(
ctx->priv, current_job, first_job, nb_jobs, nb_active_threads);
80 memory_order_relaxed);
84 return current_job == nb_jobs + nb_active_threads - 1;
116 int (*
worker_func)(
void *priv,
int jobnr,
int threadnr,
int nb_jobs,
int nb_threads),
133 nb_workers = nb_threads;
141 if (nb_workers && !(
ctx->workers =
av_calloc(nb_workers,
sizeof(*
ctx->workers)))) {
149 ctx->nb_threads = nb_threads;
150 ctx->nb_active_threads = 0;
170 for (
i = 0;
i < nb_workers;
i++) {
171 WorkerContext *
w = &
ctx->workers[
i];
208 int nb_workers,
i, is_last = 0, ret = 0;
211 ctx->nb_jobs = nb_jobs;
212 ctx->nb_active_threads =
FFMIN(nb_jobs,
ctx->nb_threads);
216 nb_workers =
ctx->nb_active_threads;
217 if (!
ctx->main_func || !execute_main)
220 for (
i = 0;
i < nb_workers;
i++) {
221 WorkerContext *
w = &
ctx->workers[
i];
228 if (
ctx->main_func && execute_main) {
229 ret =
ctx->main_func(
ctx->priv);
231 is_last = run_jobs(
ctx);
255 nb_workers =
ctx->nb_threads;
260 for (
i = 0;
i < nb_workers;
i++) {
261 WorkerContext *
w = &
ctx->workers[
i];
268 for (
i = 0;
i < nb_workers;
i++) {
269 WorkerContext *
w = &
ctx->workers[
i];
284 int (*
worker_func)(
void *priv,
int jobnr,
int threadnr,
int nb_jobs,
int nb_threads),
308#if LIBAVUTIL_VERSION_MAJOR < 62
310static int wrapper_worker(
void *priv,
int jobnr,
int threadnr,
int nb_jobs,
int nb_threads)
313 ctx->worker_func_v1(
ctx->priv_v1, jobnr, threadnr, nb_jobs, nb_threads);
320 ctx->main_func_v1(
ctx->priv_v1);
325 void (*
worker_func)(
void *priv,
int jobnr,
int threadnr,
int nb_jobs,
int nb_threads),
335 (*pctx)->priv = *pctx;
336 (*pctx)->priv_v1 = priv;
static AVFormatContext * ctx
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert0(cond)
assert() equivalent, that is always enabled.
#define i(width, name, range_min, range_max)
#define atomic_fetch_add_explicit(object, operand, order)
#define atomic_compare_exchange_strong_explicit(object, expected, desired, success, failure)
#define atomic_load_explicit(object, order)
#define atomic_store_explicit(object, desired, order)
#define atomic_init(obj, value)
common internal API header
#define attribute_align_arg
void * av_calloc(size_t nmemb, size_t size)
Memory handling functions.
static av_always_inline int pthread_cond_signal(pthread_cond_t *cond)
static av_always_inline int pthread_mutex_lock(pthread_mutex_t *mutex)
static av_always_inline int pthread_cond_destroy(pthread_cond_t *cond)
static av_always_inline int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
static av_always_inline int pthread_join(pthread_t thread, void **value_ptr)
static av_always_inline int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
static av_always_inline int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg)
static av_always_inline int pthread_mutex_unlock(pthread_mutex_t *mutex)
static av_always_inline int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
static av_always_inline int pthread_mutex_destroy(pthread_mutex_t *mutex)
int(* cond)(enum AVPixelFormat pix_fmt)
static int worker_func(void *priv, int jobnr, int threadnr, int nb_jobs, int nb_threads)
int main_func(AVCodecContext *c)
void avpriv_slicethread_execute(AVSliceThread *ctx, int nb_jobs, int execute_main)
static int wrapper_worker(void *priv, int jobnr, int threadnr, int nb_jobs, int nb_threads)
Backwards compatibility wrapper for the deprecated avpriv_ slicethread API.
int avpriv_slicethread_create(AVSliceThread **pctx, void *priv, void(*worker_func)(void *priv, int jobnr, int threadnr, int nb_jobs, int nb_threads), void(*main_func)(void *priv), int nb_threads)
static int wrapper_main(void *priv)
void avpriv_slicethread_free(AVSliceThread **pctx)
Destroy slice threading context.
int avpriv_slicethread_execute2(AVSliceThread *ctx, int nb_jobs, int execute_main)
Execute slice threading.
int avpriv_slicethread_create2(AVSliceThread **pctx, void *priv, int(*worker_func)(void *priv, int jobnr, int threadnr, int nb_jobs, int nb_threads), int(*main_func)(void *priv), int nb_threads)
Create slice threading context.
struct AVSliceThread AVSliceThread
static void error(const char *err)
CONDITION_VARIABLE pthread_cond_t