[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