summaryrefslogtreecommitdiff
path: root/www/firefox/files/patch-media_libcubeb_src_cubeb__oss.c
diff options
context:
space:
mode:
Diffstat (limited to 'www/firefox/files/patch-media_libcubeb_src_cubeb__oss.c')
-rw-r--r--www/firefox/files/patch-media_libcubeb_src_cubeb__oss.c385
1 files changed, 35 insertions, 350 deletions
diff --git a/www/firefox/files/patch-media_libcubeb_src_cubeb__oss.c b/www/firefox/files/patch-media_libcubeb_src_cubeb__oss.c
index 5ba28fea536b..e3c51232a63f 100644
--- a/www/firefox/files/patch-media_libcubeb_src_cubeb__oss.c
+++ b/www/firefox/files/patch-media_libcubeb_src_cubeb__oss.c
@@ -1,378 +1,63 @@
--- media/libcubeb/src/cubeb_oss.c.orig 2021-12-18 20:36:16 UTC
+++ media/libcubeb/src/cubeb_oss.c
-@@ -96,6 +96,8 @@ struct oss_stream {
- oss_devnode_t name;
+@@ -97,6 +97,7 @@ struct oss_stream {
int fd;
void * buf;
-+ unsigned int bufframes;
+ unsigned int bufframes;
+ unsigned int maxframes;
struct stream_info {
int channels;
-@@ -126,9 +128,6 @@ struct cubeb_stream {
- cubeb_data_callback data_cb;
- cubeb_state_callback state_cb;
- uint64_t frames_written /* (m) */;
-- unsigned int nfr; /* Number of frames allocated */
-- unsigned int nfrags;
-- unsigned int bufframes;
- };
-
- static char const *
-@@ -786,40 +785,72 @@ oss_put_play_frames(cubeb_stream * s, unsigned int nfr
- }
-
- static int
--oss_wait_playfd_for_space(cubeb_stream * s)
-+oss_wait_fds_for_space(cubeb_stream * s, long * nfrp)
- {
-- struct pollfd pfd;
-+ audio_buf_info bi;
-+ struct pollfd pfds[2];
-+ long nfr, tnfr;
-+ int i;
-
-- pfd.events = POLLOUT | POLLHUP;
-- pfd.revents = 0;
-- pfd.fd = s->play.fd;
-+ assert(s->play.fd != -1 || s->record.fd != -1);
-+ pfds[0].events = POLLOUT | POLLHUP;
-+ pfds[0].revents = 0;
-+ pfds[0].fd = s->play.fd;
-+ pfds[1].events = POLLIN | POLLHUP;
-+ pfds[1].revents = 0;
-+ pfds[1].fd = s->record.fd;
-
-- if (poll(&pfd, 1, 2000) == -1) {
-- return CUBEB_ERROR;
-- }
-+retry:
-+ nfr = LONG_MAX;
-
-- if (pfd.revents & POLLHUP) {
-+ if (poll(pfds, 2, 1000) == -1) {
- return CUBEB_ERROR;
- }
-- return 0;
--}
-
--static int
--oss_wait_recfd_for_space(cubeb_stream * s)
--{
-- struct pollfd pfd;
--
-- pfd.events = POLLIN | POLLHUP;
-- pfd.revents = 0;
-- pfd.fd = s->record.fd;
--
-- if (poll(&pfd, 1, 2000) == -1) {
-- return CUBEB_ERROR;
-+ for (i = 0; i < 2; i++) {
-+ if (pfds[i].revents & POLLHUP) {
-+ return CUBEB_ERROR;
-+ }
- }
-
-- if (pfd.revents & POLLHUP) {
-- return CUBEB_ERROR;
-+ if (s->play.fd != -1) {
-+ if (ioctl(s->play.fd, SNDCTL_DSP_GETOSPACE, &bi) == -1) {
-+ return CUBEB_STATE_ERROR;
-+ }
-+ tnfr = bi.bytes / s->play.frame_size;
-+ if (tnfr <= 0) {
-+ /* too little space - stop polling record, if any */
-+ pfds[0].fd = s->play.fd;
-+ pfds[1].fd = -1;
-+ goto retry;
+@@ -822,9 +823,9 @@ retry:
+ pfds[0].fd = s->play.fd;
+ pfds[1].fd = -1;
+ goto retry;
+- } else if (tnfr > (long)s->play.bufframes) {
+ } else if (tnfr > (long)s->play.maxframes) {
-+ /* too many frames available - limit */
+ /* too many frames available - limit */
+- tnfr = (long)s->play.bufframes;
+ tnfr = (long)s->play.maxframes;
-+ }
-+ if (nfr > tnfr) {
-+ nfr = tnfr;
-+ }
- }
-+ if (s->record.fd != -1) {
-+ if (ioctl(s->record.fd, SNDCTL_DSP_GETISPACE, &bi) == -1) {
-+ return CUBEB_STATE_ERROR;
-+ }
-+ tnfr = bi.bytes / s->record.frame_size;
-+ if (tnfr <= 0) {
-+ /* too little space - stop polling playback, if any */
-+ pfds[0].fd = -1;
-+ pfds[1].fd = s->record.fd;
-+ goto retry;
+ }
+ if (nfr > tnfr) {
+ nfr = tnfr;
+@@ -840,9 +841,9 @@ retry:
+ pfds[0].fd = -1;
+ pfds[1].fd = s->record.fd;
+ goto retry;
+- } else if (tnfr > (long)s->record.bufframes) {
+ } else if (tnfr > (long)s->record.maxframes) {
-+ /* too many frames available - limit */
+ /* too many frames available - limit */
+- tnfr = (long)s->record.bufframes;
+ tnfr = (long)s->record.maxframes;
-+ }
-+ if (nfr > tnfr) {
-+ nfr = tnfr;
-+ }
-+ }
-+
-+ *nfrp = nfr;
- return 0;
- }
-
-@@ -840,7 +871,7 @@ oss_audio_loop(cubeb_stream * s, cubeb_state * new_sta
- }
-
- trig |= PCM_ENABLE_INPUT;
-- memset(s->record.buf, 0, s->bufframes * s->record.frame_size);
-+ memset(s->record.buf, 0, s->record.bufframes * s->record.frame_size);
-
- if (ioctl(s->record.fd, SNDCTL_DSP_SETTRIGGER, &trig) == -1) {
- LOG("Error %d occured when setting trigger on record fd", errno);
-@@ -877,6 +908,7 @@ oss_audio_loop(cubeb_stream * s, cubeb_state * new_sta
- oss_linear32_to_float(s->record.buf, s->record.info.channels * nfr);
- }
- }
-+
- got = s->data_cb(s, s->user_ptr, s->record.buf, s->play.buf, nfr);
- if (got == CUBEB_ERROR) {
- state = CUBEB_STATE_ERROR;
-@@ -920,45 +952,10 @@ oss_audio_loop(cubeb_stream * s, cubeb_state * new_sta
- }
}
-
-- nfr = s->bufframes;
--
-- if (record_on) {
-- long mfr;
--
-- if (oss_wait_recfd_for_space(s) != 0) {
-- state = CUBEB_STATE_ERROR;
-- goto breakdown;
-- }
--
-- audio_buf_info bi;
-- if (ioctl(s->record.fd, SNDCTL_DSP_GETISPACE, &bi) == -1) {
-- state = CUBEB_STATE_ERROR;
-- goto breakdown;
-- }
--
-- mfr = (bi.fragsize * bi.fragments) / s->record.frame_size;
-- if (nfr > mfr)
-- nfr = mfr;
-+ if (oss_wait_fds_for_space(s, &nfr) != 0) {
-+ state = CUBEB_STATE_ERROR;
-+ goto breakdown;
- }
--
-- if (play_on) {
-- long mfr;
--
-- if (oss_wait_playfd_for_space(s) != 0) {
-- state = CUBEB_STATE_ERROR;
-- goto breakdown;
-- }
--
-- audio_buf_info bi;
-- if (ioctl(s->play.fd, SNDCTL_DSP_GETOSPACE, &bi) == -1) {
-- state = CUBEB_STATE_ERROR;
-- goto breakdown;
-- }
--
-- mfr = (bi.fragsize * bi.fragments) / s->play.frame_size;
-- if (nfr > mfr)
-- nfr = mfr;
-- }
- }
-
- return 1;
-@@ -1015,9 +1012,10 @@ static inline int
- oss_calc_frag_shift(unsigned int frames, unsigned int frame_size)
- {
- int n = 4;
-- int blksize = (frames * frame_size + OSS_NFRAGS - 1) / OSS_NFRAGS;
-- while ((1 << n) < blksize)
-+ int blksize = frames * frame_size;
-+ while ((1 << n) < blksize) {
- n++;
-+ }
- return n;
- }
-
-@@ -1037,7 +1035,6 @@ oss_stream_init(cubeb * context, cubeb_stream ** strea
- cubeb_state_callback state_callback, void * user_ptr)
- {
- int ret = CUBEB_OK;
-- unsigned int playnfr = 0, recnfr = 0;
- cubeb_stream * s = NULL;
- const char * defdsp;
-
-@@ -1051,7 +1048,6 @@ oss_stream_init(cubeb * context, cubeb_stream ** strea
- }
- s->state = CUBEB_STATE_STOPPED;
- s->record.fd = s->play.fd = -1;
-- s->nfr = latency_frames;
- if (input_device != NULL) {
- strlcpy(s->record.name, input_device, sizeof(s->record.name));
- } else {
-@@ -1064,6 +1060,8 @@ oss_stream_init(cubeb * context, cubeb_stream ** strea
- }
- if (input_stream_params != NULL) {
- unsigned int nb_channels;
-+ uint32_t minframes;
-+
- if (input_stream_params->prefs & CUBEB_STREAM_PREF_LOOPBACK) {
- LOG("Loopback not supported");
- ret = CUBEB_ERROR_NOT_SUPPORTED;
-@@ -1077,13 +1075,11 @@ oss_stream_init(cubeb * context, cubeb_stream ** strea
- ret = CUBEB_ERROR_INVALID_PARAMETER;
- goto error;
- }
-- if (s->record.fd == -1) {
-- if ((s->record.fd = open(s->record.name, O_RDONLY)) == -1) {
-- LOG("Audio device \"%s\" could not be opened as read-only",
-- s->record.name);
-- ret = CUBEB_ERROR_DEVICE_UNAVAILABLE;
-- goto error;
-- }
-+ if ((s->record.fd = open(s->record.name, O_RDONLY)) == -1) {
-+ LOG("Audio device \"%s\" could not be opened as read-only",
-+ s->record.name);
-+ ret = CUBEB_ERROR_DEVICE_UNAVAILABLE;
-+ goto error;
- }
- if ((ret = oss_copy_params(s->record.fd, s, input_stream_params,
- &s->record.info)) != CUBEB_OK) {
-@@ -1094,11 +1090,17 @@ oss_stream_init(cubeb * context, cubeb_stream ** strea
- (input_stream_params->format == CUBEB_SAMPLE_FLOAT32NE);
- s->record.frame_size =
- s->record.info.channels * (s->record.info.precision / 8);
-- recnfr = (1 << oss_calc_frag_shift(s->nfr, s->record.frame_size)) /
-- s->record.frame_size;
-+ s->record.bufframes = latency_frames;
-+
-+ oss_get_min_latency(context, *input_stream_params, &minframes);
-+ if (s->record.bufframes < minframes) {
-+ s->record.bufframes = minframes;
-+ }
- }
- if (output_stream_params != NULL) {
- unsigned int nb_channels;
-+ uint32_t minframes;
-+
- if (output_stream_params->prefs & CUBEB_STREAM_PREF_LOOPBACK) {
- LOG("Loopback not supported");
- ret = CUBEB_ERROR_NOT_SUPPORTED;
-@@ -1113,13 +1115,11 @@ oss_stream_init(cubeb * context, cubeb_stream ** strea
- ret = CUBEB_ERROR_INVALID_PARAMETER;
- goto error;
- }
-- if (s->play.fd == -1) {
-- if ((s->play.fd = open(s->play.name, O_WRONLY)) == -1) {
-- LOG("Audio device \"%s\" could not be opened as write-only",
-- s->play.name);
-- ret = CUBEB_ERROR_DEVICE_UNAVAILABLE;
-- goto error;
-- }
-+ if ((s->play.fd = open(s->play.name, O_WRONLY)) == -1) {
-+ LOG("Audio device \"%s\" could not be opened as write-only",
-+ s->play.name);
-+ ret = CUBEB_ERROR_DEVICE_UNAVAILABLE;
-+ goto error;
- }
- if ((ret = oss_copy_params(s->play.fd, s, output_stream_params,
- &s->play.info)) != CUBEB_OK) {
-@@ -1128,19 +1128,16 @@ oss_stream_init(cubeb * context, cubeb_stream ** strea
- }
- s->play.floating = (output_stream_params->format == CUBEB_SAMPLE_FLOAT32NE);
- s->play.frame_size = s->play.info.channels * (s->play.info.precision / 8);
-- playnfr = (1 << oss_calc_frag_shift(s->nfr, s->play.frame_size)) /
-- s->play.frame_size;
-+ s->play.bufframes = latency_frames;
-+
-+ oss_get_min_latency(context, *output_stream_params, &minframes);
-+ if (s->play.bufframes < minframes) {
-+ s->play.bufframes = minframes;
-+ }
- }
-- /*
-- * Use the largest nframes among playing and recording streams to set OSS
-- * buffer size. After that, use the smallest allocated nframes among both
-- * direction to allocate our temporary buffers.
-- */
-- s->nfr = (playnfr > recnfr) ? playnfr : recnfr;
-- s->nfrags = OSS_NFRAGS;
- if (s->play.fd != -1) {
-- int frag =
-- oss_get_frag_params(oss_calc_frag_shift(s->nfr, s->play.frame_size));
-+ int frag = oss_get_frag_params(
-+ oss_calc_frag_shift(s->play.bufframes, s->play.frame_size));
- if (ioctl(s->play.fd, SNDCTL_DSP_SETFRAGMENT, &frag))
- LOG("Failed to set play fd with SNDCTL_DSP_SETFRAGMENT. frag: 0x%x",
- frag);
-@@ -1148,13 +1145,28 @@ oss_stream_init(cubeb * context, cubeb_stream ** strea
- if (ioctl(s->play.fd, SNDCTL_DSP_GETOSPACE, &bi))
- LOG("Failed to get play fd's buffer info.");
+ if (nfr > tnfr) {
+ nfr = tnfr;
+@@ -1146,8 +1147,19 @@ oss_stream_init(cubeb * context, cubeb_stream ** stream,
else {
-- if (bi.fragsize / s->play.frame_size < s->nfr)
-- s->nfr = bi.fragsize / s->play.frame_size;
-+ s->play.bufframes = (bi.fragsize * bi.fragstotal) / s->play.frame_size;
+ s->play.bufframes = (bi.fragsize * bi.fragstotal) / s->play.frame_size;
}
+ int lw;
-+
+
+- int lw = s->play.frame_size;
+ /*
+ * Force 32 ms service intervals at most, or when recording is
+ * active, use the recording service intervals as a reference.
+ */
+ s->play.maxframes = (32 * output_stream_params->rate) / 1000;
+ if (s->record.fd != -1 || s->play.maxframes >= s->play.bufframes) {
-+ lw = s->play.frame_size; /* Feed data when possible. */
++ lw = s->play.frame_size; /* Feed data when possible. */
+ s->play.maxframes = s->play.bufframes;
+ } else {
+ lw = (s->play.bufframes - s->play.maxframes) * s->play.frame_size;
+ }
-+ if (ioctl(s->play.fd, SNDCTL_DSP_LOW_WATER, &lw))
-+ LOG("Audio device \"%s\" (play) could not set trigger threshold",
-+ s->play.name);
- }
- if (s->record.fd != -1) {
-- int frag =
-- oss_get_frag_params(oss_calc_frag_shift(s->nfr, s->record.frame_size));
-+ int frag = oss_get_frag_params(
-+ oss_calc_frag_shift(s->record.bufframes, s->record.frame_size));
- if (ioctl(s->record.fd, SNDCTL_DSP_SETFRAGMENT, &frag))
- LOG("Failed to set record fd with SNDCTL_DSP_SETFRAGMENT. frag: 0x%x",
- frag);
-@@ -1162,11 +1174,16 @@ oss_stream_init(cubeb * context, cubeb_stream ** strea
- if (ioctl(s->record.fd, SNDCTL_DSP_GETISPACE, &bi))
- LOG("Failed to get record fd's buffer info.");
- else {
-- if (bi.fragsize / s->record.frame_size < s->nfr)
-- s->nfr = bi.fragsize / s->record.frame_size;
-+ s->record.bufframes =
-+ (bi.fragsize * bi.fragstotal) / s->record.frame_size;
+ if (ioctl(s->play.fd, SNDCTL_DSP_LOW_WATER, &lw))
+ LOG("Audio device \"%s\" (play) could not set trigger threshold",
+ s->play.name);
+@@ -1166,6 +1178,7 @@ oss_stream_init(cubeb * context, cubeb_stream ** stream,
+ (bi.fragsize * bi.fragstotal) / s->record.frame_size;
}
-+
-+ s->record.maxframes = s->record.bufframes;
-+ int lw = s->record.frame_size;
-+ if (ioctl(s->record.fd, SNDCTL_DSP_LOW_WATER, &lw))
-+ LOG("Audio device \"%s\" (record) could not set trigger threshold",
-+ s->record.name);
- }
-- s->bufframes = s->nfr * s->nfrags;
- s->context = context;
- s->volume = 1.0;
- s->state_cb = state_callback;
-@@ -1188,13 +1205,14 @@ oss_stream_init(cubeb * context, cubeb_stream ** strea
- s->doorbell = false;
- if (s->play.fd != -1) {
-- if ((s->play.buf = calloc(s->bufframes, s->play.frame_size)) == NULL) {
-+ if ((s->play.buf = calloc(s->play.bufframes, s->play.frame_size)) == NULL) {
- ret = CUBEB_ERROR;
- goto error;
- }
- }
- if (s->record.fd != -1) {
-- if ((s->record.buf = calloc(s->bufframes, s->record.frame_size)) == NULL) {
-+ if ((s->record.buf = calloc(s->record.bufframes, s->record.frame_size)) ==
-+ NULL) {
- ret = CUBEB_ERROR;
- goto error;
- }
++ s->record.maxframes = s->record.bufframes;
+ int lw = s->record.frame_size;
+ if (ioctl(s->record.fd, SNDCTL_DSP_LOW_WATER, &lw))
+ LOG("Audio device \"%s\" (record) could not set trigger threshold",