diff options
author | Andreas Rheinhardt <andreas.rheinhardt@gmail.com> | 2021-03-21 05:00:09 +0100 |
---|---|---|
committer | Andreas Rheinhardt <andreas.rheinhardt@outlook.com> | 2021-04-08 11:52:44 +0200 |
commit | 04012468459fb896e3a24202d7cc69b1cdda1db4 (patch) | |
tree | a50cfe7d7d9a53c01c8bdd5a41ffe1895cb4b1ea | |
parent | 76b5f726aa3b7827a00d2a65e9b4e55b29cabb5a (diff) | |
download | ffmpeg-04012468459fb896e3a24202d7cc69b1cdda1db4.tar.gz |
avcodec/pthread_frame: Factor initializing single thread out
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
(cherry picked from commit 24ee1514021e2a2419b1ae9a779e6a18a4add064)
-rw-r--r-- | libavcodec/pthread_frame.c | 127 |
1 files changed, 68 insertions, 59 deletions
diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index 7bcb9a7bcc..311d6ed771 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -763,52 +763,12 @@ void ff_frame_thread_free(AVCodecContext *avctx, int thread_count) avctx->codec = NULL; } -int ff_frame_thread_init(AVCodecContext *avctx) +static av_cold int init_thread(PerThreadContext *p, + FrameThreadContext *fctx, AVCodecContext *avctx, + AVCodecContext *src, const AVCodec *codec, int first) { - int thread_count = avctx->thread_count; - const AVCodec *codec = avctx->codec; - AVCodecContext *src = avctx; - FrameThreadContext *fctx; - int i, err = 0; - - if (!thread_count) { - int nb_cpus = av_cpu_count(); - // use number of cores + 1 as thread count if there is more than one - if (nb_cpus > 1) - thread_count = avctx->thread_count = FFMIN(nb_cpus + 1, MAX_AUTO_THREADS); - else - thread_count = avctx->thread_count = 1; - } - - if (thread_count <= 1) { - avctx->active_thread_type = 0; - return 0; - } - - avctx->internal->thread_ctx = fctx = av_mallocz(sizeof(FrameThreadContext)); - if (!fctx) - return AVERROR(ENOMEM); - - fctx->threads = av_mallocz_array(thread_count, sizeof(PerThreadContext)); - if (!fctx->threads) { - av_freep(&avctx->internal->thread_ctx); - return AVERROR(ENOMEM); - } - - pthread_mutex_init(&fctx->buffer_mutex, NULL); - pthread_mutex_init(&fctx->hwaccel_mutex, NULL); - pthread_mutex_init(&fctx->async_mutex, NULL); - pthread_cond_init(&fctx->async_cond, NULL); - - fctx->async_lock = 1; - fctx->delaying = 1; - - if (codec->type == AVMEDIA_TYPE_VIDEO) - avctx->delay = src->thread_count - 1; - - for (i = 0; i < thread_count; i++) { AVCodecContext *copy = av_malloc(sizeof(AVCodecContext)); - PerThreadContext *p = &fctx->threads[i]; + int err; pthread_mutex_init(&p->mutex, NULL); pthread_mutex_init(&p->progress_mutex, NULL); @@ -819,22 +779,19 @@ int ff_frame_thread_init(AVCodecContext *avctx) p->frame = av_frame_alloc(); if (!p->frame) { av_freep(©); - err = AVERROR(ENOMEM); - goto error; + return AVERROR(ENOMEM); } p->avpkt = av_packet_alloc(); if (!p->avpkt) { av_freep(©); - err = AVERROR(ENOMEM); - goto error; + return AVERROR(ENOMEM); } p->parent = fctx; p->avctx = copy; if (!copy) { - err = AVERROR(ENOMEM); - goto error; + return AVERROR(ENOMEM); } *copy = *src; @@ -842,8 +799,7 @@ int ff_frame_thread_init(AVCodecContext *avctx) copy->internal = av_malloc(sizeof(AVCodecInternal)); if (!copy->internal) { copy->priv_data = NULL; - err = AVERROR(ENOMEM); - goto error; + return AVERROR(ENOMEM); } *copy->internal = *src->internal; copy->internal->thread_ctx = p; @@ -854,27 +810,27 @@ int ff_frame_thread_init(AVCodecContext *avctx) if (codec->priv_data_size) { copy->priv_data = av_mallocz(codec->priv_data_size); if (!copy->priv_data) { - err = AVERROR(ENOMEM); - goto error; + return AVERROR(ENOMEM); } if (codec->priv_class) { *(const AVClass **)copy->priv_data = codec->priv_class; err = av_opt_copy(copy->priv_data, src->priv_data); if (err < 0) - goto error; + return err; } } - if (i) + if (!first) copy->internal->is_copy = 1; if (codec->init) err = codec->init(copy); + if (err < 0) { + return err; + } - if (err) goto error; - - if (!i) + if (first) update_context_from_thread(avctx, copy, 1); atomic_init(&p->debug_threads, (copy->debug & FF_DEBUG_THREADS) != 0); @@ -882,6 +838,59 @@ int ff_frame_thread_init(AVCodecContext *avctx) err = AVERROR(pthread_create(&p->thread, NULL, frame_worker_thread, p)); p->thread_init= !err; if(!p->thread_init) + return err; + return 0; +} + +int ff_frame_thread_init(AVCodecContext *avctx) +{ + int thread_count = avctx->thread_count; + const AVCodec *codec = avctx->codec; + AVCodecContext *src = avctx; + FrameThreadContext *fctx; + int i, err = 0; + + if (!thread_count) { + int nb_cpus = av_cpu_count(); + // use number of cores + 1 as thread count if there is more than one + if (nb_cpus > 1) + thread_count = avctx->thread_count = FFMIN(nb_cpus + 1, MAX_AUTO_THREADS); + else + thread_count = avctx->thread_count = 1; + } + + if (thread_count <= 1) { + avctx->active_thread_type = 0; + return 0; + } + + avctx->internal->thread_ctx = fctx = av_mallocz(sizeof(FrameThreadContext)); + if (!fctx) + return AVERROR(ENOMEM); + + fctx->threads = av_mallocz_array(thread_count, sizeof(PerThreadContext)); + if (!fctx->threads) { + av_freep(&avctx->internal->thread_ctx); + return AVERROR(ENOMEM); + } + + pthread_mutex_init(&fctx->buffer_mutex, NULL); + pthread_mutex_init(&fctx->hwaccel_mutex, NULL); + pthread_mutex_init(&fctx->async_mutex, NULL); + pthread_cond_init(&fctx->async_cond, NULL); + + fctx->async_lock = 1; + fctx->delaying = 1; + + if (codec->type == AVMEDIA_TYPE_VIDEO) + avctx->delay = src->thread_count - 1; + + for (i = 0; i < thread_count; i++) { + PerThreadContext *p = &fctx->threads[i]; + int first = !i; + + err = init_thread(p, fctx, avctx, src, codec, first); + if (err < 0) goto error; } |