diff --git a/libavcodec/pthread.c b/libavcodec/pthread.c index 4c6d8784a7..b8beac3ed1 100644 --- a/libavcodec/pthread.c +++ b/libavcodec/pthread.c @@ -66,6 +66,12 @@ typedef struct ThreadContext { unsigned current_execute; int current_job; int done; + + int *entries; + int entries_count; + int thread_count; + pthread_cond_t *progress_cond; + pthread_mutex_t *progress_mutex; } ThreadContext; /** @@ -1126,3 +1132,62 @@ void ff_thread_free(AVCodecContext *avctx) else thread_free(avctx); } + +void ff_thread_report_progress2(AVCodecContext *avctx, int field, int thread, int n) +{ + ThreadContext *p = avctx->thread_opaque; + int *entries = p->entries; + + pthread_mutex_lock(&p->progress_mutex[thread]); + entries[field] +=n; + pthread_cond_signal(&p->progress_cond[thread]); + pthread_mutex_unlock(&p->progress_mutex[thread]); +} + +void ff_thread_await_progress2(AVCodecContext *avctx, int field, int thread, int shift) +{ + ThreadContext *p = avctx->thread_opaque; + int *entries = p->entries; + + if (!entries || !field) return; + + thread = thread ? thread - 1 : p->thread_count - 1; + + pthread_mutex_lock(&p->progress_mutex[thread]); + while ((entries[field - 1] - entries[field]) < shift){ + pthread_cond_wait(&p->progress_cond[thread], &p->progress_mutex[thread]); + } + pthread_mutex_unlock(&p->progress_mutex[thread]); +} + +int ff_alloc_entries(AVCodecContext *avctx, int count) +{ + int i; + + if (avctx->active_thread_type & FF_THREAD_SLICE) { + ThreadContext *p = avctx->thread_opaque; + p->thread_count = avctx->thread_count; + p->entries = av_mallocz(count * sizeof(int)); + + if (!p->entries) { + return AVERROR(ENOMEM); + } + + p->entries_count = count; + p->progress_mutex = av_malloc(p->thread_count * sizeof(pthread_mutex_t)); + p->progress_cond = av_malloc(p->thread_count * sizeof(pthread_cond_t)); + + for (i = 0; i < p->thread_count; i++) { + pthread_mutex_init(&p->progress_mutex[i], NULL); + pthread_cond_init(&p->progress_cond[i], NULL); + } + } + + return 0; +} + +void ff_reset_entries(AVCodecContext *avctx) +{ + ThreadContext *p = avctx->thread_opaque; + memset(p->entries, 0, p->entries_count * sizeof(int)); +} diff --git a/libavcodec/thread.h b/libavcodec/thread.h index 0dc04e0702..c848d7ae8b 100644 --- a/libavcodec/thread.h +++ b/libavcodec/thread.h @@ -135,4 +135,9 @@ int ff_thread_ref_frame(ThreadFrame *dst, ThreadFrame *src); int ff_thread_init(AVCodecContext *s); void ff_thread_free(AVCodecContext *s); +int ff_alloc_entries(AVCodecContext *avctx, int count); +void ff_reset_entries(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); + #endif /* AVCODEC_THREAD_H */ diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 37d6ee3a64..cde8a5331b 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -3269,6 +3269,23 @@ int ff_thread_can_start_frame(AVCodecContext *avctx) return 1; } +int ff_alloc_entries(AVCodecContext *avctx, int count) +{ + return 0; +} + +void ff_reset_entries(AVCodecContext *avctx) +{ +} + +void ff_thread_await_progress2(AVCodecContext *avctx, int field, int thread, int shift) +{ +} + +void ff_thread_report_progress2(AVCodecContext *avctx, int field, int thread, int n) +{ +} + #endif enum AVMediaType avcodec_get_type(enum AVCodecID codec_id)