aboutsummaryrefslogtreecommitdiff
path: root/www/seamonkey
diff options
context:
space:
mode:
authorBeat Gaetzi <beat@FreeBSD.org>2014-10-16 10:25:47 +0000
committerBeat Gaetzi <beat@FreeBSD.org>2014-10-16 10:25:47 +0000
commitdd4c17b1cedf6bfa50fd0b03b229ac22fcbb1b41 (patch)
tree26bdc8d7c96a38f05e815e1b26b101543a557cae /www/seamonkey
parenta683a3e9d02f08c29183cc564f77052327c2646f (diff)
Notes
Diffstat (limited to 'www/seamonkey')
-rw-r--r--www/seamonkey/Makefile10
-rw-r--r--www/seamonkey/distinfo4
-rw-r--r--www/seamonkey/files/patch-bug101554795
-rw-r--r--www/seamonkey/files/patch-bug10217611101
-rw-r--r--www/seamonkey/files/patch-bug102682820
-rw-r--r--www/seamonkey/files/patch-bug104126826
-rw-r--r--www/seamonkey/files/patch-bug107370918
-rw-r--r--www/seamonkey/files/patch-bug107698345
-rw-r--r--www/seamonkey/files/patch-bug77971320
-rw-r--r--www/seamonkey/files/patch-bug8269855
-rw-r--r--www/seamonkey/files/patch-bug8475686
-rw-r--r--www/seamonkey/files/patch-clang34-disable-stdcall13
-rw-r--r--www/seamonkey/files/patch-system-openh264218
13 files changed, 1431 insertions, 150 deletions
diff --git a/www/seamonkey/Makefile b/www/seamonkey/Makefile
index cf8b8f135f0b..3165b0cd74a0 100644
--- a/www/seamonkey/Makefile
+++ b/www/seamonkey/Makefile
@@ -2,7 +2,7 @@
# $FreeBSD$
PORTNAME= seamonkey
-DISTVERSION= 2.29.1
+DISTVERSION= 2.30
CATEGORIES?= www mail news editors irc ipv6
MASTER_SITES= MOZILLA/${PORTNAME}/releases/${DISTVERSION}/source \
https://ftp.mozilla.org/pub/mozilla.org/${PORTNAME}/candidates/${DISTVERSION}-candidates/build1/source/
@@ -32,7 +32,7 @@ BUILD_DEPENDS= nspr>=4.10.6:${PORTSDIR}/devel/nspr \
LIB_DEPENDS= libv4l2.so:${PORTSDIR}/multimedia/libv4l
EM_VERSION= 1.7.2
-L_VERSION= 3.4
+L_VERSION= 3.5
SSP_UNSAFE= yes
OBJDIR_BUILD= # in-tree build broken after bug 789837
@@ -84,9 +84,8 @@ MOZSRC:= ${WRKSRC}/mozilla
XPI_LIBDIR= ${PREFIX}/lib/xpi
# avoid clang 3.2/3.3 crash in js/src/jsgc.cpp on refillFreeList<(js::AllowGC)1>
-# http://svnweb.freebsd.org/changeset/base/255804
-.if ${OPSYS} == FreeBSD
-.if ${CHOSEN_COMPILER_TYPE} == clang && ${ARCH} == i386 && ${OSVERSION} < 1000056
+# To be removed when 9.2R goes EOL. http://llvm.org/PR15840
+.if ${ARCH} == i386 && ${CHOSEN_COMPILER_TYPE} == clang && ${COMPILER_VERSION:M3[23]}
. if ${PORT_OPTIONS:MOPTIMIZED_CFLAGS}
BROKEN= Cannot build with OPTIMIZED_CFLAGS option due to \
a ${CHOSEN_COMPILER_TYPE} bug: unset the option or \
@@ -100,7 +99,6 @@ CXXFLAGS+= -O1
. endif
. endif
.endif
-.endif
.if ${PORT_OPTIONS:MALSA}
RUN_DEPENDS+= alsa-lib>=1.0.27.2_1:${PORTSDIR}/audio/alsa-lib
diff --git a/www/seamonkey/distinfo b/www/seamonkey/distinfo
index 3ebe4925672d..eb57aaec67b4 100644
--- a/www/seamonkey/distinfo
+++ b/www/seamonkey/distinfo
@@ -1,4 +1,4 @@
-SHA256 (seamonkey-2.29.1.source.tar.bz2) = 26e345f71c6f305084ada10e10e55356fe4f08be25948cddb27eea81c0cd0679
-SIZE (seamonkey-2.29.1.source.tar.bz2) = 173439941
+SHA256 (seamonkey-2.30.source.tar.bz2) = 613eb08d80bf671b390869e9682810d7ae312a9858f6b69da76155f42ff1d516
+SIZE (seamonkey-2.30.source.tar.bz2) = 178435927
SHA256 (enigmail-1.7.2.tar.gz) = 7b3a62e83961bafec1cdac60075aa6c317c8f655a837e31a7d1f3ce6a49fc7d6
SIZE (enigmail-1.7.2.tar.gz) = 1420346
diff --git a/www/seamonkey/files/patch-bug1015547 b/www/seamonkey/files/patch-bug1015547
deleted file mode 100644
index df794794bc29..000000000000
--- a/www/seamonkey/files/patch-bug1015547
+++ /dev/null
@@ -1,95 +0,0 @@
-diff --git configure.in configure.in
-index 7bed45f..053de17 100644
---- mozilla/configure.in
-+++ mozilla/configure.in
-@@ -2950,7 +2950,7 @@ dnl Checks for library functions.
- dnl ========================================================
- AC_PROG_GCC_TRADITIONAL
- AC_FUNC_MEMCMP
--AC_CHECK_FUNCS(stat64 lstat64 truncate64 statvfs64 statvfs statfs64 statfs getpagesize localtime_r)
-+AC_CHECK_FUNCS(stat64 lstat64 truncate64 statvfs64 statvfs statfs64 statfs getpagesize localtime_r arc4random arc4random_buf)
-
- dnl check for clock_gettime(), the CLOCK_MONOTONIC clock
- AC_CACHE_CHECK(for clock_gettime(CLOCK_MONOTONIC),
-diff --git xpcom/base/nsUUIDGenerator.cpp xpcom/base/nsUUIDGenerator.cpp
-index 0687344..ca3ff8b 100644
---- mozilla/xpcom/base/nsUUIDGenerator.cpp
-+++ mozilla/xpcom/base/nsUUIDGenerator.cpp
-@@ -16,6 +16,10 @@
-
- #include "nsUUIDGenerator.h"
-
-+#ifdef ANDROID
-+extern "C" NS_EXPORT void arc4random_buf(void *, size_t);
-+#endif
-+
- using namespace mozilla;
-
- NS_IMPL_ISUPPORTS(nsUUIDGenerator, nsIUUIDGenerator)
-@@ -35,7 +39,7 @@ nsUUIDGenerator::Init()
- // We're a service, so we're guaranteed that Init() is not going
- // to be reentered while we're inside Init().
-
--#if !defined(XP_WIN) && !defined(XP_MACOSX) && !defined(ANDROID)
-+#if !defined(XP_WIN) && !defined(XP_MACOSX) && !defined(HAVE_ARC4RANDOM)
- /* initialize random number generator using NSPR random noise */
- unsigned int seed;
-
-@@ -72,7 +76,7 @@ nsUUIDGenerator::Init()
- }
- #endif
-
--#endif /* non XP_WIN and non XP_MACOSX */
-+#endif /* non XP_WIN and non XP_MACOSX and non ARC4RANDOM */
-
- return NS_OK;
- }
-@@ -122,13 +126,16 @@ nsUUIDGenerator::GenerateUUIDInPlace(nsID* aId)
- * back to it; instead, we use the value returned when we called
- * initstate, since older glibc's have broken setstate() return values
- */
--#ifndef ANDROID
-+#ifndef HAVE_ARC4RANDOM
- setstate(mState);
- #endif
-
-+#ifdef HAVE_ARC4RANDOM_BUF
-+ arc4random_buf(aId, sizeof(nsID));
-+#else /* HAVE_ARC4RANDOM_BUF */
- size_t bytesLeft = sizeof(nsID);
- while (bytesLeft > 0) {
--#ifdef ANDROID
-+#ifdef HAVE_ARC4RANDOM
- long rval = arc4random();
- const size_t mRBytes = 4;
- #else
-@@ -150,6 +157,7 @@ nsUUIDGenerator::GenerateUUIDInPlace(nsID* aId)
-
- bytesLeft -= toWrite;
- }
-+#endif /* HAVE_ARC4RANDOM_BUF */
-
- /* Put in the version */
- aId->m2 &= 0x0fff;
-@@ -159,7 +167,7 @@ nsUUIDGenerator::GenerateUUIDInPlace(nsID* aId)
- aId->m3[0] &= 0x3f;
- aId->m3[0] |= 0x80;
-
--#ifndef ANDROID
-+#ifndef HAVE_ARC4RANDOM
- /* Restore the previous RNG state */
- setstate(mSavedState);
- #endif
-diff --git xpcom/base/nsUUIDGenerator.h xpcom/base/nsUUIDGenerator.h
-index 6a24212..68ed6f2 100644
---- mozilla/xpcom/base/nsUUIDGenerator.h
-+++ mozilla/xpcom/base/nsUUIDGenerator.h
-@@ -29,7 +29,7 @@ private:
- protected:
-
- mozilla::Mutex mLock;
--#if !defined(XP_WIN) && !defined(XP_MACOSX) && !defined(ANDROID)
-+#if !defined(XP_WIN) && !defined(XP_MACOSX) && !defined(HAVE_ARC4RANDOM)
- char mState[128];
- char* mSavedState;
- uint8_t mRBytes;
diff --git a/www/seamonkey/files/patch-bug1021761 b/www/seamonkey/files/patch-bug1021761
new file mode 100644
index 000000000000..4d6d3b7e3255
--- /dev/null
+++ b/www/seamonkey/files/patch-bug1021761
@@ -0,0 +1,1101 @@
+diff --git configure.in configure.in
+index 48e60c0..ec08417 100644
+--- mozilla/configure.in
++++ mozilla/configure.in
+@@ -5438,6 +5438,60 @@ fi
+ AC_SUBST(MOZ_WEBM_ENCODER)
+
+ dnl ==================================
++dnl = Check OSS availability
++dnl ==================================
++
++dnl If using Linux, Solaris or BSDs, ensure that OSS is available
++case "$OS_TARGET" in
++Linux|SunOS|DragonFly|FreeBSD|NetBSD|GNU/kFreeBSD)
++ MOZ_OSS=1
++ ;;
++esac
++
++MOZ_ARG_DISABLE_BOOL(oss,
++[ --disable-oss Disable OpenSoundSystem support],
++ MOZ_OSS=,
++ MOZ_OSS=1)
++
++_SAVE_CFLAGS=$CFLAGS
++_SAVE_LIBS=$LIBS
++if test -n "$MOZ_OSS"; then
++ dnl Prefer 4Front implementation
++ AC_MSG_CHECKING([MOZ_OSS_CFLAGS])
++ if test -z "$MOZ_OSS_CFLAGS"; then
++ for oss_conf in /etc/oss.conf /usr/local/etc/oss.conf; do
++ if test -e "$oss_conf"; then
++ . "$oss_conf"
++ fi
++ done
++ if test -d "$OSSLIBDIR"; then
++ MOZ_OSS_CFLAGS="-I$OSSLIBDIR/include"
++ fi
++ fi
++ AC_MSG_RESULT([$MOZ_OSS_CFLAGS])
++
++ CFLAGS="$CFLAGS $MOZ_OSS_CFLAGS"
++ MOZ_CHECK_HEADERS(sys/soundcard.h linux/soundcard.h soundcard.h)
++
++ if test "$ac_cv_header_sys_soundcard_h" != "yes" -a \
++ "$ac_cv_header_linux_soundcard_h" != "yes" -a \
++ "$ac_cv_header_soundcard_h" != "yes"; then
++ AC_MSG_ERROR([Need OSS for Ogg, Wave or WebM decoding on $OS_TARGET. Disable with --disable-ogg --disable-wave --disable-webm.])
++ fi
++
++ dnl Assume NetBSD implementation over SunAudio
++ AC_CHECK_LIB(ossaudio, _oss_ioctl,
++ [AC_DEFINE_UNQUOTED(CUBEB_OSS_DEFAULT_OUTPUT, "/dev/sound")
++ MOZ_OSS_LIBS="-lossaudio"])
++fi
++CFLAGS=$_SAVE_CFLAGS
++LIBS=$_SAVE_LIBS
++
++AC_SUBST(MOZ_OSS)
++AC_SUBST_LIST(MOZ_OSS_CFLAGS)
++AC_SUBST_LIST(MOZ_OSS_LIBS)
++
++dnl ==================================
+ dnl = Check alsa availability on Linux
+ dnl ==================================
+
+@@ -5451,12 +5505,23 @@ MOZ_ARG_ENABLE_BOOL(alsa,
+ MOZ_ALSA=1,
+ MOZ_ALSA=)
+
++MOZ_ARG_DISABLE_BOOL(alsa-dlopen,
++[ --disable-alsa-dlopen Disable runtime linking of libasound.so],
++ DISABLE_LIBASOUND_DLOPEN=1,
++ DISABLE_LIBASOUND_DLOPEN=)
++
+ if test -n "$MOZ_ALSA"; then
+ PKG_CHECK_MODULES(MOZ_ALSA, alsa, ,
+ [echo "$MOZ_ALSA_PKG_ERRORS"
+ AC_MSG_ERROR([Need alsa for Ogg, Wave or WebM decoding on Linux. Disable with --disable-ogg --disable-wave --disable-webm. (On Ubuntu, you might try installing the package libasound2-dev.)])])
+ fi
+
++if test -n "$DISABLE_LIBASOUND_DLOPEN"; then
++ AC_DEFINE(DISABLE_LIBASOUND_DLOPEN)
++else
++ MOZ_ALSA_LIBS=
++fi
++
+ AC_SUBST(MOZ_ALSA)
+
+ dnl ========================================================
+diff --git media/libcubeb/AUTHORS media/libcubeb/AUTHORS
+index b441e8a..950d9e5 100644
+--- mozilla/media/libcubeb/AUTHORS
++++ mozilla/media/libcubeb/AUTHORS
+@@ -4,3 +4,4 @@ Michael Wu <mwu@mozilla.com>
+ Paul Adenot <paul@paul.cx>
+ David Richards <drichards@mozilla.com>
+ Sebastien Alaiwan <sebastien.alaiwan@gmail.com>
++Evgeniy Vodolazskiy <waterlaz@gmail.com>
+diff --git media/libcubeb/src/cubeb.c media/libcubeb/src/cubeb.c
+index 9c3adcc..45d765b 100644
+--- mozilla/media/libcubeb/src/cubeb.c
++++ mozilla/media/libcubeb/src/cubeb.c
+@@ -54,6 +54,9 @@ int opensl_init(cubeb ** context, char const * context_name);
+ #if defined(USE_AUDIOTRACK)
+ int audiotrack_init(cubeb ** context, char const * context_name);
+ #endif
++#if defined(USE_OSS)
++int oss_init(cubeb ** context, char const * context_name);
++#endif
+
+ int
+ validate_stream_params(cubeb_stream_params stream_params)
+@@ -120,6 +123,9 @@ cubeb_init(cubeb ** context, char const * context_name)
+ #if defined(USE_AUDIOTRACK)
+ audiotrack_init,
+ #endif
++#if defined(USE_OSS)
++ oss_init,
++#endif
+ };
+ int i;
+
+diff --git media/libcubeb/src/cubeb_alsa.c media/libcubeb/src/cubeb_alsa.c
+index a962553..1f780f4 100644
+--- mozilla/media/libcubeb/src/cubeb_alsa.c
++++ mozilla/media/libcubeb/src/cubeb_alsa.c
+@@ -11,6 +11,7 @@
+ #include <sys/time.h>
+ #include <assert.h>
+ #include <limits.h>
++#include <dlfcn.h>
+ #include <poll.h>
+ #include <unistd.h>
+ #include <alsa/asoundlib.h>
+@@ -24,6 +25,50 @@
+
+ #define ALSA_PA_PLUGIN "ALSA <-> PulseAudio PCM I/O Plugin"
+
++#ifdef DISABLE_LIBASOUND_DLOPEN
++#define WRAP(x) x
++#else
++#define WRAP(x) cubeb_##x
++#define MAKE_TYPEDEF(x) static typeof(x) * cubeb_##x
++MAKE_TYPEDEF(snd_config);
++MAKE_TYPEDEF(snd_config_add);
++MAKE_TYPEDEF(snd_config_copy);
++MAKE_TYPEDEF(snd_config_delete);
++MAKE_TYPEDEF(snd_config_get_id);
++MAKE_TYPEDEF(snd_config_get_string);
++MAKE_TYPEDEF(snd_config_imake_integer);
++MAKE_TYPEDEF(snd_config_search);
++MAKE_TYPEDEF(snd_config_search_definition);
++MAKE_TYPEDEF(snd_lib_error_set_handler);
++MAKE_TYPEDEF(snd_pcm_avail_update);
++MAKE_TYPEDEF(snd_pcm_close);
++MAKE_TYPEDEF(snd_pcm_delay);
++MAKE_TYPEDEF(snd_pcm_drain);
++MAKE_TYPEDEF(snd_pcm_frames_to_bytes);
++MAKE_TYPEDEF(snd_pcm_get_params);
++/* snd_pcm_hw_params_alloca is actually a macro */
++/* MAKE_TYPEDEF(snd_pcm_hw_params_alloca); */
++MAKE_TYPEDEF(snd_pcm_hw_params_sizeof);
++#define snd_pcm_hw_params_sizeof cubeb_snd_pcm_hw_params_sizeof
++MAKE_TYPEDEF(snd_pcm_hw_params_any);
++MAKE_TYPEDEF(snd_pcm_hw_params_get_channels_max);
++MAKE_TYPEDEF(snd_pcm_hw_params_get_rate);
++MAKE_TYPEDEF(snd_pcm_hw_params_set_rate_near);
++MAKE_TYPEDEF(snd_pcm_nonblock);
++MAKE_TYPEDEF(snd_pcm_open);
++MAKE_TYPEDEF(snd_pcm_open_lconf);
++MAKE_TYPEDEF(snd_pcm_pause);
++MAKE_TYPEDEF(snd_pcm_poll_descriptors);
++MAKE_TYPEDEF(snd_pcm_poll_descriptors_count);
++MAKE_TYPEDEF(snd_pcm_poll_descriptors_revents);
++MAKE_TYPEDEF(snd_pcm_recover);
++MAKE_TYPEDEF(snd_pcm_set_params);
++MAKE_TYPEDEF(snd_pcm_state);
++MAKE_TYPEDEF(snd_pcm_writei);
++
++#undef MAKE_TYPEDEF
++#endif
++
+ /* ALSA is not thread-safe. snd_pcm_t instances are individually protected
+ by the owning cubeb_stream's mutex. snd_pcm_t creation and destruction
+ is not thread-safe until ALSA 1.0.24 (see alsa-lib.git commit 91c9c8f1),
+@@ -64,6 +109,8 @@ struct cubeb {
+ workaround is not required. */
+ snd_config_t * local_config;
+ int is_pa;
++
++ void * libasound;
+ };
+
+ enum stream_state {
+@@ -262,7 +309,7 @@ alsa_refill_stream(cubeb_stream * stm)
+
+ pthread_mutex_lock(&stm->mutex);
+
+- r = snd_pcm_poll_descriptors_revents(stm->pcm, stm->fds, stm->nfds, &revents);
++ r = WRAP(snd_pcm_poll_descriptors_revents)(stm->pcm, stm->fds, stm->nfds, &revents);
+ if (r < 0 || revents != POLLOUT) {
+ /* This should be a stream error; it makes no sense for poll(2) to wake
+ for this stream and then have the stream report that it's not ready.
+@@ -271,10 +318,10 @@ alsa_refill_stream(cubeb_stream * stm)
+ return RUNNING;
+ }
+
+- avail = snd_pcm_avail_update(stm->pcm);
++ avail = WRAP(snd_pcm_avail_update)(stm->pcm);
+ if (avail == -EPIPE) {
+- snd_pcm_recover(stm->pcm, avail, 1);
+- avail = snd_pcm_avail_update(stm->pcm);
++ WRAP(snd_pcm_recover)(stm->pcm, avail, 1);
++ avail = WRAP(snd_pcm_avail_update)(stm->pcm);
+ }
+
+ /* Failed to recover from an xrun, this stream must be broken. */
+@@ -293,8 +340,8 @@ alsa_refill_stream(cubeb_stream * stm)
+ available to write. If avail is still zero here, the stream must be in
+ a funky state, so recover and try again. */
+ if (avail == 0) {
+- snd_pcm_recover(stm->pcm, -EPIPE, 1);
+- avail = snd_pcm_avail_update(stm->pcm);
++ WRAP(snd_pcm_recover)(stm->pcm, -EPIPE, 1);
++ avail = WRAP(snd_pcm_avail_update)(stm->pcm);
+ if (avail <= 0) {
+ pthread_mutex_unlock(&stm->mutex);
+ stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_ERROR);
+@@ -302,7 +349,7 @@ alsa_refill_stream(cubeb_stream * stm)
+ }
+ }
+
+- p = calloc(1, snd_pcm_frames_to_bytes(stm->pcm, avail));
++ p = calloc(1, WRAP(snd_pcm_frames_to_bytes)(stm->pcm, avail));
+ assert(p);
+
+ pthread_mutex_unlock(&stm->mutex);
+@@ -313,10 +360,10 @@ alsa_refill_stream(cubeb_stream * stm)
+ return ERROR;
+ }
+ if (got > 0) {
+- snd_pcm_sframes_t wrote = snd_pcm_writei(stm->pcm, p, got);
++ snd_pcm_sframes_t wrote = WRAP(snd_pcm_writei)(stm->pcm, p, got);
+ if (wrote == -EPIPE) {
+- snd_pcm_recover(stm->pcm, wrote, 1);
+- wrote = snd_pcm_writei(stm->pcm, p, got);
++ WRAP(snd_pcm_recover)(stm->pcm, wrote, 1);
++ wrote = WRAP(snd_pcm_writei)(stm->pcm, p, got);
+ }
+ assert(wrote >= 0 && wrote == got);
+ stm->write_position += wrote;
+@@ -342,7 +389,7 @@ alsa_refill_stream(cubeb_stream * stm)
+
+ /* Fill the remaining buffer with silence to guarantee one full period
+ has been written. */
+- snd_pcm_writei(stm->pcm, (char *) p + got, avail - got);
++ WRAP(snd_pcm_writei)(stm->pcm, (char *) p + got, avail - got);
+
+ set_timeout(&stm->drain_timeout, buffer_time * 1000);
+
+@@ -453,26 +500,26 @@ get_slave_pcm_node(snd_config_t * lconf, snd_config_t * root_pcm)
+
+ slave_def = NULL;
+
+- r = snd_config_search(root_pcm, "slave", &slave_pcm);
++ r = WRAP(snd_config_search)(root_pcm, "slave", &slave_pcm);
+ if (r < 0) {
+ return NULL;
+ }
+
+- r = snd_config_get_string(slave_pcm, &string);
++ r = WRAP(snd_config_get_string)(slave_pcm, &string);
+ if (r >= 0) {
+- r = snd_config_search_definition(lconf, "pcm_slave", string, &slave_def);
++ r = WRAP(snd_config_search_definition)(lconf, "pcm_slave", string, &slave_def);
+ if (r < 0) {
+ return NULL;
+ }
+ }
+
+ do {
+- r = snd_config_search(slave_def ? slave_def : slave_pcm, "pcm", &pcm);
++ r = WRAP(snd_config_search)(slave_def ? slave_def : slave_pcm, "pcm", &pcm);
+ if (r < 0) {
+ break;
+ }
+
+- r = snd_config_get_string(slave_def ? slave_def : slave_pcm, &string);
++ r = WRAP(snd_config_get_string)(slave_def ? slave_def : slave_pcm, &string);
+ if (r < 0) {
+ break;
+ }
+@@ -481,7 +528,7 @@ get_slave_pcm_node(snd_config_t * lconf, snd_config_t * root_pcm)
+ if (r < 0 || r > (int) sizeof(node_name)) {
+ break;
+ }
+- r = snd_config_search(lconf, node_name, &pcm);
++ r = WRAP(snd_config_search)(lconf, node_name, &pcm);
+ if (r < 0) {
+ break;
+ }
+@@ -490,7 +537,7 @@ get_slave_pcm_node(snd_config_t * lconf, snd_config_t * root_pcm)
+ } while (0);
+
+ if (slave_def) {
+- snd_config_delete(slave_def);
++ WRAP(snd_config_delete)(slave_def);
+ }
+
+ return NULL;
+@@ -513,22 +560,22 @@ init_local_config_with_workaround(char const * pcm_name)
+
+ lconf = NULL;
+
+- if (snd_config == NULL) {
++ if (*WRAP(snd_config) == NULL) {
+ return NULL;
+ }
+
+- r = snd_config_copy(&lconf, snd_config);
++ r = WRAP(snd_config_copy)(&lconf, *WRAP(snd_config));
+ if (r < 0) {
+ return NULL;
+ }
+
+ do {
+- r = snd_config_search_definition(lconf, "pcm", pcm_name, &pcm_node);
++ r = WRAP(snd_config_search_definition)(lconf, "pcm", pcm_name, &pcm_node);
+ if (r < 0) {
+ break;
+ }
+
+- r = snd_config_get_id(pcm_node, &string);
++ r = WRAP(snd_config_get_id)(pcm_node, &string);
+ if (r < 0) {
+ break;
+ }
+@@ -537,7 +584,7 @@ init_local_config_with_workaround(char const * pcm_name)
+ if (r < 0 || r > (int) sizeof(node_name)) {
+ break;
+ }
+- r = snd_config_search(lconf, node_name, &pcm_node);
++ r = WRAP(snd_config_search)(lconf, node_name, &pcm_node);
+ if (r < 0) {
+ break;
+ }
+@@ -548,12 +595,12 @@ init_local_config_with_workaround(char const * pcm_name)
+ }
+
+ /* Fetch the PCM node's type, and bail out if it's not the PulseAudio plugin. */
+- r = snd_config_search(pcm_node, "type", &node);
++ r = WRAP(snd_config_search)(pcm_node, "type", &node);
+ if (r < 0) {
+ break;
+ }
+
+- r = snd_config_get_string(node, &string);
++ r = WRAP(snd_config_get_string)(node, &string);
+ if (r < 0) {
+ break;
+ }
+@@ -564,18 +611,18 @@ init_local_config_with_workaround(char const * pcm_name)
+
+ /* Don't clobber an explicit existing handle_underrun value, set it only
+ if it doesn't already exist. */
+- r = snd_config_search(pcm_node, "handle_underrun", &node);
++ r = WRAP(snd_config_search)(pcm_node, "handle_underrun", &node);
+ if (r != -ENOENT) {
+ break;
+ }
+
+ /* Disable pcm_pulse's asynchronous underrun handling. */
+- r = snd_config_imake_integer(&node, "handle_underrun", 0);
++ r = WRAP(snd_config_imake_integer)(&node, "handle_underrun", 0);
+ if (r < 0) {
+ break;
+ }
+
+- r = snd_config_add(pcm_node, node);
++ r = WRAP(snd_config_add)(pcm_node, node);
+ if (r < 0) {
+ break;
+ }
+@@ -583,7 +630,7 @@ init_local_config_with_workaround(char const * pcm_name)
+ return lconf;
+ } while (0);
+
+- snd_config_delete(lconf);
++ WRAP(snd_config_delete)(lconf);
+
+ return NULL;
+ }
+@@ -595,9 +642,9 @@ alsa_locked_pcm_open(snd_pcm_t ** pcm, snd_pcm_stream_t stream, snd_config_t * l
+
+ pthread_mutex_lock(&cubeb_alsa_mutex);
+ if (local_config) {
+- r = snd_pcm_open_lconf(pcm, CUBEB_ALSA_PCM_NAME, stream, SND_PCM_NONBLOCK, local_config);
++ r = WRAP(snd_pcm_open_lconf)(pcm, CUBEB_ALSA_PCM_NAME, stream, SND_PCM_NONBLOCK, local_config);
+ } else {
+- r = snd_pcm_open(pcm, CUBEB_ALSA_PCM_NAME, stream, SND_PCM_NONBLOCK);
++ r = WRAP(snd_pcm_open)(pcm, CUBEB_ALSA_PCM_NAME, stream, SND_PCM_NONBLOCK);
+ }
+ pthread_mutex_unlock(&cubeb_alsa_mutex);
+
+@@ -610,7 +657,7 @@ alsa_locked_pcm_close(snd_pcm_t * pcm)
+ int r;
+
+ pthread_mutex_lock(&cubeb_alsa_mutex);
+- r = snd_pcm_close(pcm);
++ r = WRAP(snd_pcm_close)(pcm);
+ pthread_mutex_unlock(&cubeb_alsa_mutex);
+
+ return r;
+@@ -667,12 +714,65 @@ alsa_init(cubeb ** context, char const * context_name)
+ pthread_attr_t attr;
+ snd_pcm_t * dummy;
+
++ void * libasound = NULL;
++
++#ifndef DISABLE_LIBASOUND_DLOPEN
++ libasound = dlopen("libasound.so", RTLD_LAZY);
++ if (!libasound) {
++ return CUBEB_ERROR;
++ }
++
++#define LOAD(x) do { \
++ cubeb_##x = dlsym(libasound, #x); \
++ if (!cubeb_##x) { \
++ dlclose(libasound); \
++ return CUBEB_ERROR; \
++ } \
++ } while(0)
++
++ LOAD(snd_config);
++ LOAD(snd_config_add);
++ LOAD(snd_config_copy);
++ LOAD(snd_config_delete);
++ LOAD(snd_config_get_id);
++ LOAD(snd_config_get_string);
++ LOAD(snd_config_imake_integer);
++ LOAD(snd_config_search);
++ LOAD(snd_config_search_definition);
++ LOAD(snd_lib_error_set_handler);
++ LOAD(snd_pcm_avail_update);
++ LOAD(snd_pcm_close);
++ LOAD(snd_pcm_delay);
++ LOAD(snd_pcm_drain);
++ LOAD(snd_pcm_frames_to_bytes);
++ LOAD(snd_pcm_get_params);
++ /* snd_pcm_hw_params_alloca is actually a macro */
++ /* LOAD(snd_pcm_hw_params_alloca); */
++ LOAD(snd_pcm_hw_params_sizeof);
++ LOAD(snd_pcm_hw_params_any);
++ LOAD(snd_pcm_hw_params_get_channels_max);
++ LOAD(snd_pcm_hw_params_get_rate);
++ LOAD(snd_pcm_hw_params_set_rate_near);
++ LOAD(snd_pcm_nonblock);
++ LOAD(snd_pcm_open);
++ LOAD(snd_pcm_open_lconf);
++ LOAD(snd_pcm_pause);
++ LOAD(snd_pcm_poll_descriptors);
++ LOAD(snd_pcm_poll_descriptors_count);
++ LOAD(snd_pcm_poll_descriptors_revents);
++ LOAD(snd_pcm_recover);
++ LOAD(snd_pcm_set_params);
++ LOAD(snd_pcm_state);
++ LOAD(snd_pcm_writei);
++
++#undef LOAD
++#endif
+ assert(context);
+ *context = NULL;
+
+ pthread_mutex_lock(&cubeb_alsa_mutex);
+ if (!cubeb_alsa_error_handler_set) {
+- snd_lib_error_set_handler(silent_error_handler);
++ WRAP(snd_lib_error_set_handler)(silent_error_handler);
+ cubeb_alsa_error_handler_set = 1;
+ }
+ pthread_mutex_unlock(&cubeb_alsa_mutex);
+@@ -680,6 +780,8 @@ alsa_init(cubeb ** context, char const * context_name)
+ ctx = calloc(1, sizeof(*ctx));
+ assert(ctx);
+
++ ctx->libasound = libasound;
++
+ ctx->ops = &alsa_ops;
+
+ r = pthread_mutex_init(&ctx->mutex, NULL);
+@@ -729,7 +831,7 @@ alsa_init(cubeb ** context, char const * context_name)
+ config fails with EINVAL, the PA PCM is too old for this workaround. */
+ if (r == -EINVAL) {
+ pthread_mutex_lock(&cubeb_alsa_mutex);
+- snd_config_delete(ctx->local_config);
++ WRAP(snd_config_delete)(ctx->local_config);
+ pthread_mutex_unlock(&cubeb_alsa_mutex);
+ ctx->local_config = NULL;
+ } else if (r >= 0) {
+@@ -768,9 +870,13 @@ alsa_destroy(cubeb * ctx)
+ pthread_mutex_destroy(&ctx->mutex);
+ free(ctx->fds);
+
++ if (ctx->libasound) {
++ dlclose(ctx->libasound);
++ }
++
+ if (ctx->local_config) {
+ pthread_mutex_lock(&cubeb_alsa_mutex);
+- snd_config_delete(ctx->local_config);
++ WRAP(snd_config_delete)(ctx->local_config);
+ pthread_mutex_unlock(&cubeb_alsa_mutex);
+ }
+
+@@ -838,7 +944,7 @@ alsa_stream_init(cubeb * ctx, cubeb_stream ** stream, char const * stream_name,
+ return CUBEB_ERROR;
+ }
+
+- r = snd_pcm_nonblock(stm->pcm, 1);
++ r = WRAP(snd_pcm_nonblock)(stm->pcm, 1);
+ assert(r == 0);
+
+ /* Ugly hack: the PA ALSA plugin allows buffer configurations that can't
+@@ -848,23 +954,23 @@ alsa_stream_init(cubeb * ctx, cubeb_stream ** stream, char const * stream_name,
+ latency = latency < 500 ? 500 : latency;
+ }
+
+- r = snd_pcm_set_params(stm->pcm, format, SND_PCM_ACCESS_RW_INTERLEAVED,
+- stm->params.channels, stm->params.rate, 1,
+- latency * 1000);
++ r = WRAP(snd_pcm_set_params)(stm->pcm, format, SND_PCM_ACCESS_RW_INTERLEAVED,
++ stm->params.channels, stm->params.rate, 1,
++ latency * 1000);
+ if (r < 0) {
+ alsa_stream_destroy(stm);
+ return CUBEB_ERROR_INVALID_FORMAT;
+ }
+
+- r = snd_pcm_get_params(stm->pcm, &stm->buffer_size, &stm->period_size);
++ r = WRAP(snd_pcm_get_params)(stm->pcm, &stm->buffer_size, &stm->period_size);
+ assert(r == 0);
+
+- stm->nfds = snd_pcm_poll_descriptors_count(stm->pcm);
++ stm->nfds = WRAP(snd_pcm_poll_descriptors_count)(stm->pcm);
+ assert(stm->nfds > 0);
+
+ stm->saved_fds = calloc(stm->nfds, sizeof(struct pollfd));
+ assert(stm->saved_fds);
+- r = snd_pcm_poll_descriptors(stm->pcm, stm->saved_fds, stm->nfds);
++ r = WRAP(snd_pcm_poll_descriptors)(stm->pcm, stm->saved_fds, stm->nfds);
+ assert((nfds_t) r == stm->nfds);
+
+ r = pthread_cond_init(&stm->cond, NULL);
+@@ -895,7 +1001,7 @@ alsa_stream_destroy(cubeb_stream * stm)
+ pthread_mutex_lock(&stm->mutex);
+ if (stm->pcm) {
+ if (stm->state == DRAINING) {
+- snd_pcm_drain(stm->pcm);
++ WRAP(snd_pcm_drain)(stm->pcm);
+ }
+ alsa_locked_pcm_close(stm->pcm);
+ stm->pcm = NULL;
+@@ -937,12 +1043,12 @@ alsa_get_max_channel_count(cubeb * ctx, uint32_t * max_channels)
+ return CUBEB_ERROR;
+ }
+
+- rv = snd_pcm_hw_params_any(stm->pcm, hw_params);
++ rv = WRAP(snd_pcm_hw_params_any)(stm->pcm, hw_params);
+ if (rv < 0) {
+ return CUBEB_ERROR;
+ }
+
+- rv = snd_pcm_hw_params_get_channels_max(hw_params, max_channels);
++ rv = WRAP(snd_pcm_hw_params_get_channels_max)(hw_params, max_channels);
+ if (rv < 0) {
+ return CUBEB_ERROR;
+ }
+@@ -962,34 +1068,34 @@ alsa_get_preferred_sample_rate(cubeb * ctx, uint32_t * rate) {
+
+ /* get a pcm, disabling resampling, so we get a rate the
+ * hardware/dmix/pulse/etc. supports. */
+- rv = snd_pcm_open(&pcm, "", SND_PCM_STREAM_PLAYBACK | SND_PCM_NO_AUTO_RESAMPLE, 0);
++ rv = WRAP(snd_pcm_open)(&pcm, "", SND_PCM_STREAM_PLAYBACK | SND_PCM_NO_AUTO_RESAMPLE, 0);
+ if (rv < 0) {
+ return CUBEB_ERROR;
+ }
+
+- rv = snd_pcm_hw_params_any(pcm, hw_params);
++ rv = WRAP(snd_pcm_hw_params_any)(pcm, hw_params);
+ if (rv < 0) {
+- snd_pcm_close(pcm);
++ WRAP(snd_pcm_close)(pcm);
+ return CUBEB_ERROR;
+ }
+
+- rv = snd_pcm_hw_params_get_rate(hw_params, rate, &dir);
++ rv = WRAP(snd_pcm_hw_params_get_rate)(hw_params, rate, &dir);
+ if (rv >= 0) {
+ /* There is a default rate: use it. */
+- snd_pcm_close(pcm);
++ WRAP(snd_pcm_close)(pcm);
+ return CUBEB_OK;
+ }
+
+ /* Use a common rate, alsa may adjust it based on hw/etc. capabilities. */
+ *rate = 44100;
+
+- rv = snd_pcm_hw_params_set_rate_near(pcm, hw_params, rate, NULL);
++ rv = WRAP(snd_pcm_hw_params_set_rate_near)(pcm, hw_params, rate, NULL);
+ if (rv < 0) {
+- snd_pcm_close(pcm);
++ WRAP(snd_pcm_close)(pcm);
+ return CUBEB_ERROR;
+ }
+
+- snd_pcm_close(pcm);
++ WRAP(snd_pcm_close)(pcm);
+
+ return CUBEB_OK;
+ }
+@@ -1013,7 +1119,7 @@ alsa_stream_start(cubeb_stream * stm)
+ ctx = stm->context;
+
+ pthread_mutex_lock(&stm->mutex);
+- snd_pcm_pause(stm->pcm, 0);
++ WRAP(snd_pcm_pause)(stm->pcm, 0);
+ gettimeofday(&stm->last_activity, NULL);
+ pthread_mutex_unlock(&stm->mutex);
+
+@@ -1047,7 +1153,7 @@ alsa_stream_stop(cubeb_stream * stm)
+ pthread_mutex_unlock(&ctx->mutex);
+
+ pthread_mutex_lock(&stm->mutex);
+- snd_pcm_pause(stm->pcm, 1);
++ WRAP(snd_pcm_pause)(stm->pcm, 1);
+ pthread_mutex_unlock(&stm->mutex);
+
+ return CUBEB_OK;
+@@ -1063,8 +1169,8 @@ alsa_stream_get_position(cubeb_stream * stm, uint64_t * position)
+ pthread_mutex_lock(&stm->mutex);
+
+ delay = -1;
+- if (snd_pcm_state(stm->pcm) != SND_PCM_STATE_RUNNING ||
+- snd_pcm_delay(stm->pcm, &delay) != 0) {
++ if (WRAP(snd_pcm_state)(stm->pcm) != SND_PCM_STATE_RUNNING ||
++ WRAP(snd_pcm_delay)(stm->pcm, &delay) != 0) {
+ *position = stm->last_position;
+ pthread_mutex_unlock(&stm->mutex);
+ return CUBEB_OK;
+@@ -1089,7 +1195,7 @@ alsa_stream_get_latency(cubeb_stream * stm, uint32_t * latency)
+ snd_pcm_sframes_t delay;
+ /* This function returns the delay in frames until a frame written using
+ snd_pcm_writei is sent to the DAC. The DAC delay should be < 1ms anyways. */
+- if (snd_pcm_delay(stm->pcm, &delay)) {
++ if (WRAP(snd_pcm_delay)(stm->pcm, &delay)) {
+ return CUBEB_ERROR;
+ }
+
+diff --git media/libcubeb/src/cubeb_oss.c media/libcubeb/src/cubeb_oss.c
+new file mode 100644
+index 0000000..5e38e27
+--- /dev/null
++++ mozilla/media/libcubeb/src/cubeb_oss.c
+@@ -0,0 +1,399 @@
++/*
++ * Copyright © 2014 Mozilla Foundation
++ *
++ * This program is made available under an ISC-style license. See the
++ * accompanying file LICENSE for details.
++ */
++#if defined(HAVE_SYS_SOUNDCARD_H)
++#include <sys/soundcard.h>
++#elif defined(HAVE_LINUX_SOUNDCARD_H)
++#include <linux/soundcard.h>
++#else
++#include <soundcard.h>
++#endif
++#include <unistd.h>
++#include <stdlib.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <fcntl.h>
++#include <sys/ioctl.h>
++#include <errno.h>
++#include <pthread.h>
++#include <stdio.h>
++
++#include "cubeb/cubeb.h"
++#include "cubeb-internal.h"
++
++#ifndef CUBEB_OSS_DEFAULT_OUTPUT
++#define CUBEB_OSS_DEFAULT_OUTPUT "/dev/dsp"
++#endif
++
++#define OSS_BUFFER_SIZE 1024
++
++struct cubeb {
++ struct cubeb_ops const * ops;
++};
++
++struct cubeb_stream {
++ cubeb * context;
++
++ cubeb_data_callback data_callback;
++ cubeb_state_callback state_callback;
++ void * user_ptr;
++ float volume;
++ float panning;
++
++ pthread_mutex_t state_mutex;
++ pthread_cond_t state_cond;
++
++ int running;
++ int stopped;
++ int floating;
++
++ /* These two vars are needed to support old versions of OSS */
++ unsigned int position_bytes;
++ unsigned int last_position_bytes;
++
++ uint64_t written_frags; /* The number of fragments written to /dev/dsp */
++ uint64_t missed_frags; /* fragments output with stopped stream */
++
++ cubeb_stream_params params;
++ int fd;
++ pthread_t th;
++};
++
++static struct cubeb_ops const oss_ops;
++
++int oss_init(cubeb ** context, char const * context_name)
++{
++ cubeb* ctx = (cubeb*)malloc(sizeof(cubeb));
++ ctx->ops = &oss_ops;
++ *context = ctx;
++ return CUBEB_OK;
++}
++
++static void oss_destroy(cubeb *ctx)
++{
++ free(ctx);
++}
++
++static char const * oss_get_backend_id(cubeb * context)
++{
++ static char oss_name[] = "oss";
++ return oss_name;
++}
++
++static int oss_get_max_channel_count(cubeb * ctx, uint32_t * max_channels)
++{
++ *max_channels = 2; /* Let's support only stereo for now */
++ return CUBEB_OK;
++}
++
++static int oss_get_min_latency(cubeb * context, cubeb_stream_params params,
++ uint32_t * latency_ms)
++{
++ /* 40ms is a big enough number to work ok */
++ *latency_ms = 40;
++ return CUBEB_OK;
++}
++
++static int oss_get_preferred_sample_rate(cubeb *context, uint32_t * rate)
++{
++ /* 48000 seems a prefered choice for most audio devices
++ * and a good choice for OSS */
++ *rate = 48000;
++ return CUBEB_OK;
++}
++
++static void run_state_callback(cubeb_stream *stream, cubeb_state state)
++{
++ if (stream->state_callback) {
++ stream->state_callback(stream, stream->user_ptr, state);
++ }
++}
++
++static long run_data_callback(cubeb_stream *stream, void *buffer, long nframes)
++{
++ long got = 0;
++ pthread_mutex_lock(&stream->state_mutex);
++ if (stream->data_callback && stream->running && !stream->stopped) {
++ pthread_mutex_unlock(&stream->state_mutex);
++ got = stream->data_callback(stream, stream->user_ptr, buffer, nframes);
++ } else {
++ pthread_mutex_unlock(&stream->state_mutex);
++ }
++ return got;
++}
++
++static void apply_volume(int16_t* buffer, unsigned int n,
++ float volume, float panning)
++{
++ float left = volume;
++ float right = volume;
++ unsigned int i;
++ int pan[2];
++ if (panning<0) {
++ right *= (1+panning);
++ } else {
++ left *= (1-panning);
++ }
++ pan[0] = 128.0*left;
++ pan[1] = 128.0*right;
++ for(i=0; i<n; i++){
++ buffer[i] = ((int)buffer[i])*pan[i%2]/128;
++ }
++}
++
++static void *writer(void *stm)
++{
++ cubeb_stream* stream = (cubeb_stream*)stm;
++ int16_t buffer[OSS_BUFFER_SIZE];
++ float f_buffer[OSS_BUFFER_SIZE];
++ int got;
++ unsigned long i;
++ while (stream->running) {
++ pthread_mutex_lock(&stream->state_mutex);
++ if (stream->stopped) {
++ pthread_mutex_unlock(&stream->state_mutex);
++ run_state_callback(stream, CUBEB_STATE_STOPPED);
++ pthread_mutex_lock(&stream->state_mutex);
++ while (stream->stopped) {
++ pthread_cond_wait(&stream->state_cond, &stream->state_mutex);
++ }
++ pthread_mutex_unlock(&stream->state_mutex);
++ run_state_callback(stream, CUBEB_STATE_STARTED);
++ continue;
++ }
++ pthread_mutex_unlock(&stream->state_mutex);
++ if (stream->floating) {
++ got = run_data_callback(stream, f_buffer,
++ OSS_BUFFER_SIZE/stream->params.channels);
++ for (i=0; i<((unsigned long)got)*stream->params.channels; i++) {
++ buffer[i] = f_buffer[i]*32767.0;
++ }
++ } else {
++ got = run_data_callback(stream, buffer,
++ OSS_BUFFER_SIZE/stream->params.channels);
++ }
++ apply_volume(buffer, got*stream->params.channels,
++ stream->volume, stream->panning);
++ if (got<0) {
++ run_state_callback(stream, CUBEB_STATE_ERROR);
++ break;
++ }
++ if (!got) {
++ run_state_callback(stream, CUBEB_STATE_DRAINED);
++ }
++ if (got) {
++ size_t i = 0;
++ size_t s = got*stream->params.channels*sizeof(int16_t);
++ while (i < s) {
++ ssize_t n = write(stream->fd, ((char*)buffer) + i, s - i);
++ if (n<=0) {
++ run_state_callback(stream, CUBEB_STATE_ERROR);
++ break;
++ }
++ i+=n;
++ }
++ stream->written_frags+=got;
++ }
++ }
++ return NULL;
++}
++
++static void oss_try_set_latency(cubeb_stream* stream, unsigned int latency)
++{
++ unsigned int latency_bytes, n_frag;
++ int frag;
++ /* fragment size of 1024 is a good choice with good chances to be accepted */
++ unsigned int frag_size=1024;
++ unsigned int frag_log=10; /* 2^frag_log = frag_size */
++ latency_bytes =
++ latency*stream->params.rate*stream->params.channels*sizeof(uint16_t)/1000;
++ n_frag = latency_bytes>>frag_log;
++ frag = (n_frag<<16) | frag_log;
++ /* Even if this fails we wish to continue, not checking for errors */
++ ioctl(stream->fd, SNDCTL_DSP_SETFRAGMENT, &frag);
++}
++
++static int oss_stream_init(cubeb * context, cubeb_stream ** stm,
++ char const * stream_name,
++ cubeb_stream_params stream_params,
++ unsigned int latency,
++ cubeb_data_callback data_callback,
++ cubeb_state_callback state_callback, void * user_ptr)
++{
++ cubeb_stream* stream = (cubeb_stream*)malloc(sizeof(cubeb_stream));
++ stream->context = context;
++ stream->data_callback = data_callback;
++ stream->state_callback = state_callback;
++ stream->user_ptr = user_ptr;
++
++ if ((stream->fd = open(CUBEB_OSS_DEFAULT_OUTPUT, O_WRONLY)) == -1) {
++ free(stream);
++ return CUBEB_ERROR;
++ }
++#define SET(what, to) do { unsigned int i = to; \
++ int j = ioctl(stream->fd, what, &i); \
++ if (j == -1 || i != to) { \
++ close(stream->fd); \
++ free(stream); \
++ return CUBEB_ERROR_INVALID_FORMAT; } } while (0)
++
++ stream->params = stream_params;
++ stream->volume = 1.0;
++ stream->panning = 0.0;
++
++ oss_try_set_latency(stream, latency);
++
++ stream->floating = 0;
++ SET(SNDCTL_DSP_CHANNELS, stream_params.channels);
++ SET(SNDCTL_DSP_SPEED, stream_params.rate);
++ switch (stream_params.format) {
++ case CUBEB_SAMPLE_S16LE:
++ SET(SNDCTL_DSP_SETFMT, AFMT_S16_LE);
++ break;
++ case CUBEB_SAMPLE_S16BE:
++ SET(SNDCTL_DSP_SETFMT, AFMT_S16_BE);
++ break;
++ case CUBEB_SAMPLE_FLOAT32LE:
++ SET(SNDCTL_DSP_SETFMT, AFMT_S16_NE);
++ stream->floating = 1;
++ break;
++ default:
++ close(stream->fd);
++ free(stream);
++ return CUBEB_ERROR;
++ }
++
++
++ pthread_mutex_init(&stream->state_mutex, NULL);
++ pthread_cond_init(&stream->state_cond, NULL);
++
++ stream->running = 1;
++ stream->stopped = 1;
++ stream->position_bytes = 0;
++ stream->last_position_bytes = 0;
++ stream->written_frags = 0;
++ stream->missed_frags = 0;
++
++ pthread_create(&stream->th, NULL, writer, (void*)stream);
++
++ *stm = stream;
++
++ return CUBEB_OK;
++}
++
++static void oss_stream_destroy(cubeb_stream * stream)
++{
++ pthread_mutex_lock(&stream->state_mutex);
++
++ stream->running = 0;
++ stream->stopped = 0;
++ pthread_cond_signal(&stream->state_cond);
++
++ pthread_mutex_unlock(&stream->state_mutex);
++
++ pthread_join(stream->th, NULL);
++
++ pthread_mutex_destroy(&stream->state_mutex);
++ pthread_cond_destroy(&stream->state_cond);
++ close(stream->fd);
++ free(stream);
++}
++
++static int oss_stream_get_latency(cubeb_stream * stream, uint32_t * latency)
++{
++ if (ioctl(stream->fd, SNDCTL_DSP_GETODELAY, latency)==-1) {
++ return CUBEB_ERROR;
++ }
++ /* Convert latency from bytes to frames */
++ *latency /= stream->params.channels*sizeof(int16_t);
++ return CUBEB_OK;
++}
++
++
++static int oss_stream_current_optr(cubeb_stream * stream, uint64_t * position)
++{
++ count_info ci;
++ /* Unfortunately, this ioctl is only available in OSS 4.x */
++#ifdef SNDCTL_DSP_CURRENT_OPTR
++ oss_count_t count;
++ if (ioctl(stream->fd, SNDCTL_DSP_CURRENT_OPTR, &count) != -1) {
++ *position = count.samples;// + count.fifo_samples;
++ return CUBEB_OK;
++ }
++#endif
++ /* Fall back to this ioctl in case the previous one fails */
++ if (ioctl(stream->fd, SNDCTL_DSP_GETOPTR, &ci) == -1) {
++ return CUBEB_ERROR;
++ }
++ /* ci.bytes is only 32 bit and will start to wrap after arithmetic overflow */
++ stream->position_bytes += ci.bytes - stream->last_position_bytes;
++ stream->last_position_bytes = ci.bytes;
++ *position = stream->position_bytes/stream->params.channels/sizeof(int16_t);
++ return CUBEB_OK;
++}
++
++static int oss_stream_get_position(cubeb_stream * stream, uint64_t * position)
++{
++ if ( oss_stream_current_optr(stream, position) == CUBEB_OK ){
++ *position -= stream->missed_frags;
++ return CUBEB_OK;
++ }
++ /* If no correct method to get position works we resort to this */
++ *position = stream->written_frags;
++ return CUBEB_OK;
++}
++
++
++static int oss_stream_start(cubeb_stream * stream)
++{
++ pthread_mutex_lock(&stream->state_mutex);
++ if (stream->stopped) {
++ uint64_t ptr;
++ oss_stream_current_optr(stream, &ptr);
++ stream->missed_frags = ptr - stream->written_frags;
++ stream->stopped = 0;
++ pthread_cond_signal(&stream->state_cond);
++ }
++ pthread_mutex_unlock(&stream->state_mutex);
++ return CUBEB_OK;
++}
++
++static int oss_stream_stop(cubeb_stream * stream)
++{
++ pthread_mutex_lock(&stream->state_mutex);
++ stream->stopped = 1;
++ pthread_mutex_unlock(&stream->state_mutex);
++ return CUBEB_OK;
++}
++
++int oss_stream_set_panning(cubeb_stream * stream, float panning)
++{
++ if (stream->params.channels == 2) {
++ stream->panning=panning;
++ }
++ return CUBEB_OK;
++}
++
++int oss_stream_set_volume(cubeb_stream * stream, float volume)
++{
++ stream->volume=volume;
++ return CUBEB_OK;
++}
++
++static struct cubeb_ops const oss_ops = {
++ .init = oss_init,
++ .get_backend_id = oss_get_backend_id,
++ .get_max_channel_count = oss_get_max_channel_count,
++ .get_min_latency = oss_get_min_latency,
++ .get_preferred_sample_rate = oss_get_preferred_sample_rate,
++ .destroy = oss_destroy,
++ .stream_init = oss_stream_init,
++ .stream_destroy = oss_stream_destroy,
++ .stream_start = oss_stream_start,
++ .stream_stop = oss_stream_stop,
++ .stream_get_position = oss_stream_get_position,
++ .stream_get_latency = oss_stream_get_latency
++};
+diff --git media/libcubeb/src/moz.build media/libcubeb/src/moz.build
+index 8b7a0dd..31212ce 100644
+--- mozilla/media/libcubeb/src/moz.build
++++ mozilla/media/libcubeb/src/moz.build
+@@ -17,6 +17,12 @@ if CONFIG['MOZ_ALSA']:
+ ]
+ DEFINES['USE_ALSA'] = True
+
++if CONFIG['MOZ_OSS']:
++ SOURCES += [
++ 'cubeb_oss.c',
++ ]
++ DEFINES['USE_OSS'] = True
++
+ if CONFIG['MOZ_PULSEAUDIO']:
+ SOURCES += [
+ 'cubeb_pulse.c',
+@@ -75,5 +81,6 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
+
+ FAIL_ON_WARNINGS = True
+
++CFLAGS += CONFIG['MOZ_OSS_CFLAGS']
+ CFLAGS += CONFIG['MOZ_ALSA_CFLAGS']
+ CFLAGS += CONFIG['MOZ_PULSEAUDIO_CFLAGS']
+diff --git toolkit/library/libxul.mk toolkit/library/libxul.mk
+index e191f13..4fb268a 100644
+--- mozilla/toolkit/library/libxul.mk
++++ mozilla/toolkit/library/libxul.mk
+@@ -146,6 +146,10 @@ OS_LIBS += $(call EXPAND_LIBNAME,secur32
+ endif
+ endif
+
++ifdef MOZ_OSS
++EXTRA_DSO_LDOPTS += $(MOZ_OSS_LIBS)
++endif
++
+ ifdef MOZ_ALSA
+ EXTRA_DSO_LDOPTS += $(MOZ_ALSA_LIBS)
+ endif
diff --git a/www/seamonkey/files/patch-bug1026828 b/www/seamonkey/files/patch-bug1026828
deleted file mode 100644
index b52dcd4e9788..000000000000
--- a/www/seamonkey/files/patch-bug1026828
+++ /dev/null
@@ -1,20 +0,0 @@
-diff --git storage/src/moz.build storage/src/moz.build
-index 4cd2551..5c40536 100644
---- mozilla/storage/src/moz.build
-+++ mozilla/storage/src/moz.build
-@@ -50,11 +50,14 @@ FINAL_LIBRARY = 'storagecomps'
- # (such as NSS) might trigger an initialization of sqlite and allocation
- # of memory using the default allocator, prior to the storage service
- # registering its allocator, causing memory management failures (bug 938730).
-+# However, this is not an issue if both the jemalloc allocator and the default
-+# allocator are the same thing.
- #
- # Note: On Windows our sqlite build assumes we use jemalloc. If you disable
- # MOZ_STORAGE_MEMORY on Windows, you will also need to change the "ifdef
- # MOZ_MEMORY" options in db/sqlite3/src/Makefile.in.
--if CONFIG['MOZ_MEMORY'] and not CONFIG['MOZ_NATIVE_SQLITE']:
-+if CONFIG['MOZ_MEMORY'] and (not CONFIG['MOZ_NATIVE_SQLITE']
-+ or CONFIG['MOZ_NATIVE_JEMALLOC']):
- if CONFIG['OS_TARGET'] != 'Android':
- DEFINES['MOZ_STORAGE_MEMORY'] = True
-
diff --git a/www/seamonkey/files/patch-bug1041268 b/www/seamonkey/files/patch-bug1041268
new file mode 100644
index 000000000000..39ddbbdb490f
--- /dev/null
+++ b/www/seamonkey/files/patch-bug1041268
@@ -0,0 +1,26 @@
+diff --git media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer.cc media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer.cc
+index 97f69d3..77a50b3 100644
+--- mozilla/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer.cc
++++ mozilla/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer.cc
+@@ -18,7 +18,7 @@ ScreenCapturer* ScreenCapturer::Create() {
+ return Create(DesktopCaptureOptions::CreateDefault());
+ }
+
+-#if defined(WEBRTC_LINUX)
++#if defined(WEBRTC_LINUX) || defined(WEBRTC_BSD)
+ ScreenCapturer* ScreenCapturer::CreateWithXDamage(
+ bool use_update_notifications) {
+ DesktopCaptureOptions options;
+diff --git media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer.h media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer.h
+index a8d40a7..177a6c1 100644
+--- mozilla/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer.h
++++ mozilla/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer.h
+@@ -74,7 +74,7 @@ class ScreenCapturer : public DesktopCapturer {
+ static ScreenCapturer* Create(const DesktopCaptureOptions& options);
+ static ScreenCapturer* Create();
+
+-#if defined(WEBRTC_LINUX)
++#if defined(WEBRTC_LINUX) || defined(WEBRTC_BSD)
+ // Creates platform-specific capturer and instructs it whether it should use
+ // X DAMAGE support.
+ static ScreenCapturer* CreateWithXDamage(bool use_x_damage);
diff --git a/www/seamonkey/files/patch-bug1073709 b/www/seamonkey/files/patch-bug1073709
new file mode 100644
index 000000000000..054ed2725747
--- /dev/null
+++ b/www/seamonkey/files/patch-bug1073709
@@ -0,0 +1,18 @@
+diff --git mfbt/Atomics.h mfbt/Atomics.h
+index 495a9d3..c7f7601 100644
+--- mozilla/mfbt/Atomics.h
++++ mozilla/mfbt/Atomics.h
+@@ -34,10 +34,12 @@
+ * loose typing of the atomic builtins. GCC 4.5 and 4.6 lacks inline
+ * definitions for unspecialized std::atomic and causes linking errors.
+ * Therefore, we require at least 4.7.0 for using libstdc++.
++ *
++ * libc++ <atomic> is only functional with clang.
+ */
+ # if MOZ_USING_LIBSTDCXX && MOZ_LIBSTDCXX_VERSION_AT_LEAST(4, 7, 0)
+ # define MOZ_HAVE_CXX11_ATOMICS
+-# elif MOZ_USING_LIBCXX
++# elif MOZ_USING_LIBCXX && defined(__clang__)
+ # define MOZ_HAVE_CXX11_ATOMICS
+ # endif
+ /*
diff --git a/www/seamonkey/files/patch-bug1076983 b/www/seamonkey/files/patch-bug1076983
new file mode 100644
index 000000000000..ff764be7398f
--- /dev/null
+++ b/www/seamonkey/files/patch-bug1076983
@@ -0,0 +1,45 @@
+commit e10ee74
+Author: Martin Thomson <martin.thomson@gmail.com>
+Date: Tue Oct 14 17:17:35 2014 -0700
+
+ Bug 1076983 - Disabling SSL 3.0 with pref
+---
+ netwerk/base/public/security-prefs.js | 2 +-
+ security/manager/ssl/src/nsNSSComponent.cpp | 7 +++----
+ 2 files changed, 4 insertions(+), 5 deletions(-)
+
+diff --git netwerk/base/public/security-prefs.js netwerk/base/public/security-prefs.js
+index 352552e..c12731b 100644
+--- mozilla/netwerk/base/public/security-prefs.js
++++ mozilla/netwerk/base/public/security-prefs.js
+@@ -2,7 +2,7 @@
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+-pref("security.tls.version.min", 0);
++pref("security.tls.version.min", 1);
+ pref("security.tls.version.max", 3);
+
+ pref("security.ssl.allow_unrestricted_renego_everywhere__temporarily_available_pref", false);
+diff --git security/manager/ssl/src/nsNSSComponent.cpp security/manager/ssl/src/nsNSSComponent.cpp
+index 8cab67b..772959d 100644
+--- mozilla/security/manager/ssl/src/nsNSSComponent.cpp
++++ mozilla/security/manager/ssl/src/nsNSSComponent.cpp
+@@ -829,14 +829,13 @@ void nsNSSComponent::setValidationOptions(bool isInitialSetting,
+ mDefaultCertVerifier = new SharedCertVerifier(odc, osc, ogc, pinningMode);
+ }
+
+-// Enable the TLS versions given in the prefs, defaulting to SSL 3.0 (min
+-// version) and TLS 1.2 (max version) when the prefs aren't set or set to
+-// invalid values.
++// Enable the TLS versions given in the prefs, defaulting to TLS 1.0 (min) and
++// TLS 1.2 (max) when the prefs aren't set or set to invalid values.
+ nsresult
+ nsNSSComponent::setEnabledTLSVersions()
+ {
+ // keep these values in sync with security-prefs.js
+- static const int32_t PSM_DEFAULT_MIN_TLS_VERSION = 0;
++ static const int32_t PSM_DEFAULT_MIN_TLS_VERSION = 1;
+ static const int32_t PSM_DEFAULT_MAX_TLS_VERSION = 3;
+
+ int32_t minVersion = Preferences::GetInt("security.tls.version.min",
diff --git a/www/seamonkey/files/patch-bug779713 b/www/seamonkey/files/patch-bug779713
index cb721cba24a4..0291c554a056 100644
--- a/www/seamonkey/files/patch-bug779713
+++ b/www/seamonkey/files/patch-bug779713
@@ -47,7 +47,15 @@ diff --git mfbt/Attributes.h mfbt/Attributes.h
index d317766..ddb13da 100644
--- mozilla/mfbt/Attributes.h
+++ mozilla/mfbt/Attributes.h
-@@ -54,6 +54,9 @@
+@@ -51,6 +51,7 @@
+ * http://stackoverflow.com/questions/20498142/visual-studio-2013-explicit-keyword-bug
+ */
+ # if _MSC_VER >= 1800
++# define MOZ_HAVE_CXX11_ALIGNAS
+ # define MOZ_HAVE_CXX11_DELETE
+ # endif
+ # if _MSC_VER >= 1700
+@@ -74,6 +75,9 @@
# ifndef __has_extension
# define __has_extension __has_feature /* compatibility, for older versions of clang */
# endif
@@ -57,7 +65,7 @@ index d317766..ddb13da 100644
# if __has_extension(cxx_constexpr)
# define MOZ_HAVE_CXX11_CONSTEXPR
# endif
-@@ -75,6 +78,9 @@
+@@ -95,6 +99,9 @@
# endif
#elif defined(__GNUC__)
# if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L
@@ -67,11 +75,3 @@ index d317766..ddb13da 100644
# if MOZ_GCC_VERSION_AT_LEAST(4, 7, 0)
# define MOZ_HAVE_CXX11_OVERRIDE
# define MOZ_HAVE_CXX11_FINAL final
-@@ -96,6 +102,7 @@
- # define MOZ_HAVE_NORETURN __attribute__((noreturn))
- #elif defined(_MSC_VER)
- # if _MSC_VER >= 1800
-+# define MOZ_HAVE_CXX11_ALIGNAS
- # define MOZ_HAVE_CXX11_DELETE
- # endif
- # if _MSC_VER >= 1700
diff --git a/www/seamonkey/files/patch-bug826985 b/www/seamonkey/files/patch-bug826985
index 9d34ae0eafb2..8f07dc1d02a1 100644
--- a/www/seamonkey/files/patch-bug826985
+++ b/www/seamonkey/files/patch-bug826985
@@ -132,7 +132,7 @@ index d46b5aa..e452223 100644
'targets': [
{
'target_name': 'video_capture_module',
-@@ -46,6 +49,16 @@
+@@ -46,6 +49,19 @@
'linux/video_capture_linux.cc',
'linux/video_capture_linux.h',
],
@@ -141,6 +141,9 @@ index d46b5aa..e452223 100644
+ 'defines': [
+ 'HAVE_LIBV4L2',
+ ],
++ 'cflags_mozilla': [
++ '$(MOZ_LIBV4L2_CFLAGS)',
++ ],
+ 'libraries': [
+ '-lv4l2',
+ ],
diff --git a/www/seamonkey/files/patch-bug847568 b/www/seamonkey/files/patch-bug847568
index 2eb54438a5b6..d95a12344f32 100644
--- a/www/seamonkey/files/patch-bug847568
+++ b/www/seamonkey/files/patch-bug847568
@@ -164,9 +164,9 @@ diff --git intl/unicharutil/util/Makefile.in intl/unicharutil/util/Makefile.in
index f6b9f7c..60863f4 100644
--- mozilla/intl/unicharutil/util/Makefile.in
+++ mozilla/intl/unicharutil/util/Makefile.in
-@@ -21,3 +21,7 @@ ifdef _MSC_VER
- OS_COMPILE_CXXFLAGS += -Zl
- OS_COMPILE_CFLAGS += -Zl
+@@ -15,3 +15,7 @@ include $(topsrcdir)/config/rules.mk
+ ifdef ENABLE_INTL_API
+ LOCAL_INCLUDES += $(MOZ_ICU_CFLAGS)
endif
+
+ifdef MOZ_NATIVE_HARFBUZZ
diff --git a/www/seamonkey/files/patch-clang34-disable-stdcall b/www/seamonkey/files/patch-clang34-disable-stdcall
deleted file mode 100644
index 2b91fba7197f..000000000000
--- a/www/seamonkey/files/patch-clang34-disable-stdcall
+++ /dev/null
@@ -1,13 +0,0 @@
-# http://llvm.org/bugs/show_bug.cgi?id=19007
-
---- mozilla/xpcom/base/nscore.h~
-+++ mozilla/xpcom/base/nscore.h
-@@ -110,7 +110,7 @@
- * NS_HIDDEN_(int) NS_FASTCALL func2(char *foo);
- */
-
--#if defined(__i386__) && defined(__GNUC__)
-+#if defined(__i386__) && defined(__GNUC__) && !(defined(__clang__) && __clang_major__ == 3 && __clang_minor__ == 4 && __clang_patchlevel__ == 0)
- #define NS_FASTCALL __attribute__ ((regparm (3), stdcall))
- #define NS_CONSTRUCTOR_FASTCALL __attribute__ ((regparm (3), stdcall))
- #elif defined(XP_WIN) && !defined(_WIN64)
diff --git a/www/seamonkey/files/patch-system-openh264 b/www/seamonkey/files/patch-system-openh264
new file mode 100644
index 000000000000..d318a9d68c7e
--- /dev/null
+++ b/www/seamonkey/files/patch-system-openh264
@@ -0,0 +1,218 @@
+# Revert bug 1045209 to allow using absolute path
+
+diff --git content/media/gmp/GMPChild.cpp content/media/gmp/GMPChild.cpp
+index 4165a75..81914d5 100644
+--- mozilla/content/media/gmp/GMPChild.cpp
++++ mozilla/content/media/gmp/GMPChild.cpp
+@@ -66,19 +66,11 @@
+ }
+ #endif
+
+- nsCOMPtr<nsIFile> parent;
+- rv = aLibFile->GetParent(getter_AddRefs(parent));
+- if (NS_FAILED(rv)) {
+- return false;
+- }
+-
+- nsAutoString parentLeafName;
+- rv = parent->GetLeafName(parentLeafName);
+- if (NS_FAILED(rv)) {
++ nsAutoString leafName;
++ if (NS_FAILED(aLibFile->GetLeafName(leafName))) {
+ return false;
+ }
+-
+- nsAutoString baseName(Substring(parentLeafName, 4, parentLeafName.Length() - 1));
++ nsAutoString baseName(Substring(leafName, 4, leafName.Length() - 1));
+
+ #if defined(XP_MACOSX)
+ nsAutoString binaryName = NS_LITERAL_STRING("lib") + baseName + NS_LITERAL_STRING(".dylib");
+diff --git content/media/gmp/GMPParent.cpp content/media/gmp/GMPParent.cpp
+index e63453e..bf83b30 100644
+--- mozilla/content/media/gmp/GMPParent.cpp
++++ mozilla/content/media/gmp/GMPParent.cpp
+@@ -87,23 +87,16 @@
+ mService = aService;
+ mDirectory = aPluginDir;
+
+- // aPluginDir is <profile-dir>/<gmp-plugin-id>/<version>
+- // where <gmp-plugin-id> should be gmp-gmpopenh264
+- nsCOMPtr<nsIFile> parent;
+- nsresult rv = aPluginDir->GetParent(getter_AddRefs(parent));
+- if (NS_FAILED(rv)) {
+- return rv;
+- }
+- nsAutoString parentLeafName;
+- rv = parent->GetLeafName(parentLeafName);
++ nsAutoString leafname;
++ nsresult rv = aPluginDir->GetLeafName(leafname);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+ LOGD(("%s::%s: %p for %s", __CLASS__, __FUNCTION__, this,
+- NS_LossyConvertUTF16toASCII(parentLeafName).get()));
++ NS_LossyConvertUTF16toASCII(leafname).get()));
+
+- MOZ_ASSERT(parentLeafName.Length() > 4);
+- mName = Substring(parentLeafName, 4);
++ MOZ_ASSERT(leafname.Length() > 4);
++ mName = Substring(leafname, 4);
+
+ return ReadGMPMetaData();
+ }
+diff --git toolkit/modules/GMPInstallManager.jsm toolkit/modules/GMPInstallManager.jsm
+index 9593492..470384b 100644
+--- mozilla/toolkit/modules/GMPInstallManager.jsm
++++ mozilla/toolkit/modules/GMPInstallManager.jsm
+@@ -107,6 +107,7 @@
+ */
+ KEY_LOG_ENABLED: "media.gmp-manager.log",
+ KEY_ADDON_LAST_UPDATE: "media.{0}.lastUpdate",
++ KEY_ADDON_PATH: "media.{0}.path",
+ KEY_ADDON_VERSION: "media.{0}.version",
+ KEY_ADDON_AUTOUPDATE: "media.{0}.autoupdate",
+ KEY_URL: "media.gmp-manager.url",
+@@ -888,9 +889,7 @@
+ let gmpAddon = this._gmpAddon;
+ let installToDirPath = Cc["@mozilla.org/file/local;1"].
+ createInstance(Ci.nsIFile);
+- let path = OS.Path.join(OS.Constants.Path.profileDir,
+- gmpAddon.id,
+- gmpAddon.version);
++ let path = OS.Path.join(OS.Constants.Path.profileDir, gmpAddon.id);
+ installToDirPath.initWithPath(path);
+ log.info("install to directory path: " + installToDirPath.path);
+ let gmpInstaller = new GMPExtractor(zipPath, installToDirPath.path);
+@@ -899,10 +898,12 @@
+ // Success, set the prefs
+ let now = Math.round(Date.now() / 1000);
+ GMPPrefs.set(GMPPrefs.KEY_ADDON_LAST_UPDATE, now, gmpAddon.id);
+- // Setting the version pref signals installation completion to consumers,
+- // if you need to set other prefs etc. do it before this.
++ // Setting the path pref signals installation completion to consumers,
++ // so set the version and potential other information they use first.
+ GMPPrefs.set(GMPPrefs.KEY_ADDON_VERSION, gmpAddon.version,
+ gmpAddon.id);
++ GMPPrefs.set(GMPPrefs.KEY_ADDON_PATH,
++ installToDirPath.path, gmpAddon.id);
+ this._deferred.resolve(extractedPaths);
+ }, err => {
+ this._deferred.reject(err);
+diff --git toolkit/mozapps/extensions/internal/OpenH264Provider.jsm toolkit/mozapps/extensions/internal/OpenH264Provider.jsm
+index 1f3a0b1..93517be 100644
+--- mozilla/toolkit/mozapps/extensions/internal/OpenH264Provider.jsm
++++ mozilla/toolkit/mozapps/extensions/internal/OpenH264Provider.jsm
+@@ -29,6 +29,7 @@
+ const OPENH264_PLUGIN_ID = "gmp-gmpopenh264";
+ const OPENH264_PREF_BRANCH = "media." + OPENH264_PLUGIN_ID + ".";
+ const OPENH264_PREF_ENABLED = "enabled";
++const OPENH264_PREF_PATH = "path";
+ const OPENH264_PREF_VERSION = "version";
+ const OPENH264_PREF_LASTUPDATE = "lastUpdate";
+ const OPENH264_PREF_AUTOUPDATE = "autoupdate";
+@@ -93,7 +94,12 @@
+
+ get description() { return pluginsBundle.GetStringFromName("openH264_description"); },
+
+- get version() { return prefs.get(OPENH264_PREF_VERSION, ""); },
++ get version() {
++ if (this.isInstalled) {
++ return prefs.get(OPENH264_PREF_VERSION, "");
++ }
++ return "";
++ },
+
+ get isActive() { return !this.userDisabled; },
+ get appDisabled() { return false; },
+@@ -217,24 +223,17 @@
+
+ get pluginMimeTypes() { return []; },
+ get pluginLibraries() {
+- if (this.isInstalled) {
+- let path = this.version;
+- return [path];
+- }
+- return [];
++ let path = prefs.get(OPENH264_PREF_PATH, null);
++ return path && path.length ? [OS.Path.basename(path)] : [];
+ },
+ get pluginFullpath() {
+- if (this.isInstalled) {
+- let path = OS.Path.join(OS.Constants.Path.profileDir,
+- OPENH264_PLUGIN_ID,
+- this.version);
+- return [path];
+- }
+- return [];
++ let path = prefs.get(OPENH264_PREF_PATH, null);
++ return path && path.length ? [path] : [];
+ },
+
+ get isInstalled() {
+- return this.version.length > 0;
++ let path = prefs.get(OPENH264_PREF_PATH, "");
++ return path.length > 0;
+ },
+ };
+
+@@ -245,19 +244,14 @@
+ "OpenH264Provider" + "::");
+ OpenH264Wrapper._log = Log.repository.getLoggerWithMessagePrefix("Toolkit.OpenH264Provider",
+ "OpenH264Wrapper" + "::");
+- this.gmpPath = null;
+- if (OpenH264Wrapper.isInstalled) {
+- this.gmpPath = OS.Path.join(OS.Constants.Path.profileDir,
+- OPENH264_PLUGIN_ID,
+- prefs.get(OPENH264_PREF_VERSION, null));
+- }
++ this.gmpPath = prefs.get(OPENH264_PREF_PATH, null);
+ let enabled = prefs.get(OPENH264_PREF_ENABLED, true);
+ this._log.trace("startup() - enabled=" + enabled + ", gmpPath="+this.gmpPath);
+
+
+ Services.obs.addObserver(this, AddonManager.OPTIONS_NOTIFICATION_DISPLAYED, false);
+ prefs.observe(OPENH264_PREF_ENABLED, this.onPrefEnabledChanged, this);
+- prefs.observe(OPENH264_PREF_VERSION, this.onPrefVersionChanged, this);
++ prefs.observe(OPENH264_PREF_PATH, this.onPrefPathChanged, this);
+ prefs.observe(OPENH264_PREF_LOGGING, configureLogging);
+
+ if (this.gmpPath && enabled) {
+@@ -270,7 +264,7 @@
+ this._log.trace("shutdown()");
+ Services.obs.removeObserver(this, AddonManager.OPTIONS_NOTIFICATION_DISPLAYED);
+ prefs.ignore(OPENH264_PREF_ENABLED, this.onPrefEnabledChanged, this);
+- prefs.ignore(OPENH264_PREF_VERSION, this.onPrefVersionChanged, this);
++ prefs.ignore(OPENH264_PREF_PATH, this.onPrefPathChanged, this);
+ prefs.ignore(OPENH264_PREF_LOGGING, configureLogging);
+
+ return OpenH264Wrapper._updateTask;
+@@ -296,25 +290,20 @@
+ wrapper);
+ },
+
+- onPrefVersionChanged: function() {
++ onPrefPathChanged: function() {
+ let wrapper = OpenH264Wrapper;
+
+ AddonManagerPrivate.callAddonListeners("onUninstalling", wrapper, false);
+ if (this.gmpPath) {
+- this._log.info("onPrefVersionChanged() - unregistering gmp directory " + this.gmpPath);
++ this._log.info("onPrefPathChanged() - removing gmp directory " + this.gmpPath);
+ gmpService.removePluginDirectory(this.gmpPath);
+ }
+ AddonManagerPrivate.callAddonListeners("onUninstalled", wrapper);
+
+ AddonManagerPrivate.callInstallListeners("onExternalInstall", null, wrapper, null, false);
+- this.gmpPath = null;
+- if (OpenH264Wrapper.isInstalled) {
+- this.gmpPath = OS.Path.join(OS.Constants.Path.profileDir,
+- OPENH264_PLUGIN_ID,
+- prefs.get(OPENH264_PREF_VERSION, null));
+- }
++ this.gmpPath = prefs.get(OPENH264_PREF_PATH, null);
+ if (this.gmpPath && wrapper.isActive) {
+- this._log.info("onPrefVersionChanged() - registering gmp directory " + this.gmpPath);
++ this._log.info("onPrefPathChanged() - adding gmp directory " + this.gmpPath);
+ gmpService.addPluginDirectory(this.gmpPath);
+ }
+ AddonManagerPrivate.callAddonListeners("onInstalled", wrapper);