git: 98a1992fb1f4 - main - net/mediastreamer: Improve OSS backend code.
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 08 Mar 2022 09:45:46 UTC
The branch main has been updated by hselasky:
URL: https://cgit.FreeBSD.org/ports/commit/?id=98a1992fb1f4753315449c2ab721404cc205633b
commit 98a1992fb1f4753315449c2ab721404cc205633b
Author: Hans Petter Selasky <hselasky@FreeBSD.org>
AuthorDate: 2022-03-08 09:28:40 +0000
Commit: Hans Petter Selasky <hselasky@FreeBSD.org>
CommitDate: 2022-03-08 09:44:56 +0000
net/mediastreamer: Improve OSS backend code.
- Reduced jitter and latency.
- Tested with Linphone.
Approved by: pi (implicit)
---
net/mediastreamer/Makefile | 2 +-
.../files/patch-src__audiofilters__oss.c | 244 +++++++++++++++++++--
2 files changed, 222 insertions(+), 24 deletions(-)
diff --git a/net/mediastreamer/Makefile b/net/mediastreamer/Makefile
index 98affa033a07..e67624a99cdd 100644
--- a/net/mediastreamer/Makefile
+++ b/net/mediastreamer/Makefile
@@ -2,7 +2,7 @@
PORTNAME= mediastreamer
PORTVERSION= 2.16.1
-PORTREVISION= 6
+PORTREVISION= 7
CATEGORIES= net
MASTER_SITES= https://www.linphone.org/releases/sources/mediastreamer/
diff --git a/net/mediastreamer/files/patch-src__audiofilters__oss.c b/net/mediastreamer/files/patch-src__audiofilters__oss.c
index be2241878ab5..23abb375018e 100644
--- a/net/mediastreamer/files/patch-src__audiofilters__oss.c
+++ b/net/mediastreamer/files/patch-src__audiofilters__oss.c
@@ -1,23 +1,76 @@
---- src/audiofilters/oss.c.orig 2015-01-30 09:36:13 UTC
+--- src/audiofilters/oss.c.orig 2017-04-06 09:27:56 UTC
+++ src/audiofilters/oss.c
-@@ -41,7 +41,7 @@ static int configure_fd(int fd, int bits
+@@ -37,95 +37,65 @@ MSFilter *ms_oss_read_new(MSSndCard *card);
+ MSFilter *ms_oss_write_new(MSSndCard *card);
+
+
+-static int configure_fd(int fd, int bits,int stereo, int rate, int *minsz)
++static int configure_fd(int fd, int bits,int stereo, int rate, int *minsz, int *mindly)
{
- int p=0,cond=0;
- int i=0;
+- int p=0,cond=0;
+- int i=0;
- int min_size=0,blocksize=512;
++ int p=0;
+ int min_size=0, blocksize=0;
++ int smp_size = bits / 8;
int err;
- //g_message("opening sound device");
-@@ -78,54 +78,17 @@ static int configure_fd(int fd, int bits
+- //g_message("opening sound device");
+- /* unset nonblocking mode */
+- /* We wanted non blocking open but now put it back to normal ; thanks Xine !*/
+- fcntl(fd, F_SETFL, fcntl(fd, F_GETFL)&~O_NONBLOCK);
++ err = 1;
++ ioctl(fd, FIONBIO, &err);
+
+- /* reset is maybe not needed but takes time*/
+- /*ioctl(fd, SNDCTL_DSP_RESET, 0); */
++ switch (bits) {
++ case 16:
++ p=AFMT_S16_NE;
++ break;
++ default:
++ close(fd);
++ return (-1);
++ }
+
+- p=AFMT_S16_NE;
+-
+ err=ioctl(fd,SNDCTL_DSP_SETFMT,&p);
+ if (err<0){
+ ms_warning("oss_open: can't set sample format:%s.",strerror(errno));
++ close(fd);
++ return (-1);
+ }
+
+-
+- p = bits; /* 16 bits */
+- err=ioctl(fd, SNDCTL_DSP_SAMPLESIZE, &p);
+- if (err<0){
+- ms_warning("oss_open: can't set sample size to %i:%s.",bits,strerror(errno));
+- }
+-
+ p = rate; /* rate in khz*/
+ err=ioctl(fd, SNDCTL_DSP_SPEED, &p);
+- if (err<0){
++ if (err<0 || p != rate){
+ ms_warning("oss_open: can't set sample rate to %i:%s.",rate,strerror(errno));
++ close(fd);
++ return (-1);
+ }
+
+ p = stereo; /* stereo or not */
+ err=ioctl(fd, SNDCTL_DSP_STEREO, &p);
+ if (err<0){
ms_warning("oss_open: can't set mono/stereo mode:%s.",strerror(errno));
++ close(fd);
++ return (-1);
}
- if (rate==16000) blocksize=4096; /* oss emulation is not very good at 16khz */
- else blocksize=blocksize*(rate/8000);
-
- ioctl(fd, SNDCTL_DSP_GETBLKSIZE, &min_size);
-
+- ioctl(fd, SNDCTL_DSP_GETBLKSIZE, &min_size);
+-
- /**
- * first try SNDCTL_DSP_SETFRAGMENT
- */
@@ -49,20 +102,25 @@
- min_size=1 << (frag&0x0FFFF);
- ms_message("Max fragment=%x, size selector=%x block size=%i",frag>>16,frag&0x0FFFF,min_size);
- }
-- }
--
++ err=ioctl(fd, SNDCTL_DSP_GETBLKSIZE, &min_size);
++ if (err<0){
++ close(fd);
++ return (-1);
+ }
+
- if (min_size>blocksize)
- {
- ms_warning("dsp block size set to %i.",min_size);
- }else{
- /* no need to access the card with less latency than needed*/
- min_size=blocksize;
-- }
-+ /* compute 20ms buffer */
-+ blocksize = (rate / 50) * 2;
-+ if (stereo)
++ /* compute a 20ms buffer by default */
++ blocksize = (rate / 50) * smp_size;
++ if (stereo) {
+ blocksize *= 2;
-+ if (min_size > blocksize)
++ smp_size *= 2;
+ }
++ if (blocksize > min_size)
+ blocksize = min_size;
ms_message("/dev/dsp opened: rate=%i,bits=%i,stereo=%i blocksize=%i.",
@@ -71,25 +129,165 @@
/* start recording !!! Alex */
{
-@@ -135,7 +98,7 @@ static int configure_fd(int fd, int bits
+@@ -135,7 +105,8 @@ static int configure_fd(int fd, int bits,int stereo, i
res=ioctl(fd, SNDCTL_DSP_SETTRIGGER, &fl);
if (res<0) ms_warning("OSS_TRIGGER: %s",strerror(errno));
}
- *minsz=min_size;
+ *minsz=blocksize;
++ *mindly = ((uint64_t)1000000 * (uint64_t)blocksize) / (uint64_t)(2 * rate * smp_size);
return fd;
}
-@@ -365,7 +328,11 @@ static void * oss_thread(void *p){
+@@ -156,23 +127,23 @@ typedef struct OssData{
+ bool_t stereo;
+ } OssData;
+
+-static void oss_open(OssData* d, int *minsz){
++static void oss_open(OssData* d, int *minsz, int *mindly){
+ int fd=open(d->pcmdev,O_RDWR|O_NONBLOCK);
+ if (fd>0) {
+- d->pcmfd_read=d->pcmfd_write=configure_fd(fd, d->bits, d->stereo, d->rate, minsz);
++ d->pcmfd_read=d->pcmfd_write=configure_fd(fd, d->bits, d->stereo, d->rate, minsz, mindly);
+ return ;
+ }
+ ms_warning ("Cannot open a single fd in rw mode for [%s] trying to open two",d->pcmdev);
+
+ d->pcmfd_read=open(d->pcmdev,O_RDONLY|O_NONBLOCK);
+ if (d->pcmfd_read > 0) {
+- d->pcmfd_read=configure_fd(d->pcmfd_read, d->bits, d->stereo, d->rate, minsz);
++ d->pcmfd_read=configure_fd(d->pcmfd_read, d->bits, d->stereo, d->rate, minsz, mindly);
+ } else {
+ ms_error("Cannot open fd in ro mode for [%s]",d->pcmdev);
+ }
+ d->pcmfd_write=open(d->pcmdev,O_WRONLY|O_NONBLOCK);
+ if (d->pcmfd_write > 0) {
+- d->pcmfd_write=configure_fd(d->pcmfd_write, d->bits, d->stereo, d->rate, minsz);
++ d->pcmfd_write=configure_fd(d->pcmfd_write, d->bits, d->stereo, d->rate, minsz, mindly);
+ } else {
+ ms_error("Cannot open fd in wr mode for [%s]",d->pcmdev);
+ }
+@@ -327,61 +298,78 @@ static void * oss_thread(void *p){
+ MSSndCard *card=(MSSndCard*)p;
+ OssData *d=(OssData*)card->data;
+ int bsize=0;
+- uint8_t *rtmpbuff=NULL;
+- uint8_t *wtmpbuff=NULL;
++ int mindly=1000;
++ uint8_t *tmpbuff;
+ int err;
+- mblk_t *rm=NULL;
+- bool_t did_read=FALSE;
+
+- oss_open(d,&bsize);
+- if (d->pcmfd_read>=0){
+- rtmpbuff=(uint8_t*)alloca(bsize);
+- }
+- if (d->pcmfd_write>=0){
+- wtmpbuff=(uint8_t*)alloca(bsize);
+- }
++ oss_open(d,&bsize,&mindly);
++
++ tmpbuff=(uint8_t*)alloca(bsize);
++
+ while(d->read_started || d->write_started){
+- did_read=FALSE;
+- if (d->pcmfd_read>=0){
++ while (d->pcmfd_read>=0){
+ if (d->read_started){
+- if (rm==NULL) rm=allocb(bsize,0);
+- err=read(d->pcmfd_read,rm->b_wptr,bsize);
++ err=read(d->pcmfd_read,tmpbuff,bsize);
+ if (err<0){
+- ms_warning("Fail to read %i bytes from soundcard: %s",
+- bsize,strerror(errno));
+- }else{
+- did_read=TRUE;
++ if (errno != EWOULDBLOCK) {
++ ms_warning("Fail to read %i bytes from soundcard: %s",
++ bsize,strerror(errno));
++ }
++ break;
++ }else if (err>0) {
++ mblk_t *rm=allocb(err,0);
++ memcpy(rm->b_wptr,tmpbuff,err);
+ rm->b_wptr+=err;
+ ms_mutex_lock(&d->mutex);
+ putq(&d->rq,rm);
+ ms_mutex_unlock(&d->mutex);
+- rm=NULL;
++ } else {
++ break;
+ }
+ }else {
+ /* case where we have no reader filtern the read is performed for synchronisation */
+- int sz = read(d->pcmfd_read,rtmpbuff,bsize);
+- if( sz==-1) ms_warning("sound device read error %s ",strerror(errno));
+- else did_read=TRUE;
++ int sz = read(d->pcmfd_read,tmpbuff,bsize);
++ if(sz<0){
++ ms_warning("sound device read error %s ",strerror(errno));
++ break;
++ }
}
}
- if (d->pcmfd_write>=0){
+- if (d->pcmfd_write>=0){
- if (d->write_started){
-+ int bufsize = 0;
-+ ioctl(d->pcmfd_write, SNDCTL_DSP_GETODELAY, &bufsize);
-+ if (bufsize >= bsize){
+- err=ms_bufferizer_read(d->bufferizer,wtmpbuff,bsize);
++
++ while (d->pcmfd_write>=0){
++ struct audio_buf_info ai;
++ int bufsize;
++ if (ioctl(d->pcmfd_write, SNDCTL_DSP_GETOSPACE, &ai) < 0)
++ break;
++ bufsize = ai.fragstotal * ai.fragsize - ai.bytes;
++ if (bufsize >= (2 * bsize)){
+ /* wait for buffer to empty */
++ break;
+ }else if (d->write_started){
- err=ms_bufferizer_read(d->bufferizer,wtmpbuff,bsize);
++ ms_mutex_lock(&d->mutex);
++ err=ms_bufferizer_read(d->bufferizer,tmpbuff,bsize);
++ ms_mutex_unlock(&d->mutex);
if (err==bsize){
- err=write(d->pcmfd_write,wtmpbuff,bsize);
+- err=write(d->pcmfd_write,wtmpbuff,bsize);
++ err=write(d->pcmfd_write,tmpbuff,bsize);
+ if (err<0){
+ ms_warning("Fail to write %i bytes from soundcard: %s",
+- bsize,strerror(errno));
++ bsize,strerror(errno));
++ break;
+ }
++ } else {
++ break;
+ }
+ }else {
+ int sz;
+- memset(wtmpbuff,0,bsize);
+- sz = write(d->pcmfd_write,wtmpbuff,bsize);
+- if( sz!=bsize) ms_warning("sound device write returned %i !",sz);
++ memset(tmpbuff,0,bsize);
++ sz = write(d->pcmfd_write,tmpbuff,bsize);
++ if(sz!=bsize) {
++ ms_warning("sound device write returned %i !",sz);
++ break;
++ }
+ }
+ }
+- if (!did_read) usleep(20000); /*avoid 100%cpu loop for nothing*/
++ usleep(mindly);
+ }
+ if (d->pcmfd_read==d->pcmfd_write && d->pcmfd_read>=0 ) {
+ close(d->pcmfd_read);
+@@ -509,10 +497,10 @@ static int set_nchannels(MSFilter *f, void *arg){
+ }
+
+ static MSFilterMethod oss_methods[]={
+- { MS_FILTER_SET_SAMPLE_RATE , set_rate },
++ { MS_FILTER_SET_SAMPLE_RATE , set_rate },
+ { MS_FILTER_GET_SAMPLE_RATE , get_rate },
+ { MS_FILTER_SET_NCHANNELS , set_nchannels },
+- { 0 , NULL }
++ { 0 , NULL }
+ };
+
+ MSFilterDesc oss_read_desc={