[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