diff options
author | jbeich <jbeich@FreeBSD.org> | 2018-11-21 02:54:51 +0800 |
---|---|---|
committer | jbeich <jbeich@FreeBSD.org> | 2018-11-21 02:54:51 +0800 |
commit | 098a888c8d8ec393674d12df7494fb81efbe12d8 (patch) | |
tree | 3275386cff4261cf7fcd8d7487d133aa4ddc7cc9 /www | |
parent | ca2bf799f55fbeb51a26dbd8d92057224cdade7b (diff) | |
download | freebsd-ports-gnome-098a888c8d8ec393674d12df7494fb81efbe12d8.tar.gz freebsd-ports-gnome-098a888c8d8ec393674d12df7494fb81efbe12d8.tar.zst freebsd-ports-gnome-098a888c8d8ec393674d12df7494fb81efbe12d8.zip |
gecko: drop OSS audio backend
- Poor latency
- No multichannel support
- No input device support
- No device selection
- No upstream maintainer
Diffstat (limited to 'www')
-rw-r--r-- | www/firefox-esr/Makefile | 2 | ||||
-rw-r--r-- | www/firefox-esr/files/patch-bug1021761 | 1269 | ||||
-rw-r--r-- | www/firefox-esr/pkg-message | 4 | ||||
-rw-r--r-- | www/firefox/Makefile | 1 | ||||
-rw-r--r-- | www/firefox/files/patch-bug1021761 | 1268 | ||||
-rw-r--r-- | www/firefox/pkg-message | 4 | ||||
-rw-r--r-- | www/seamonkey/Makefile | 2 | ||||
-rw-r--r-- | www/seamonkey/files/patch-bug1021761 | 1157 |
8 files changed, 7 insertions, 3700 deletions
diff --git a/www/firefox-esr/Makefile b/www/firefox-esr/Makefile index b8abc3929ef0..e74798ee6aee 100644 --- a/www/firefox-esr/Makefile +++ b/www/firefox-esr/Makefile @@ -3,7 +3,7 @@ PORTNAME= firefox DISTVERSION= 60.3.0 -PORTREVISION= 3 +PORTREVISION= 4 PORTEPOCH= 1 CATEGORIES= www ipv6 MASTER_SITES= MOZILLA/${PORTNAME}/releases/${DISTVERSION}esr/source \ diff --git a/www/firefox-esr/files/patch-bug1021761 b/www/firefox-esr/files/patch-bug1021761 deleted file mode 100644 index 245f4fd8695a..000000000000 --- a/www/firefox-esr/files/patch-bug1021761 +++ /dev/null @@ -1,1269 +0,0 @@ -commit f9bcf9c81c4a -Author: Evgeniy Vodolazskiy <waterlaz@gmail.com> -Date: Tue Sep 9 14:38:00 2014 -0700 - - Bug 1021761 - Make ALSA optional on Linux, allowing fallback to another backend. r=kinetik r=glandium ---- - media/libcubeb/gtest/moz.build | 1 - - media/libcubeb/src/cubeb_alsa.c | 228 +++++++++++++++++++++++++++++----------- - toolkit/library/moz.build | 3 - - 3 files changed, 168 insertions(+), 64 deletions(-) - -diff --git media/libcubeb/gtest/moz.build media/libcubeb/gtest/moz.build -index 558130188c2e..0cf157d41903 100644 ---- media/libcubeb/gtest/moz.build -+++ media/libcubeb/gtest/moz.build -@@ -72,7 +72,6 @@ elif CONFIG['OS_TARGET'] == 'OpenBSD': - 'sndio', - ] - else: -- OS_LIBS += CONFIG['MOZ_ALSA_LIBS'] - OS_LIBS += CONFIG['MOZ_PULSEAUDIO_LIBS'] - - if CONFIG['CC_TYPE'] in ('clang', 'gcc'): -diff --git media/libcubeb/src/cubeb_alsa.c media/libcubeb/src/cubeb_alsa.c -index bfd4d8f199d4..213c1eaa3d07 100644 ---- media/libcubeb/src/cubeb_alsa.c -+++ media/libcubeb/src/cubeb_alsa.c -@@ -12,6 +12,7 @@ - #include <sys/time.h> - #include <assert.h> - #include <limits.h> -+#include <dlfcn.h> - #include <poll.h> - #include <unistd.h> - #include <alsa/asoundlib.h> -@@ -25,6 +26,52 @@ - - #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_readi); -+MAKE_TYPEDEF(snd_pcm_recover); -+MAKE_TYPEDEF(snd_pcm_set_params); -+MAKE_TYPEDEF(snd_pcm_start); -+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), -@@ -65,6 +112,8 @@ struct cubeb { - workaround is not required. */ - snd_config_t * local_config; - int is_pa; -+ -+ void * libasound; - }; - - enum stream_state { -@@ -245,8 +294,8 @@ set_timeout(struct timeval * timeout, unsigned int ms) - static void - stream_buffer_decrement(cubeb_stream * stm, long count) - { -- char * bufremains = stm->buffer + snd_pcm_frames_to_bytes(stm->pcm, count); -- memmove(stm->buffer, bufremains, snd_pcm_frames_to_bytes(stm->pcm, stm->bufframes - count)); -+ char * bufremains = stm->buffer + WRAP(snd_pcm_frames_to_bytes)(stm->pcm, count); -+ memmove(stm->buffer, bufremains, WRAP(snd_pcm_frames_to_bytes)(stm->pcm, stm->bufframes - count)); - stm->bufframes -= count; - } - -@@ -278,9 +327,9 @@ alsa_process_stream(cubeb_stream * stm) - /* Call _poll_descriptors_revents() even if we don't use it - to let underlying plugins clear null events. Otherwise poll() - may wake up again and again, producing unnecessary CPU usage. */ -- snd_pcm_poll_descriptors_revents(stm->pcm, stm->fds, stm->nfds, &revents); -+ WRAP(snd_pcm_poll_descriptors_revents)(stm->pcm, stm->fds, stm->nfds, &revents); - -- avail = snd_pcm_avail_update(stm->pcm); -+ avail = WRAP(snd_pcm_avail_update)(stm->pcm); - - /* Got null event? Bail and wait for another wakeup. */ - if (avail == 0) { -@@ -303,7 +352,7 @@ alsa_process_stream(cubeb_stream * stm) - // TODO: should it be marked as DRAINING? - } - -- got = snd_pcm_readi(stm->pcm, stm->buffer+stm->bufframes, avail); -+ got = WRAP(snd_pcm_readi)(stm->pcm, stm->buffer+stm->bufframes, avail); - - if (got < 0) { - avail = got; // the error handler below will recover us -@@ -347,7 +396,7 @@ alsa_process_stream(cubeb_stream * stm) - (!stm->other_stream || stm->other_stream->bufframes > 0)) { - long got = avail - stm->bufframes; - void * other_buffer = stm->other_stream ? stm->other_stream->buffer : NULL; -- char * buftail = stm->buffer + snd_pcm_frames_to_bytes(stm->pcm, stm->bufframes); -+ char * buftail = stm->buffer + WRAP(snd_pcm_frames_to_bytes)(stm->pcm, stm->bufframes); - - /* Correct read size to the other stream available frames */ - if (stm->other_stream && got > (snd_pcm_sframes_t) stm->other_stream->bufframes) { -@@ -374,8 +423,8 @@ alsa_process_stream(cubeb_stream * stm) - long drain_frames = avail - stm->bufframes; - double drain_time = (double) drain_frames / stm->params.rate; - -- char * buftail = stm->buffer + snd_pcm_frames_to_bytes(stm->pcm, stm->bufframes); -- memset(buftail, 0, snd_pcm_frames_to_bytes(stm->pcm, drain_frames)); -+ char * buftail = stm->buffer + WRAP(snd_pcm_frames_to_bytes)(stm->pcm, stm->bufframes); -+ memset(buftail, 0, WRAP(snd_pcm_frames_to_bytes)(stm->pcm, drain_frames)); - stm->bufframes = avail; - - /* Mark as draining, unless we're waiting for capture */ -@@ -402,7 +451,7 @@ alsa_process_stream(cubeb_stream * stm) - } - } - -- wrote = snd_pcm_writei(stm->pcm, stm->buffer, avail); -+ wrote = WRAP(snd_pcm_writei)(stm->pcm, stm->buffer, avail); - if (wrote < 0) { - avail = wrote; // the error handler below will recover us - } else { -@@ -415,13 +464,13 @@ alsa_process_stream(cubeb_stream * stm) - - /* Got some error? Let's try to recover the stream. */ - if (avail < 0) { -- avail = snd_pcm_recover(stm->pcm, avail, 0); -+ avail = WRAP(snd_pcm_recover)(stm->pcm, avail, 0); - - /* Capture pcm must be started after initial setup/recover */ - if (avail >= 0 && - stm->stream_type == SND_PCM_STREAM_CAPTURE && -- snd_pcm_state(stm->pcm) == SND_PCM_STATE_PREPARED) { -- avail = snd_pcm_start(stm->pcm); -+ WRAP(snd_pcm_state)(stm->pcm) == SND_PCM_STATE_PREPARED) { -+ avail = WRAP(snd_pcm_start)(stm->pcm); - } - } - -@@ -537,26 +586,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; - } -@@ -565,7 +614,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; - } -@@ -574,7 +623,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; -@@ -597,22 +646,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; - } -@@ -621,7 +670,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; - } -@@ -632,12 +681,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; - } -@@ -648,18 +697,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; - } -@@ -667,7 +716,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; - } -@@ -679,9 +728,9 @@ alsa_locked_pcm_open(snd_pcm_t ** pcm, char const * pcm_name, snd_pcm_stream_t s - - pthread_mutex_lock(&cubeb_alsa_mutex); - if (local_config) { -- r = snd_pcm_open_lconf(pcm, pcm_name, stream, SND_PCM_NONBLOCK, local_config); -+ r = WRAP(snd_pcm_open_lconf)(pcm, pcm_name, stream, SND_PCM_NONBLOCK, local_config); - } else { -- r = snd_pcm_open(pcm, pcm_name, stream, SND_PCM_NONBLOCK); -+ r = WRAP(snd_pcm_open)(pcm, pcm_name, stream, SND_PCM_NONBLOCK); - } - pthread_mutex_unlock(&cubeb_alsa_mutex); - -@@ -694,7 +743,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; -@@ -757,12 +806,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); -@@ -770,6 +872,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); -@@ -819,7 +923,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) { -@@ -859,9 +963,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); - } - -@@ -948,7 +1056,7 @@ alsa_stream_init_single(cubeb * ctx, cubeb_stream ** stream, char const * stream - return CUBEB_ERROR; - } - -- r = snd_pcm_nonblock(stm->pcm, 1); -+ r = WRAP(snd_pcm_nonblock)(stm->pcm, 1); - assert(r == 0); - - latency_us = latency_frames * 1e6 / stm->params.rate; -@@ -961,7 +1069,7 @@ alsa_stream_init_single(cubeb * ctx, cubeb_stream ** stream, char const * stream - latency_us = latency_us < min_latency ? min_latency: latency_us; - } - -- r = snd_pcm_set_params(stm->pcm, format, SND_PCM_ACCESS_RW_INTERLEAVED, -+ r = WRAP(snd_pcm_set_params)(stm->pcm, format, SND_PCM_ACCESS_RW_INTERLEAVED, - stm->params.channels, stm->params.rate, 1, - latency_us); - if (r < 0) { -@@ -969,20 +1077,20 @@ alsa_stream_init_single(cubeb * ctx, cubeb_stream ** stream, char const * stream - return CUBEB_ERROR_INVALID_FORMAT; - } - -- r = snd_pcm_get_params(stm->pcm, &stm->buffer_size, &period_size); -+ r = WRAP(snd_pcm_get_params)(stm->pcm, &stm->buffer_size, &period_size); - assert(r == 0); - - /* Double internal buffer size to have enough space when waiting for the other side of duplex connection */ - stm->buffer_size *= 2; -- stm->buffer = calloc(1, snd_pcm_frames_to_bytes(stm->pcm, stm->buffer_size)); -+ stm->buffer = calloc(1, WRAP(snd_pcm_frames_to_bytes)(stm->pcm, stm->buffer_size)); - assert(stm->buffer); - -- 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); - - if (alsa_register_stream(ctx, stm) != 0) { -@@ -1054,7 +1162,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; -@@ -1100,12 +1208,12 @@ alsa_get_max_channel_count(cubeb * ctx, uint32_t * max_channels) - - assert(stm); - -- r = snd_pcm_hw_params_any(stm->pcm, hw_params); -+ r = WRAP(snd_pcm_hw_params_any)(stm->pcm, hw_params); - if (r < 0) { - return CUBEB_ERROR; - } - -- r = snd_pcm_hw_params_get_channels_max(hw_params, max_channels); -+ r = WRAP(snd_pcm_hw_params_get_channels_max)(hw_params, max_channels); - if (r < 0) { - return CUBEB_ERROR; - } -@@ -1126,34 +1234,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. */ -- r = snd_pcm_open(&pcm, CUBEB_ALSA_PCM_NAME, SND_PCM_STREAM_PLAYBACK, SND_PCM_NO_AUTO_RESAMPLE); -+ r = WRAP(snd_pcm_open)(&pcm, CUBEB_ALSA_PCM_NAME, SND_PCM_STREAM_PLAYBACK, SND_PCM_NO_AUTO_RESAMPLE); - if (r < 0) { - return CUBEB_ERROR; - } - -- r = snd_pcm_hw_params_any(pcm, hw_params); -+ r = WRAP(snd_pcm_hw_params_any)(pcm, hw_params); - if (r < 0) { -- snd_pcm_close(pcm); -+ WRAP(snd_pcm_close)(pcm); - return CUBEB_ERROR; - } - -- r = snd_pcm_hw_params_get_rate(hw_params, rate, &dir); -+ r = WRAP(snd_pcm_hw_params_get_rate)(hw_params, rate, &dir); - if (r >= 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; - -- r = snd_pcm_hw_params_set_rate_near(pcm, hw_params, rate, NULL); -+ r = WRAP(snd_pcm_hw_params_set_rate_near)(pcm, hw_params, rate, NULL); - if (r < 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; - } -@@ -1186,10 +1294,10 @@ alsa_stream_start(cubeb_stream * stm) - pthread_mutex_lock(&stm->mutex); - /* Capture pcm must be started after initial setup/recover */ - if (stm->stream_type == SND_PCM_STREAM_CAPTURE && -- snd_pcm_state(stm->pcm) == SND_PCM_STATE_PREPARED) { -- snd_pcm_start(stm->pcm); -+ WRAP(snd_pcm_state)(stm->pcm) == SND_PCM_STATE_PREPARED) { -+ WRAP(snd_pcm_start)(stm->pcm); - } -- snd_pcm_pause(stm->pcm, 0); -+ WRAP(snd_pcm_pause)(stm->pcm, 0); - gettimeofday(&stm->last_activity, NULL); - pthread_mutex_unlock(&stm->mutex); - -@@ -1229,7 +1337,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; -@@ -1245,8 +1353,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; -@@ -1271,7 +1379,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 toolkit/library/moz.build toolkit/library/moz.build -index b0df6b98b91f..e06592daa265 100644 ---- toolkit/library/moz.build -+++ toolkit/library/moz.build -@@ -247,9 +247,6 @@ if CONFIG['MOZ_SYSTEM_LIBVPX']: - if not CONFIG['MOZ_TREE_PIXMAN']: - OS_LIBS += CONFIG['MOZ_PIXMAN_LIBS'] - --if CONFIG['MOZ_ALSA']: -- OS_LIBS += CONFIG['MOZ_ALSA_LIBS'] -- - if CONFIG['HAVE_CLOCK_MONOTONIC']: - OS_LIBS += CONFIG['REALTIME_LIBS'] - - -commit 161bcd671217 -Author: Evgeniy Vodolazskiy <waterlaz@gmail.com> -Date: Wed Sep 3 10:47:00 2014 -0700 - - Bug 1021761 - Add OSS backend to libcubeb, default but last on Linux. r=kinetik r=glandium ---- - build/moz.configure/old.configure | 1 + - dom/media/CubebUtils.cpp | 3 +- - media/libcubeb/AUTHORS | 1 + - media/libcubeb/src/cubeb.c | 10 + - media/libcubeb/src/cubeb_oss.c | 453 ++++++++++++++++++++++++++++++++++++++ - media/libcubeb/src/moz.build | 7 + - media/libcubeb/update.sh | 1 + - old-configure.in | 62 ++++++ - toolkit/library/moz.build | 3 + - 9 files changed, 540 insertions(+), 1 deletion(-) - -diff --git build/moz.configure/old.configure build/moz.configure/old.configure -index 17d0c5bf3420..3e6dbc16ca14 100644 ---- build/moz.configure/old.configure -+++ build/moz.configure/old.configure -@@ -262,6 +262,7 @@ def old_configure_options(*options): - '--with-nspr-prefix', - '--with-nss-exec-prefix', - '--with-nss-prefix', -+ '--with-oss', - '--with-pthreads', - '--with-qemu-exe', - '--with-sixgill', -diff --git dom/media/CubebUtils.cpp dom/media/CubebUtils.cpp -index 88063ed3a4d6..8613f86dbd16 100644 ---- dom/media/CubebUtils.cpp -+++ dom/media/CubebUtils.cpp -@@ -149,7 +149,8 @@ const char* AUDIOSTREAM_BACKEND_ID_STR[] = { - "sndio", - "opensl", - "audiotrack", -- "kai" -+ "kai", -+ "oss", - }; - /* Index for failures to create an audio stream the first time. */ - const int CUBEB_BACKEND_INIT_FAILURE_FIRST = -diff --git media/libcubeb/AUTHORS media/libcubeb/AUTHORS -index f0f9595227f2..e7e7048190ab 100644 ---- media/libcubeb/AUTHORS -+++ media/libcubeb/AUTHORS -@@ -4,6 +4,7 @@ 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> - KO Myung-Hun <komh@chollian.net> - Haakon Sporsheim <haakon.sporsheim@telenordigital.com> - Alex Chronopoulos <achronop@gmail.com> -diff --git media/libcubeb/src/cubeb.c media/libcubeb/src/cubeb.c -index bb35e0ce349f..e523d94108a3 100644 ---- media/libcubeb/src/cubeb.c -+++ media/libcubeb/src/cubeb.c -@@ -60,6 +60,9 @@ int audiotrack_init(cubeb ** context, char const * context_name); - #if defined(USE_KAI) - int kai_init(cubeb ** context, char const * context_name); - #endif -+#if defined(USE_OSS) -+int oss_init(cubeb ** context, char const * context_name); -+#endif - - static int - validate_stream_params(cubeb_stream_params * input_stream_params, -@@ -159,6 +162,10 @@ cubeb_init(cubeb ** context, char const * context_name, char const * backend_nam - } else if (!strcmp(backend_name, "kai")) { - #if defined(USE_KAI) - init_oneshot = kai_init; -+#endif -+ } else if (!strcmp(backend_name, "oss")) { -+#if defined(USE_OSS) -+ init_oneshot = oss_init; - #endif - } else { - /* Already set */ -@@ -203,6 +210,9 @@ cubeb_init(cubeb ** context, char const * context_name, char const * backend_nam - #endif - #if defined(USE_KAI) - kai_init, -+#endif -+#if defined(USE_OSS) -+ oss_init, - #endif - }; - int i; -diff --git media/libcubeb/src/cubeb_oss.c media/libcubeb/src/cubeb_oss.c -new file mode 100644 -index 000000000000..7d96168b9ea6 ---- /dev/null -+++ media/libcubeb/src/cubeb_oss.c -@@ -0,0 +1,454 @@ -+/* -+ * 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> -+#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 <assert.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 { -+ /* Note: Must match cubeb_stream layout in cubeb.c. */ -+ cubeb * context; -+ void * user_ptr; -+ /**/ -+ -+ cubeb_data_callback data_callback; -+ cubeb_state_callback state_callback; -+ 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_frames) -+{ -+ (void)context; -+ /* 40ms is a big enough number to work ok */ -+ *latency_frames = 40 * params.rate / 1000; -+ 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, NULL, buffer, nframes); -+ } else { -+ pthread_mutex_unlock(&stream->state_mutex); -+ } -+ return got; -+} -+ -+static void apply_volume_int(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 apply_volume_float(float* buffer, unsigned int n, -+ float volume, float panning) -+{ -+ float left = volume; -+ float right = volume; -+ unsigned int i; -+ float pan[2]; -+ if (panning<0) { -+ right *= (1+panning); -+ } else { -+ left *= (1-panning); -+ } -+ pan[0] = left; -+ pan[1] = right; -+ for(i=0; i<n; i++){ -+ buffer[i] = buffer[i]*pan[i%2]; -+ } -+} -+ -+ -+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); -+ apply_volume_float(f_buffer, got*stream->params.channels, -+ stream->volume, stream->panning); -+ for (i=0; i<((unsigned long)got)*stream->params.channels; i++) { -+ /* Clipping is prefered to overflow */ -+ if(f_buffer[i]>=1.0){ -+ f_buffer[i]=1.0; -+ } -+ if(f_buffer[i]<=-1.0){ -+ f_buffer[i]=-1.0; -+ } -+ /* One might think that multipling by 32767.0 is logical but results in clipping */ -+ buffer[i] = f_buffer[i]*32767.0; -+ } -+ } else { -+ got = run_data_callback(stream, buffer, -+ OSS_BUFFER_SIZE/stream->params.channels); -+ apply_volume_int(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_log=10; /* 2^frag_log = fragment 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_devid input_device, -+ cubeb_stream_params * input_stream_params, -+ cubeb_devid output_device, -+ cubeb_stream_params * output_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; -+ -+ assert(!input_stream_params && "not supported."); -+ if (input_device || output_device) { -+ /* Device selection not yet implemented. */ -+ return CUBEB_ERROR_DEVICE_UNAVAILABLE; -+ } -+ -+ if ((input_stream_params && input_stream_params->prefs & CUBEB_STREAM_PREF_LOOPBACK) || -+ (output_stream_params && output_stream_params->prefs & CUBEB_STREAM_PREF_LOOPBACK)) { -+ return CUBEB_ERROR_NOT_SUPPORTED; -+ } -+ -+ 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 = *output_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, -+ .get_preferred_channel_layout = NULL, -+ .enumerate_devices = NULL, -+ .device_collection_destroy = NULL, -+ .destroy = oss_destroy, -+ .stream_init = oss_stream_init, -+ .stream_destroy = oss_stream_destroy, -+ .stream_start = oss_stream_start, -+ .stream_stop = oss_stream_stop, -+ .stream_reset_default_device = NULL, -+ .stream_get_position = oss_stream_get_position, -+ .stream_get_latency = oss_stream_get_latency, -+ .stream_set_volume = oss_stream_set_volume, -+ .stream_set_panning = oss_stream_set_panning, -+ .stream_get_current_device = NULL, -+ .stream_device_destroy = NULL, -+ .stream_register_device_changed_callback = NULL, -+ .register_device_collection_changed = NULL -+}; -diff --git media/libcubeb/src/moz.build media/libcubeb/src/moz.build -index e1fea30ca417..a5b1100f1014 100644 ---- media/libcubeb/src/moz.build -+++ media/libcubeb/src/moz.build -@@ -23,6 +23,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'] or CONFIG['MOZ_JACK']: - SOURCES += [ - 'cubeb_resampler.cpp', -@@ -88,6 +94,7 @@ if CONFIG['OS_TARGET'] == 'Android': - FINAL_LIBRARY = 'gkmedias' - - CFLAGS += CONFIG['MOZ_ALSA_CFLAGS'] -+CFLAGS += CONFIG['MOZ_OSS_CFLAGS'] - CFLAGS += CONFIG['MOZ_PULSEAUDIO_CFLAGS'] - - # We allow warnings for third-party code that can be updated from upstream. -diff --git media/libcubeb/update.sh media/libcubeb/update.sh -index 0bb6345c9fa9..78a102dc47cb 100755 ---- media/libcubeb/update.sh -+++ media/libcubeb/update.sh -@@ -20,6 +20,7 @@ cp $1/src/cubeb_log.h src - cp $1/src/cubeb_mixer.cpp src - cp $1/src/cubeb_mixer.h src - cp $1/src/cubeb_opensl.c src -+cp $1/src/cubeb_oss.c src - cp $1/src/cubeb-jni.cpp src - cp $1/src/cubeb-jni.h src - cp $1/src/android/cubeb-output-latency.h src/android -diff --git old-configure.in old-configure.in -index 28e1a9e48d61..edacedcf6e5d 100644 ---- old-configure.in -+++ old-configure.in -@@ -2598,6 +2598,67 @@ MOZ_WEBM_ENCODER=1 - AC_DEFINE(MOZ_WEBM_ENCODER) - 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_WITH_STRING(oss, -+[ --with-oss[=PFX] Enable OpenSoundSystem support [installed at prefix PFX]], -+ OSSPREFIX=$withval) -+ -+if test -n "$OSSPREFIX"; then -+ if test "$OSSPREFIX" != "no"; then -+ MOZ_OSS=1 -+ else -+ MOZ_OSS= -+ fi -+fi -+ -+_SAVE_CFLAGS=$CFLAGS -+_SAVE_LIBS=$LIBS -+if test -n "$MOZ_OSS"; then -+ dnl Prefer 4Front implementation -+ AC_MSG_CHECKING([MOZ_OSS_CFLAGS]) -+ if test "$OSSPREFIX" != "yes"; then -+ oss_conf=${OSSPREFIX%/usr}/etc/oss.conf -+ if test -f "$oss_conf"; then -+ . "$oss_conf" -+ else -+ OSSLIBDIR=$OSSPREFIX/lib/oss -+ fi -+ if test -d "$OSSLIBDIR"; then -+ MOZ_OSS_CFLAGS="$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 soundcard.h) -+ -+ if test "$ac_cv_header_sys_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 --without-oss.]) -+ 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="$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 ================================== -diff --git toolkit/library/moz.build toolkit/library/moz.build -index e06592daa265..ce016b96c2bc 100644 ---- toolkit/library/moz.build -+++ toolkit/library/moz.build -@@ -247,6 +247,9 @@ if CONFIG['MOZ_SYSTEM_LIBVPX']: - if not CONFIG['MOZ_TREE_PIXMAN']: - OS_LIBS += CONFIG['MOZ_PIXMAN_LIBS'] - -+if CONFIG['MOZ_OSS']: -+ OS_LIBS += CONFIG['MOZ_OSS_LIBS'] -+ - if CONFIG['HAVE_CLOCK_MONOTONIC']: - OS_LIBS += CONFIG['REALTIME_LIBS'] - diff --git a/www/firefox-esr/pkg-message b/www/firefox-esr/pkg-message index 350197ac33d4..a947abccda5c 100644 --- a/www/firefox-esr/pkg-message +++ b/www/firefox-esr/pkg-message @@ -1,7 +1,7 @@ ====================================================================== Some features available on other platforms are not implemented: -- Native audio (OSS backend is incomplete, doesn't support WebRTC) +- Native audio (requires OSS backend, feature parity with ALSA or PulseAudio) - Encrypted Media Extensions (requires Widevine CDM binary) - Process sandboxing (requires Capsicum backend) - Reduced memory usage (requires mozjemalloc) @@ -22,7 +22,7 @@ $ sysctl net.local.stream.recvspace=16384 To select non-default audio backend open about:config page and create media.cubeb.backend preference. Supported values are: alsa, jack, -pulse, pulse-rust, oss, sndio. Currently used backend can be inspected +pulse, pulse-rust, sndio. Currently used backend can be inspected on about:support page. ====================================================================== diff --git a/www/firefox/Makefile b/www/firefox/Makefile index 4564f3d69d59..a6a03a9f8c4c 100644 --- a/www/firefox/Makefile +++ b/www/firefox/Makefile @@ -3,6 +3,7 @@ PORTNAME= firefox DISTVERSION= 63.0.3 +PORTREVISION= 1 PORTEPOCH= 1 CATEGORIES= www ipv6 MASTER_SITES= MOZILLA/${PORTNAME}/releases/${DISTVERSION}/source \ diff --git a/www/firefox/files/patch-bug1021761 b/www/firefox/files/patch-bug1021761 deleted file mode 100644 index a771d13a6cfc..000000000000 --- a/www/firefox/files/patch-bug1021761 +++ /dev/null @@ -1,1268 +0,0 @@ -commit f9bcf9c81c4a -Author: Evgeniy Vodolazskiy <waterlaz@gmail.com> -Date: Tue Sep 9 14:38:00 2014 -0700 - - Bug 1021761 - Make ALSA optional on Linux, allowing fallback to another backend. r=kinetik r=glandium ---- - media/libcubeb/gtest/moz.build | 1 - - media/libcubeb/src/cubeb_alsa.c | 228 +++++++++++++++++++++++++++++----------- - toolkit/library/moz.build | 3 - - 3 files changed, 168 insertions(+), 64 deletions(-) - -diff --git media/libcubeb/gtest/moz.build media/libcubeb/gtest/moz.build -index 558130188c2e..0cf157d41903 100644 ---- media/libcubeb/gtest/moz.build -+++ media/libcubeb/gtest/moz.build -@@ -72,7 +72,6 @@ elif CONFIG['OS_TARGET'] == 'OpenBSD': - 'sndio', - ] - else: -- OS_LIBS += CONFIG['MOZ_ALSA_LIBS'] - OS_LIBS += CONFIG['MOZ_PULSEAUDIO_LIBS'] - - if CONFIG['CC_TYPE'] in ('clang', 'gcc'): -diff --git media/libcubeb/src/cubeb_alsa.c media/libcubeb/src/cubeb_alsa.c -index bfd4d8f199d4..213c1eaa3d07 100644 ---- media/libcubeb/src/cubeb_alsa.c -+++ media/libcubeb/src/cubeb_alsa.c -@@ -12,6 +12,7 @@ - #include <sys/time.h> - #include <assert.h> - #include <limits.h> -+#include <dlfcn.h> - #include <poll.h> - #include <unistd.h> - #include <alsa/asoundlib.h> -@@ -25,6 +26,52 @@ - - #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_readi); -+MAKE_TYPEDEF(snd_pcm_recover); -+MAKE_TYPEDEF(snd_pcm_set_params); -+MAKE_TYPEDEF(snd_pcm_start); -+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), -@@ -65,6 +112,8 @@ struct cubeb { - workaround is not required. */ - snd_config_t * local_config; - int is_pa; -+ -+ void * libasound; - }; - - enum stream_state { -@@ -245,8 +294,8 @@ set_timeout(struct timeval * timeout, unsigned int ms) - static void - stream_buffer_decrement(cubeb_stream * stm, long count) - { -- char * bufremains = stm->buffer + snd_pcm_frames_to_bytes(stm->pcm, count); -- memmove(stm->buffer, bufremains, snd_pcm_frames_to_bytes(stm->pcm, stm->bufframes - count)); -+ char * bufremains = stm->buffer + WRAP(snd_pcm_frames_to_bytes)(stm->pcm, count); -+ memmove(stm->buffer, bufremains, WRAP(snd_pcm_frames_to_bytes)(stm->pcm, stm->bufframes - count)); - stm->bufframes -= count; - } - -@@ -278,9 +327,9 @@ alsa_process_stream(cubeb_stream * stm) - /* Call _poll_descriptors_revents() even if we don't use it - to let underlying plugins clear null events. Otherwise poll() - may wake up again and again, producing unnecessary CPU usage. */ -- snd_pcm_poll_descriptors_revents(stm->pcm, stm->fds, stm->nfds, &revents); -+ WRAP(snd_pcm_poll_descriptors_revents)(stm->pcm, stm->fds, stm->nfds, &revents); - -- avail = snd_pcm_avail_update(stm->pcm); -+ avail = WRAP(snd_pcm_avail_update)(stm->pcm); - - /* Got null event? Bail and wait for another wakeup. */ - if (avail == 0) { -@@ -303,7 +352,7 @@ alsa_process_stream(cubeb_stream * stm) - // TODO: should it be marked as DRAINING? - } - -- got = snd_pcm_readi(stm->pcm, stm->buffer+stm->bufframes, avail); -+ got = WRAP(snd_pcm_readi)(stm->pcm, stm->buffer+stm->bufframes, avail); - - if (got < 0) { - avail = got; // the error handler below will recover us -@@ -347,7 +396,7 @@ alsa_process_stream(cubeb_stream * stm) - (!stm->other_stream || stm->other_stream->bufframes > 0)) { - long got = avail - stm->bufframes; - void * other_buffer = stm->other_stream ? stm->other_stream->buffer : NULL; -- char * buftail = stm->buffer + snd_pcm_frames_to_bytes(stm->pcm, stm->bufframes); -+ char * buftail = stm->buffer + WRAP(snd_pcm_frames_to_bytes)(stm->pcm, stm->bufframes); - - /* Correct read size to the other stream available frames */ - if (stm->other_stream && got > (snd_pcm_sframes_t) stm->other_stream->bufframes) { -@@ -374,8 +423,8 @@ alsa_process_stream(cubeb_stream * stm) - long drain_frames = avail - stm->bufframes; - double drain_time = (double) drain_frames / stm->params.rate; - -- char * buftail = stm->buffer + snd_pcm_frames_to_bytes(stm->pcm, stm->bufframes); -- memset(buftail, 0, snd_pcm_frames_to_bytes(stm->pcm, drain_frames)); -+ char * buftail = stm->buffer + WRAP(snd_pcm_frames_to_bytes)(stm->pcm, stm->bufframes); -+ memset(buftail, 0, WRAP(snd_pcm_frames_to_bytes)(stm->pcm, drain_frames)); - stm->bufframes = avail; - - /* Mark as draining, unless we're waiting for capture */ -@@ -402,7 +451,7 @@ alsa_process_stream(cubeb_stream * stm) - } - } - -- wrote = snd_pcm_writei(stm->pcm, stm->buffer, avail); -+ wrote = WRAP(snd_pcm_writei)(stm->pcm, stm->buffer, avail); - if (wrote < 0) { - avail = wrote; // the error handler below will recover us - } else { -@@ -415,13 +464,13 @@ alsa_process_stream(cubeb_stream * stm) - - /* Got some error? Let's try to recover the stream. */ - if (avail < 0) { -- avail = snd_pcm_recover(stm->pcm, avail, 0); -+ avail = WRAP(snd_pcm_recover)(stm->pcm, avail, 0); - - /* Capture pcm must be started after initial setup/recover */ - if (avail >= 0 && - stm->stream_type == SND_PCM_STREAM_CAPTURE && -- snd_pcm_state(stm->pcm) == SND_PCM_STATE_PREPARED) { -- avail = snd_pcm_start(stm->pcm); -+ WRAP(snd_pcm_state)(stm->pcm) == SND_PCM_STATE_PREPARED) { -+ avail = WRAP(snd_pcm_start)(stm->pcm); - } - } - -@@ -537,26 +586,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; - } -@@ -565,7 +614,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; - } -@@ -574,7 +623,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; -@@ -597,22 +646,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; - } -@@ -621,7 +670,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; - } -@@ -632,12 +681,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; - } -@@ -648,18 +697,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; - } -@@ -667,7 +716,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; - } -@@ -679,9 +728,9 @@ alsa_locked_pcm_open(snd_pcm_t ** pcm, char const * pcm_name, snd_pcm_stream_t s - - pthread_mutex_lock(&cubeb_alsa_mutex); - if (local_config) { -- r = snd_pcm_open_lconf(pcm, pcm_name, stream, SND_PCM_NONBLOCK, local_config); -+ r = WRAP(snd_pcm_open_lconf)(pcm, pcm_name, stream, SND_PCM_NONBLOCK, local_config); - } else { -- r = snd_pcm_open(pcm, pcm_name, stream, SND_PCM_NONBLOCK); -+ r = WRAP(snd_pcm_open)(pcm, pcm_name, stream, SND_PCM_NONBLOCK); - } - pthread_mutex_unlock(&cubeb_alsa_mutex); - -@@ -694,7 +743,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; -@@ -757,12 +806,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); -@@ -770,6 +872,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); -@@ -819,7 +923,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) { -@@ -859,9 +963,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); - } - -@@ -948,7 +1056,7 @@ alsa_stream_init_single(cubeb * ctx, cubeb_stream ** stream, char const * stream - return CUBEB_ERROR; - } - -- r = snd_pcm_nonblock(stm->pcm, 1); -+ r = WRAP(snd_pcm_nonblock)(stm->pcm, 1); - assert(r == 0); - - latency_us = latency_frames * 1e6 / stm->params.rate; -@@ -961,7 +1069,7 @@ alsa_stream_init_single(cubeb * ctx, cubeb_stream ** stream, char const * stream - latency_us = latency_us < min_latency ? min_latency: latency_us; - } - -- r = snd_pcm_set_params(stm->pcm, format, SND_PCM_ACCESS_RW_INTERLEAVED, -+ r = WRAP(snd_pcm_set_params)(stm->pcm, format, SND_PCM_ACCESS_RW_INTERLEAVED, - stm->params.channels, stm->params.rate, 1, - latency_us); - if (r < 0) { -@@ -969,20 +1077,20 @@ alsa_stream_init_single(cubeb * ctx, cubeb_stream ** stream, char const * stream - return CUBEB_ERROR_INVALID_FORMAT; - } - -- r = snd_pcm_get_params(stm->pcm, &stm->buffer_size, &period_size); -+ r = WRAP(snd_pcm_get_params)(stm->pcm, &stm->buffer_size, &period_size); - assert(r == 0); - - /* Double internal buffer size to have enough space when waiting for the other side of duplex connection */ - stm->buffer_size *= 2; -- stm->buffer = calloc(1, snd_pcm_frames_to_bytes(stm->pcm, stm->buffer_size)); -+ stm->buffer = calloc(1, WRAP(snd_pcm_frames_to_bytes)(stm->pcm, stm->buffer_size)); - assert(stm->buffer); - -- 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); - - if (alsa_register_stream(ctx, stm) != 0) { -@@ -1054,7 +1162,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; -@@ -1100,12 +1208,12 @@ alsa_get_max_channel_count(cubeb * ctx, uint32_t * max_channels) - - assert(stm); - -- r = snd_pcm_hw_params_any(stm->pcm, hw_params); -+ r = WRAP(snd_pcm_hw_params_any)(stm->pcm, hw_params); - if (r < 0) { - return CUBEB_ERROR; - } - -- r = snd_pcm_hw_params_get_channels_max(hw_params, max_channels); -+ r = WRAP(snd_pcm_hw_params_get_channels_max)(hw_params, max_channels); - if (r < 0) { - return CUBEB_ERROR; - } -@@ -1126,34 +1234,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. */ -- r = snd_pcm_open(&pcm, CUBEB_ALSA_PCM_NAME, SND_PCM_STREAM_PLAYBACK, SND_PCM_NO_AUTO_RESAMPLE); -+ r = WRAP(snd_pcm_open)(&pcm, CUBEB_ALSA_PCM_NAME, SND_PCM_STREAM_PLAYBACK, SND_PCM_NO_AUTO_RESAMPLE); - if (r < 0) { - return CUBEB_ERROR; - } - -- r = snd_pcm_hw_params_any(pcm, hw_params); -+ r = WRAP(snd_pcm_hw_params_any)(pcm, hw_params); - if (r < 0) { -- snd_pcm_close(pcm); -+ WRAP(snd_pcm_close)(pcm); - return CUBEB_ERROR; - } - -- r = snd_pcm_hw_params_get_rate(hw_params, rate, &dir); -+ r = WRAP(snd_pcm_hw_params_get_rate)(hw_params, rate, &dir); - if (r >= 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; - -- r = snd_pcm_hw_params_set_rate_near(pcm, hw_params, rate, NULL); -+ r = WRAP(snd_pcm_hw_params_set_rate_near)(pcm, hw_params, rate, NULL); - if (r < 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; - } -@@ -1186,10 +1294,10 @@ alsa_stream_start(cubeb_stream * stm) - pthread_mutex_lock(&stm->mutex); - /* Capture pcm must be started after initial setup/recover */ - if (stm->stream_type == SND_PCM_STREAM_CAPTURE && -- snd_pcm_state(stm->pcm) == SND_PCM_STATE_PREPARED) { -- snd_pcm_start(stm->pcm); -+ WRAP(snd_pcm_state)(stm->pcm) == SND_PCM_STATE_PREPARED) { -+ WRAP(snd_pcm_start)(stm->pcm); - } -- snd_pcm_pause(stm->pcm, 0); -+ WRAP(snd_pcm_pause)(stm->pcm, 0); - gettimeofday(&stm->last_activity, NULL); - pthread_mutex_unlock(&stm->mutex); - -@@ -1229,7 +1337,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; -@@ -1245,8 +1353,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; -@@ -1271,7 +1379,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 toolkit/library/moz.build toolkit/library/moz.build -index b0df6b98b91f..e06592daa265 100644 ---- toolkit/library/moz.build -+++ toolkit/library/moz.build -@@ -247,9 +247,6 @@ if CONFIG['MOZ_SYSTEM_LIBVPX']: - if not CONFIG['MOZ_TREE_PIXMAN']: - OS_LIBS += CONFIG['MOZ_PIXMAN_LIBS'] - --if CONFIG['MOZ_ALSA']: -- OS_LIBS += CONFIG['MOZ_ALSA_LIBS'] -- - if CONFIG['HAVE_CLOCK_MONOTONIC']: - OS_LIBS += CONFIG['REALTIME_LIBS'] - - -commit 161bcd671217 -Author: Evgeniy Vodolazskiy <waterlaz@gmail.com> -Date: Wed Sep 3 10:47:00 2014 -0700 - - Bug 1021761 - Add OSS backend to libcubeb, default but last on Linux. r=kinetik r=glandium ---- - build/moz.configure/old.configure | 1 + - dom/media/CubebUtils.cpp | 3 +- - media/libcubeb/AUTHORS | 1 + - media/libcubeb/src/cubeb.c | 10 + - media/libcubeb/src/cubeb_oss.c | 453 ++++++++++++++++++++++++++++++++++++++ - media/libcubeb/src/moz.build | 7 + - media/libcubeb/update.sh | 1 + - old-configure.in | 62 ++++++ - toolkit/library/moz.build | 3 + - 9 files changed, 540 insertions(+), 1 deletion(-) - -diff --git build/moz.configure/old.configure build/moz.configure/old.configure -index 17d0c5bf3420..3e6dbc16ca14 100644 ---- build/moz.configure/old.configure -+++ build/moz.configure/old.configure -@@ -259,6 +259,7 @@ def old_configure_options(*options): - '--with-nspr-prefix', - '--with-nss-exec-prefix', - '--with-nss-prefix', -+ '--with-oss', - '--with-qemu-exe', - '--with-sixgill', - '--with-soft-float', -diff --git dom/media/CubebUtils.cpp dom/media/CubebUtils.cpp -index 88063ed3a4d6..8613f86dbd16 100644 ---- dom/media/CubebUtils.cpp -+++ dom/media/CubebUtils.cpp -@@ -149,7 +149,8 @@ const char* AUDIOSTREAM_BACKEND_ID_STR[] = { - "sndio", - "opensl", - "audiotrack", -- "kai" -+ "kai", -+ "oss", - }; - /* Index for failures to create an audio stream the first time. */ - const int CUBEB_BACKEND_INIT_FAILURE_FIRST = -diff --git media/libcubeb/AUTHORS media/libcubeb/AUTHORS -index f0f9595227f2..e7e7048190ab 100644 ---- media/libcubeb/AUTHORS -+++ media/libcubeb/AUTHORS -@@ -4,6 +4,7 @@ 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> - KO Myung-Hun <komh@chollian.net> - Haakon Sporsheim <haakon.sporsheim@telenordigital.com> - Alex Chronopoulos <achronop@gmail.com> -diff --git media/libcubeb/src/cubeb.c media/libcubeb/src/cubeb.c -index bb35e0ce349f..e523d94108a3 100644 ---- media/libcubeb/src/cubeb.c -+++ media/libcubeb/src/cubeb.c -@@ -60,6 +60,9 @@ int audiotrack_init(cubeb ** context, char const * context_name); - #if defined(USE_KAI) - int kai_init(cubeb ** context, char const * context_name); - #endif -+#if defined(USE_OSS) -+int oss_init(cubeb ** context, char const * context_name); -+#endif - - static int - validate_stream_params(cubeb_stream_params * input_stream_params, -@@ -159,6 +162,10 @@ cubeb_init(cubeb ** context, char const * context_name, char const * backend_nam - } else if (!strcmp(backend_name, "kai")) { - #if defined(USE_KAI) - init_oneshot = kai_init; -+#endif -+ } else if (!strcmp(backend_name, "oss")) { -+#if defined(USE_OSS) -+ init_oneshot = oss_init; - #endif - } else { - /* Already set */ -@@ -203,6 +210,9 @@ cubeb_init(cubeb ** context, char const * context_name, char const * backend_nam - #endif - #if defined(USE_KAI) - kai_init, -+#endif -+#if defined(USE_OSS) -+ oss_init, - #endif - }; - int i; -diff --git media/libcubeb/src/cubeb_oss.c media/libcubeb/src/cubeb_oss.c -new file mode 100644 -index 000000000000..7d96168b9ea6 ---- /dev/null -+++ media/libcubeb/src/cubeb_oss.c -@@ -0,0 +1,453 @@ -+/* -+ * 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> -+#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 <assert.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 { -+ /* Note: Must match cubeb_stream layout in cubeb.c. */ -+ cubeb * context; -+ void * user_ptr; -+ /**/ -+ -+ cubeb_data_callback data_callback; -+ cubeb_state_callback state_callback; -+ 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_frames) -+{ -+ (void)context; -+ /* 40ms is a big enough number to work ok */ -+ *latency_frames = 40 * params.rate / 1000; -+ 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, NULL, buffer, nframes); -+ } else { -+ pthread_mutex_unlock(&stream->state_mutex); -+ } -+ return got; -+} -+ -+static void apply_volume_int(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 apply_volume_float(float* buffer, unsigned int n, -+ float volume, float panning) -+{ -+ float left = volume; -+ float right = volume; -+ unsigned int i; -+ float pan[2]; -+ if (panning<0) { -+ right *= (1+panning); -+ } else { -+ left *= (1-panning); -+ } -+ pan[0] = left; -+ pan[1] = right; -+ for(i=0; i<n; i++){ -+ buffer[i] = buffer[i]*pan[i%2]; -+ } -+} -+ -+ -+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); -+ apply_volume_float(f_buffer, got*stream->params.channels, -+ stream->volume, stream->panning); -+ for (i=0; i<((unsigned long)got)*stream->params.channels; i++) { -+ /* Clipping is prefered to overflow */ -+ if(f_buffer[i]>=1.0){ -+ f_buffer[i]=1.0; -+ } -+ if(f_buffer[i]<=-1.0){ -+ f_buffer[i]=-1.0; -+ } -+ /* One might think that multipling by 32767.0 is logical but results in clipping */ -+ buffer[i] = f_buffer[i]*32767.0; -+ } -+ } else { -+ got = run_data_callback(stream, buffer, -+ OSS_BUFFER_SIZE/stream->params.channels); -+ apply_volume_int(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_log=10; /* 2^frag_log = fragment 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_devid input_device, -+ cubeb_stream_params * input_stream_params, -+ cubeb_devid output_device, -+ cubeb_stream_params * output_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; -+ -+ assert(!input_stream_params && "not supported."); -+ if (input_device || output_device) { -+ /* Device selection not yet implemented. */ -+ return CUBEB_ERROR_DEVICE_UNAVAILABLE; -+ } -+ -+ if ((input_stream_params && input_stream_params->prefs & CUBEB_STREAM_PREF_LOOPBACK) || -+ (output_stream_params && output_stream_params->prefs & CUBEB_STREAM_PREF_LOOPBACK)) { -+ return CUBEB_ERROR_NOT_SUPPORTED; -+ } -+ -+ 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 = *output_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, -+ .enumerate_devices = NULL, -+ .device_collection_destroy = NULL, -+ .destroy = oss_destroy, -+ .stream_init = oss_stream_init, -+ .stream_destroy = oss_stream_destroy, -+ .stream_start = oss_stream_start, -+ .stream_stop = oss_stream_stop, -+ .stream_reset_default_device = NULL, -+ .stream_get_position = oss_stream_get_position, -+ .stream_get_latency = oss_stream_get_latency, -+ .stream_set_volume = oss_stream_set_volume, -+ .stream_set_panning = oss_stream_set_panning, -+ .stream_get_current_device = NULL, -+ .stream_device_destroy = NULL, -+ .stream_register_device_changed_callback = NULL, -+ .register_device_collection_changed = NULL -+}; -diff --git media/libcubeb/src/moz.build media/libcubeb/src/moz.build -index e1fea30ca417..a5b1100f1014 100644 ---- media/libcubeb/src/moz.build -+++ media/libcubeb/src/moz.build -@@ -23,6 +23,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'] or CONFIG['MOZ_JACK']: - SOURCES += [ - 'cubeb_resampler.cpp', -@@ -89,6 +95,7 @@ FINAL_LIBRARY = 'gkmedias' - - CFLAGS += CONFIG['MOZ_ALSA_CFLAGS'] - CFLAGS += CONFIG['MOZ_JACK_CFLAGS'] -+CFLAGS += CONFIG['MOZ_OSS_CFLAGS'] - CFLAGS += CONFIG['MOZ_PULSEAUDIO_CFLAGS'] - - # We allow warnings for third-party code that can be updated from upstream. -diff --git media/libcubeb/update.sh media/libcubeb/update.sh -index 0bb6345c9fa9..78a102dc47cb 100755 ---- media/libcubeb/update.sh -+++ media/libcubeb/update.sh -@@ -20,6 +20,7 @@ cp $1/src/cubeb_log.h src - cp $1/src/cubeb_mixer.cpp src - cp $1/src/cubeb_mixer.h src - cp $1/src/cubeb_opensl.c src -+cp $1/src/cubeb_oss.c src - cp $1/src/cubeb-jni.cpp src - cp $1/src/cubeb-jni.h src - cp $1/src/android/cubeb-output-latency.h src/android -diff --git old-configure.in old-configure.in -index 28e1a9e48d61..edacedcf6e5d 100644 ---- old-configure.in -+++ old-configure.in -@@ -2598,6 +2598,67 @@ MOZ_WEBM_ENCODER=1 - AC_DEFINE(MOZ_WEBM_ENCODER) - 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_WITH_STRING(oss, -+[ --with-oss[=PFX] Enable OpenSoundSystem support [installed at prefix PFX]], -+ OSSPREFIX=$withval) -+ -+if test -n "$OSSPREFIX"; then -+ if test "$OSSPREFIX" != "no"; then -+ MOZ_OSS=1 -+ else -+ MOZ_OSS= -+ fi -+fi -+ -+_SAVE_CFLAGS=$CFLAGS -+_SAVE_LIBS=$LIBS -+if test -n "$MOZ_OSS"; then -+ dnl Prefer 4Front implementation -+ AC_MSG_CHECKING([MOZ_OSS_CFLAGS]) -+ if test "$OSSPREFIX" != "yes"; then -+ oss_conf=${OSSPREFIX%/usr}/etc/oss.conf -+ if test -f "$oss_conf"; then -+ . "$oss_conf" -+ else -+ OSSLIBDIR=$OSSPREFIX/lib/oss -+ fi -+ if test -d "$OSSLIBDIR"; then -+ MOZ_OSS_CFLAGS="$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 soundcard.h) -+ -+ if test "$ac_cv_header_sys_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 --without-oss.]) -+ 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="$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 NegotiateAuth - dnl ======================================================== -diff --git toolkit/library/moz.build toolkit/library/moz.build -index e06592daa265..ce016b96c2bc 100644 ---- toolkit/library/moz.build -+++ toolkit/library/moz.build -@@ -247,6 +247,9 @@ if CONFIG['MOZ_SYSTEM_LIBVPX']: - if not CONFIG['MOZ_TREE_PIXMAN']: - OS_LIBS += CONFIG['MOZ_PIXMAN_LIBS'] - -+if CONFIG['MOZ_OSS']: -+ OS_LIBS += CONFIG['MOZ_OSS_LIBS'] -+ - if CONFIG['HAVE_CLOCK_MONOTONIC']: - OS_LIBS += CONFIG['REALTIME_LIBS'] - diff --git a/www/firefox/pkg-message b/www/firefox/pkg-message index 1210f5390de8..3fbe33357346 100644 --- a/www/firefox/pkg-message +++ b/www/firefox/pkg-message @@ -1,7 +1,7 @@ ====================================================================== Some features available on other platforms are not implemented: -- Native audio (OSS backend is incomplete, doesn't support WebRTC) +- Native audio (requires OSS backend, feature parity with ALSA or PulseAudio) - Encrypted Media Extensions (requires Widevine CDM binary) - Process sandboxing (requires Capsicum backend) - Reduced memory usage (requires mozjemalloc) @@ -23,7 +23,7 @@ $ sysctl net.local.stream.recvspace=16384 To select non-default audio backend open about:config page and create media.cubeb.backend preference. Supported values are: alsa, jack, -pulse, pulse-rust, oss, sndio. Currently used backend can be inspected +pulse, pulse-rust, sndio. Currently used backend can be inspected on about:support page. ====================================================================== diff --git a/www/seamonkey/Makefile b/www/seamonkey/Makefile index 7c1d24ca0b64..94c81dfcac12 100644 --- a/www/seamonkey/Makefile +++ b/www/seamonkey/Makefile @@ -3,7 +3,7 @@ PORTNAME= seamonkey DISTVERSION= 2.49.4 -PORTREVISION= 15 +PORTREVISION= 16 MOZILLA_VER= 52 # above + 3 CATEGORIES?= www mail news editors irc ipv6 MASTER_SITES= MOZILLA/${PORTNAME}/releases/${DISTVERSION}/source \ diff --git a/www/seamonkey/files/patch-bug1021761 b/www/seamonkey/files/patch-bug1021761 deleted file mode 100644 index fda170e0e3d0..000000000000 --- a/www/seamonkey/files/patch-bug1021761 +++ /dev/null @@ -1,1157 +0,0 @@ -diff --git build/moz.configure/old.configure build/moz.configure/old.configure -index b95dd2b..4cbefd5 100644 ---- mozilla/build/moz.configure/old.configure -+++ mozilla/build/moz.configure/old.configure -@@ -305,6 +305,7 @@ def old_configure_options(*options): - '--with-nspr-prefix', - '--with-nss-exec-prefix', - '--with-nss-prefix', -+ '--with-oss', - '--with-pthreads', - '--with-qemu-exe', - '--with-servo', -diff --git old-configure.in configure.in -index 48e60c0..ec08417 100644 ---- mozilla/old-configure.in -+++ mozilla/old-configure.in -@@ -5591,6 +5591,67 @@ 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_WITH_STRING(oss, -+[ --with-oss[=PFX] Enable OpenSoundSystem support [installed at prefix PFX]], -+ OSSPREFIX=$withval) -+ -+if test -n "$OSSPREFIX"; then -+ if test "$OSSPREFIX" != "no"; then -+ MOZ_OSS=1 -+ else -+ MOZ_OSS= -+ fi -+fi -+ -+_SAVE_CFLAGS=$CFLAGS -+_SAVE_LIBS=$LIBS -+if test -n "$MOZ_OSS"; then -+ dnl Prefer 4Front implementation -+ AC_MSG_CHECKING([MOZ_OSS_CFLAGS]) -+ if test "$OSSPREFIX" != "yes"; then -+ oss_conf=${OSSPREFIX%/usr}/etc/oss.conf -+ if test -f "$oss_conf"; then -+ . "$oss_conf" -+ else -+ OSSLIBDIR=$OSSPREFIX/lib/oss -+ fi -+ if test -d "$OSSLIBDIR"; then -+ MOZ_OSS_CFLAGS="$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 soundcard.h) -+ -+ if test "$ac_cv_header_sys_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 --without-oss.]) -+ 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="$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 ================================== - -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 { -@@ -260,10 +307,10 @@ alsa_refill_stream(cubeb_stream * stm) - - pthread_mutex_lock(&stm->mutex); - -- avail = snd_pcm_avail_update(stm->pcm); -+ avail = WRAP(snd_pcm_avail_update)(stm->pcm); - if (avail < 0) { -- 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. */ -@@ -286,7 +333,7 @@ alsa_refill_stream(cubeb_stream * stm) - return RUNNING; - } - -- 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); -@@ -312,10 +359,10 @@ alsa_refill_stream(cubeb_stream * stm) - b[i] *= stm->volume; - } - } -- wrote = snd_pcm_writei(stm->pcm, p, got); -+ wrote = WRAP(snd_pcm_writei)(stm->pcm, p, got); - if (wrote < 0) { -- 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); - - latency_us = latency_frames * 1e6 / stm->params.rate; -@@ -855,7 +961,7 @@ alsa_stream_init(cubeb * ctx, cubeb_stre - latency_us = latency_us < min_latency ? min_latency: latency_us; - } - -- r = snd_pcm_set_params(stm->pcm, format, SND_PCM_ACCESS_RW_INTERLEAVED, -+ r = WRAP(snd_pcm_set_params)(stm->pcm, format, SND_PCM_ACCESS_RW_INTERLEAVED, - stm->params.channels, stm->params.rate, 1, - latency_us); - if (r < 0) { -@@ -867,15 +973,15 @@ alsa_stream_init(cubeb * ctx, cubeb_stre - return CUBEB_ERROR_INVALID_FORMAT; - } - -- r = snd_pcm_get_params(stm->pcm, &stm->buffer_size, &period_size); -+ r = WRAP(snd_pcm_get_params)(stm->pcm, &stm->buffer_size, &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; -@@ -938,12 +1044,12 @@ alsa_get_max_channel_count(cubeb * ctx, uint32_t * max_channels) - return CUBEB_ERROR; - } - -- r = snd_pcm_hw_params_any(stm->pcm, hw_params); -+ r = WRAP(snd_pcm_hw_params_any)(stm->pcm, hw_params); - if (r < 0) { - return CUBEB_ERROR; - } - -- r = snd_pcm_hw_params_get_channels_max(hw_params, max_channels); -+ r = WRAP(snd_pcm_hw_params_get_channels_max)(hw_params, max_channels); - if (r < 0) { - return CUBEB_ERROR; - } -@@ -969,34 +1075,34 @@ alsa_get_preferred_sample_rate(cubeb * c - - /* get a pcm, disabling resampling, so we get a rate the - * hardware/dmix/pulse/etc. supports. */ -- r = snd_pcm_open(&pcm, CUBEB_ALSA_PCM_NAME, SND_PCM_STREAM_PLAYBACK, SND_PCM_NO_AUTO_RESAMPLE); -+ r = WRAP(snd_pcm_open)(&pcm, CUBEB_ALSA_PCM_NAME, SND_PCM_STREAM_PLAYBACK, SND_PCM_NO_AUTO_RESAMPLE); - if (r < 0) { - return CUBEB_ERROR; - } - -- r = snd_pcm_hw_params_any(pcm, hw_params); -+ r = WRAP(snd_pcm_hw_params_any)(pcm, hw_params); - if (r < 0) { -- snd_pcm_close(pcm); -+ WRAP(snd_pcm_close)(pcm); - return CUBEB_ERROR; - } - -- r = snd_pcm_hw_params_get_rate(hw_params, rate, &dir); -+ r = WRAP(snd_pcm_hw_params_get_rate)(hw_params, rate, &dir); - if (r >= 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; - -- r = snd_pcm_hw_params_set_rate_near(pcm, hw_params, rate, NULL); -+ r = WRAP(snd_pcm_hw_params_set_rate_near)(pcm, hw_params, rate, NULL); - if (r < 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,442 @@ -+/* -+ * 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> -+#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 <assert.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, NULL, buffer, nframes); -+ } else { -+ pthread_mutex_unlock(&stream->state_mutex); -+ } -+ return got; -+} -+ -+static void apply_volume_int(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 apply_volume_float(float* buffer, unsigned int n, -+ float volume, float panning) -+{ -+ float left = volume; -+ float right = volume; -+ unsigned int i; -+ float pan[2]; -+ if (panning<0) { -+ right *= (1+panning); -+ } else { -+ left *= (1-panning); -+ } -+ pan[0] = left; -+ pan[1] = right; -+ for(i=0; i<n; i++){ -+ buffer[i] = buffer[i]*pan[i%2]; -+ } -+} -+ -+ -+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); -+ apply_volume_float(f_buffer, got*stream->params.channels, -+ stream->volume, stream->panning); -+ for (i=0; i<((unsigned long)got)*stream->params.channels; i++) { -+ /* Clipping is prefered to overflow */ -+ if(f_buffer[i]>=1.0){ -+ f_buffer[i]=1.0; -+ } -+ if(f_buffer[i]<=-1.0){ -+ f_buffer[i]=-1.0; -+ } -+ /* One might think that multipling by 32767.0 is logical but results in clipping */ -+ buffer[i] = f_buffer[i]*32767.0; -+ } -+ } else { -+ got = run_data_callback(stream, buffer, -+ OSS_BUFFER_SIZE/stream->params.channels); -+ apply_volume_int(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_devid input_device, -+ cubeb_stream_params * input_stream_params, -+ cubeb_devid output_device, -+ cubeb_stream_params * output_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; -+ -+ assert(!input_stream_params && "not supported."); -+ if (input_device || output_device) { -+ /* Device selection not yet implemented. */ -+ return CUBEB_ERROR_DEVICE_UNAVAILABLE; -+ } -+ -+ 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 = *output_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, -+ .stream_set_volume = oss_stream_set_volume, -+ .stream_set_panning = oss_stream_set_panning, -+ .stream_get_current_device = NULL, -+ .stream_device_destroy = NULL, -+ .stream_register_device_changed_callback = NULL -+}; -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 media/libcubeb/tests/moz.build media/libcubeb/tests/moz.build -index 1b17c7b..48b56c2 100644 ---- mozilla/media/libcubeb/tests/moz.build -+++ mozilla/media/libcubeb/tests/moz.build -@@ -73,7 +73,6 @@ elif CONFIG['OS_TARGET'] == 'OpenBSD': - 'sndio', - ] - else: -- OS_LIBS += CONFIG['MOZ_ALSA_LIBS'] - OS_LIBS += CONFIG['MOZ_PULSEAUDIO_LIBS'] - - if CONFIG['GNU_CXX']: -diff --git media/libcubeb/update.sh media/libcubeb/update.sh -index a96badd..2f9585e 100755 ---- mozilla/media/libcubeb/update.sh -+++ mozilla/media/libcubeb/update.sh -@@ -16,6 +16,7 @@ cp $1/src/cubeb_audiounit.cpp src - cp $1/src/cubeb_osx_run_loop.h src - cp $1/src/cubeb_jack.cpp src - cp $1/src/cubeb_opensl.c src -+cp $1/src/cubeb_oss.c src - cp $1/src/cubeb_panner.cpp src - cp $1/src/cubeb_panner.h src - cp $1/src/cubeb_pulse.c src -diff --git media/webrtc/signaling/test/common.build media/webrtc/signaling/test/common.build -index 991f03f..3d99eb5 100644 ---- mozilla/media/webrtc/signaling/test/common.build -+++ mozilla/media/webrtc/signaling/test/common.build -@@ -102,8 +102,8 @@ USE_LIBS += ['mozglue'] - OS_LIBS += CONFIG['MOZ_WEBRTC_X11_LIBS'] - OS_LIBS += CONFIG['REALTIME_LIBS'] - --if CONFIG['MOZ_ALSA']: -- OS_LIBS += CONFIG['MOZ_ALSA_LIBS'] -+if CONFIG['MOZ_OSS']: -+ OS_LIBS += CONFIG['MOZ_OSS_LIBS'] - - if CONFIG['MOZ_SYSTEM_JPEG']: - OS_LIBS += CONFIG['MOZ_JPEG_LIBS'] -diff --git toolkit/library/moz.build toolkit/library/moz.build -index e191f13..4fb268a 100644 ---- mozilla/toolkit/library/moz.build -+++ mozilla/toolkit/library/moz.build -@@ -234,8 +234,8 @@ if CONFIG['MOZ_SYSTEM_LIBVPX']: - if not CONFIG['MOZ_TREE_PIXMAN']: - OS_LIBS += CONFIG['MOZ_PIXMAN_LIBS'] - --if CONFIG['MOZ_ALSA']: -- OS_LIBS += CONFIG['MOZ_ALSA_LIBS'] -+if CONFIG['MOZ_OSS']: -+ OS_LIBS += CONFIG['MOZ_OSS_LIBS'] - - if CONFIG['HAVE_CLOCK_MONOTONIC']: - OS_LIBS += CONFIG['REALTIME_LIBS'] |