You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
169 lines
4.8 KiB
169 lines
4.8 KiB
/*
|
|
The mediastreamer library aims at providing modular media processing and I/O
|
|
for linphone, but also for any telephony application.
|
|
Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Lesser General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 2.1 of the License, or (at your option) any later version.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
License along with this library; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
#include <errno.h>
|
|
#include <string.h>
|
|
#include "msutils.h"
|
|
#include "msfifo.h"
|
|
|
|
MSFifo * ms_fifo_new(MSBuffer *buf, gint r_gran, gint w_gran, gint r_offset, gint w_offset)
|
|
{
|
|
MSFifo *fifo;
|
|
gint saved_offset=MAX(r_gran+r_offset,w_offset);
|
|
|
|
g_return_val_if_fail(saved_offset<=(buf->size),NULL);
|
|
fifo=g_malloc(sizeof(MSFifo));
|
|
fifo->buffer=buf;
|
|
fifo->r_gran=r_gran;
|
|
fifo->w_gran=w_gran;
|
|
fifo->begin=fifo->wr_ptr=fifo->rd_ptr=buf->buffer+saved_offset;
|
|
fifo->readsize=0;
|
|
fifo->size=fifo->writesize=buf->size-saved_offset;
|
|
fifo->saved_offset= saved_offset;
|
|
fifo->r_end=fifo->w_end=buf->buffer+buf->size;
|
|
fifo->pre_end=fifo->w_end-saved_offset;
|
|
buf->ref_count++;
|
|
fifo->prev_data=NULL;
|
|
fifo->next_data=NULL;
|
|
ms_trace("fifo base=%x, begin=%x, end=%x, saved_offset=%i, size=%i"
|
|
,fifo->buffer->buffer,fifo->begin,fifo->w_end,fifo->saved_offset,fifo->size);
|
|
return(fifo);
|
|
}
|
|
|
|
MSFifo * ms_fifo_new_with_buffer(gint r_gran, gint w_gran, gint r_offset, gint w_offset,
|
|
gint min_fifo_size)
|
|
{
|
|
MSFifo *fifo;
|
|
MSBuffer *buf;
|
|
gint saved_offset=MAX(r_gran+r_offset,w_offset);
|
|
gint fifo_size;
|
|
gint tmp;
|
|
if (min_fifo_size==0) min_fifo_size=w_gran;
|
|
|
|
/* we must allocate a fifo with a size multiple of min_fifo_size,
|
|
with a saved_offset */
|
|
if (min_fifo_size>MS_BUFFER_LARGE)
|
|
fifo_size=(min_fifo_size) + saved_offset;
|
|
else fifo_size=(6*min_fifo_size) + saved_offset;
|
|
buf=ms_buffer_new(fifo_size);
|
|
fifo=ms_fifo_new(buf,r_gran,w_gran,r_offset,w_offset);
|
|
ms_trace("fifo_size=%i",fifo_size);
|
|
return(fifo);
|
|
}
|
|
|
|
void ms_fifo_destroy( MSFifo *fifo)
|
|
{
|
|
g_free(fifo);
|
|
}
|
|
|
|
void ms_fifo_destroy_with_buffer(MSFifo *fifo)
|
|
{
|
|
ms_buffer_destroy(fifo->buffer);
|
|
ms_fifo_destroy(fifo);
|
|
}
|
|
|
|
gint ms_fifo_get_read_ptr(MSFifo *fifo, gint bsize, void **ret_ptr)
|
|
{
|
|
gchar *rnext;
|
|
|
|
*ret_ptr=NULL;
|
|
/* //ms_trace("ms_fifo_get_read_ptr: entering.");*/
|
|
g_return_val_if_fail(bsize<=fifo->r_gran,-EINVAL);
|
|
|
|
if (bsize>fifo->readsize)
|
|
{
|
|
ms_trace("Not enough data: bsize=%i, readsize=%i",bsize,fifo->readsize);
|
|
return (-ENODATA);
|
|
}
|
|
|
|
rnext=fifo->rd_ptr+bsize;
|
|
if (rnext<=fifo->r_end){
|
|
|
|
*ret_ptr=fifo->rd_ptr;
|
|
fifo->rd_ptr=rnext;
|
|
}else{
|
|
int unread=fifo->r_end-fifo->rd_ptr;
|
|
*ret_ptr=fifo->begin-unread;
|
|
memcpy(fifo->buffer->buffer,fifo->r_end-fifo->saved_offset,fifo->saved_offset);
|
|
fifo->rd_ptr=(char*)(*ret_ptr) + bsize;
|
|
fifo->r_end=fifo->w_end; /* this is important ! */
|
|
ms_trace("moving read ptr to %x",fifo->rd_ptr);
|
|
|
|
}
|
|
/* update write size*/
|
|
fifo->writesize+=bsize;
|
|
fifo->readsize-=bsize;
|
|
return bsize;
|
|
}
|
|
|
|
|
|
void ms_fifo_update_write_ptr(MSFifo *fifo, gint written){
|
|
gint reserved=fifo->wr_ptr-fifo->prev_wr_ptr;
|
|
gint unwritten;
|
|
g_return_if_fail(reserved>=0);
|
|
unwritten=reserved-written;
|
|
g_return_if_fail(unwritten>=0);
|
|
/* fix readsize and writesize */
|
|
fifo->readsize-=unwritten;
|
|
fifo->writesize+=unwritten;
|
|
fifo->wr_ptr+=written;
|
|
}
|
|
|
|
gint ms_fifo_get_write_ptr(MSFifo *fifo, gint bsize, void **ret_ptr)
|
|
{
|
|
gchar *wnext;
|
|
|
|
*ret_ptr=NULL;
|
|
/* //ms_trace("ms_fifo_get_write_ptr: Entering.");*/
|
|
g_return_val_if_fail(bsize<=fifo->w_gran,-EINVAL);
|
|
if (bsize>fifo->writesize)
|
|
{
|
|
ms_trace("Not enough space: bsize=%i, writesize=%i",bsize,fifo->writesize);
|
|
*ret_ptr=NULL;
|
|
return(-ENODATA);
|
|
}
|
|
wnext=fifo->wr_ptr+bsize;
|
|
if (wnext<=fifo->w_end){
|
|
*ret_ptr=fifo->wr_ptr;
|
|
fifo->wr_ptr=wnext;
|
|
}else{
|
|
*ret_ptr=fifo->begin;
|
|
fifo->r_end=fifo->wr_ptr;
|
|
fifo->wr_ptr=fifo->begin+bsize;
|
|
ms_trace("moving write ptr to %x",fifo->wr_ptr);
|
|
}
|
|
fifo->prev_wr_ptr=*ret_ptr;
|
|
/* update readsize*/
|
|
fifo->readsize+=bsize;
|
|
fifo->writesize-=bsize;
|
|
/* //ms_trace("ms_fifo_get_write_ptr: readsize=%i, writesize=%i",fifo->readsize,fifo->writesize);*/
|
|
return bsize;
|
|
}
|
|
|
|
gint ms_fifo_get_rw_ptr(MSFifo *f1,void **p1,gint minsize1,
|
|
MSFifo *f2,void **p2,gint minsize2)
|
|
{
|
|
gint rbsize,wbsize;
|
|
|
|
rbsize=MIN(f1->readsize,(f1->pre_end-f1->rd_ptr));
|
|
wbsize=MIN(f2->writesize,(f2->w_end-f2->wr_ptr));
|
|
return 0;
|
|
}
|