[xiph-commits] r2995 - liboggplay/trunk/plugin

tahn at svn.annodex.net tahn at svn.annodex.net
Mon Jun 18 23:10:08 PDT 2007


Author: tahn
Date: 2007-06-18 23:10:08 -0700 (Mon, 18 Jun 2007)
New Revision: 2995

Modified:
   liboggplay/trunk/plugin/plugin.cpp
   liboggplay/trunk/plugin/plugin.h
Log:
The Mac doesn't like cross-thread calls between the browser and the plugin, so we need to store CMML data as the gui display thread extracts it, then pass it back using the browser-originated HandleEvent function.


Modified: liboggplay/trunk/plugin/plugin.cpp
===================================================================
--- liboggplay/trunk/plugin/plugin.cpp	2007-06-19 06:06:06 UTC (rev 2994)
+++ liboggplay/trunk/plugin/plugin.cpp	2007-06-19 06:10:08 UTC (rev 2995)
@@ -238,10 +238,14 @@
   mCallback(NULL)
 #if defined(XP_MACOSX)
   ,
-  mOutputCleared(FALSE)
+  mOutputCleared(FALSE),
+  mCmmlDataProvided(FALSE)
 #endif
 {
   mString[0] = '\0';
+#if defined(XP_MACOSX)
+  pthread_mutex_init(&mCmmlMutex, NULL);
+#endif
 }
 
 nsPluginInstance::~nsPluginInstance()
@@ -254,6 +258,9 @@
     mScriptablePeer->SetInstance(NULL);
     NS_IF_RELEASE(mScriptablePeer);
   }
+#if defined(XP_MACOSX)
+  pthread_mutex_destroy(&mCmmlMutex);
+#endif
 }
 
 NPBool 
@@ -347,14 +354,25 @@
 void
 nsPluginInstance::onCMMLData(char **cmml_data, int cmml_size) {
 
-  int i;
-
   if (mCallback != NULL) {
-    for (i = 0; i < cmml_size; i++) {
+#if defined(XP_MACOSX)
+    // The Mac doesn't like cross-thread calls between the plugin and
+    // the browser. We need to execute the cmml callback in the main browser
+    // thread, but this function is called from the GUI display thread. So we
+    // buffer up the cmml strings here and piggyback on the browser-originated
+    // calls to HandleEvent below to send the strings to the browser.
+    pthread_mutex_lock(&mCmmlMutex);
+    for (int i = 0; i < cmml_size; i++) {
+      mCmmlStrings.push_back(cmml_data[i]);
+    }
+    mCmmlDataProvided = TRUE;
+    pthread_mutex_unlock(&mCmmlMutex);
+#else
+    for (int i = 0; i < cmml_size; i++) {
       mCallback->CmmlCallback(cmml_data[i]);
     }
+#endif
   }
-
 }
 
 extern "C" void 
@@ -463,15 +481,31 @@
 #if defined(XP_MACOSX)
   NPEvent * event = (NPEvent *)aEvent;
 
+  // The browser sends a constant stream of events to this function, most of
+  // which are the null event. While this is not exactly efficient, it does
+  // turn out to be useful for a couple of things.
+  //
+  // First, to send the cmml strings collected by onCMMLData to the browser..
+  if (mCmmlDataProvided) {
+    pthread_mutex_lock(&mCmmlMutex);
+    for (unsigned int i = 0; i < mCmmlStrings.size(); i++) {
+      mCallback->CmmlCallback(mCmmlStrings[i]);
+    }
+    mCmmlStrings.clear();
+    mCmmlDataProvided = FALSE;
+    pthread_mutex_unlock(&mCmmlMutex);
+  }
+
+  // ..and second, to handle hiding our output when the user changes tabs or
+  // scrolls the media off the page.
+  //
   // As per the comment in SetWindow, we want to update our clip region when
   // we receive an update event. This is complicated by the fact that our output
   // needs to be hidden when the user changes tabs, and the browser does this by
   // passing us a zero-sized clip in a SetWindow call -- which we're ignoring.
   // We can't distinguish between a spurious zero-clip-SetWindow and a real one,
-  // and we don't receive an update event for a tab change. "Luckily", the
-  // browser sends us a constant stream of null events (even when the user is
-  // not doing anything), so we can use that to detect the first zero-clip and
-  // hide our output accordingly.
+  // and we don't receive an update event for a tab change. So we need to detect
+  // the first null event with a zero-clip and hide our output accordingly.
   switch (event->what) {
     case nullEvent:
       if (mWindow->clipRect.right <= mWindow->clipRect.left ||

Modified: liboggplay/trunk/plugin/plugin.h
===================================================================
--- liboggplay/trunk/plugin/plugin.h	2007-06-19 06:06:06 UTC (rev 2994)
+++ liboggplay/trunk/plugin/plugin.h	2007-06-19 06:10:08 UTC (rev 2995)
@@ -47,6 +47,11 @@
 #include <gtk/gtk.h>
 #endif
  
+#if defined(XP_MACOSX)
+#include <pthread.h>
+#include <vector>
+#endif
+ 
 class nsPluginInstance : public nsPluginInstanceBase
 {
 public:
@@ -109,6 +114,9 @@
   WNDPROC             lpOldProc;  
 #elif defined(XP_MACOSX)
   NPBool              mOutputCleared;
+  volatile NPBool     mCmmlDataProvided;
+  pthread_mutex_t     mCmmlMutex;
+  std::vector<char*>  mCmmlStrings;
 #endif
 
 public:



More information about the commits mailing list