summaryrefslogtreecommitdiff
path: root/www/firefox68/patches/patch-media_libcubeb_src_cubeb__oss.c
diff options
context:
space:
mode:
Diffstat (limited to 'www/firefox68/patches/patch-media_libcubeb_src_cubeb__oss.c')
-rw-r--r--www/firefox68/patches/patch-media_libcubeb_src_cubeb__oss.c461
1 files changed, 0 insertions, 461 deletions
diff --git a/www/firefox68/patches/patch-media_libcubeb_src_cubeb__oss.c b/www/firefox68/patches/patch-media_libcubeb_src_cubeb__oss.c
deleted file mode 100644
index b2ac1757bfa..00000000000
--- a/www/firefox68/patches/patch-media_libcubeb_src_cubeb__oss.c
+++ /dev/null
@@ -1,461 +0,0 @@
-$NetBSD: patch-media_libcubeb_src_cubeb__oss.c,v 1.1 2019/09/21 07:31:44 ryoon Exp $
-
-* Restore OSS audio support code
-* fix wrong latency values in stream_init (PR pkg/54206)
-
---- media/libcubeb/src/cubeb_oss.c.orig 2019-05-24 13:05:19.117086384 +0000
-+++ 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_frames)
-+{
-+ 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_frames*stream->params.channels*sizeof(uint16_t);
-+ 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_frames,
-+ 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_frames);
-+
-+ 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
-+};