[xiph-commits] r3028 - in liboggplay/trunk/plugin: . test win32

laser13 at svn.annodex.net laser13 at svn.annodex.net
Sun Jun 24 03:29:05 PDT 2007


Author: laser13
Date: 2007-06-24 03:29:05 -0700 (Sun, 24 Jun 2007)
New Revision: 3028

Modified:
   liboggplay/trunk/plugin/plugin.cpp
   liboggplay/trunk/plugin/plugin.h
   liboggplay/trunk/plugin/plugin_gui_win32.c
   liboggplay/trunk/plugin/plugin_oggplay.c
   liboggplay/trunk/plugin/test/test.html
   liboggplay/trunk/plugin/win32/liboggplugin.rc
   liboggplay/trunk/plugin/win32/resource.h
Log:
CMML support for Win32 with no audio in the plugin. Audio will follow. A couple of clean up changes to get Win32 and MACOSX CMML callbacks handling. Plus some minor fixes in main plugin file.

Modified: liboggplay/trunk/plugin/plugin.cpp
===================================================================
--- liboggplay/trunk/plugin/plugin.cpp	2007-06-24 07:47:21 UTC (rev 3027)
+++ liboggplay/trunk/plugin/plugin.cpp	2007-06-24 10:29:05 UTC (rev 3028)
@@ -21,7 +21,7 @@
  * Portions created by the Initial Developer are Copyright (C) 1998
  * the Initial Developer. All Rights Reserved.
  *
- * Contributor(s): Shane Stephens (CSIRO), Michael Martin
+ * Contributor(s): Shane Stephens (CSIRO), Michael Martin, Marcin Lubonski
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -46,6 +46,7 @@
 
 #include <windows.h>
 #include <windowsx.h>
+#include <resource.h>
 #ifdef NDEBUG
 #pragma warning ( disable : 4311 ) // pointer truncation
 #pragma warning ( disable : 4312 ) // conversion to type of greater size
@@ -70,6 +71,14 @@
 
 #define PLUGIN_VERSION    "1.0"
 
+#if defined (XP_WIN)
+// polling period for plugin timer
+#define POLLING_PERIOD 10
+
+static VOID CALLBACK
+PluginCallbackProc(HWND hWnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime);
+#endif
+
 #if defined(XP_UX) || defined(XP_MACOSX)
 
 #define MIME_TYPES_HANDLED      "application/liboggplay"
@@ -222,6 +231,10 @@
 #if defined(XP_MACOSX)
   ,
   mOutputCleared(FALSE)
+#elif defined (XP_WIN)
+  ,
+  mPollingStarted(false),
+  mPollingPeriod(POLLING_PERIOD)
 #endif
 {
   mString[0] = '\0';
@@ -249,14 +262,22 @@
   if (mEndPlayCallback != NULL) {
     NS_RELEASE(mEndPlayCallback);
   }
+
+#if defined(XP_WIN)
+  if (this->mPollingStarted == true) {
+    KillTimer((HWND)mWindow->window, IDT_CALLBACK_TIMER);     
+  }
+#endif
+
   SEM_CLOSE(mCmmlSem);
   SEM_CLOSE(mEndPlaySem);
-#if defined(XP_MACOSX)
+#if defined(XP_MACOSX) || defined(XP_WIN)
   clearCmmlStrings();
 #endif
+
 }
 
-#if defined(XP_MACOSX)
+#if defined(XP_MACOSX) || defined (XP_WIN)
 void
 nsPluginInstance::clearCmmlStrings() {
   for (unsigned int i = 0; i < mCmmlStrings.size(); i++) {
@@ -320,8 +341,7 @@
   // in HandleEvent with the correct clip. Therefore, we want to ignore the
   // SetWindow calls and only update the clip size in the event handler.
   // -- MAC OS X SPECIFIC -
-  if (mWindowInitialised == FALSE) {
- 
+  if (mWindowInitialised == FALSE) {    
     if (getSource() == NULL) {
       return NPERR_NO_ERROR;
     }
@@ -334,11 +354,23 @@
     mGuiHandle = initialise_gui(this, aWindow, mOggHandle);
     mWindow = aWindow;
     mWindowInitialised = TRUE;
+
+#if defined(XP_WIN)
+    HWND hWnd;
+    // set callback data timer on main browser window
+    // and pass pointer to the plugin object instance 
+    // to the callback handler procedure
+    NPN_GetValue(mInstance, NPNVnetscapeWindow, &hWnd);
+    SetWindowLongPtr((HWND)hWnd, GWL_USERDATA, (LONG)this);
+    SetTimer((HWND)hWnd, IDT_CALLBACK_TIMER, mPollingPeriod,(TIMERPROC)PluginCallbackProc); 
+    mPollingStarted = true;
+#endif
   }
 
   return NPERR_NO_ERROR;
 }
 
+
 NPError nsPluginInstance::NewStream(NPMIMEType type, NPStream* stream, NPBool seekable, uint16* stype)
 {
   printf("URL %s for this Mime-Type %s\n", (char*)type, stream->url);
@@ -350,7 +382,7 @@
  */
 uint16 
 nsPluginInstance::HandleEvent(void *aEvent)
-{
+{  
 #if defined(XP_MACOSX)
   NPEvent * event = (NPEvent *)aEvent;
 
@@ -358,20 +390,8 @@
   // 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..
-  // (since this function is called very frequently, we don't want to grab
-  // the semaphore every time, but checking the pointer for null before locking
-  // introduces a potential race condition, so we need to double-check).
-  if (mCmmlCallback != NULL) {
-    SEM_WAIT(mCmmlSem);
-    if (mCmmlCallback != NULL && mCmmlStrings.size() > 0) {
-      for (unsigned int i = 0; i < mCmmlStrings.size(); i++) {
-        mCmmlCallback->Call(mCmmlStrings[i]);
-      }
-      clearCmmlStrings();
-    }
-    SEM_CLOSE(mCmmlSem);
-  }
+  // First, to send the cmml strings collected by onCMMLData to the browser..  
+  executeCmmlCallback();
 
   // ..and second, to handle hiding our output when the user changes tabs or
   // scrolls the media off the page.
@@ -401,7 +421,6 @@
       break;
   }
 #endif
-
   return 1;
 }
 
@@ -629,15 +648,20 @@
 nsPluginInstance::onCMMLData(char **cmml_data, int cmml_size) {
   SEM_WAIT(mCmmlSem);
   if (mCmmlCallback != NULL) {
-#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
+#if defined(XP_MACOSX) || (XP_WIN)   
+    // The Mac and Windows don't like cross-thread calls between the GUI thread and
+    // the plugin/browser thread. 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 to send the strings to the browser. We need to make
-    // copies of the strings because the oggplay frame can be freed before we
-    // get in to HandleEvent.
-    for (int i = 0; i < cmml_size; i++) {
+    // buffer up the cmml strings here.
+    // [MACOSX]
+    //   On Mac we piggyback on the browser-originated calls to HandleEvent to send the strings 
+    //   to the browser. 
+    // [Win32]
+    //   On Windows we use a timer introduced to provide an artificial heartbeat 
+    //   similar to ongoing event processing on Mac.    
+    // We need to make copies of the strings because the oggplay frame can be freed before we
+    // get in to HandleEvent (Mac) or timer handler funtion (Win32).
+    for (int i = 0; i < cmml_size; i++) {      
       mCmmlStrings.push_back(strdup(cmml_data[i]));
     }
 #else
@@ -658,18 +682,50 @@
   SEM_SIGNAL(mEndPlaySem);
 }
 
+void 
+nsPluginInstance::executeCmmlCallback() {
+  // (since this function is called very frequently, we don't want to grab
+  // the semaphore every time, but checking the pointer for null before locking
+  // introduces a potential race condition, so we need to double-check).  
+  if (mCmmlCallback != NULL) {    
+    SEM_WAIT(mCmmlSem);
+    if (mCmmlCallback != NULL && mCmmlStrings.size() > 0) {
+      for (unsigned int i = 0; i < mCmmlStrings.size(); i++) {
+        //printf("Sending CMML to Javascript: %s\n", mCmmlStrings[i]);
+        mCmmlCallback->Call(mCmmlStrings[i]);
+      }
+      clearCmmlStrings();
+    }    
+    SEM_SIGNAL(mCmmlSem);
+  }  
+}
+
+#if defined(XP_WIN)
+VOID CALLBACK
+PluginCallbackProc(HWND hWnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) {    
+  nsPluginInstance * plugin = NULL;
+  
+  plugin = (nsPluginInstance *)GetWindowLongPtr(hWnd, GWL_USERDATA);  
+  plugin->executeCmmlCallback();
+}
+#endif
+
 extern "C" {
 void
-onCMMLData(nsPluginInstance *i, char **cmml_data, int cmml_size) {
-  i->onCMMLData(cmml_data, cmml_size);
+onCMMLData(nsPluginInstance *i, char **cmml_data, int cmml_size) {  
+  i->onCMMLData(cmml_data, cmml_size);  
 }
 
 void
 onEndPlay(nsPluginInstance *i) {
   i->onEndPlay();
 }
+
 } // extern "C"
 
+
+
+
 /* //!todo
 void
 nsPluginInstance::setPlaylistCallback(const char *callback) {

Modified: liboggplay/trunk/plugin/plugin.h
===================================================================
--- liboggplay/trunk/plugin/plugin.h	2007-06-24 07:47:21 UTC (rev 3027)
+++ liboggplay/trunk/plugin/plugin.h	2007-06-24 10:29:05 UTC (rev 3028)
@@ -47,8 +47,8 @@
 #include <X11/Intrinsic.h>
 #include <gtk/gtk.h>
 #endif
- 
-#if defined(XP_MACOSX)
+
+#if defined(XP_MACOSX) || defined(XP_WIN)
 #include <vector>
 #endif
  
@@ -72,10 +72,18 @@
   NPError NewStream(NPMIMEType type, NPStream* stream,  
 			NPBool seekable, uint16* stype);    
 
+// FIX ME: this method seem not to be implemented at all!!!
 #if defined(XP_UX)
   void redraw(Widget widget, XtPointer call_data);
 #endif
 
+#if defined (XP_MACOSX) || defined(XP_WIN)
+  // wrapper method (for MACOSX and Win32 only)   
+  // this is used only in Win32 and MACOSX version of the plugin
+  // to pass back CMML callback and associated data to Javascript  
+  void executeCmmlCallback();
+#endif
+
   nsScriptablePeer* getScriptablePeer();
 
   // Javascript API
@@ -109,7 +117,7 @@
   void setMovieAt(int position, const char *url);
   void appendMovie(const char *url); 
 */
-
+ 
 private:
   void    setSource(const char *source);
   char  * getSource();
@@ -121,7 +129,7 @@
   nsScriptablePeer  * mScriptablePeer;
   void              * mOggHandle;
   void              * mGuiHandle;
-  char              * mSource;
+  char              * mSource;  
 
   nsILibOggCallbackString   * mCmmlCallback;
   nsILibOggCallbackNoArg    * mEndPlayCallback;
@@ -129,10 +137,14 @@
   semaphore                   mEndPlaySem;
 
 #if defined(XP_WIN)
-  WNDPROC             lpOldProc;  
+  WNDPROC             lpOldProc;
+  bool                mPollingStarted;
+  UINT                mPollingPeriod;  
+  std::vector<char*>  mCmmlStrings;
+  void clearCmmlStrings();
 #elif defined(XP_MACOSX)
   NPBool              mOutputCleared;
-  std::vector<char*>  mCmmlStrings;
+  std::vector<char*>  mCmmlStrings;    
   void clearCmmlStrings();
 #endif
 

Modified: liboggplay/trunk/plugin/plugin_gui_win32.c
===================================================================
--- liboggplay/trunk/plugin/plugin_gui_win32.c	2007-06-24 07:47:21 UTC (rev 3027)
+++ liboggplay/trunk/plugin/plugin_gui_win32.c	2007-06-24 10:29:05 UTC (rev 3028)
@@ -54,13 +54,13 @@
   HWND                window;
   HWND                parent_window;
   WNDPROC             old_wnd_proc;
-  HANDLE              thread;
+  HANDLE              thread;  
   int                 shutdown_gui;
   void            *   ogg_handle;
   semaphore           oggplay_replace_sem;
   semaphore           start_stop_sem;
   semaphore           playback_sem;
-  semaphore           synch_sem;
+  semaphore           synch_sem;  
   PluginPlaybackState   playback_state;
   void            *   new_oggplay_handle;
 #ifdef USE_AUDIO
@@ -95,8 +95,10 @@
 DWORD WINAPI display_thread(void *_info) {  
   HWND                hWnd;  
   RECT                r;
-  PluginWindowInfo *  info = (PluginWindowInfo*)_info;  
+  BOOL                has_cmml;
+  PluginWindowInfo *  info = (PluginWindowInfo*)_info;    
   
+
   info->shutdown_gui = 0;
   hWnd = (HWND)(info->window);
   /* signal that thread has been started sucessfully */
@@ -123,7 +125,12 @@
       // force refresh    
       GetClientRect(hWnd, &r);      
       InvalidateRect(hWnd, &r, FALSE);     
-      UpdateWindow(hWnd);      
+      UpdateWindow(hWnd); 
+      has_cmml = ((info->frame_data->cmml_strings != NULL) && (info->frame_data->cmml_size > 0)) ? TRUE : FALSE;
+      if (has_cmml == TRUE) {
+        onCMMLData(info->plugin_instance, info->frame_data->cmml_strings, info->frame_data->cmml_size);      
+      }
+      free_oggplay_frame(info->ogg_handle, info->frame_data); 
       SEM_WAIT(info->synch_sem);
     }      
     
@@ -143,7 +150,7 @@
  * Comments: Fuction notifies the display
  * */
 void *
-initialise_gui(HWND parent_window, nsPluginInstance *instance, NPWindow *np_window, 
+initialise_gui(nsPluginInstance *instance, NPWindow *np_window, 
                 void *oggplay_handle) {
   
   DWORD                 disp_id;
@@ -153,8 +160,7 @@
   /* allocate structure */     
   info = (PluginWindowInfo*)malloc(sizeof(PluginWindowInfo));
   info->width = np_window->width;
-  info->height = np_window->height;
-  info->plugin_instance = instance;
+  info->height = np_window->height;  
   info->ogg_handle = oggplay_handle;
   info->frame_data = (PluginOggFrame*)malloc(sizeof(PluginOggFrame));
   info->frame_data->frame = NULL;
@@ -165,8 +171,8 @@
   info->new_oggplay_handle = NULL;
   info->playback_state = PLAYING;
   /* calback members initialisation */
-  info->plugin_instance = NULL;
-
+  info->plugin_instance = instance;
+  
   /*
    * create semaphore to lock replacement of oggplay object
    */
@@ -230,7 +236,7 @@
 
   SEM_CLOSE(info->start_stop_sem);  
   SEM_CLOSE(info->oggplay_replace_sem);  
-  SEM_CLOSE(info->playback_sem);
+  SEM_CLOSE(info->playback_sem);  
 
   if (info->frame_data != NULL) {
     free(info->frame_data);  
@@ -338,7 +344,7 @@
   has_cmml = ((info->frame_data->cmml_strings != NULL) && (info->frame_data->cmml_size > 0)) ? TRUE : FALSE;
   
   /* if there is need to update plugin GUI then go to next frame */
-  if ((has_video == FALSE) && (has_audio == FALSE)
+  if ((has_video == TRUE) && (has_audio == TRUE)
     /* && (has_cmml) */
   ) {
     SEM_SIGNAL(info->synch_sem);
@@ -348,15 +354,15 @@
   /* display frame */
   update_frame(info);
 
-  /* call CMML data callback using plugin's main thread call */
-  if (has_cmml == TRUE) {    
+  /* call CMML data callback using plugin's main thread call 
+  if (has_cmml == true) {    
     onCMMLData(info->plugin_instance, info->frame_data->cmml_strings, info->frame_data->cmml_size);      
-  }          
+  }*/
 
 //cleanup:
   SEM_SIGNAL(info->synch_sem);
   // progress with decoding  
-  free_oggplay_frame(info->ogg_handle, info->frame_data);  
+  //free_oggplay_frame(info->ogg_handle, info->frame_data);  
   return;
 }
 
@@ -369,7 +375,7 @@
   PluginWindowInfo * info = NULL;
   switch (msg) {
     case WM_PAINT:      
-      info = (PluginWindowInfo*)GetWindowLongPtr(hWnd, GWL_USERDATA);
+      info = (PluginWindowInfo*)GetWindowLongPtr(hWnd, GWL_USERDATA);      
       process_frame_data(info);
       break;
     case WM_CLOSE :      

Modified: liboggplay/trunk/plugin/plugin_oggplay.c
===================================================================
--- liboggplay/trunk/plugin/plugin_oggplay.c	2007-06-24 07:47:21 UTC (rev 3027)
+++ liboggplay/trunk/plugin/plugin_oggplay.c	2007-06-24 10:29:05 UTC (rev 3028)
@@ -53,6 +53,7 @@
 #include "plugin_tools.h"
 
 #define LIBOGGPLAY_BUFFER_SIZE 20
+#define AUDIO_TRACK_OFFSET 250L
 
 #include <npapi.h>
 #include <math.h>
@@ -171,13 +172,13 @@
 #ifdef USE_AUDIO
     } else if (oggplay_get_track_type (player, i) == OGGZ_CONTENT_VORBIS) {
       oggplay_set_track_active(player, i);
-      oggplay_set_offset(player, i, 250L);
+      oggplay_set_offset(player, i, AUDIO_TRACK_OFFSET);
       oggplay_get_audio_samplerate(player, i, &(pointers->audio_rate));
       oggplay_get_audio_channels(player, i, &(pointers->audio_channels));
       audio_track = i;
     } else if (oggplay_get_track_type (player, i) == OGGZ_CONTENT_SPEEX) {
       oggplay_set_track_active(player, i);
-      oggplay_set_offset(player, i, 250L);
+      oggplay_set_offset(player, i, AUDIO_TRACK_OFFSET);
       oggplay_get_audio_samplerate(player, i, &(pointers->audio_rate));
       oggplay_get_audio_channels(player, i, &(pointers->audio_channels));
       audio_track = i;
@@ -208,7 +209,7 @@
     
    
     r = E_OGGPLAY_TIMEOUT;
-    while (r == E_OGGPLAY_TIMEOUT) {
+    while (r == E_OGGPLAY_TIMEOUT) {      
       if (pointers->shutdown_oggplay) {
         goto thread_shutdown;
       }

Modified: liboggplay/trunk/plugin/test/test.html
===================================================================
--- liboggplay/trunk/plugin/test/test.html	2007-06-24 07:47:21 UTC (rev 3027)
+++ liboggplay/trunk/plugin/test/test.html	2007-06-24 10:29:05 UTC (rev 3028)
@@ -179,6 +179,7 @@
 
 function showCMML(data) {
   /* clear the old CMML clip */
+  output.value = data; 
   var element = document.getElementById("cmml");
   while (element.firstChild != null) {
     element.removeChild(element.firstChild);

Modified: liboggplay/trunk/plugin/win32/liboggplugin.rc
===================================================================
--- liboggplay/trunk/plugin/win32/liboggplugin.rc	2007-06-24 07:47:21 UTC (rev 3027)
+++ liboggplay/trunk/plugin/win32/liboggplugin.rc	2007-06-24 10:29:05 UTC (rev 3028)
@@ -27,8 +27,8 @@
 //
 
 VS_VERSION_INFO VERSIONINFO
- FILEVERSION 1,0,0,1
- PRODUCTVERSION 1,0,0,1
+ FILEVERSION 1,0,0,0
+ PRODUCTVERSION 1,0,0,0
  FILEFLAGSMASK 0x3fL
 #ifdef _DEBUG
  FILEFLAGS 0x1L
@@ -47,13 +47,13 @@
             VALUE "FileDescription", "npliboggplugin"
             VALUE "FileExtents", "scr"
             VALUE "FileOpenName", "npliboggplugin"
-            VALUE "FileVersion", "1, 0, 0, 1"
+            VALUE "FileVersion", "1, 0, 0, 0"
             VALUE "InternalName", "npliboggplugin"
             VALUE "LegalCopyright", "Copyright CSIRO © 2007"
             VALUE "MIMEType", "application/liboggplay"
             VALUE "OriginalFilename", "npliboggplugin.dll"
-            VALUE "ProductName", "Vorbis/Theora OGG Player Plugin for Mozilla"
-            VALUE "ProductVersion", "1, 0, 0, 1"
+            VALUE "ProductName", "Liboggplay Annodex Media Plugin"
+            VALUE "ProductVersion", "1, 0, 0, 0"
         END
     END
     BLOCK "VarFileInfo"

Modified: liboggplay/trunk/plugin/win32/resource.h
===================================================================
--- liboggplay/trunk/plugin/win32/resource.h	2007-06-24 07:47:21 UTC (rev 3027)
+++ liboggplay/trunk/plugin/win32/resource.h	2007-06-24 10:29:05 UTC (rev 3028)
@@ -18,3 +18,6 @@
 #define _APS_NEXT_SYMED_VALUE           101
 #endif
 #endif
+
+#define IDT_CALLBACK_TIMER                   12001
+



More information about the commits mailing list