Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
To: ffmpeg-devel@ffmpeg.org
Cc: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Subject: [FFmpeg-devel] [PATCH 07/18] avcodec/vp8: Pass mb_y explicitly
Date: Sat, 10 Sep 2022 03:07:18 +0200
Message-ID: <AS8P250MB0744B382750A30A1476138BE8F429@AS8P250MB0744.EURP250.PROD.OUTLOOK.COM> (raw)
In-Reply-To: <AS8P250MB0744923C03A16E5BF7BE11B28F429@AS8P250MB0744.EURP250.PROD.OUTLOOK.COM>

Avoids atomic stores and loads and is a prerequisite for
removing all atomic synchronizations for VP7.
Notice that removing the explicit atomic_store() in
vp78_decode_mb_row_sliced() does not negatively affect
parallelism during slice-threading, because no check_thread_pos()
ever waits for an (mb_x, mb_y) pair with mb_x == 0
(which this atomic store signalled).

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
---
Btw: The code in update_pos looks fishy to me; namely
the part that tries to avoid the broadcast. Consider the scenario
in which the other threads (prev and next, A and B) are not waiting
when the current thread C checks their wait_mb_pos. Then
one of the other threads reads C's thread_mb_pos and notices that
it needs to wait for an update from C. It therefore locks C's mutex,
stores its wait_mb_pos, checks C's thread_mb_pos again (still reading
the old value in this scenario) and waits via pthread_cond_wait().

Then C updates its thread_mb_pos, but because C uses outdated values
for A and B's wait_mb_pos, it never signals a broadcast. Who will
then wake up the waiting thread?

This should be fixable by moving the loads after C's update
of thread_mb_pos: In case C's read of A's wait_mb_pos value happens
before A updates it, then C's update of its thread_mb_pos
happens before A updates its wait_mb_pos and A will therefore read
C's updated value of thread_mb_pos its atomic_load while holding
C's lock (and will therefore never call pthread_cond_wait()).
In case C's read of A's wait_mb_pos value happens after A updates it,
C will emit its broadcast, waking A which reads the updated value
and stops.

 libavcodec/vp8.c | 30 +++++++++++++++---------------
 libavcodec/vp8.h |  4 ++--
 2 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c
index c259f3588c..5ecb9b07e5 100644
--- a/libavcodec/vp8.c
+++ b/libavcodec/vp8.c
@@ -2389,11 +2389,11 @@ static int vp8_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *cur_frame,
 #endif
 
 static av_always_inline int decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata,
-                                        int jobnr, int threadnr, int is_vp7)
+                                                    int jobnr, int threadnr, int mb_y,
+                                                    int is_vp7)
 {
     VP8Context *s = avctx->priv_data;
     VP8ThreadData *prev_td, *next_td, *td = &s->thread_data[threadnr];
-    int mb_y = atomic_load(&td->thread_mb_pos) >> 16;
     int mb_x, mb_xy = mb_y * s->mb_width;
     int num_jobs = s->num_jobs;
     const VP8Frame *prev_frame = s->prev_frame;
@@ -2518,23 +2518,24 @@ static av_always_inline int decode_mb_row_no_filter(AVCodecContext *avctx, void
 }
 
 static int vp7_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata,
-                                        int jobnr, int threadnr)
+                                       int jobnr, int threadnr, int mb_y)
 {
-    return decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr, 1);
+    return decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr, mb_y, 1);
 }
 
 static int vp8_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata,
-                                        int jobnr, int threadnr)
+                                       int jobnr, int threadnr, int mb_y)
 {
-    return decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr, 0);
+    return decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr, mb_y, 0);
 }
 
 static av_always_inline void filter_mb_row(AVCodecContext *avctx, void *tdata,
-                              int jobnr, int threadnr, int is_vp7)
+                                           int jobnr, int threadnr, int mb_y,
+                                           int is_vp7)
 {
     VP8Context *s = avctx->priv_data;
     VP8ThreadData *td = &s->thread_data[threadnr];
-    int mb_x, mb_y = atomic_load(&td->thread_mb_pos) >> 16, num_jobs = s->num_jobs;
+    int mb_x, num_jobs = s->num_jobs;
     AVFrame *curframe = s->curframe->tf.f;
     VP8Macroblock *mb;
     VP8ThreadData *prev_td, *next_td;
@@ -2589,15 +2590,15 @@ static av_always_inline void filter_mb_row(AVCodecContext *avctx, void *tdata,
 }
 
 static void vp7_filter_mb_row(AVCodecContext *avctx, void *tdata,
-                              int jobnr, int threadnr)
+                              int jobnr, int threadnr, int mb_y)
 {
-    filter_mb_row(avctx, tdata, jobnr, threadnr, 1);
+    filter_mb_row(avctx, tdata, jobnr, threadnr, mb_y, 1);
 }
 
 static void vp8_filter_mb_row(AVCodecContext *avctx, void *tdata,
-                              int jobnr, int threadnr)
+                              int jobnr, int threadnr, int mb_y)
 {
-    filter_mb_row(avctx, tdata, jobnr, threadnr, 0);
+    filter_mb_row(avctx, tdata, jobnr, threadnr, mb_y, 0);
 }
 
 static av_always_inline
@@ -2615,14 +2616,13 @@ int vp78_decode_mb_row_sliced(AVCodecContext *avctx, void *tdata, int jobnr,
     td->mv_bounds.mv_min.y   = -MARGIN - 64 * threadnr;
     td->mv_bounds.mv_max.y   = ((s->mb_height - 1) << 6) + MARGIN - 64 * threadnr;
     for (mb_y = jobnr; mb_y < s->mb_height; mb_y += num_jobs) {
-        atomic_store(&td->thread_mb_pos, mb_y << 16);
-        ret = s->decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr);
+        ret = s->decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr, mb_y);
         if (ret < 0) {
             update_pos(td, s->mb_height, INT_MAX & 0xFFFF);
             return ret;
         }
         if (s->deblock_filter)
-            s->filter_mb_row(avctx, tdata, jobnr, threadnr);
+            s->filter_mb_row(avctx, tdata, jobnr, threadnr, mb_y);
         update_pos(td, mb_y, INT_MAX & 0xFFFF);
 
         td->mv_bounds.mv_min.y -= 64 * num_jobs;
diff --git a/libavcodec/vp8.h b/libavcodec/vp8.h
index 30aeb4cb06..ed79bc79c1 100644
--- a/libavcodec/vp8.h
+++ b/libavcodec/vp8.h
@@ -330,8 +330,8 @@ typedef struct VP8Context {
      */
     int mb_layout;
 
-    int (*decode_mb_row_no_filter)(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr);
-    void (*filter_mb_row)(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr);
+    int (*decode_mb_row_no_filter)(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr, int mb_y);
+    void (*filter_mb_row)(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr, int mb_y);
 
     int vp7;
 
-- 
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".

  parent reply	other threads:[~2022-09-10  1:08 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-09-10  0:19 [FFmpeg-devel] [PATCH 01/18] avcodec/vp8: Disable segmentation for VP7 Andreas Rheinhardt
2022-09-10  1:07 ` [FFmpeg-devel] [PATCH 02/18] avcodec/vp8: Disable lf_delta " Andreas Rheinhardt
2022-09-11  4:29   ` Peter Ross
2022-09-11  4:38     ` Andreas Rheinhardt
2022-09-11 14:41       ` Ronald S. Bultje
2022-09-11 15:09         ` Ronald S. Bultje
2022-09-11 22:41       ` Peter Ross
2022-09-10  1:07 ` [FFmpeg-devel] [PATCH 03/18] avcodec/vp8: Remove unused macros Andreas Rheinhardt
2022-09-10  1:07 ` [FFmpeg-devel] [PATCH 04/18] avcodec/vp8: Inline mb_layout for VP7 Andreas Rheinhardt
2022-09-10  1:07 ` [FFmpeg-devel] [PATCH 05/18] avcodec/vp8: Inline inner_filter " Andreas Rheinhardt
2022-09-10  1:07 ` [FFmpeg-devel] [PATCH 06/18] avcodec/vp8: Inline mbskip_enabled " Andreas Rheinhardt
2022-09-10  1:07 ` Andreas Rheinhardt [this message]
2022-09-10  1:07 ` [FFmpeg-devel] [PATCH 08/18] avcodec/vp8: Inline num_coeff_partitions " Andreas Rheinhardt
2022-09-10  1:07 ` [FFmpeg-devel] [PATCH 09/18] avcodec/vp8: Disable slice-thread synchronization code " Andreas Rheinhardt
2022-09-10  1:07 ` [FFmpeg-devel] [PATCH 10/18] avcodec/vp8: Inline num_jobs " Andreas Rheinhardt
2022-09-10  1:07 ` [FFmpeg-devel] [PATCH 11/18] avcodec/vp8: Inline jobnr, threadnr " Andreas Rheinhardt
2022-09-10  1:07 ` [FFmpeg-devel] [PATCH 12/18] avcodec/vp8: Inline update_last " Andreas Rheinhardt
2022-09-10  1:07 ` [FFmpeg-devel] [PATCH 13/18] avcodec/vp8: Don't use avctx->execute2 " Andreas Rheinhardt
2022-09-10  1:07 ` [FFmpeg-devel] [PATCH 14/18] avcodec/vp8: Move fade_present from context to stack Andreas Rheinhardt
2022-09-10  1:07 ` [FFmpeg-devel] [PATCH 15/18] avcodec/vp8: Disable frame-threading code for VP7 Andreas Rheinhardt
2022-09-10  1:07 ` [FFmpeg-devel] [PATCH 16/18] avcodec/vp8dsp: Remove declarations of inexistent functions Andreas Rheinhardt
2022-09-10  1:07 ` [FFmpeg-devel] [PATCH 17/18] avcodec/vp8dsp: Constify src in vp8_mc_func Andreas Rheinhardt
2022-09-10  1:07 ` [FFmpeg-devel] [PATCH 18/18] avcodec/vp8: Add const where appropriate Andreas Rheinhardt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=AS8P250MB0744B382750A30A1476138BE8F429@AS8P250MB0744.EURP250.PROD.OUTLOOK.COM \
    --to=andreas.rheinhardt@outlook.com \
    --cc=ffmpeg-devel@ffmpeg.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

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