Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
* [FFmpeg-devel] [PATCH v2 01/18] avcodec/pthread_slice: Don't reinitialise initialised mutex
@ 2022-06-30 21:48 Andreas Rheinhardt
  2022-06-30 22:29 ` [FFmpeg-devel] [PATCH 02/18] fate/hevc: add clip for persistent_rice_adaptation_enabled_flag Andreas Rheinhardt
                   ` (17 more replies)
  0 siblings, 18 replies; 37+ messages in thread
From: Andreas Rheinhardt @ 2022-06-30 21:48 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Andreas Rheinhardt

It results in undefined behaviour. Instead initialize the mutexes
and condition variables once during init (and check these
initializations).

Also combine the corresponding mutex and condition variable
into one structure so that one can allocate their array
jointly.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
Now also adding the fallback function in case threads are disabled.

 libavcodec/hevcdec.c       |  7 +++-
 libavcodec/pthread_slice.c | 83 ++++++++++++++++++++++++--------------
 libavcodec/thread.h        |  1 +
 libavcodec/utils.c         |  5 +++
 4 files changed, 63 insertions(+), 33 deletions(-)

diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c
index 7037048d53..f222f20706 100644
--- a/libavcodec/hevcdec.c
+++ b/libavcodec/hevcdec.c
@@ -3803,9 +3803,12 @@ static av_cold int hevc_decode_init(AVCodecContext *avctx)
     HEVCContext *s = avctx->priv_data;
     int ret;
 
-    if(avctx->active_thread_type & FF_THREAD_SLICE)
+    if (avctx->active_thread_type & FF_THREAD_SLICE) {
         s->threads_number = avctx->thread_count;
-    else
+        ret = ff_slice_thread_init_progress(avctx);
+        if (ret < 0)
+            return ret;
+    } else
         s->threads_number = 1;
 
     if((avctx->active_thread_type & FF_THREAD_FRAME) && avctx->thread_count > 1)
diff --git a/libavcodec/pthread_slice.c b/libavcodec/pthread_slice.c
index 0ad1965a22..e34116116d 100644
--- a/libavcodec/pthread_slice.c
+++ b/libavcodec/pthread_slice.c
@@ -41,6 +41,11 @@ typedef int (action_func)(AVCodecContext *c, void *arg);
 typedef int (action_func2)(AVCodecContext *c, void *arg, int jobnr, int threadnr);
 typedef int (main_func)(AVCodecContext *c);
 
+typedef struct Progress {
+    pthread_cond_t  cond;
+    pthread_mutex_t mutex;
+} Progress;
+
 typedef struct SliceThreadContext {
     AVSliceThread *thread;
     action_func *func;
@@ -53,8 +58,7 @@ typedef struct SliceThreadContext {
     int *entries;
     int entries_count;
     int thread_count;
-    pthread_cond_t *progress_cond;
-    pthread_mutex_t *progress_mutex;
+    Progress *progress;
 } SliceThreadContext;
 
 static void main_function(void *priv) {
@@ -83,13 +87,13 @@ void ff_slice_thread_free(AVCodecContext *avctx)
     avpriv_slicethread_free(&c->thread);
 
     for (i = 0; i < c->thread_count; i++) {
-        pthread_mutex_destroy(&c->progress_mutex[i]);
-        pthread_cond_destroy(&c->progress_cond[i]);
+        Progress *const progress = &c->progress[i];
+        pthread_mutex_destroy(&progress->mutex);
+        pthread_cond_destroy(&progress->cond);
     }
 
     av_freep(&c->entries);
-    av_freep(&c->progress_mutex);
-    av_freep(&c->progress_cond);
+    av_freep(&c->progress);
     av_freep(&avctx->internal->thread_ctx);
 }
 
@@ -172,65 +176,82 @@ int ff_slice_thread_init(AVCodecContext *avctx)
     return 0;
 }
 
+int av_cold ff_slice_thread_init_progress(AVCodecContext *avctx)
+{
+    SliceThreadContext *const p = avctx->internal->thread_ctx;
+    int err, i = 0, thread_count = avctx->thread_count;
+
+    p->progress = av_calloc(thread_count, sizeof(*p->progress));
+    if (!p->progress) {
+        err = AVERROR(ENOMEM);
+        goto fail;
+    }
+
+    for (; i < thread_count; i++) {
+        Progress *const progress = &p->progress[i];
+        err = pthread_mutex_init(&progress->mutex, NULL);
+        if (err) {
+            err = AVERROR(err);
+            goto fail;
+        }
+        err = pthread_cond_init (&progress->cond,  NULL);
+        if (err) {
+            err = AVERROR(err);
+            pthread_mutex_destroy(&progress->mutex);
+            goto fail;
+        }
+    }
+    err = 0;
+fail:
+    p->thread_count = i;
+    return err;
+}
+
 void ff_thread_report_progress2(AVCodecContext *avctx, int field, int thread, int n)
 {
     SliceThreadContext *p = avctx->internal->thread_ctx;
+    Progress *const progress = &p->progress[thread];
     int *entries = p->entries;
 
-    pthread_mutex_lock(&p->progress_mutex[thread]);
+    pthread_mutex_lock(&progress->mutex);
     entries[field] +=n;
-    pthread_cond_signal(&p->progress_cond[thread]);
-    pthread_mutex_unlock(&p->progress_mutex[thread]);
+    pthread_cond_signal(&progress->cond);
+    pthread_mutex_unlock(&progress->mutex);
 }
 
 void ff_thread_await_progress2(AVCodecContext *avctx, int field, int thread, int shift)
 {
     SliceThreadContext *p  = avctx->internal->thread_ctx;
+    Progress *progress;
     int *entries      = p->entries;
 
     if (!entries || !field) return;
 
     thread = thread ? thread - 1 : p->thread_count - 1;
+    progress = &p->progress[thread];
 
-    pthread_mutex_lock(&p->progress_mutex[thread]);
+    pthread_mutex_lock(&progress->mutex);
     while ((entries[field - 1] - entries[field]) < shift){
-        pthread_cond_wait(&p->progress_cond[thread], &p->progress_mutex[thread]);
+        pthread_cond_wait(&progress->cond, &progress->mutex);
     }
-    pthread_mutex_unlock(&p->progress_mutex[thread]);
+    pthread_mutex_unlock(&progress->mutex);
 }
 
 int ff_alloc_entries(AVCodecContext *avctx, int count)
 {
-    int i;
-
     if (avctx->active_thread_type & FF_THREAD_SLICE)  {
         SliceThreadContext *p = avctx->internal->thread_ctx;
 
         if (p->entries) {
-            av_assert0(p->thread_count == avctx->thread_count);
             av_freep(&p->entries);
         }
 
-        p->thread_count  = avctx->thread_count;
         p->entries       = av_calloc(count, sizeof(*p->entries));
-
-        if (!p->progress_mutex) {
-            p->progress_mutex = av_malloc_array(p->thread_count, sizeof(pthread_mutex_t));
-            p->progress_cond  = av_malloc_array(p->thread_count, sizeof(pthread_cond_t));
-        }
-
-        if (!p->entries || !p->progress_mutex || !p->progress_cond) {
-            av_freep(&p->entries);
-            av_freep(&p->progress_mutex);
-            av_freep(&p->progress_cond);
+        if (!p->entries) {
+            p->entries_count = 0;
             return AVERROR(ENOMEM);
         }
         p->entries_count  = count;
-
-        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;
diff --git a/libavcodec/thread.h b/libavcodec/thread.h
index d36dc83bd7..92cbd927f1 100644
--- a/libavcodec/thread.h
+++ b/libavcodec/thread.h
@@ -106,6 +106,7 @@ int ff_slice_thread_execute_with_mainfunc(AVCodecContext *avctx,
 void ff_thread_free(AVCodecContext *s);
 int ff_alloc_entries(AVCodecContext *avctx, int count);
 void ff_reset_entries(AVCodecContext *avctx);
+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);
 
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index 940f25fe7a..f78475d0ad 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -958,6 +958,11 @@ int ff_thread_can_start_frame(AVCodecContext *avctx)
     return 1;
 }
 
+int ff_slice_thread_init_progress(AVCodecContext *avctx)
+{
+    return 0;
+}
+
 int ff_alloc_entries(AVCodecContext *avctx, int count)
 {
     return 0;
-- 
2.34.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-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 37+ messages in thread

end of thread, other threads:[~2022-07-25 19:58 UTC | newest]

Thread overview: 37+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-30 21:48 [FFmpeg-devel] [PATCH v2 01/18] avcodec/pthread_slice: Don't reinitialise initialised mutex Andreas Rheinhardt
2022-06-30 22:29 ` [FFmpeg-devel] [PATCH 02/18] fate/hevc: add clip for persistent_rice_adaptation_enabled_flag Andreas Rheinhardt
2022-06-30 22:29 ` [FFmpeg-devel] [PATCH 03/18] avcodec/hevcdec: Don't initialize HEVCContexts twice Andreas Rheinhardt
2022-06-30 22:29 ` [FFmpeg-devel] [PATCH 04/18] avcodec/hevcdec: Add pointers to logctx and parent ctx to HEVCLocalCtx Andreas Rheinhardt
2022-06-30 22:29 ` [FFmpeg-devel] [PATCH 05/18] avcodec/hevc_refs: Constify ff_hevc_get_ref_list() Andreas Rheinhardt
2022-06-30 22:29 ` [FFmpeg-devel] [PATCH 06/18] avcodec/hevc_cabac: Don't cast const away unnecessarily Andreas Rheinhardt
2022-06-30 22:29 ` [FFmpeg-devel] [PATCH 07/18] avcodec/hevc_mvs: Pass HEVCLocalContext when slice-threading Andreas Rheinhardt
2022-06-30 22:29 ` [FFmpeg-devel] [PATCH 08/18] avcodec/hevc_filter: " Andreas Rheinhardt
2022-06-30 22:29 ` [FFmpeg-devel] [PATCH 09/18] avcodec/hevcdec: Add stat_coeffs to HEVCABACState Andreas Rheinhardt
2022-07-02  8:34   ` Anton Khirnov
2022-07-02 10:40     ` Andreas Rheinhardt
2022-07-02 11:31       ` Andreas Rheinhardt
2022-07-02 11:43         ` Andreas Rheinhardt
2022-06-30 22:29 ` [FFmpeg-devel] [PATCH 10/18] avcodec/hevc_cabac: Pass HEVCLocalContext when slice-threading Andreas Rheinhardt
2022-06-30 22:29 ` [FFmpeg-devel] [PATCH 11/18] avcodec/hevcpred: " Andreas Rheinhardt
2022-06-30 22:29 ` [FFmpeg-devel] [PATCH 12/18] avcodec/hevcdec: " Andreas Rheinhardt
2022-06-30 22:29 ` [FFmpeg-devel] [PATCH 13/18] avcodec/hevcdec: Pass HEVCLocalContext** via execute2 Andreas Rheinhardt
2022-06-30 22:29 ` [FFmpeg-devel] [PATCH 14/18] avcodec/hevcdec: Don't allocate redundant HEVCContexts Andreas Rheinhardt
2022-07-01 21:25   ` Michael Niedermayer
2022-07-02  6:32     ` Andreas Rheinhardt
2022-07-05 22:24       ` Michael Niedermayer
2022-07-06  8:21         ` Andreas Rheinhardt
2022-07-23  5:44           ` Andreas Rheinhardt
2022-07-23 14:38             ` Michael Niedermayer
2022-07-23 21:42               ` Andreas Rheinhardt
2022-07-24 21:23                 ` Michael Niedermayer
2022-07-24 21:26                   ` Andreas Rheinhardt
2022-07-25 19:44                     ` Michael Niedermayer
2022-07-25 19:58                       ` Andreas Rheinhardt
2022-06-30 22:29 ` [FFmpeg-devel] [PATCH 15/18] avcodec/hevcdec: Check allocation Andreas Rheinhardt
2022-06-30 22:29 ` [FFmpeg-devel] [PATCH 16/18] avcodec/pthread_slice: Combine allocating and zeroing entries Andreas Rheinhardt
2022-06-30 22:29 ` [FFmpeg-devel] [PATCH 17/18] avcodec/pthread_slice: Reuse buffer if possible Andreas Rheinhardt
2022-07-01 11:33   ` Paul B Mahol
2022-07-01 13:21   ` Tomas Härdin
2022-07-22 20:04     ` Andreas Rheinhardt
2022-06-30 22:29 ` [FFmpeg-devel] [PATCH 18/18] avcodec/hevcdec: Move allocation after error checks Andreas Rheinhardt
2022-07-01 13:30 ` [FFmpeg-devel] [PATCH v2 01/18] avcodec/pthread_slice: Don't reinitialise initialised mutex Tomas Härdin

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git