Will be useful in following commits. --- libavcodec/cfhd.c | 4 +++- libavcodec/ffv1dec.c | 4 +++- libavcodec/h263dec.c | 14 ++++++++++---- libavcodec/h264dec.c | 5 ++++- libavcodec/hevc/hevcdec.c | 7 +++++-- libavcodec/mimic.c | 4 +++- libavcodec/mpeg12dec.c | 7 +++++-- libavcodec/pngdec.c | 9 ++++++--- libavcodec/proresdec.c | 5 ++++- libavcodec/pthread_frame.c | 26 ++++++++++++++++++++------ libavcodec/rv34.c | 5 ++++- libavcodec/takdec.c | 5 ++++- libavcodec/thread.h | 2 +- libavcodec/utils.c | 3 ++- libavcodec/vp3.c | 4 +++- libavcodec/vp8.c | 7 +++++-- libavcodec/vp9.c | 16 ++++++++++++---- libavcodec/wavpack.c | 4 +++- 18 files changed, 97 insertions(+), 34 deletions(-)
diff --git a/libavcodec/cfhd.c b/libavcodec/cfhd.c index 6f1d960058..0886f8d9da 100644 --- a/libavcodec/cfhd.c +++ b/libavcodec/cfhd.c @@ -910,7 +910,9 @@ finish: s->planes = 4; } - ff_thread_finish_setup(avctx); + ret = ff_thread_finish_setup(avctx); + if (ret < 0) + goto end; if (!s->a_width || !s->a_height || s->a_format == AV_PIX_FMT_NONE || s->a_transform_type == INT_MIN || diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c index ac8cc8a31d..5690a38074 100644 --- a/libavcodec/ffv1dec.c +++ b/libavcodec/ffv1dec.c @@ -928,7 +928,9 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *rframe, av_log(avctx, AV_LOG_DEBUG, "ver:%d keyframe:%d coder:%d ec:%d slices:%d bps:%d\n", f->version, !!(p->flags & AV_FRAME_FLAG_KEY), f->ac, f->ec, f->slice_count, f->avctx->bits_per_raw_sample); - ff_thread_finish_setup(avctx); + ret = ff_thread_finish_setup(avctx); + if (ret < 0) + return ret; buf_p = buf + buf_size; for (int i = f->slice_count - 1; i >= 0; i--) { diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c index 0c23012584..7a9abccbe0 100644 --- a/libavcodec/h263dec.c +++ b/libavcodec/h263dec.c @@ -584,8 +584,11 @@ retry: if ((ret = ff_mpv_frame_start(s, avctx)) < 0) return ret; - if (!s->divx_packed && !avctx->hwaccel) - ff_thread_finish_setup(avctx); + if (!s->divx_packed && !avctx->hwaccel) { + ret = ff_thread_finish_setup(avctx); + if (ret < 0) + return ret; + } if (avctx->hwaccel) { ret = FF_HW_CALL(avctx, start_frame, @@ -656,8 +659,11 @@ frame_end: if (CONFIG_MPEG4_DECODER && avctx->codec_id == AV_CODEC_ID_MPEG4) ff_mpeg4_frame_end(avctx, buf, buf_size); - if (!s->divx_packed && avctx->hwaccel) - ff_thread_finish_setup(avctx); + if (!s->divx_packed && avctx->hwaccel) { + ret = ff_thread_finish_setup(avctx); + if (ret < 0) + return ret; + } av_assert1(s->pict_type == s->cur_pic.ptr->f->pict_type); if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) { diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c index af0913ca2c..0cc24d15a9 100644 --- a/libavcodec/h264dec.c +++ b/libavcodec/h264dec.c @@ -665,7 +665,10 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size) if (h->current_slice == 1) { if (avctx->active_thread_type & FF_THREAD_FRAME && i >= nals_needed && !h->setup_finished && h->cur_pic_ptr) { - ff_thread_finish_setup(avctx); + ret = ff_thread_finish_setup(avctx); + if (ret < 0) + goto end; + h->setup_finished = 1; } diff --git a/libavcodec/hevc/hevcdec.c b/libavcodec/hevc/hevcdec.c index 1ea8df0fa0..ea1b4c6218 100644 --- a/libavcodec/hevc/hevcdec.c +++ b/libavcodec/hevc/hevcdec.c @@ -3318,8 +3318,11 @@ static int hevc_frame_start(HEVCContext *s, HEVCLayerContext *l, if (l == &s->layers[0]) s->finish_setup_nal_idx = find_finish_setup_nal(s); - if (nal_idx >= s->finish_setup_nal_idx) - ff_thread_finish_setup(s->avctx); + if (nal_idx >= s->finish_setup_nal_idx) { + ret = ff_thread_finish_setup(s->avctx); + if (ret < 0) + goto fail; + } return 0; diff --git a/libavcodec/mimic.c b/libavcodec/mimic.c index 2925aa50f7..054ecf54be 100644 --- a/libavcodec/mimic.c +++ b/libavcodec/mimic.c @@ -390,7 +390,9 @@ static int mimic_decode_frame(AVCodecContext *avctx, AVFrame *rframe, ctx->next_prev_index = ctx->cur_index; ctx->next_cur_index = (ctx->cur_index - 1) & 15; - ff_thread_finish_setup(avctx); + res = ff_thread_finish_setup(avctx); + if (res < 0) + return res; av_fast_padded_malloc(&ctx->swap_buf, &ctx->swap_buf_size, swap_buf_size); if (!ctx->swap_buf) diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c index c0ed6a9d5b..4503f3edfe 100644 --- a/libavcodec/mpeg12dec.c +++ b/libavcodec/mpeg12dec.c @@ -1332,8 +1332,11 @@ static int mpeg_field_start(Mpeg1Context *s1, const uint8_t *buf, int buf_size) s1->has_afd = 0; } - if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_FRAME)) - ff_thread_finish_setup(avctx); + if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_FRAME)) { + ret = ff_thread_finish_setup(avctx); + if (ret < 0) + return ret; + } } else { // second field second_field = 1; if (!s->cur_pic.ptr) { diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c index c5b32c166d..a805bf8eb8 100644 --- a/libavcodec/pngdec.c +++ b/libavcodec/pngdec.c @@ -656,8 +656,8 @@ static int decode_phys_chunk(AVCodecContext *avctx, PNGDecContext *s, /* * This populates AVCodecContext fields so it must be called before - * ff_thread_finish_setup() to avoid a race condition with respect to the - * generic copying of avctx fields. + * ff_thread_finish_setup() to propagate them correctly to following + * threads. */ static int populate_avctx_color_fields(AVCodecContext *avctx, AVFrame *frame) { @@ -908,7 +908,10 @@ static int decode_idat_chunk(AVCodecContext *avctx, PNGDecContext *s, if ((ret = populate_avctx_color_fields(avctx, p)) < 0) return ret; - ff_thread_finish_setup(avctx); + + ret = ff_thread_finish_setup(avctx); + if (ret < 0) + return ret; /* compute the compressed row size */ if (!s->interlace_type) { diff --git a/libavcodec/proresdec.c b/libavcodec/proresdec.c index 6a256107b4..bddc70b2e7 100644 --- a/libavcodec/proresdec.c +++ b/libavcodec/proresdec.c @@ -801,7 +801,10 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *frame, if ((ret = ff_thread_get_buffer(avctx, frame, 0)) < 0) return ret; - ff_thread_finish_setup(avctx); + + ret = ff_thread_finish_setup(avctx); + if (ret < 0) + return ret; if (avctx->hwaccel) { const FFHWAccel *hwaccel = ffhwaccel(avctx->hwaccel); diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index 78e6cf668b..8a52e418ad 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -273,8 +273,13 @@ static attribute_align_arg void *frame_worker_thread(void *arg) if (p->die) break; - if (!codec->update_thread_context) - ff_thread_finish_setup(avctx); + if (!codec->update_thread_context) { + ret = ff_thread_finish_setup(avctx); + if (ret < 0) { + p->result = ret; + goto alloc_fail; + } + } /* If a decoder supports hwaccel, then it must call ff_get_format(). * Since that call must happen before ff_thread_finish_setup(), the @@ -312,8 +317,13 @@ static attribute_align_arg void *frame_worker_thread(void *arg) p->result = (ret == AVERROR(EAGAIN)) ? 0 : ret; } - if (atomic_load(&p->state) == STATE_SETTING_UP) - ff_thread_finish_setup(avctx); + if (atomic_load(&p->state) == STATE_SETTING_UP) { + ret = ff_thread_finish_setup(avctx); + if (ret < 0) { + p->result = ret; + goto alloc_fail; + } + } alloc_fail: if (p->hwaccel_serializing) { @@ -684,11 +694,13 @@ void ff_thread_await_progress(const ThreadFrame *f, int n, int field) pthread_mutex_unlock(&p->progress_mutex); } -void ff_thread_finish_setup(AVCodecContext *avctx) { +int ff_thread_finish_setup(AVCodecContext *avctx) +{ ChildDecoder *cd; PerThreadContext *p; - if (!(avctx->active_thread_type&FF_THREAD_FRAME)) return; + if (!(avctx->active_thread_type & FF_THREAD_FRAME)) + return 0; cd = avctx->internal->thread_ctx; p = cd->thread; @@ -729,6 +741,8 @@ void ff_thread_finish_setup(AVCodecContext *avctx) { pthread_cond_broadcast(&p->progress_cond); pthread_mutex_unlock(&p->progress_mutex); + + return 0; } /// Waits for all threads to finish. diff --git a/libavcodec/rv34.c b/libavcodec/rv34.c index d94285431e..2627e9bdb0 100644 --- a/libavcodec/rv34.c +++ b/libavcodec/rv34.c @@ -1750,7 +1750,10 @@ int ff_rv34_decode_frame(AVCodecContext *avctx, AVFrame *pict, } } s->mb_x = s->mb_y = 0; - ff_thread_finish_setup(s->avctx); + + ret = ff_thread_finish_setup(s->avctx); + if (ret < 0) + return ret; } else if (s->context_reinit) { av_log(s->avctx, AV_LOG_ERROR, "Decoder needs full frames to " "reinitialize (start MB is %d).\n", si.start); diff --git a/libavcodec/takdec.c b/libavcodec/takdec.c index cfa69f4217..c1bf697f55 100644 --- a/libavcodec/takdec.c +++ b/libavcodec/takdec.c @@ -745,7 +745,10 @@ static int tak_decode_frame(AVCodecContext *avctx, AVFrame *frame, frame->nb_samples = s->nb_samples; if ((ret = ff_thread_get_buffer(avctx, frame, 0)) < 0) return ret; - ff_thread_finish_setup(avctx); + + ret = ff_thread_finish_setup(avctx); + if (ret < 0) + return ret; if (avctx->bits_per_raw_sample <= 16) { int buf_size = av_samples_get_buffer_size(NULL, avctx->ch_layout.nb_channels, diff --git a/libavcodec/thread.h b/libavcodec/thread.h index 7df5839ed0..12f4cbff24 100644 --- a/libavcodec/thread.h +++ b/libavcodec/thread.h @@ -41,7 +41,7 @@ int ff_thread_can_start_frame(AVCodecContext *avctx); * * @param avctx The context. */ -void ff_thread_finish_setup(AVCodecContext *avctx); +int ff_thread_finish_setup(AVCodecContext *avctx); /** * Wrapper around get_buffer() for frame-multithreaded codecs. diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 28023a4a4d..5f04cb8c78 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -897,8 +897,9 @@ void ff_thread_release_ext_buffer(ThreadFrame *f) av_frame_unref(f->f); } -void ff_thread_finish_setup(AVCodecContext *avctx) +int ff_thread_finish_setup(AVCodecContext *avctx) { + return 0; } void ff_thread_report_progress(ThreadFrame *f, int progress, int field) diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c index d03a1c9dbc..a0d3d878b4 100644 --- a/libavcodec/vp3.c +++ b/libavcodec/vp3.c @@ -2733,7 +2733,9 @@ static int vp3_decode_frame(AVCodecContext *avctx, AVFrame *frame, ff_progress_frame_report(&s->golden_frame, INT_MAX); } } - ff_thread_finish_setup(avctx); + ret = ff_thread_finish_setup(avctx); + if (ret < 0) + goto error; memset(s->all_fragments, 0, s->fragment_count * sizeof(Vp3Fragment)); diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c index d6df018655..3d3039c9d4 100644 --- a/libavcodec/vp8.c +++ b/libavcodec/vp8.c @@ -2748,8 +2748,11 @@ int vp78_decode_frame(AVCodecContext *avctx, AVFrame *rframe, int *got_frame, s->next_framep[VP8_FRAME_CURRENT] = curframe; - if (!is_vp7 && !s->actually_webp) - ff_thread_finish_setup(avctx); + if (!is_vp7 && !s->actually_webp) { + ret = ff_thread_finish_setup(avctx); + if (ret < 0) + goto err; + } if (avctx->hwaccel) { const FFHWAccel *hwaccel = ffhwaccel(avctx->hwaccel); diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c index 8ede2e2eb3..acf325fa21 100644 --- a/libavcodec/vp9.c +++ b/libavcodec/vp9.c @@ -1566,7 +1566,9 @@ static int vp9_decode_frame(AVCodecContext *avctx, AVFrame *frame, } for (int i = 0; i < 8; i++) ff_progress_frame_replace(&s->next_refs[i], &s->s.refs[i]); - ff_thread_finish_setup(avctx); + ret = ff_thread_finish_setup(avctx); + if (ret < 0) + return ret; ff_progress_frame_await(&s->s.refs[ref], INT_MAX); if ((ret = av_frame_ref(frame, s->s.refs[ref].f)) < 0) @@ -1655,9 +1657,13 @@ static int vp9_decode_frame(AVCodecContext *avctx, AVFrame *frame, break; } s->prob_ctx[s->s.h.framectxid].p = s->prob.p; - ff_thread_finish_setup(avctx); + ret = ff_thread_finish_setup(avctx); + if (ret < 0) + return ret; } else if (!s->s.h.refreshctx) { - ff_thread_finish_setup(avctx); + ret = ff_thread_finish_setup(avctx); + if (ret < 0) + return ret; } #if HAVE_THREADS @@ -1726,7 +1732,9 @@ static int vp9_decode_frame(AVCodecContext *avctx, AVFrame *frame, if (s->pass < 2 && s->s.h.refreshctx && !s->s.h.parallelmode) { ff_vp9_adapt_probs(s); - ff_thread_finish_setup(avctx); + ret = ff_thread_finish_setup(avctx); + if (ret < 0) + goto fail; } } while (s->pass++ == 1); diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c index bf9aa0cdce..a850cd155d 100644 --- a/libavcodec/wavpack.c +++ b/libavcodec/wavpack.c @@ -1560,7 +1560,9 @@ static int wavpack_decode_block(AVCodecContext *avctx, AVFrame *frame, int block *new_progress = 1; } av_assert1(!!wc->dsdctx == !!wc->curr_progress); - ff_thread_finish_setup(avctx); + ret = ff_thread_finish_setup(avctx); + if (ret < 0) + return ret; } } -- 2.43.0 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".