This is useful when the lifetime of the object to be shared is the whole decoding process as it allows to avoid having to sync them every time in update_thread_context.
Signed-off-by: Andreas Rheinhardt <andreas.rheinha...@outlook.com> --- libavcodec/decode.c | 7 +++++++ libavcodec/pthread_frame.c | 20 ++++++++++++++++++++ libavcodec/thread.h | 30 ++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+) diff --git a/libavcodec/decode.c b/libavcodec/decode.c index f18f85c33c..e196c05f11 100644 --- a/libavcodec/decode.c +++ b/libavcodec/decode.c @@ -1747,6 +1747,13 @@ void ff_progress_frame_await(const ProgressFrame *f, int n) ff_thread_progress_await(&f->progress->progress, n); } +#if !HAVE_THREADS +enum ThreadingStatus ff_thread_sync_ref(AVCodecContext *avctx, size_t offset) +{ + return FF_THREAD_NO_FRAME_THREADING; +} +#endif /* !HAVE_THREADS */ + static av_cold int progress_frame_pool_init_cb(FFRefStructOpaque opaque, void *obj) { const AVCodecContext *avctx = opaque.nc; diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index 6b2c4312e0..ee571be610 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -1001,3 +1001,23 @@ void ff_thread_release_ext_buffer(ThreadFrame *f) if (f->f) av_frame_unref(f->f); } + +enum ThreadingStatus ff_thread_sync_ref(AVCodecContext *avctx, size_t offset) +{ + PerThreadContext *p; + const void *ref; + + if (!avctx->internal->is_copy) + return avctx->active_thread_type & FF_THREAD_FRAME ? + FF_THREAD_IS_FIRST_THREAD : FF_THREAD_NO_FRAME_THREADING; + + p = avctx->internal->thread_ctx; + + av_assert1(memcpy(&ref, (char*)avctx->priv_data + offset, sizeof(ref)) && ref == NULL); + + memcpy(&ref, (const char*)p->parent->threads[0].avctx->priv_data + offset, sizeof(ref)); + av_assert1(ref); + ff_refstruct_replace((char*)avctx->priv_data + offset, ref); + + return FF_THREAD_IS_COPY; +} diff --git a/libavcodec/thread.h b/libavcodec/thread.h index f772d7ff18..5ab12848b4 100644 --- a/libavcodec/thread.h +++ b/libavcodec/thread.h @@ -84,4 +84,34 @@ int ff_slice_thread_init_progress(AVCodecContext *avctx); void ff_thread_report_progress2(AVCodecContext *avctx, int field, int thread, int n); void ff_thread_await_progress2(AVCodecContext *avctx, int field, int thread, int shift); +enum ThreadingStatus { + FF_THREAD_IS_COPY, + FF_THREAD_IS_FIRST_THREAD, + FF_THREAD_NO_FRAME_THREADING, +}; + +/** + * Allows to synchronize objects whose lifetime is the whole decoding + * process among all frame threads. + * + * When called from a non-copy thread, do nothing. + * When called from another thread, place a new RefStruct reference + * at the given offset in the calling thread's private data from + * the RefStruct reference in the private data of the first decoding thread. + * The first thread must have a valid RefStruct reference at the given + * offset in its private data; the calling thread must not have + * a reference at this offset in its private data (must be NULL). + * + * @param avctx an AVCodecContext + * @param offset offset of the RefStruct reference in avctx's private data + * + * @retval FF_THREAD_IS_COPY if frame-threading is in use and the + * calling thread is a copy; in this case, the RefStruct reference + * will be set. + * @retval FF_THREAD_IS_MAIN_THREAD if frame-threading is in use + * and the calling thread is the main thread. + * @retval FF_THREAD_NO_FRAME_THREADING if frame-threading is not in use. + */ +enum ThreadingStatus ff_thread_sync_ref(AVCodecContext *avctx, size_t offset); + #endif /* AVCODEC_THREAD_H */ -- 2.40.1 _______________________________________________ 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".