From 24ee1514021e2a2419b1ae9a779e6a18a4add064 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt Date: Sun, 21 Mar 2021 05:00:09 +0100 Subject: [PATCH] avcodec/pthread_frame: Factor initializing single thread out Signed-off-by: Andreas Rheinhardt --- libavcodec/pthread_frame.c | 155 ++++++++++++++++++++----------------- 1 file changed, 82 insertions(+), 73 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,6 +763,85 @@ void ff_frame_thread_free(AVCodecContext *avctx, int thread_count) avctx->codec = NULL; } +static av_cold int init_thread(PerThreadContext *p, + FrameThreadContext *fctx, AVCodecContext *avctx, + AVCodecContext *src, const AVCodec *codec, int first) +{ + AVCodecContext *copy = av_malloc(sizeof(AVCodecContext)); + int err; + + pthread_mutex_init(&p->mutex, NULL); + pthread_mutex_init(&p->progress_mutex, NULL); + pthread_cond_init(&p->input_cond, NULL); + pthread_cond_init(&p->progress_cond, NULL); + pthread_cond_init(&p->output_cond, NULL); + + p->frame = av_frame_alloc(); + if (!p->frame) { + av_freep(©); + return AVERROR(ENOMEM); + } + p->avpkt = av_packet_alloc(); + if (!p->avpkt) { + av_freep(©); + return AVERROR(ENOMEM); + } + + p->parent = fctx; + p->avctx = copy; + + if (!copy) { + return AVERROR(ENOMEM); + } + + *copy = *src; + + copy->internal = av_malloc(sizeof(AVCodecInternal)); + if (!copy->internal) { + copy->priv_data = NULL; + return AVERROR(ENOMEM); + } + *copy->internal = *src->internal; + copy->internal->thread_ctx = p; + copy->internal->last_pkt_props = p->avpkt; + + copy->delay = avctx->delay; + + if (codec->priv_data_size) { + copy->priv_data = av_mallocz(codec->priv_data_size); + if (!copy->priv_data) { + 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) + return err; + } + } + + if (!first) + copy->internal->is_copy = 1; + + if (codec->init) + err = codec->init(copy); + if (err < 0) { + return err; + } + + if (first) + update_context_from_thread(avctx, copy, 1); + + atomic_init(&p->debug_threads, (copy->debug & FF_DEBUG_THREADS) != 0); + + 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; @@ -807,81 +886,11 @@ int ff_frame_thread_init(AVCodecContext *avctx) 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 first = !i; - pthread_mutex_init(&p->mutex, NULL); - pthread_mutex_init(&p->progress_mutex, NULL); - pthread_cond_init(&p->input_cond, NULL); - pthread_cond_init(&p->progress_cond, NULL); - pthread_cond_init(&p->output_cond, NULL); - - p->frame = av_frame_alloc(); - if (!p->frame) { - av_freep(©); - err = AVERROR(ENOMEM); - goto error; - } - p->avpkt = av_packet_alloc(); - if (!p->avpkt) { - av_freep(©); - err = AVERROR(ENOMEM); - goto error; - } - - p->parent = fctx; - p->avctx = copy; - - if (!copy) { - err = AVERROR(ENOMEM); - goto error; - } - - *copy = *src; - - copy->internal = av_malloc(sizeof(AVCodecInternal)); - if (!copy->internal) { - copy->priv_data = NULL; - err = AVERROR(ENOMEM); - goto error; - } - *copy->internal = *src->internal; - copy->internal->thread_ctx = p; - copy->internal->last_pkt_props = p->avpkt; - - copy->delay = avctx->delay; - - if (codec->priv_data_size) { - copy->priv_data = av_mallocz(codec->priv_data_size); - if (!copy->priv_data) { - err = AVERROR(ENOMEM); - goto error; - } - - 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; - } - } - - if (i) - copy->internal->is_copy = 1; - - if (codec->init) - err = codec->init(copy); - - if (err) goto error; - - if (!i) - update_context_from_thread(avctx, copy, 1); - - atomic_init(&p->debug_threads, (copy->debug & FF_DEBUG_THREADS) != 0); - - err = AVERROR(pthread_create(&p->thread, NULL, frame_worker_thread, p)); - p->thread_init= !err; - if(!p->thread_init) + err = init_thread(p, fctx, avctx, src, codec, first); + if (err < 0) goto error; }