FFmpeg
Loading...
Searching...
No Matches
pthread_slice.c
Go to the documentation of this file.
1/*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19/**
20 * @file
21 * Slice multithreading support functions
22 * @see doc/multithreading.txt
23 */
24
25#include "avcodec.h"
26#include "codec_internal.h"
27#include "internal.h"
28#include "pthread_internal.h"
29#include "thread.h"
30
32#include "libavutil/cpu.h"
33#include "libavutil/macros.h"
34#include "libavutil/mem.h"
36
37typedef int (action_func)(AVCodecContext *c, void *arg);
38typedef int (action_func2)(AVCodecContext *c, void *arg, int jobnr, int threadnr);
39typedef int (main_func)(AVCodecContext *c);
40
50
51static int main_function(void *priv) {
52 AVCodecContext *avctx = priv;
54 c->mainfunc(avctx);
55 return 0;
56}
57
58static int worker_func(void *priv, int jobnr, int threadnr, int nb_jobs, int nb_threads)
59{
60 AVCodecContext *avctx = priv;
62 int ret;
63
64 ret = c->func ? c->func(avctx, (char *)c->args + c->job_size * jobnr)
65 : c->func2(avctx, c->args, jobnr, threadnr);
66 if (c->rets)
67 c->rets[jobnr] = ret;
68
69 return 0;
70}
71
80
81static int thread_execute(AVCodecContext *avctx, action_func* func, void *arg, int *ret, int job_count, int job_size)
82{
84
85 if (!(avctx->active_thread_type&FF_THREAD_SLICE) || avctx->thread_count <= 1)
86 return avcodec_default_execute(avctx, func, arg, ret, job_count, job_size);
87
88 if (job_count <= 0)
89 return 0;
90
91 c->job_size = job_size;
92 c->args = arg;
93 c->func = func;
94 c->rets = ret;
95
96 avpriv_slicethread_execute2(c->thread, job_count, !!c->mainfunc );
97 return 0;
98}
99
100static int thread_execute2(AVCodecContext *avctx, action_func2* func2, void *arg, int *ret, int job_count)
101{
103 c->func2 = func2;
104 return thread_execute(avctx, NULL, arg, ret, job_count, 0);
105}
106
107int ff_slice_thread_execute_with_mainfunc(AVCodecContext *avctx, action_func2* func2, main_func *mainfunc, void *arg, int *ret, int job_count)
108{
110 c->func2 = func2;
111 c->mainfunc = mainfunc;
112 return thread_execute(avctx, NULL, arg, ret, job_count, 0);
113}
114
116{
118 int thread_count = avctx->thread_count;
119 int (*mainfunc)(void *);
120
121 if (!thread_count) {
122 int nb_cpus = av_cpu_count();
123 if (avctx->height)
124 nb_cpus = FFMIN(nb_cpus, (avctx->height+15)/16);
125 // use number of cores + 1 as thread count if there is more than one
126 if (nb_cpus > 1)
127 thread_count = avctx->thread_count = FFMIN(nb_cpus + 1, MAX_AUTO_THREADS);
128 else
129 thread_count = avctx->thread_count = 1;
130 }
131
132 if (thread_count <= 1) {
133 avctx->active_thread_type = 0;
134 return 0;
135 }
136
137 avctx->internal->thread_ctx = c = av_mallocz(sizeof(*c));
138 if (!c)
139 return AVERROR(ENOMEM);
141 thread_count = avpriv_slicethread_create2(&c->thread, avctx, worker_func,
142 mainfunc, thread_count);
143 if (thread_count <= 1) {
145 avctx->thread_count = 1;
146 avctx->active_thread_type = 0;
147 return thread_count < 0 ? thread_count : 0;
148 }
149 avctx->thread_count = thread_count;
150
151 avctx->execute = thread_execute;
152 avctx->execute2 = thread_execute2;
153 return 0;
154}
static double(*const func2[])(void *, double, double)
Definition af_afftfilt.c:99
Libavcodec external API header.
#define FF_THREAD_SLICE
Decode more than one part of a single frame at once.
Definition avcodec.h:1591
#define FF_CODEC_CAP_SLICE_THREAD_HAS_MF
Codec initializes slice-based threading with a main function.
static av_always_inline const FFCodec * ffcodec(const AVCodec *codec)
#define NULL
Definition coverity.c:32
int avcodec_default_execute(AVCodecContext *c, int(*func)(AVCodecContext *c2, void *arg2), void *arg, int *ret, int count, int size)
Definition avcodec.c:73
#define AVERROR(e)
Definition error.h:45
common internal api header.
int(* func)(AVBPrint *dst, const char *in, const char *arg)
Definition jacosubdec.c:66
const char * arg
Definition jacosubdec.c:65
Multithreading API for decoders.
Macro definitions for various function/variable attributes.
#define av_cold
Definition attributes.h:117
int av_cpu_count(void)
Definition cpu.c:228
Utility Preprocessor macros.
#define FFMIN(a, b)
Definition macros.h:49
Memory handling functions.
#define MAX_AUTO_THREADS
av_cold int ff_slice_thread_init(AVCodecContext *avctx)
int ff_slice_thread_execute_with_mainfunc(AVCodecContext *avctx, action_func2 *func2, main_func *mainfunc, void *arg, int *ret, int job_count)
static int thread_execute(AVCodecContext *avctx, action_func *func, void *arg, int *ret, int job_count, int job_size)
static int worker_func(void *priv, int jobnr, int threadnr, int nb_jobs, int nb_threads)
av_cold void ff_slice_thread_free(AVCodecContext *avctx)
static int thread_execute2(AVCodecContext *avctx, action_func2 *func2, void *arg, int *ret, int job_count)
int action_func(AVCodecContext *c, void *arg)
int main_func(AVCodecContext *c)
static int main_function(void *priv)
int action_func2(AVCodecContext *c, void *arg, int jobnr, int threadnr)
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
Definition slicethread.h:25
main external API structure.
Definition avcodec.h:443
int active_thread_type
Which multithreading methods are in use by the codec.
Definition avcodec.h:1598
const struct AVCodec * codec
Definition avcodec.h:452
int(* execute)(struct AVCodecContext *c, int(*func)(struct AVCodecContext *c2, void *arg), void *arg2, int *ret, int count, int size)
The codec may call this to execute several independent things.
Definition avcodec.h:1609
int thread_count
thread count is used to decide how many independent tasks should be passed to execute()
Definition avcodec.h:1579
int(* execute2)(struct AVCodecContext *c, int(*func)(struct AVCodecContext *c2, void *arg, int jobnr, int threadnr), void *arg2, int *ret, int count)
The codec may call this to execute several independent things.
Definition avcodec.h:1628
struct AVCodecInternal * internal
Private context used for internal data.
Definition avcodec.h:478
void * thread_ctx
Definition internal.h:73
unsigned caps_internal
Internal codec capabilities FF_CODEC_CAP_*.
action_func2 * func2
AVSliceThread * thread
action_func * func
main_func * mainfunc
#define av_mallocz(s)
#define av_freep(p)
static double c[64]