vlc | branch: master | Alexandre Janniaux <aja...@videolabs.io> | Thu Feb 18 
16:23:54 2021 +0100| [14fdbf872d48473894c1ad8e4da09fd9c3753346] | committer: 
Alexandre Janniaux

VLCVideoUIView: report event in another thread

Report events from a different thread than the main thread, and continue
to execute the main CFRunLoop, but filter the events to only execute
the ones queued by potential display, ie. those tagged with the mode
"vlc_runloop".

The vlc_runloop mode is designed to be executed even when an event is
being reported by the vout_window used, ie. when there is a call to
CFRunLoopInMode(CFRunLoopGetMain(), CFSTR("vlc_runloop"), ..).

Clients should ensure they also tag their blocks with the default mode
too. Otherwise, they are likely to never be executed.

Async tasks can still be dispatched without the "vlc_runloop" mode but
every sync tasks in the display must be done under this mode to prevent
deadlock from happening between the main thread and the vout_thread,
typically with the following code:

    /* The main loop to run the block into */
    CFRunLoopRef runloop = CFRunLoopGetMain();

    /* The modes to execute the block in */
    CFStringRef modes_cfstrings[] = { kCFRunLoopDefaultMode, 
CFSTR("vlc_runloop") };
    CFArrayRef modes = CFArrayCreate(NULL, (const void **)modes_cfstrings,
            ARRAY_SIZE(modes_cfstrings), &kCFTypeArrayCallBacks);

    CFRunLoopPerformBlock(runloop, modes, ^{
        /* The block content to execute */
    });

    /* Don't forget to signal the runloop
    CFRunLoopWakeUp(runloop);
    CFRelease(modes);

To achieve a blocking/sync behaviour, clients can share a binary
semaphore between the block and the outside of the block. When using a
vlc_sem_t object, it must be qualified with __block to be modified
inside of the block.

Refs #23571

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=14fdbf872d48473894c1ad8e4da09fd9c3753346
---

 modules/video_output/apple/VLCVideoUIView.m | 46 ++++++++++++++++++++++-------
 1 file changed, 35 insertions(+), 11 deletions(-)

diff --git a/modules/video_output/apple/VLCVideoUIView.m 
b/modules/video_output/apple/VLCVideoUIView.m
index 3a4c749816..d5fc143beb 100644
--- a/modules/video_output/apple/VLCVideoUIView.m
+++ b/modules/video_output/apple/VLCVideoUIView.m
@@ -161,6 +161,20 @@
     }
 }
 
+- (void)reportEvent:(void(^)())eventBlock
+{
+    CFStringRef mode = CFSTR("org.videolan.vlccore.window");
+    CFRunLoopRef runloop = CFRunLoopGetCurrent();
+    CFRunLoopPerformBlock(runloop, mode, ^{
+        dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY, 0), ^{
+            (eventBlock)();
+            CFRunLoopStop(runloop);
+        });
+    });
+    CFRunLoopWakeUp(runloop);
+    CFRunLoopRunInMode(mode, 0, NO);
+}
+
 - (void)detachFromParent
 {
     /* We need to lock because we consider that _wnd might be destroyed
@@ -263,11 +277,16 @@
     /* We need to lock to ensure _wnd is still valid, see detachFromParent. */
     vlc_mutex_lock(&_mutex);
     if (_wnd == NULL)
-        goto end;
-    vout_window_ReportSize(_wnd,
-            viewSize.width * scaleFactor,
-            viewSize.height * scaleFactor);
-end:
+    {
+        vlc_mutex_unlock(&_mutex);
+        return;
+    }
+
+    [self reportEvent:^{
+        vout_window_ReportSize(_wnd,
+                viewSize.width * scaleFactor,
+                viewSize.height * scaleFactor);
+    }];
     vlc_mutex_unlock(&_mutex);
 }
 
@@ -280,12 +299,17 @@ end:
     /* We need to lock to ensure _wnd is still valid, see detachFromParent. */
     vlc_mutex_lock(&_mutex);
     if (_wnd == NULL)
-        goto end;
-    vout_window_ReportMouseMoved(_wnd,
-            (int)touchPoint.x * scaleFactor, (int)touchPoint.y * scaleFactor);
-    vout_window_ReportMousePressed(_wnd, MOUSE_BUTTON_LEFT);
-    vout_window_ReportMouseReleased(_wnd, MOUSE_BUTTON_LEFT);
-end:
+    {
+        vlc_mutex_unlock(&_mutex);
+        return;
+    }
+
+    [self reportEvent:^{
+        vout_window_ReportMouseMoved(_wnd,
+                (int)touchPoint.x * scaleFactor, (int)touchPoint.y * 
scaleFactor);
+        vout_window_ReportMousePressed(_wnd, MOUSE_BUTTON_LEFT);
+        vout_window_ReportMouseReleased(_wnd, MOUSE_BUTTON_LEFT);
+    }];
     vlc_mutex_unlock(&_mutex);
 }
 

_______________________________________________
vlc-commits mailing list
vlc-commits@videolan.org
https://mailman.videolan.org/listinfo/vlc-commits

Reply via email to