[xiph-commits] r3482 - in browser_plugin/trunk: . src

j at svn.annodex.net j at svn.annodex.net
Sun Feb 17 21:20:34 PST 2008


Author: j
Date: 2008-02-17 21:20:34 -0800 (Sun, 17 Feb 2008)
New Revision: 3482

Modified:
   browser_plugin/trunk/configure.ac
   browser_plugin/trunk/src/Makefile.am
   browser_plugin/trunk/src/plugin_gui_linux.c
Log:
* port linux gui to use new sydney api
* switch sydney backend from oss to alsa



Modified: browser_plugin/trunk/configure.ac
===================================================================
--- browser_plugin/trunk/configure.ac	2008-02-18 05:19:07 UTC (rev 3481)
+++ browser_plugin/trunk/configure.ac	2008-02-18 05:20:34 UTC (rev 3482)
@@ -56,6 +56,13 @@
 AC_SUBST(IMLIB2_CFLAGS)
 
 dnl
+dnl  Detect alsa
+dnl
+PKG_CHECK_MODULES(ALSA, alsa)
+AC_SUBST(ALSA_CFLAGS)
+AC_SUBST(ALSA_LIBS)
+
+dnl
 dnl Detect Firefox (needed for the linux plugin)
 dnl
 PKG_CHECK_MODULES(FIREFOX, firefox-plugin firefox-xpcom firefox-nspr firefox-nss nspr nss)

Modified: browser_plugin/trunk/src/Makefile.am
===================================================================
--- browser_plugin/trunk/src/Makefile.am	2008-02-18 05:19:07 UTC (rev 3481)
+++ browser_plugin/trunk/src/Makefile.am	2008-02-18 05:20:34 UTC (rev 3482)
@@ -15,7 +15,7 @@
 			-g $(SSE2_CFLAGS) -Wno-strict-aliasing $(OGGZ_CFLAGS) $(OGGPLAY_CFLAGS)
 AM_CFLAGS = -Wall -Werror -DXP_UX -DMOZ_X11 -DUSE_AUDIO -shared \
 			-g $(SSE2_CFLAGS) -Wno-strict-aliasing $(OGGZ_CFLAGS) \
-			$(IMLIB2_CFLAGS) $(OGGPLAY_CFLAGS) -Wdeclaration-after-statement
+			$(ALSA_CFLAGS) $(IMLIB2_CFLAGS) $(OGGPLAY_CFLAGS) -Wdeclaration-after-statement
 
 
 INCLUDES=-I$(srcdir)/include -I$(srcdir)/support -I$(srcdir)/audio @GTK_CFLAGS@ @FIREFOX_CFLAGS@
@@ -50,12 +50,12 @@
 	support/npp_gate.cpp			\
 	support/np_entry.cpp			\
 	support/npn_gate.cpp			\
-	audio/sydney_audio_oss.c		\
+	audio/sydney_audio_alsa.c		\
 	plugin_cmml.c
-libnpoggplugin_la_LIBADD = -lX11 -lXt $(LIBOGGPLAY_STATICLIBS) $(PTHREAD_LIBS)
+libnpoggplugin_la_LIBADD = -lX11 -lXt $(LIBOGGPLAY_STATICLIBS) $(PTHREAD_LIBS) ${ALSA_LIBS}
 
 libnpoggplugin_dynamic_la_SOURCES = $(libnpoggplugin_la_SOURCES)
-libnpoggplugin_dynamic_la_LIBADD = -lX11 -lXt $(LIBOGGPLAY_LIBS) $(IMLIB2_LIBS) $(PTHREAD_LIBS)
+libnpoggplugin_dynamic_la_LIBADD = -lX11 -lXt $(LIBOGGPLAY_LIBS) $(ALSA_LIBS) $(IMLIB2_LIBS) $(PTHREAD_LIBS)
 
 EXTRA_libnpoggplugin_la_SOURCES = nsILibOggPlugin.idl
 nodist_libnpoggplugin_la_SOURCES = nsILibOggPlugin.h

Modified: browser_plugin/trunk/src/plugin_gui_linux.c
===================================================================
--- browser_plugin/trunk/src/plugin_gui_linux.c	2008-02-18 05:19:07 UTC (rev 3481)
+++ browser_plugin/trunk/src/plugin_gui_linux.c	2008-02-18 05:20:34 UTC (rev 3482)
@@ -30,7 +30,7 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
- * ***** END LICENSE BLOCK ***** */  
+ * ***** END LICENSE BLOCK ***** */
 
 #include <pthread.h>
 #include "std_semaphore.h"
@@ -50,8 +50,11 @@
 #include <oggplay/oggplay_tools.h>
 #include "plugin_tools.h"
 
-#include "sydney_audio.h"
+#include "sydney_audio_new.h"
 
+#define OGGPLAY_FRAME_SKIP_OFFSET -30
+#define OGGPLAY_MIN_OFFSET        3
+
 typedef struct {
   int                   width;
   int                   height;
@@ -63,67 +66,66 @@
   semaphore             oggplay_replace_sem;
   semaphore             start_stop_sem;
   PluginPlaybackState   playback_state;
+  int64_t               playback_target;
   int                   playback_finished;
   void                * new_oggplay_handle;
-  SAAudioHandle       * audio_handle;
+  sa_stream_t         * audio_handle;
   gboolean	            audio_opened;
-  gboolean	            tried_audio;
-  int64_t               playback_target;
-  nsPluginInstance    * pluginInstance;
   float                 volume;
+  nsPluginInstance    * pluginInstance;
  } PluginWindowInfo;
 
 void
 open_audio(PluginWindowInfo *info) {
-  int err;
-
   info->audio_opened = TRUE;
   info->playback_target = 0;
-
-  err = sa_device_create_pcm(&(info->audio_handle), "Mozilla Plugin", 
-                  SA_PCM_WRONLY, SA_PCM_S16_LE, 
-                  get_audio_rate(info->ogg_handle), 
-                  get_audio_channels(info->ogg_handle));
-  
-  if (err) {
+  if (sa_stream_create_pcm(&(info->audio_handle),
+                  "liboggplay browser plugin",
+                  SA_MODE_WRONLY,
+                  SA_PCM_FORMAT_S16_LE,
+                  get_audio_rate(info->ogg_handle),
+                  get_audio_channels(info->ogg_handle)) != SA_SUCCESS
+  ) {
   	info->audio_opened = FALSE;
+    info->audio_handle = NULL;
     return;
-  } 
+  }
 
-  err = sa_device_open(info->audio_handle);
-  if (err) {
+  if (sa_stream_open(info->audio_handle) != SA_SUCCESS) {
+    sa_stream_destroy(info->audio_handle);
   	info->audio_opened = FALSE;
-    info->playback_target = oggplay_sys_time_in_ms() << 16; 
+    info->audio_handle = NULL;
     return;
-  } 
+  }
   return;
 }
 
 void
 close_audio(PluginWindowInfo *info) {
-  if (info->audio_opened == TRUE)
-    sa_device_close(info->audio_handle);
-  info->audio_opened = FALSE;
-  info->tried_audio = FALSE;
+  if (info->audio_handle != NULL) {
+    sa_stream_destroy(info->audio_handle);
+    info->audio_handle = NULL;
+    info->audio_opened = FALSE;
+    info->playback_target = 0;
+    printf("Audio device closed\n");
+  }
 }
 
-int maybe_switch_oggplays(PluginWindowInfo *info) {
+int switch_oggplays(PluginWindowInfo *info) {
 
   void * old_ogg_handle;
-  
+
   if (info->new_oggplay_handle != NULL) {
-    
     SEM_WAIT(info->oggplay_replace_sem);
     old_ogg_handle = info->ogg_handle;
     info->ogg_handle = (void *)info->new_oggplay_handle;
     info->new_oggplay_handle = NULL;
     info->playback_finished = FALSE;
     close_audio(info);
-    SEM_SIGNAL(info->oggplay_replace_sem); 
+    SEM_SIGNAL(info->oggplay_replace_sem);
     shut_oggplay(old_ogg_handle);
     return TRUE;
   }
-  
   return FALSE;
 }
 
@@ -132,19 +134,13 @@
   Imlib_Image image;
 
   convert_oggplay_frame(info->ogg_handle, frame_data, BGR);
-  image = imlib_create_image_using_data(frame_data->width, 
+  image = imlib_create_image_using_data(frame_data->width,
                     frame_data->height, (unsigned int *)frame_data->frame);
   imlib_context_set_image(image);
   imlib_render_image_on_drawable_at_size(0, 0, info->width, info->height);
   imlib_free_image_and_decache();
 }
 
-
-#define OGGPLAY_FRAME_SKIP_OFFSET -30
-#define OGGPLAY_MIN_OFFSET        2
-
-
-
 gboolean
 update_frame(gpointer _info) {
 
@@ -152,24 +148,23 @@
   int64_t             offset;
   PluginOggFrame      frame_data;
   int64_t 	          bytes;
-  int64_t             cur_time;
+  int64_t             ref_time;
 
   frame_data.frame = NULL;
   frame_data.samples = NULL;
   frame_data.cmml_strings = NULL;
   frame_data.size = 0;
 
-  maybe_switch_oggplays(info);
-
+  switch_oggplays(info);
   /*
    * if we are paused, then don't do anything
    */
   if (info->playback_state == PAUSED || info->playback_finished) {
+    sa_stream_pause(info->audio_handle);
     return TRUE;
   }
 
   get_oggplay_frame(info->ogg_handle, &frame_data);
-
   switch (get_oggplay_stream_info(info->ogg_handle, &frame_data)) {
     case OGGPLAY_STREAM_JUST_SEEKED:
       close_audio(info);
@@ -185,85 +180,73 @@
       break;
   }
 
-  if (frame_data.video_data != NULL) {    
-    render_frame_to_screen(info, &frame_data);
-  } else if (frame_data.samples == NULL) {
+  /* if there is need to update plugin GUI then go to next frame */
+  if (frame_data.video_data == NULL && frame_data.samples == NULL) {
     return TRUE;
   }
 
-  if (info->tried_audio == FALSE) {
-    info->tried_audio = TRUE;
-    if (frame_data.samples != NULL) {
+  if (frame_data.video_data != NULL) {
+    render_frame_to_screen(info, &frame_data);
+  }
+
+  /* below: audio, timing calculations and frame skipping */
+calc_offset:
+
+  if (frame_data.samples != NULL) {
+    if (info->audio_opened == FALSE) {
       open_audio(info);
-    } else {
-      info->playback_target = oggplay_sys_time_in_ms() << 16; 
     }
+
+    if (info->audio_opened == TRUE) {
+      /* apply volume */
+      if (frame_data.size > 0 && info->volume < 1.0) {
+        short * samples = (short *)frame_data.samples;
+        int     i;
+        for (i = 0; i < frame_data.size/sizeof(short); i ++) {
+          samples[i] *= info->volume;
+        }
+      }
+    	/* wirte audio */
+    	if (sa_stream_write(info->audio_handle, frame_data.samples,
+    	              frame_data.size) != SA_SUCCESS) {
+        /* can't write data */
+        close_audio(info);
+      }
+    }
   }
 
-  if (frame_data.cmml_strings != NULL) {      
-      onCMMLData(info->pluginInstance, frame_data.cmml_strings, 
+  /* call CMML data callback using plugin's main thread call */
+  if (frame_data.cmml_strings != NULL) {
+      onCMMLData(info->pluginInstance, frame_data.cmml_strings,
                       frame_data.cmml_size, 0);
   }
 
-calc_offset:
-  
   if (info->audio_opened == TRUE) {
-    /* apply volume */
-    if (frame_data.size > 0 && info->volume < 1.0) {
-      short * samples = (short *)frame_data.samples;
-      int     i;
-      for (i = 0; i < frame_data.size/sizeof(short); i ++) {
-        samples[i] *= info->volume;
-      }
-    }
-
-    if (frame_data.size == 0) {
-      /* no audio */
-  	  cur_time = oggplay_sys_time_in_ms();	
-      info->playback_target = (cur_time << 16);
-      close_audio(info);
-    }
-
-  	/* buffer audio */
-  	if 
-    (
-      frame_data.size > 0 
-      && 
-      sa_device_write(info->audio_handle, frame_data.size, 
-        frame_data.samples) > 0
-    ) 
-    {
-      /* can't write data */
-  	  cur_time = oggplay_sys_time_in_ms();	
-      info->playback_target = cur_time;
-      close_audio(info);
-	  } 
-    /* get audio playback progress */ 
-  	else if (sa_device_get_position(info->audio_handle, 
-                            SA_PCM_WRITE_SOFTWARE_POS, &bytes) > 0) {
+    // calculate audio playback progress based on number of audio samples played
+  	if (sa_stream_get_position(info->audio_handle,
+                            SA_POSITION_WRITE_SOFTWARE, &bytes) != SA_SUCCESS) {
       /* can't get progress */
-	    cur_time = oggplay_sys_time_in_ms();
+  	  ref_time = (info->playback_target >> 16);
   	} else {
       /* calculate time from playback bytepos */
-    	cur_time = (bytes * 1000 / get_audio_rate(info->ogg_handle) / 
+    	ref_time = (bytes * 1000 / get_audio_rate(info->ogg_handle) /
                         (sizeof(short) * get_audio_channels(info->ogg_handle)));
   	}
-  } 
-  else 
-  {
-    cur_time = oggplay_sys_time_in_ms();
+  } else {
+  	  ref_time = (info->playback_target >> 16);
   }
 
   /* clean up */
-
   free_oggplay_frame(info->ogg_handle, &frame_data);
 
+  /* calculate how long we should wait with processing the next frame */
   info->playback_target += get_callback_period(info->ogg_handle);
-  offset = (info->playback_target >> 16) - cur_time;
-
+  offset = (info->playback_target >> 16) - ref_time;
   /*
-   * if we're WAAAY behind, discard the next frame
-   */
+  printf("offset: %lld target: %lld ref_time %lld\n",
+          offset, info->playback_target >> 16, ref_time);
+  */
+  /* check if we are not lagging with display */
   if (offset < OGGPLAY_FRAME_SKIP_OFFSET) {
     get_oggplay_frame(info->ogg_handle, &frame_data);
     goto calc_offset;
@@ -272,22 +255,22 @@
   }
 
   /*
-   * set new timeout and invalidate old one
-   */
+  * set new timeout and invalidate old one
+  */
   info->timeout_id = g_timeout_add((int)offset, update_frame, (gpointer)info);
   return FALSE;
 }
 
-gboolean 
+gboolean
 thread_delete(GtkWidget * widget, GdkEvent * event, gpointer user_data) {
- 
+
   PluginWindowInfo    * info = (PluginWindowInfo *)user_data;
-  
+
   g_source_remove(info->timeout_id);
   gtk_main_quit();
 
   return 1;
-  
+
 }
 
 gboolean
@@ -320,7 +303,7 @@
   gtk_widget_show(GTK_WIDGET(info->window));
   info->timeout_id = g_timeout_add(40, update_frame, (gpointer)info);
 
-  g_signal_connect(GTK_WIDGET(info->window), "destroy-event", 
+  g_signal_connect(GTK_WIDGET(info->window), "destroy-event",
                   (GCallback)thread_delete, info);
 
   //SEM_SIGNAL(info->start_stop_sem);
@@ -328,26 +311,23 @@
 
   gtk_main();
 
-  if (info->audio_opened == TRUE)
-    sa_device_close(info->audio_handle);
-  info->audio_handle = NULL;
-  info->audio_opened = FALSE;
+  close_audio(info);
   info->shutdown_gui = 0;
 
   pthread_exit(NULL);
-  
+
 }
 
 void *
-initialise_gui(nsPluginInstance *instance, NPWindow * aWindow, 
+initialise_gui(nsPluginInstance *instance, NPWindow * aWindow,
                 void * ogg_handle) {
 
   GtkWidget * plug;
   PluginWindowInfo * info;
 
   plug = gtk_plug_new((Window)aWindow->window);
-  
-  /* allocate structure */ 
+
+  /* allocate structure */
   info = malloc(sizeof(PluginWindowInfo));
   info->pluginInstance = instance;
   info->width = aWindow->width;
@@ -356,26 +336,27 @@
   info->shutdown_gui = 0;
   info->window = (GtkWidget*)plug;
   info->new_oggplay_handle = NULL;
-  info->tried_audio = FALSE;
   info->audio_opened = FALSE;
+  info->audio_handle = NULL;
   // set depending on the plugin startup settings
-  info->playback_state = PLAYING; 
+  info->playback_state = PLAYING;
+  info->playback_target = 0;
   info->playback_finished = FALSE;
   info->volume = 1.0;
   /*
    * create semaphore to lock replacement of oggplay object
    */
   SEM_CREATE(info->oggplay_replace_sem, 1);
-  
+
   /*
    * create semaphore to use for startup / shutdown synchronisation
    */
   SEM_CREATE(info->start_stop_sem, 1);
   SEM_WAIT(info->start_stop_sem);
 
-  /* create gtk thread */ 
+  /* create gtk thread */
   pthread_create((pthread_t*)&(info->thread), NULL, display_thread, info);
- 
+
   /*
    * wait for the thread to start up
    */
@@ -383,7 +364,7 @@
 
   return info;
 
-}  
+}
 
 /*
  * not required on the linux platform - window changes are automatically
@@ -393,18 +374,18 @@
 update_gui_with_new_display_size(void *gui_handle, NPWindow *np_window) {}
 
 void
-update_gui_with_new_oggplay(void *handle, void *oggplay_handle) 
+update_gui_with_new_oggplay(void *handle, void *oggplay_handle)
 {
 
   PluginWindowInfo  * info = (PluginWindowInfo *)handle;
- 
+
   SEM_WAIT(info->oggplay_replace_sem);
   if (info->new_oggplay_handle != NULL)
   {
     shut_oggplay(info->new_oggplay_handle);
   }
   info->new_oggplay_handle = oggplay_handle;
-  SEM_SIGNAL(info->oggplay_replace_sem); 
+  SEM_SIGNAL(info->oggplay_replace_sem);
 }
 
 void gui_pause(void *handle) {
@@ -423,8 +404,8 @@
 
   if (info->playback_state == PAUSED) {
     return 0;
-  } 
-  
+  }
+
   if (info->playback_finished) {
     return 2;
   }



More information about the commits mailing list