[FFmpeg-cvslog] pthread_frame: call update_context_from_user() after acquiring lock.

Ronald S. Bultje git at videolan.org
Mon Apr 3 16:49:24 EEST 2017


ffmpeg | branch: master | Ronald S. Bultje <rsbultje at gmail.com> | Mon Apr  3 09:48:53 2017 -0400| [1269cd5b6f540bef5913bf134d2f461aac50d70b] | committer: Ronald S. Bultje

pthread_frame: call update_context_from_user() after acquiring lock.

Otherwise the thread may still be in the middle of decoding a previous
frame, which would effectively trigger a race condition on any field
concurrently read and written.

In practice, this fixes tsan warnings like the following:

WARNING: ThreadSanitizer: data race (pid=17380)
  Write of size 4 at 0x7d64000160fc by main thread:
    #0 update_context_from_user src/libavcodec/pthread_frame.c:335 (ffmpeg+0x000000dca515)
[..]
  Previous read of size 4 at 0x7d64000160fc by thread T2 (mutexes: write M1821):
    #0 ff_thread_report_progress src/libavcodec/pthread_frame.c:565 (ffmpeg+0x000000dcb08a)

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=1269cd5b6f540bef5913bf134d2f461aac50d70b
---

 libavcodec/pthread_frame.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c
index 4e1ad9d..9a6b83a 100644
--- a/libavcodec/pthread_frame.c
+++ b/libavcodec/pthread_frame.c
@@ -380,7 +380,8 @@ static void release_delayed_buffers(PerThreadContext *p)
     }
 }
 
-static int submit_packet(PerThreadContext *p, AVPacket *avpkt)
+static int submit_packet(PerThreadContext *p, AVCodecContext *user_avctx,
+                         AVPacket *avpkt)
 {
     FrameThreadContext *fctx = p->parent;
     PerThreadContext *prev_thread = fctx->prev_thread;
@@ -392,6 +393,12 @@ static int submit_packet(PerThreadContext *p, AVPacket *avpkt)
 
     pthread_mutex_lock(&p->mutex);
 
+    ret = update_context_from_user(p->avctx, user_avctx);
+    if (ret) {
+        pthread_mutex_unlock(&p->mutex);
+        return ret;
+    }
+
     release_delayed_buffers(p);
 
     if (prev_thread) {
@@ -480,10 +487,7 @@ int ff_thread_decode_frame(AVCodecContext *avctx,
      */
 
     p = &fctx->threads[fctx->next_decoding];
-    err = update_context_from_user(p->avctx, avctx);
-    if (err)
-        goto finish;
-    err = submit_packet(p, avpkt);
+    err = submit_packet(p, avctx, avpkt);
     if (err)
         goto finish;
 



More information about the ffmpeg-cvslog mailing list