summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndoni Morales Alastruey <ylatuya@gmail.com>2012-08-02 01:48:29 +0200
committerSebastian Dröge <sebastian.droege@collabora.co.uk>2012-08-06 10:55:41 +0200
commit9a68d18f31264ae5bb223aaacead0bdd3304c22d (patch)
tree9d105f1b85d9b2699d45746ee38aa5837f800e75
parent417cbcf34f01f4d18c40094413143f483ad366f0 (diff)
osxvideosink: add a better detection for the main run loop
-rw-r--r--sys/osxvideo/osxvideosink.h5
-rw-r--r--sys/osxvideo/osxvideosink.m65
2 files changed, 69 insertions, 1 deletions
diff --git a/sys/osxvideo/osxvideosink.h b/sys/osxvideo/osxvideosink.h
index 37b68c2f6..622f0ade0 100644
--- a/sys/osxvideo/osxvideosink.h
+++ b/sys/osxvideo/osxvideosink.h
@@ -90,6 +90,10 @@ struct _GstOSXVideoSink {
#else
guint cocoa_timeout;
#endif
+ GMutex *mrl_check_lock;
+ GCond *mrl_check_cond;
+ gboolean mrl_check_done;
+ gboolean main_run_loop_running;
gboolean app_started;
gboolean keep_par;
gboolean embed;
@@ -145,6 +149,7 @@ GType gst_osx_video_sink_get_type(void);
#ifdef RUN_NS_APP_THREAD
+ (BOOL) isMainThread;
-(void) nsAppThread;
+-(void) checkMainRunLoop;
#endif
@end
diff --git a/sys/osxvideo/osxvideosink.m b/sys/osxvideo/osxvideosink.m
index 44ffb4ced..3ee25803b 100644
--- a/sys/osxvideo/osxvideosink.m
+++ b/sys/osxvideo/osxvideosink.m
@@ -115,6 +115,51 @@ run_ns_app_loop (void) {
}
static void
+gst_osx_videosink_check_main_run_loop (GstOSXVideoSink *sink)
+{
+ /* check if the main run loop is running */
+ gboolean is_running;
+
+ if (sink->mrl_check_done) {
+ return;
+ }
+ /* the easy way */
+ is_running = [[NSRunLoop mainRunLoop] currentMode] != nil;
+ if (is_running) {
+ goto exit;
+ } else {
+ /* the previous check doesn't always work with main loops that run
+ * cocoa's main run loop manually, like the gdk one, giving false
+ * negatives. This check defers a call to the main thread and waits to
+ * be awaken by this function. */
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ GstOSXVideoSinkObject * object = (GstOSXVideoSinkObject *) sink->osxvideosinkobject;
+ GTimeVal abstime;
+
+ g_mutex_lock(sink->mrl_check_lock);
+ [object performSelectorOnMainThread:
+ @selector(checkMainRunLoop)
+ withObject:nil waitUntilDone:NO];
+ /* Wait 100 ms */
+ g_get_current_time (&abstime);
+ g_time_val_add (&abstime, 100 * 1000);
+ is_running = g_cond_timed_wait(sink->mrl_check_cond,
+ sink->mrl_check_lock, &abstime);
+ g_mutex_unlock(sink->mrl_check_lock);
+
+ [pool release];
+ }
+
+exit:
+ {
+ GST_DEBUG_OBJECT(sink, "The main runloop %s is running",
+ is_running ? "" : " not ");
+ sink->main_run_loop_running = is_running;
+ sink->mrl_check_done = TRUE;
+ }
+}
+
+static void
gst_osx_video_sink_run_cocoa_loop (GstOSXVideoSink * sink )
{
/* Cocoa applications require a main runloop running to dispatch UI
@@ -124,7 +169,7 @@ gst_osx_video_sink_run_cocoa_loop (GstOSXVideoSink * sink )
* external NSView is passed to the sink through the GstXOverlay API,
* we need to run the cocoa mainloop somehow.
*/
- if ([[NSRunLoop mainRunLoop] currentMode] == nil) {
+ if (!sink->main_run_loop_running) {
#ifdef RUN_NS_APP_THREAD
/* run the main runloop in a separate thread */
@@ -205,6 +250,7 @@ gst_osx_video_sink_osxwindow_create (GstOSXVideoSink * osxvideosink, gint width,
GST_INFO_OBJECT (osxvideosink, "'have-ns-view' message sent");
osxvideosink->ns_app_thread = [NSThread mainThread];
+ gst_osx_videosink_check_main_run_loop (osxvideosink);
gst_osx_video_sink_run_cocoa_loop (osxvideosink);
[osxwindow->gstview setMainThread:osxvideosink->ns_app_thread];
@@ -462,6 +508,10 @@ gst_osx_video_sink_init (GstOSXVideoSink * sink)
sink->loop_thread_lock = g_mutex_new ();
sink->loop_thread_cond = g_cond_new ();
#endif
+ sink->mrl_check_lock = g_mutex_new ();
+ sink->mrl_check_cond = g_cond_new ();
+ sink->mrl_check_done = FALSE;
+ sink->main_run_loop_running = FALSE;
sink->app_started = FALSE;
sink->keep_par = FALSE;
}
@@ -490,6 +540,12 @@ gst_osx_video_sink_finalize (GObject *object)
if (osxvideosink->osxvideosinkobject)
[(GstOSXVideoSinkObject*)(osxvideosink->osxvideosinkobject) release];
+ if (osxvideosink->mrl_check_lock)
+ g_mutex_free (osxvideosink->mrl_check_lock);
+
+ if (osxvideosink->mrl_check_cond)
+ g_cond_free (osxvideosink->mrl_check_cond);
+
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -891,6 +947,13 @@ gst_osx_video_sink_get_type (void)
}
#endif
+-(void) checkMainRunLoop
+{
+ g_mutex_lock(osxvideosink->mrl_check_lock);
+ g_cond_signal(osxvideosink->mrl_check_cond);
+ g_mutex_unlock(osxvideosink->mrl_check_lock);
+}
+
@end
@ implementation GstBufferObject